123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- /******************************************************************************
- *
- * Author: Xilinx, Inc.
- *
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- *
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
- * XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
- * FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
- * ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
- * WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
- * CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- * Xilinx hardware products are not intended for use in life support
- * appliances, devices, or systems. Use in such applications is
- * expressly prohibited.
- *
- *
- * (c) Copyright 2002-2004 Xilinx Inc.
- * All rights reserved.
- *
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ******************************************************************************/
- /*****************************************************************************/
- /*
- *
- * @file xpacket_fifo_v1_00_b.c
- *
- * Contains functions for the XPacketFifoV100b component. See xpacket_fifo_v1_00_b.h
- * for more information about the component.
- *
- * <pre>
- * MODIFICATION HISTORY:
- *
- * Ver Who Date Changes
- * ----- ---- -------- -----------------------------------------------
- * 1.00b rpm 03/26/02 First release
- * </pre>
- *
- *****************************************************************************/
- /***************************** Include Files *********************************/
- #include "xbasic_types.h"
- #include "xio.h"
- #include "xstatus.h"
- #include "xpacket_fifo_v1_00_b.h"
- /************************** Constant Definitions *****************************/
- /* width of a FIFO word */
- #define XPF_FIFO_WIDTH_BYTE_COUNT 4UL
- /**************************** Type Definitions *******************************/
- /***************** Macros (Inline Functions) Definitions *********************/
- /************************* Variable Definitions ******************************/
- /************************** Function Prototypes ******************************/
- /*****************************************************************************/
- /*
- *
- * This function initializes a packet FIFO. Initialization resets the
- * FIFO such that it's empty and ready to use.
- *
- * @param InstancePtr contains a pointer to the FIFO to operate on.
- * @param RegBaseAddress contains the base address of the registers for
- * the packet FIFO.
- * @param DataBaseAddress contains the base address of the data for
- * the packet FIFO.
- *
- * @return
- *
- * Always returns XST_SUCCESS.
- *
- * @note
- *
- * None.
- *
- ******************************************************************************/
- XStatus
- XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr,
- u32 RegBaseAddress, u32 DataBaseAddress)
- {
- /* assert to verify input argument are valid */
- XASSERT_NONVOID(InstancePtr != NULL);
- /* initialize the component variables to the specified state */
- InstancePtr->RegBaseAddress = RegBaseAddress;
- InstancePtr->DataBaseAddress = DataBaseAddress;
- InstancePtr->IsReady = XCOMPONENT_IS_READY;
- /* reset the FIFO such that it's empty and ready to use and indicate the
- * initialization was successful, note that the is ready variable must be
- * set prior to calling the reset function to prevent an assert
- */
- XPF_V100B_RESET(InstancePtr);
- return XST_SUCCESS;
- }
- /*****************************************************************************/
- /*
- *
- * This function performs a self-test on the specified packet FIFO. The self
- * test resets the FIFO and reads a register to determine if it is the correct
- * reset value. This test is destructive in that any data in the FIFO will
- * be lost.
- *
- * @param InstancePtr is a pointer to the packet FIFO to be operated on.
- *
- * @param FifoType specifies the type of FIFO, read or write, for the self test.
- * The FIFO type is specified by the values XPF_READ_FIFO_TYPE or
- * XPF_WRITE_FIFO_TYPE.
- *
- * @return
- *
- * XST_SUCCESS is returned if the selftest is successful, or
- * XST_PFIFO_BAD_REG_VALUE indicating that the value readback from the
- * occupancy/vacancy count register after a reset does not match the
- * specified reset value.
- *
- * @note
- *
- * None.
- *
- ******************************************************************************/
- XStatus
- XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType)
- {
- u32 Register;
- /* assert to verify valid input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID((FifoType == XPF_READ_FIFO_TYPE) ||
- (FifoType == XPF_WRITE_FIFO_TYPE));
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* reset the fifo and then check to make sure the occupancy/vacancy
- * register contents are correct for a reset condition
- */
- XPF_V100B_RESET(InstancePtr);
- Register = XIo_In32(InstancePtr->RegBaseAddress +
- XPF_COUNT_STATUS_REG_OFFSET);
- /* check the value of the register to ensure that it's correct for the
- * specified FIFO type since both FIFO types reset to empty, but a bit
- * in the register changes definition based upon FIFO type
- */
- if (FifoType == XPF_READ_FIFO_TYPE) {
- /* check the regiser value for a read FIFO which should be empty */
- if (Register != XPF_EMPTY_FULL_MASK) {
- return XST_PFIFO_BAD_REG_VALUE;
- }
- } else {
- /* check the register value for a write FIFO which should not be full
- * on reset
- */
- if ((Register & XPF_EMPTY_FULL_MASK) != 0) {
- return XST_PFIFO_BAD_REG_VALUE;
- }
- }
- /* the test was successful */
- return XST_SUCCESS;
- }
- /*****************************************************************************/
- /*
- *
- * Read data from a FIFO and puts it into a specified buffer. The packet FIFO is
- * currently 32 bits wide such that an input buffer which is a series of bytes
- * is filled from the FIFO a word at a time. If the requested byte count is not
- * a multiple of 32 bit words, it is necessary for this function to format the
- * remaining 32 bit word from the FIFO into a series of bytes in the buffer.
- * There may be up to 3 extra bytes which must be extracted from the last word
- * of the FIFO and put into the buffer.
- *
- * @param InstancePtr contains a pointer to the FIFO to operate on.
- * @param BufferPtr points to the memory buffer to write the data into. This
- * buffer must be 32 bit aligned or an alignment exception could be
- * generated. Since this buffer is a byte buffer, the data is assumed to
- * be endian independent.
- * @param ByteCount contains the number of bytes to read from the FIFO. This
- * number of bytes must be present in the FIFO or an error will be
- * returned.
- *
- * @return
- *
- * XST_SUCCESS indicates the operation was successful. If the number of
- * bytes specified by the byte count is not present in the FIFO
- * XST_PFIFO_LACK_OF_DATA is returned.
- *
- * If the function was successful, the specified buffer is modified to contain
- * the bytes which were removed from the FIFO.
- *
- * @note
- *
- * Note that the exact number of bytes which are present in the FIFO is
- * not known by this function. It can only check for a number of 32 bit
- * words such that if the byte count specified is incorrect, but is still
- * possible based on the number of words in the FIFO, up to 3 garbage bytes
- * may be present at the end of the buffer.
- * <br><br>
- * This function assumes that if the device consuming data from the FIFO is
- * a byte device, the order of the bytes to be consumed is from the most
- * significant byte to the least significant byte of a 32 bit word removed
- * from the FIFO.
- *
- ******************************************************************************/
- XStatus
- XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr,
- u8 * BufferPtr, u32 ByteCount)
- {
- u32 FifoCount;
- u32 WordCount;
- u32 ExtraByteCount;
- u32 *WordBuffer = (u32 *) BufferPtr;
- /* assert to verify valid input arguments including 32 bit alignment of
- * the buffer pointer
- */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(BufferPtr != NULL);
- XASSERT_NONVOID(((u32) BufferPtr &
- (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
- XASSERT_NONVOID(ByteCount != 0);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* get the count of how many 32 bit words are in the FIFO, if there aren't
- * enought words to satisfy the request, return an error
- */
- FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
- XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
- if ((FifoCount * XPF_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
- return XST_PFIFO_LACK_OF_DATA;
- }
- /* calculate the number of words to read from the FIFO before the word
- * containing the extra bytes, and calculate the number of extra bytes
- * the extra bytes are defined as those at the end of the buffer when
- * the buffer does not end on a 32 bit boundary
- */
- WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
- ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
- /* Read the 32 bit words from the FIFO for all the buffer except the
- * last word which contains the extra bytes, the following code assumes
- * that the buffer is 32 bit aligned, otherwise an alignment exception could
- * be generated
- */
- for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
- WordBuffer[FifoCount] = XIo_In32(InstancePtr->DataBaseAddress);
- }
- /* if there are extra bytes to handle, read the last word from the FIFO
- * and insert the extra bytes into the buffer
- */
- if (ExtraByteCount > 0) {
- u32 LastWord;
- u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
- /* get the last word from the FIFO for the extra bytes */
- LastWord = XIo_In32(InstancePtr->DataBaseAddress);
- /* one extra byte in the last word, put the byte into the next location
- * of the buffer, bytes in a word of the FIFO are ordered from most
- * significant byte to least
- */
- if (ExtraByteCount == 1) {
- ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
- }
- /* two extra bytes in the last word, put each byte into the next two
- * locations of the buffer
- */
- else if (ExtraByteCount == 2) {
- ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
- ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
- }
- /* three extra bytes in the last word, put each byte into the next three
- * locations of the buffer
- */
- else if (ExtraByteCount == 3) {
- ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
- ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
- ExtraBytesBuffer[2] = (u8) (LastWord >> 8);
- }
- }
- return XST_SUCCESS;
- }
- /*****************************************************************************/
- /*
- *
- * Write data into a packet FIFO. The packet FIFO is currently 32 bits wide
- * such that an input buffer which is a series of bytes must be written into the
- * FIFO a word at a time. If the buffer is not a multiple of 32 bit words, it is
- * necessary for this function to format the remaining bytes into a single 32
- * bit word to be inserted into the FIFO. This is necessary to avoid any
- * accesses past the end of the buffer.
- *
- * @param InstancePtr contains a pointer to the FIFO to operate on.
- * @param BufferPtr points to the memory buffer that data is to be read from
- * and written into the FIFO. Since this buffer is a byte buffer, the data
- * is assumed to be endian independent. This buffer must be 32 bit aligned
- * or an alignment exception could be generated.
- * @param ByteCount contains the number of bytes to read from the buffer and to
- * write to the FIFO.
- *
- * @return
- *
- * XST_SUCCESS is returned if the operation succeeded. If there is not enough
- * room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
- * returned.
- *
- * @note
- *
- * This function assumes that if the device inserting data into the FIFO is
- * a byte device, the order of the bytes in each 32 bit word is from the most
- * significant byte to the least significant byte.
- *
- ******************************************************************************/
- XStatus
- XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr,
- u8 * BufferPtr, u32 ByteCount)
- {
- u32 FifoCount;
- u32 WordCount;
- u32 ExtraByteCount;
- u32 *WordBuffer = (u32 *) BufferPtr;
- /* assert to verify valid input arguments including 32 bit alignment of
- * the buffer pointer
- */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(BufferPtr != NULL);
- XASSERT_NONVOID(((u32) BufferPtr &
- (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
- XASSERT_NONVOID(ByteCount != 0);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* get the count of how many words may be inserted into the FIFO */
- FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
- XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
- /* Calculate the number of 32 bit words required to insert the specified
- * number of bytes in the FIFO and determine the number of extra bytes
- * if the buffer length is not a multiple of 32 bit words
- */
- WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
- ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
- /* take into account the extra bytes in the total word count */
- if (ExtraByteCount > 0) {
- WordCount++;
- }
- /* if there's not enough room in the FIFO to hold the specified
- * number of bytes, then indicate an error,
- */
- if (FifoCount < WordCount) {
- return XST_PFIFO_NO_ROOM;
- }
- /* readjust the word count to not take into account the extra bytes */
- if (ExtraByteCount > 0) {
- WordCount--;
- }
- /* Write all the bytes of the buffer which can be written as 32 bit
- * words into the FIFO, waiting to handle the extra bytes seperately
- */
- for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
- XIo_Out32(InstancePtr->DataBaseAddress, WordBuffer[FifoCount]);
- }
- /* if there are extra bytes to handle, extract them from the buffer
- * and create a 32 bit word and write it to the FIFO
- */
- if (ExtraByteCount > 0) {
- u32 LastWord = 0;
- u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
- /* one extra byte in the buffer, put the byte into the last word
- * to be inserted into the FIFO, perform this processing inline rather
- * than in a loop to help performance
- */
- if (ExtraByteCount == 1) {
- LastWord = ExtraBytesBuffer[0] << 24;
- }
- /* two extra bytes in the buffer, put each byte into the last word
- * to be inserted into the FIFO
- */
- else if (ExtraByteCount == 2) {
- LastWord = ExtraBytesBuffer[0] << 24 |
- ExtraBytesBuffer[1] << 16;
- }
- /* three extra bytes in the buffer, put each byte into the last word
- * to be inserted into the FIFO
- */
- else if (ExtraByteCount == 3) {
- LastWord = ExtraBytesBuffer[0] << 24 |
- ExtraBytesBuffer[1] << 16 |
- ExtraBytesBuffer[2] << 8;
- }
- /* write the last 32 bit word to the FIFO and return with no errors */
- XIo_Out32(InstancePtr->DataBaseAddress, LastWord);
- }
- return XST_SUCCESS;
- }
|