xpacket_fifo_v1_00_b.c
来自「适合KS8695X」· C语言 代码 · 共 449 行 · 第 1/2 页
C
449 行
* 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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?