diff --git a/XilinxProcessorIPLib/drivers/llfifo/data/llfifo.mdd b/XilinxProcessorIPLib/drivers/llfifo/data/llfifo.mdd new file mode 100755 index 00000000..63585bbb --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/data/llfifo.mdd @@ -0,0 +1,47 @@ +############################################################################### +# +# Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# Ver Who Date Changes +# -------- ------ -------- -------------------------------------------------- +# 4.0 adk 10/12/13 Removed support for xps_ll_fifo +############################################################################## +OPTION psf_version = 2.1; + +BEGIN driver llfifo + + OPTION supported_peripherals = (axi_fifo_mm_s_v[4-9]_[1-9]); + OPTION driver_state = ACTIVE; + OPTION copyfiles = all; + OPTION VERSION = 5.0; + OPTION NAME = llfifo; + +END driver diff --git a/XilinxProcessorIPLib/drivers/llfifo/data/llfifo.tcl b/XilinxProcessorIPLib/drivers/llfifo/data/llfifo.tcl new file mode 100755 index 00000000..0f4d7929 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/data/llfifo.tcl @@ -0,0 +1,53 @@ +############################################################################### +# +# Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# Modification History +# +# Ver Who Date Changes +# ----- ---- -------- ----------------------------------------------- +# 2.00a sdm 07/26/10 Updated to use the string "Axi_Fifo" in canonical +# definitions for AxiFifo +# 3.00a adk 08/10/13 Added parameters C_AXI4_BASEADDR and C_AXI4_HIGHADDR +# and C_DATA_INTERFACE_TYPE inorder to support AXI4 +# Datainterface. +# 4.0 adk 12/10/13 Updated as per the New Tcl API's +# +############################################################################## + + +proc generate {drv_handle} { + ::hsi::utils::define_include_file $drv_handle "xparameters.h" "XLlFifo" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_AXI4_BASEADDR" "C_AXI4_HIGHADDR" "C_DATA_INTERFACE_TYPE" + + ::hsi::utils::define_canonical_xpars $drv_handle "xparameters.h" "Axi_Fifo" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_AXI4_BASEADDR" "C_AXI4_HIGHADDR" "C_DATA_INTERFACE_TYPE" + + ::hsi::utils::define_config_file $drv_handle "xllfifo_g.c" "XLlFifo" "DEVICE_ID" "C_BASEADDR" "C_AXI4_BASEADDR" "C_DATA_INTERFACE_TYPE" +} \ No newline at end of file diff --git a/XilinxProcessorIPLib/drivers/llfifo/examples/index.html b/XilinxProcessorIPLib/drivers/llfifo/examples/index.html new file mode 100755 index 00000000..8bc609c4 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/examples/index.html @@ -0,0 +1,18 @@ + + + + + +Driver example applications + + + +

Example Applications for the driver llfifo_v4_0

+
+ +

Copyright � 1995-2014 Xilinx, Inc. All rights reserved.

+ + \ No newline at end of file diff --git a/XilinxProcessorIPLib/drivers/llfifo/examples/xllfifo_interrupt_example.c b/XilinxProcessorIPLib/drivers/llfifo/examples/xllfifo_interrupt_example.c new file mode 100644 index 00000000..85f00caa --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/examples/xllfifo_interrupt_example.c @@ -0,0 +1,619 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** + * + * @file xllfifo_interrupt_example.c + * This file demonstrates how to use the Streaming fifo driver on the xilinx AXI + * Streaming FIFO IP.The AXI4-Stream FIFO core allows memory mapped access to a + * AXI-Stream interface. The core can be used to interface to AXI Streaming IPs + * similar to the LogiCORE IP AXI Ethernet core, without having to use full DMA + * solution. + * + * This is the interrupt example for the FIFO it assumes that at the + * h/w level FIFO is connected in loopback.In these we write known amount of + * data to the FIFO and wait for interrupts and after compltely receiving the + * data compares it with the data transmitted. + * + * Note: The TDEST Must be enabled in the H/W design inorder to get + * correct RDR value. + * + *
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 3.00a adk 08/10/2013 initial release CR:727787
+ *
+ * 
+ * + * *************************************************************************** + */ + +/***************************** Include Files *********************************/ +#include "xparameters.h" +#include "xil_exception.h" +#include "xstreamer.h" +#include "xil_cache.h" +#include "xllfifo.h" +#include "xstatus.h" + +#ifdef XPAR_UARTNS550_0_BASEADDR +#include "xuartns550_l.h" /* to use uartns550 */ +#endif + +#ifdef XPAR_INTC_0_DEVICE_ID + #include "xintc.h" +#else + #include "xscugic.h" +#endif + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define FIFO_DEV_ID XPAR_AXI_FIFO_0_DEVICE_ID + +#ifdef XPAR_INTC_0_DEVICE_ID +#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID +#define FIFO_INTR_ID XPAR_INTC_0_LLFIFO_0_VEC_ID +#else +#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID +#define FIFO_INTR_ID XPAR_FABRIC_LLFIFO_0_VEC_ID +#endif + +#ifdef XPAR_INTC_0_DEVICE_ID + #define INTC XIntc + #define INTC_HANDLER XIntc_InterruptHandler +#else + #define INTC XScuGic + #define INTC_HANDLER XScuGic_InterruptHandler +#endif + + +#define WORD_SIZE 4 /* Size of words in bytes */ + +#define MAX_PACKET_LEN 4 + +#define NO_OF_PACKETS 64 + +#define MAX_DATA_BUFFER_SIZE NO_OF_PACKETS*MAX_PACKET_LEN + +#undef DEBUG + +/************************** Function Prototypes ******************************/ +#ifdef XPAR_UARTNS550_0_BASEADDR +static void Uart550_Setup(void); +#endif + +int XLlFifoInterruptExample(XLlFifo *InstancePtr, u16 DeviceId); +int TxSend(XLlFifo *InstancePtr, u32 *SourceAddr); +static void FifoHandler(XLlFifo *Fifo); +static void FifoRecvHandler(XLlFifo *Fifo); +static void FifoSendHandler(XLlFifo *Fifo); +static void FifoErrorHandler(XLlFifo *InstancePtr, u32 Pending); +int SetupInterruptSystem(INTC *IntcInstancePtr, XLlFifo *InstancePtr, + u16 FifoIntrId); +static void DisableIntrSystem(INTC *IntcInstancePtr, u16 FifoIntrId); + +/* + * Flags interrupt handlers use to notify the application context the events. + */ +volatile int Done; +volatile int Error; + +/************************** Variable Definitions *****************************/ + +/* + * Device instance definitions + */ +XLlFifo FifoInstance; + +/* + * Instance of the Interrupt Controller + */ +static INTC Intc; + +u32 SourceBuffer[MAX_DATA_BUFFER_SIZE * WORD_SIZE]; +u32 DestinationBuffer[MAX_DATA_BUFFER_SIZE * WORD_SIZE]; + +/*****************************************************************************/ +/** +* +* Main function +* +* This function is the main entry of the AXI FIFO interrupt test. +* +* @param None +* +* @return - XST_SUCCESS if tests pass +* - XST_FAILURE if fails. +* +* @note None +* +******************************************************************************/ +int main() +{ + int Status; + + xil_printf("--- Entering main() ---\n\r"); + + Status = XLlFifoInterruptExample(&FifoInstance, FIFO_DEV_ID); + if (Status != XST_SUCCESS) { + xil_printf("Axi Streaming FIFO Interrupt Example Test Failed"); + xil_printf("--- Exiting main() ---\n\r"); + return XST_FAILURE; + } + + xil_printf("Axi Streaming FIFO Interrupt Example Test passed\n\r"); + xil_printf("--- Exiting main() ---\n\r"); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function demonstrates the usage of AXI FIFO +* It does the following: +* - Set up the output terminal if UART16550 is in the hardware build +* - Initialize the Axi FIFO Device. +* - Set up the interrupt handler for fifo +* - Transmit the data +* - Compare the data +* - Return the result +* +* @param InstancePtr is a pointer to the instance of the +* XLlFifo instance. +* @param DeviceId is Device ID of the Axi Fifo Deive instance, +* typically XPAR__DEVICE_ID value from +* xparameters.h. +* +* @return -XST_SUCCESS to indicate success +* -XST_FAILURE to indicate failure +* +******************************************************************************/ +int XLlFifoInterruptExample(XLlFifo *InstancePtr, u16 DeviceId) +{ + XLlFifo_Config *Config; + int Status; + int i; + int err; + Status = XST_SUCCESS; + + /* Initial setup for Uart16550 */ +#ifdef XPAR_UARTNS550_0_BASEADDR + + Uart550_Setup(); + +#endif + + /* Initialize the Device Configuration Interface driver */ + Config = XLlFfio_LookupConfig(DeviceId); + if (!Config) { + xil_printf("No config found for %d\r\n", DeviceId); + return XST_FAILURE; + } + + /* + * This is where the virtual address would be used, this example + * uses physical address. + */ + Status = XLlFifo_CfgInitialize(InstancePtr, Config, Config->BaseAddress); + if (Status != XST_SUCCESS) { + xil_printf("Initialization failed\n\r"); + return Status; + } + + /* Check for the Reset value */ + Status = XLlFifo_Status(InstancePtr); + XLlFifo_IntClear(InstancePtr,0xffffffff); + Status = XLlFifo_Status(InstancePtr); + if(Status != 0x0) { + xil_printf("\n ERROR : Reset value of ISR0 : 0x%x\t" + "Expected : 0x0\n\r", + XLlFifo_Status(InstancePtr)); + return XST_FAILURE; + } + + /* + * Connect the Axi Streaming FIFO to the interrupt subsystem such + * that interrupts can occur. This function is application specific. + */ + Status = SetupInterruptSystem(&Intc, InstancePtr, FIFO_INTR_ID); + if (Status != XST_SUCCESS) { + xil_printf("Failed intr setup\r\n"); + return XST_FAILURE; + } + + XLlFifo_IntEnable(InstancePtr, XLLF_INT_ALL_MASK); + + Done = 0; + /* Transmit the Data Stream */ + Status = TxSend(InstancePtr, SourceBuffer); + if (Status != XST_SUCCESS){ + xil_printf("Transmission of Data failed\n\r"); + return XST_FAILURE; + } + while(!Done); + + /* Check for errors */ + if(Error) { + xil_printf("Errors in the FIFO\n\r"); + return XST_FAILURE; + } + + err = 0; + + /* Compare the data sent with the data received */ + xil_printf("Comparing data...\n\r"); + for( i=0 ; iCpuBaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + XScuGic_SetPriorityTriggerType(IntcInstancePtr, FifoIntrId, 0xA0, 0x3); + + /* + * Connect the device driver handler that will be called when an + * interrupt for the device occurs, the handler defined above performs + * the specific interrupt processing for the device. + */ + Status = XScuGic_Connect(IntcInstancePtr, FifoIntrId, + (Xil_InterruptHandler)FifoHandler, + InstancePtr); + if (Status != XST_SUCCESS) { + return Status; + } + + XScuGic_Enable(IntcInstancePtr, FifoIntrId); +#endif + + /* + * Initialize the exception table. + */ + Xil_ExceptionInit(); + + /* + * Register the interrupt controller handler with the exception table. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler)INTC_HANDLER, + (void *)IntcInstancePtr);; + + /* + * Enable exceptions. + */ + Xil_ExceptionEnable(); + + return XST_SUCCESS; +} +/*****************************************************************************/ +/** +* +* This function disables the interrupts for the AXI FIFO device. +* +* @param IntcInstancePtr is the pointer to the INTC component instance +* @param FifoIntrId is interrupt ID associated for the FIFO component +* +* @return None +* +* @note None +* +******************************************************************************/ +static void DisableIntrSystem(INTC *IntcInstancePtr, u16 FifoIntrId) +{ +#ifdef XPAR_INTC_0_DEVICE_ID + /* Disconnect the interrupts */ + XIntc_Disconnect(IntcInstancePtr, FifoIntrId); +#else + XScuGic_Disconnect(IntcInstancePtr, FifoIntrId); +#endif +} + +#ifdef XPAR_UARTNS550_0_BASEADDR +/*****************************************************************************/ +/* +* +* Uart16550 setup routine, need to set baudrate to 9600 and data bits to 8 +* +* @param None +* +* @return None +* +* @note None +* +******************************************************************************/ +static void Uart550_Setup(void) +{ + + XUartNs550_SetBaud(XPAR_UARTNS550_0_BASEADDR, + XPAR_XUARTNS550_CLOCK_HZ, 9600); + + XUartNs550_SetLineControlReg(XPAR_UARTNS550_0_BASEADDR, + XUN_LCR_8_DATA_BITS); +} +#endif diff --git a/XilinxProcessorIPLib/drivers/llfifo/examples/xllfifo_polling_example.c b/XilinxProcessorIPLib/drivers/llfifo/examples/xllfifo_polling_example.c new file mode 100644 index 00000000..6b018ba5 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/examples/xllfifo_polling_example.c @@ -0,0 +1,361 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** + * + * @file XLlFifo_polling_example.c + * This file demonstrates how to use the Streaming fifo driver on the xilinx AXI + * Streaming FIFO IP.The AXI4-Stream FIFO core allows memory mapped access to a + * AXI-Stream interface. The core can be used to interface to AXI Streaming IPs + * similar to the LogiCORE IP AXI Ethernet core, without having to use full DMA + * solution. + * + * This is the polling example for the FIFO it assumes that at the + * h/w level FIFO is connected in loopback.In these we write known amount of + * data to the FIFO and Receive the data and compare with the data transmitted. + * + * Note: The TDEST Must be enabled in the H/W design inorder to + * get correct RDR value. + * + *
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 3.00a adk 08/10/2013 initial release CR:727787
+ *
+ * 
+ * + * *************************************************************************** + */ + +/***************************** Include Files *********************************/ +#include "xparameters.h" +#include "xil_exception.h" +#include "xstreamer.h" +#include "xil_cache.h" +#include "xllfifo.h" +#include "xstatus.h" + +#ifdef XPAR_UARTNS550_0_BASEADDR +#include "xuartns550_l.h" /* to use uartns550 */ +#endif + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define FIFO_DEV_ID XPAR_AXI_FIFO_0_DEVICE_ID + +#define WORD_SIZE 4 /* Size of words in bytes */ + +#define MAX_PACKET_LEN 4 + +#define NO_OF_PACKETS 64 + +#define MAX_DATA_BUFFER_SIZE NO_OF_PACKETS*MAX_PACKET_LEN + +#undef DEBUG + +/************************** Function Prototypes ******************************/ +#ifdef XPAR_UARTNS550_0_BASEADDR +static void Uart550_Setup(void); +#endif + +int XLlFifoPollingExample(XLlFifo *InstancePtr, u16 DeviceId); +int TxSend(XLlFifo *InstancePtr, u32 *SourceAddr); +int RxReceive(XLlFifo *InstancePtr, u32 *DestinationAddr); + +/************************** Variable Definitions *****************************/ +/* + * Device instance definitions + */ +XLlFifo FifoInstance; + +u32 SourceBuffer[MAX_DATA_BUFFER_SIZE * WORD_SIZE]; +u32 DestinationBuffer[MAX_DATA_BUFFER_SIZE * WORD_SIZE]; + +/*****************************************************************************/ +/** +* +* Main function +* +* This function is the main entry of the Axi FIFO Polling test. +* +* @param None +* +* @return - XST_SUCCESS if tests pass +* - XST_FAILURE if fails. +* +* @note None +* +******************************************************************************/ +int main() +{ + int Status; + + xil_printf("--- Entering main() ---\n\r"); + + Status = XLlFifoPollingExample(&FifoInstance, FIFO_DEV_ID); + if (Status != XST_SUCCESS) { + xil_printf("Axi Streaming FIFO Polling Example TestFailed\n\r"); + xil_printf("--- Exiting main() ---\n\r"); + return XST_FAILURE; + } + + xil_printf("Axi Streaming FIFO Polling Example Test passed\n\r"); + xil_printf("--- Exiting main() ---\n\r"); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function demonstrates the usage AXI FIFO +* It does the following: +* - Set up the output terminal if UART16550 is in the hardware build +* - Initialize the Axi FIFO Device. +* - Transmit the data +* - Receive the data from fifo +* - Compare the data +* - Return the result +* +* @param InstancePtr is a pointer to the instance of the +* XLlFifo component. +* @param DeviceId is Device ID of the Axi Fifo Deive instance, +* typically XPAR__DEVICE_ID value from +* xparameters.h. +* +* @return -XST_SUCCESS to indicate success +* -XST_FAILURE to indicate failure +* +******************************************************************************/ +int XLlFifoPollingExample(XLlFifo *InstancePtr, u16 DeviceId) +{ + XLlFifo_Config *Config; + int Status; + int i; + int Error; + Status = XST_SUCCESS; + + /* Initial setup for Uart16550 */ +#ifdef XPAR_UARTNS550_0_BASEADDR + + Uart550_Setup(); + +#endif + + /* Initialize the Device Configuration Interface driver */ + Config = XLlFfio_LookupConfig(DeviceId); + if (!Config) { + xil_printf("No config found for %d\r\n", DeviceId); + return XST_FAILURE; + } + + /* + * This is where the virtual address would be used, this example + * uses physical address. + */ + Status = XLlFifo_CfgInitialize(InstancePtr, Config, Config->BaseAddress); + if (Status != XST_SUCCESS) { + xil_printf("Initialization failed\n\r"); + return Status; + } + + /* Check for the Reset value */ + Status = XLlFifo_Status(InstancePtr); + XLlFifo_IntClear(InstancePtr,0xffffffff); + Status = XLlFifo_Status(InstancePtr); + if(Status != 0x0) { + xil_printf("\n ERROR : Reset value of ISR0 : 0x%x\t" + "Expected : 0x0\n\r", + XLlFifo_Status(InstancePtr)); + return XST_FAILURE; + } + + /* Transmit the Data Stream */ + Status = TxSend(InstancePtr, SourceBuffer); + if (Status != XST_SUCCESS){ + xil_printf("Transmisson of Data failed\n\r"); + return XST_FAILURE; + } + + /* Revceive the Data Stream */ + Status = RxReceive(InstancePtr, DestinationBuffer); + if (Status != XST_SUCCESS){ + xil_printf("Receiving data failed"); + return XST_FAILURE; + } + + Error = 0; + + /* Compare the data send with the data received */ + xil_printf(" Comparing data ...\n\r"); + for( i=0 ; i + * MODIFICATION HISTORY: + * + * Ver Who Date Changes + * ----- ---- -------- ------------------------------------------------------- + * 1.00a jvb 10/13/06 First release + * 1.00a xd 12/17/07 Added type casting to fix CR #456850 + * 1.02a jz 12/04/09 Hal phase 1 support + * 2.00a hbm 01/20/10 Hal phase 1 support, bump up major release + * 2.01a asa 09/17/10 Added code for resetting Streaming interface + * for CR574868 + * 3.00a adk 08/10/13 Added support for AXI4 Datainterface.Updated + * XLlFifo_RxGetWord, XLlFifo_TxPutword inorder to + * handle AXI4 Datainterface. Added Config + * initialization for the driver. + * + ******************************************************************************/ + + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xllfifo.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ +#define FIFO_WIDTH_BYTES 4 + +/* + * Implementation Notes: + * + * This Fifo driver makes use of a byte streamer driver (xstreamer.h). The code + * is structured like so: + * + * +--------------------+ + * | llfifo | + * | +----------------+ + * | | +--------------+ + * | | | xstreamer | + * | | +--------------+ + * | +----------------+ + * | | + * +--------------------+ + * + * Initialization + * At initialization time this driver (llfifo) sets up the streamer objects to + * use routines in this driver (llfifo) to perform the actual I/O to the H/W + * FIFO core. + * + * Operation + * Once the streamer objects are set up, the API routines in this driver, just + * call through to the streamer driver to perform the read/write operations. + * The streamer driver will eventually make calls back into the routines (which + * reside in this driver) given at initialization to peform the actual I/O. + * + * Interrupts + * Interrupts are handled in the OS/Application layer above this driver. + */ + +xdbg_stmnt(u32 _xllfifo_rr_value;) +xdbg_stmnt(u32 _xllfifo_ipie_value;) +xdbg_stmnt(u32 _xllfifo_ipis_value;) + +/*****************************************************************************/ +/* +* +* XLlFifo_iRxOccupancy returns the number of 32-bit words available (occupancy) +* to be read from the receive channel of the FIFO, specified by +* InstancePtr. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_iRxOccupancy returns the occupancy count in 32-bit words for +* the specified FIFO. +* +******************************************************************************/ +u32 XLlFifo_iRxOccupancy(XLlFifo *InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr); + + return XLlFifo_ReadReg(InstancePtr->BaseAddress, + XLLF_RDFO_OFFSET); +} + +/*****************************************************************************/ +/* +* +* XLlFifo_iRxGetLen notifies the hardware that the program is ready to receive the +* next frame from the receive channel of the FIFO specified by InstancePtr. +* +* Note that the program must first call XLlFifo_iRxGetLen before pulling data +* out of the receive channel of the FIFO with XLlFifo_Read. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_iRxGetLen returns the number of bytes available in the next +* frame. +* +******************************************************************************/ +u32 XLlFifo_iRxGetLen(XLlFifo *InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr); + + return XLlFifo_ReadReg(InstancePtr->BaseAddress, + XLLF_RLF_OFFSET); +} + +/*****************************************************************************/ +/* +* +* XLlFifo_iRead_Aligned reads, WordCount, words from the FIFO referenced by +* InstancePtr to the block of memory, referenced by BufPtr. +* +* XLlFifo_iRead_Aligned assumes that BufPtr is already aligned according +* to the following hardware limitations: +* ppc - aligned on 32 bit boundaries to avoid performance penalties +* from unaligned exception handling. +* microblaze - aligned on 32 bit boundaries as microblaze does not handle +* unaligned transfers. +* +* Care must be taken to ensure that the number of words read with one or more +* calls to XLlFifo_Read() does not exceed the number of bytes (rounded up to +* the nearest whole 32 bit word) available given from the last call to +* XLlFifo_RxGetLen(). +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param BufPtr specifies the memory address to place the data read. +* +* @param WordCount specifies the number of 32 bit words to read. +* +* @return XLlFifo_iRead_Aligned always returns XST_SUCCESS. Error handling is +* otherwise handled through hardware exceptions and interrupts. +* +* @note +* +* C Signature: int XLlFifo_iRead_Aligned(XLlFifo *InstancePtr, +* void *BufPtr, unsigned WordCount); +* +******************************************************************************/ +/* static */ int XLlFifo_iRead_Aligned(XLlFifo *InstancePtr, void *BufPtr, + unsigned WordCount) +{ + unsigned WordsRemaining = WordCount; + u32 *BufPtrIdx = (u32 *)BufPtr; + + xdbg_printf(XDBG_DEBUG_FIFO_RX, "XLlFifo_iRead_Aligned: start\n"); + Xil_AssertNonvoid(InstancePtr); + Xil_AssertNonvoid(BufPtr); + /* assert bufer is 32 bit aligned */ + Xil_AssertNonvoid(((unsigned)BufPtr & 0x3) == 0x0); + xdbg_printf(XDBG_DEBUG_FIFO_RX, "XLlFifo_iRead_Aligned: after asserts\n"); + + while (WordsRemaining) { +/* xdbg_printf(XDBG_DEBUG_FIFO_RX, + "XLlFifo_iRead_Aligned: WordsRemaining: %d\n", + WordsRemaining); +*/ + *BufPtrIdx = XLlFifo_RxGetWord(InstancePtr); + BufPtrIdx++; + WordsRemaining--; + } + xdbg_printf(XDBG_DEBUG_FIFO_RX, + "XLlFifo_iRead_Aligned: returning SUCCESS\n"); + return XST_SUCCESS; +} + +/****************************************************************************/ +/* +* +* XLlFifo_iTxVacancy returns the number of unused 32 bit words available +* (vacancy) in the send channel of the FIFO, specified by InstancePtr. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_iTxVacancy returns the vacancy count in 32-bit words for +* the specified FIFO. +* +*****************************************************************************/ +u32 XLlFifo_iTxVacancy(XLlFifo *InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr); + + return XLlFifo_ReadReg(InstancePtr->BaseAddress, + XLLF_TDFV_OFFSET); +} + +/*****************************************************************************/ +/* +* +* XLlFifo_iTxSetLen begins a hardware transfer of data out of the transmit +* channel of the FIFO, specified by InstancePtr. Bytes specifies the number +* of bytes in the frame to transmit. +* +* Note that Bytes (rounded up to the nearest whole 32 bit word) must be same +* number of words just written using one or more calls to +* XLlFifo_iWrite_Aligned() +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param Bytes specifies the number of bytes to transmit. +* +* @return N/A +* +******************************************************************************/ +void XLlFifo_iTxSetLen(XLlFifo *InstancePtr, u32 Bytes) +{ + Xil_AssertVoid(InstancePtr); + + XLlFifo_WriteReg(InstancePtr->BaseAddress, XLLF_TLF_OFFSET, + Bytes); +} + +/*****************************************************************************/ +/* +* +* XLlFifo_iWrite_Aligned writes, WordCount, words to the FIFO referenced by +* InstancePtr from the block of memory, referenced by BufPtr. +* +* XLlFifo_iWrite_Aligned assumes that BufPtr is already aligned according +* to the following hardware limitations: +* ppc - aligned on 32 bit boundaries to avoid performance penalties +* from unaligned exception handling. +* microblaze - aligned on 32 bit boundaries as microblaze does not handle +* unaligned transfers. +* +* Care must be taken to ensure that the number of words written with one or +* more calls to XLlFifo_iWrite_Aligned() matches the number of bytes (rounded up +* to the nearest whole 32 bit word) given in the next call to +* XLlFifo_iTxSetLen(). +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param BufPtr specifies the memory address to place the data read. +* +* @param WordCount specifies the number of 32 bit words to read. +* +* @return XLlFifo_iWrite_Aligned always returns XST_SUCCESS. Error handling is +* otherwise handled through hardware exceptions and interrupts. +* +* @note +* +* C Signature: int XLlFifo_iWrite_Aligned(XLlFifo *InstancePtr, +* void *BufPtr, unsigned WordCount); +* +******************************************************************************/ +/* static */ int XLlFifo_iWrite_Aligned(XLlFifo *InstancePtr, void *BufPtr, + unsigned WordCount) +{ + unsigned WordsRemaining = WordCount; + u32 *BufPtrIdx = (u32 *)BufPtr; + + xdbg_printf(XDBG_DEBUG_FIFO_TX, + "XLlFifo_iWrite_Aligned: Inst: %p; Buff: %p; Count: %d\n", + InstancePtr, BufPtr, WordCount); + Xil_AssertNonvoid(InstancePtr); + Xil_AssertNonvoid(BufPtr); + /* assert bufer is 32 bit aligned */ + Xil_AssertNonvoid(((unsigned)BufPtr & 0x3) == 0x0); + + xdbg_printf(XDBG_DEBUG_FIFO_TX, + "XLlFifo_iWrite_Aligned: WordsRemaining: %d\n", + WordsRemaining); + while (WordsRemaining) { + XLlFifo_TxPutWord(InstancePtr, *BufPtrIdx); + BufPtrIdx++; + WordsRemaining--; + } + + xdbg_printf(XDBG_DEBUG_FIFO_TX, + "XLlFifo_iWrite_Aligned: returning SUCCESS\n"); + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* XLlFifo_CfgInitialize initializes an XPS_ll_Fifo device along with the +* InstancePtr that references it. +* +* @param InstancePtr is a pointer to the Axi Streaming FIFO instance +* to be worked on. +* @param CfgPtr references the structure holding the hardware +* configuration for the Axi Streaming FIFO core to initialize. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. The caller is responsible for keeping the +* address mapping from EffectiveAddr to the device physical base +* address unchanged once this function is invoked. Unexpected +* errors may occur if the address mapping changes after this +* function is called. If address translation is not used, +* use Config->BaseAddress for this parameters, passing the +* physical address instead. +* +* @return N/A +* +******************************************************************************/ +int XLlFifo_CfgInitialize(XLlFifo *InstancePtr, + XLlFifo_Config *Config, u32 EffectiveAddress) +{ + Xil_AssertNonvoid(InstancePtr); + + if(!Config) { + return XST_INVALID_PARAM; + } + + + /* Clear instance memory */ + memset(InstancePtr, 0, sizeof(XLlFifo)); + + /* + * We don't care about the physical base address, just copy the + * processor address over it. + */ + InstancePtr->BaseAddress = EffectiveAddress; + + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + InstancePtr->Datainterface = Config->Datainterface; + InstancePtr->Axi4BaseAddress = Config->Axi4BaseAddress; + if (InstancePtr->Datainterface == 0) + InstancePtr->Axi4BaseAddress = EffectiveAddress; + + XLlFifo_TxReset(InstancePtr); + XLlFifo_RxReset(InstancePtr); + + /* + * Reset the core and generate the external reset by writing to + * the Local Link/AXI Streaming Reset Register. + */ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_LLR_OFFSET, + XLLF_RDFR_RESET_MASK); + + XStrm_RxInitialize(&(InstancePtr->RxStreamer), FIFO_WIDTH_BYTES, + (void *)InstancePtr, + (XStrm_XferFnType)XLlFifo_iRead_Aligned, + (XStrm_GetLenFnType)XLlFifo_iRxGetLen, + (XStrm_GetOccupancyFnType)XLlFifo_iRxOccupancy); + + XStrm_TxInitialize(&(InstancePtr->TxStreamer), FIFO_WIDTH_BYTES, + (void *)InstancePtr, + (XStrm_XferFnType)XLlFifo_iWrite_Aligned, + (XStrm_SetLenFnType)XLlFifo_iTxSetLen, + (XStrm_GetVacancyFnType)XLlFifo_iTxVacancy); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/* +* +* XLlFifo_RxGetWord reads one 32 bit word from the FIFO specified by +* InstancePtr. +* +* XLlFifo_RxGetLen or XLlFifo_iRxGetLen must be called before calling +* XLlFifo_RxGetWord. Otherwise, the hardware will raise an Over Read +* Exception. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_RxGetWord returns the 32 bit word read from the FIFO. +* +* @note +* C-style signature: +* u32 XLlFifo_RxGetWord(XLlFifo *InstancePtr) +* +*****************************************************************************/ +u32 XLlFifo_RxGetWord(XLlFifo *InstancePtr) +{ + return XLlFifo_ReadReg((InstancePtr)->Axi4BaseAddress, + XLLF_RDFD_OFFSET); +} + +/****************************************************************************/ +/* +* +* XLlFifo_TxPutWord writes the 32 bit word, Word to the FIFO specified by +* InstancePtr. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return N/A +* +* @note +* C-style signature: +* void XLlFifo_TxPutWord(XLlFifo *InstancePtr, u32 Word) +* +*****************************************************************************/ +void XLlFifo_TxPutWord(XLlFifo *InstancePtr, u32 Word) +{ + + XLlFifo_WriteReg((InstancePtr)->Axi4BaseAddress, + XLLF_TDFD_OFFSET, (Word)); + +} + +/*****************************************************************************/ +/** +* +* XLlFifo_Initialize initializes an XPS_ll_Fifo device along with the +* InstancePtr that references it. +* +* @param InstancePtr references the memory instance to be associated with +* the FIFO device upon initialization. +* +* @param BaseAddress is the processor address used to access the +* base address of the Fifo device. +* +* @return N/A +* +******************************************************************************/ +void XLlFifo_Initialize(XLlFifo *InstancePtr, u32 BaseAddress) +{ + Xil_AssertVoid(InstancePtr); + Xil_AssertVoid(BaseAddress); + + /* Clear instance memory */ + memset(InstancePtr, 0, sizeof(XLlFifo)); + + /* + * We don't care about the physical base address, just copy the + * processor address over it. + */ + InstancePtr->BaseAddress = BaseAddress; + + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + InstancePtr->Axi4BaseAddress = BaseAddress; + + XLlFifo_TxReset(InstancePtr); + XLlFifo_RxReset(InstancePtr); + + /* + * Reset the core and generate the external reset by writing to + * the Local Link/AXI Streaming Reset Register. + */ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_LLR_OFFSET, + XLLF_RDFR_RESET_MASK); + + XStrm_RxInitialize(&(InstancePtr->RxStreamer), FIFO_WIDTH_BYTES, + (void *)InstancePtr, + (XStrm_XferFnType)XLlFifo_iRead_Aligned, + (XStrm_GetLenFnType)XLlFifo_iRxGetLen, + (XStrm_GetOccupancyFnType)XLlFifo_iRxOccupancy); + + XStrm_TxInitialize(&(InstancePtr->TxStreamer), FIFO_WIDTH_BYTES, + (void *)InstancePtr, + (XStrm_XferFnType)XLlFifo_iWrite_Aligned, + (XStrm_SetLenFnType)XLlFifo_iTxSetLen, + (XStrm_GetVacancyFnType)XLlFifo_iTxVacancy); +} diff --git a/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo.h b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo.h new file mode 100644 index 00000000..db742c9b --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo.h @@ -0,0 +1,709 @@ +/****************************************************************************** +* +* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** + * + * @file xllfifo.h + * + * The Xilinx Dual Channel Fifo driver component. This driver supports the + * Virtex-5(TM) and Virtex-4(TM) XPS_ll_Fifo and the AxiFifo. + * + * For a full description of the bridge features, please see the HW spec. This + * driver supports the following features: + * - Memory mapped access to host interface registers + * - API for polled frame transfers + * - API for interrupt driven frame transfers + * - Virtual memory support + * - Full duplex operation + * + *

Driver Description

+ * + * This driver enables higher layer software to access the XPS_llFifo core + * using any alignment in the data buffers. + * + * This driver supports send and receive channels in the same instance + * structure in the same fashion as the hardware core. + * + *

Initialization

+ * + * An instance of this driver is initialized using a call to Initialize(). + * + *

Usage

+ * + * It is fairly simple to use the API provided by this FIFO driver. The + * only somewhat tricky part is that the calling code must correctly call + * a couple routines in the right sequence for receive and transmit. + * + * This sequence is described here. Check the routine functional + * descriptions for information on how to use a specific API routine. + * + *

Receive

+ * + * A frame is received by using the following sequence:
+ * 1) call XLlFifo_RxOccupancy() to check the occupancy count
+ * 2) call XLlFifo_RxGetLen() to get the length of the next incoming frame
+ * 3) call XLlFifo_Read() one or more times to read the number of bytes + * reported by XLlFifo_RxGetLen().
+ * + * For example: + *
+ * 	while (XLlFifo_RxOccupancy(&RxInstance)) {
+ * 		frame_len = XLlFifo_RxGetLen(&RxInstance);
+ *		while (frame_len) {
+ * 			unsigned bytes = min(sizeof(buffer), frame_len);
+ * 			XLlFifo_Read(&RxInstance, buffer, bytes);
+ * 			// ********
+ * 			// do something with buffer here
+ * 			// ********
+ * 			frame_len -= bytes;
+ *		}
+ * 	}
+ * 
+ * + * This FIFO hardware core does not support a sequence where the + * calling code calls RxGetLen() twice in a row and then receive the data + * for two frames. Each frame must be read in by calling RxGetLen() just + * prior to reading the data. + * + *

Transmit

+ * A frame is transmittted by using the following sequence:
+ * 1) call XLlFifo_Write() one or more times to write all the of bytes in + * the next frame.
+ * 2) call XLlFifo_TxSetLen() to begin the transmission of frame just + * written.
+ * + * For example: + *
+ * 	frame_left = frame_len;
+ * 	while (frame_left) {
+ * 		unsigned bytes = min(sizeof(buffer), frame_left);
+ * 		XLlFifo_Write(&TxInstance, buffer, bytes);
+ * 		// ********
+ * 		// do something here to refill buffer
+ * 		// ********
+ * 		frame_left -= bytes;
+ * 	}
+ * 	XLlFifo_TxSetLen(&RxInstance, frame_len);
+ * 
+ * + * This FIFO hardware core does not support a sequence where the + * calling code writes the data for two frames and then calls TxSetLen() + * twice in a row. Each frame must be written by writting the data for one + * frame and then calling TxSetLen(). + * + *

Interrupts

+ * This driver does not handle interrupts from the FIFO hardware. The + * software layer above may make use of the interrupts by setting up its + * own handlers for the interrupts. + * + *
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  10/12/06 First release
+ * 1.01a sdm  08/22/08 Removed support for static interrupt handlers from the
+ *		       MDD file
+ * 1.02a jz   12/04/09 Hal phase 1 support
+ * 2.01a asa  09/17/10 Added code for resetting Local Link/AXI Streaming
+ *		       interface for CR574868
+ * 2.02a asa  12/27/11 Changed the function XStrm_Read in xtreamer.c to reset
+ *		       HeadIndex to zero when all bytes have been read.
+ *		       Changed the macro XStrm_IsRxInternalEmpty in file
+ *		       xtreamer.h to use FrmByteCnt instead of HeadIndex.
+ *		       When FrmByteCnt is zero, this means all internal buffers
+ *		       in streamer are empty. Earlier implementation using
+ *		       HeadIndex was not very clear and could give improper
+ *		       results for some cases.
+ *		       Changed the macro XLlFifo_IsRxEmpty in file xllfifo.h
+ *		       These changes are done to fix the CR 604650.
+  * 2.03a asa  14/08/12  Added XLLF_TDR_OFFSET, XLLF_RDR_OFFSET
+ *		         defines for the new registers, and XLLF_INT_TFPF_MASK,
+ *		         XLLF_INT_TFPE_MASK, XLLF_INT_RFPF_MASK and
+ *		         XLLF_INT_RFPE_MASK for the new version of the
+ *		         AXI4-Stream FIFO core (v2.01a and later)
+ *
+ * 3.00a adk 08/10/13 Added support for AXI4 Datainterface.Changes are
+ * 		      In Xllfifo.c file XLlFifo_RxGetWord,XLlFifo_TxPutword.
+ * 		      In XLlfifo.h file updated XLlfifo structure for
+ * 		      Axi4BaseAddress and for Datainterface type provided
+ *		      polling and interrupt examples. XLlfifo_IsRxDone Macro
+ *		      Is added in the XLlfifo.h file for polledmode exmaple.
+ *		      Added Static initialzation for the driver.
+ *		      XLlFifo_Initialize is still used to make the driver
+ *		      backward compatible.
+ * 4.0   adk  19/12/13 Updated as per the New Tcl API's
+ *
+ * 
+ * + *****************************************************************************/ +#ifndef XLLFIFO_H /* prevent circular inclusions */ +#define XLLFIFO_H /* by using preprocessor symbols */ + +/* force C linkage */ +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +/* This order needs to be kept this way to avoid xstatus/xil_types conflict */ +#include "xstreamer.h" +#include "xllfifo_hw.h" + +/**************************** Type Definitions *******************************/ + +/** + * This typedef defines a run-time instance of an XLlFifo device. + */ +typedef struct XLlFifo { + u32 BaseAddress; /**< BaseAddress is the physical base address of the + * device's registers + */ + + u32 IsReady; /**< IsReady is non-zero if the driver instance + * has been initialized. + */ + + u32 Axi4BaseAddress; /**< BaseAddress if the FIFO Data interface is + * AXI4 this address should use for FIFO + * access + */ + u32 Datainterface; /**< Data interface of the FIFO. This value is zero + * if the Datainterface is AXI4-lite. + */ + XStrm_RxFifoStreamer RxStreamer; /**< RxStreamer is the byte streamer + * instance for the receive channel. + */ + XStrm_TxFifoStreamer TxStreamer; /**< TxStreamer is the byte streamer + * instance for the transmit channel. + */ +} XLlFifo; + +typedef struct XLlFifo_Config { + u32 DeviceId; /**< Deviceid of the AXI FIFO */ + u32 BaseAddress; /**< Base Address of the AXI FIFO */ + u32 Axi4BaseAddress; /**< Axi4 interface Base address */ + u32 Datainterface; /**< Type of Datainterface */ +}XLlFifo_Config; + +/****************************************************************************/ +/** +* +* XLlFifo_Reset resets both the Tx and Rx channels and the local link interface +* the FIFO specified by InstancePtr. XLlFifo_TxReset resets also sends a +* reset pulse to the downstream device (e.g. TEMAC). XLlFifo_Reset drops any +* bytes in the FIFO not yet retrieved. XLlFifo_Reset drops any bytes in the FIFO +* not yet transmitted. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return N/A +* +* @note +* C-style signature: +* void XLlFifo_Reset(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_Reset(InstancePtr) \ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_LLR_OFFSET, \ + XLLF_LLR_RESET_MASK) + + +/****************************************************************************/ +/** +* +* XLlFifo_Status returns a bit mask of the interrupt status register (ISR) +* for the FIFO specified by InstancePtr. XLlFifo_Status can be used +* to query the status of the FIFO without having to have interrupts enabled. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_IntStatus returns a bit mask of the status conditions. +* The mask will be a set of bitwise or'd values from the +* XLLF_INT_*_MASK preprocessor symbols. +* +* @note +* C-style signature: +* u32 XLlFifo_IntStatus(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_Status(InstancePtr) \ + XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) + +/****************************************************************************/ +/** +* +* XLlFifo_IntEnable enables the interrupts specified in Mask for the +* FIFO specified by InstancePtr. The corresponding interrupt for each bit +* set to 1 in Mask, will be enabled. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param Mask contains a bit mask of the interrupts to enable. The mask +* can be formed using a set of bitwise or'd values from the +* XLLF_INT_*_MASK preprocessor symbols. +* +* @return N/A +* +* @note +* C-style signature: +* void XLlFifo_IntEnable(XLlFifo *InstancePtr, u32 Mask) +* +*****************************************************************************/ +#define XLlFifo_IntEnable(InstancePtr, Mask) \ +{ \ + u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \ + XLLF_IER_OFFSET); \ + Reg |= ((Mask) & XLLF_INT_ALL_MASK); \ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \ + Reg); \ +} + +/****************************************************************************/ +/** +* +* XLlFifo_IntDisable disables the interrupts specified in Mask for the +* FIFO specified by InstancePtr. The corresponding interrupt for each bit +* set to 1 in Mask, will be disabled. In other words, XLlFifo_IntDisable +* uses the "set a bit to clear it" scheme. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param Mask contains a bit mask of the interrupts to disable. The mask +* can be formed using a set of bitwise or'd values from the +* XLLF_INT_*_MASK preprocessor symbols. +* +* @return N/A +* +* @note +* C-style signature: +* void XLlFifo_IntDisable(XLlFifo *InstancePtr, u32 Mask) +* +*****************************************************************************/ +#define XLlFifo_IntDisable(InstancePtr, Mask) \ +{ \ + u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \ + XLLF_IER_OFFSET); \ + Reg &= ~((Mask) & XLLF_INT_ALL_MASK); \ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \ + Reg); \ +} + +/****************************************************************************/ +/** +* +* XLlFifo_IntPending returns a bit mask of the pending interrupts for the +* FIFO specified by InstancePtr. Each bit set to 1 in the return value +* represents a pending interrupt. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_IntPending returns a bit mask of the interrupts that are +* pending. The mask will be a set of bitwise or'd values from the +* XLLF_INT_*_MASK preprocessor symbols. +* +* @note +* C-style signature: +* u32 XLlFifo_IntPending(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#ifdef DEBUG +extern u32 _xllfifo_ipie_value; +extern u32 _xllfifo_ipis_value; +#define XLlFifo_IntPending(InstancePtr) \ + (_xllfifo_ipie_value = XLlFifo_ReadReg( \ + (InstancePtr)->BaseAddress, XLLF_IER_OFFSET), \ + _xllfifo_ipis_value = XLlFifo_ReadReg( \ + (InstancePtr)->BaseAddress, XLLF_ISR_OFFSET), \ + (_xllfifo_ipie_value & _xllfifo_ipis_value)) +#else +#define XLlFifo_IntPending(InstancePtr) \ + (XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET) & \ + XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET)) +#endif + +/****************************************************************************/ +/** +* +* XLlFifo_IntClear clears pending interrupts specified in Mask for the +* FIFO specified by InstancePtr. The corresponding pending interrupt for +* each bit set to 1 in Mask, will be cleared. In other words, +* XLlFifo_IntClear uses the "set a bit to clear it" scheme. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param Mask contains a bit mask of the pending interrupts to clear. The +* mask can be formed using a set of bitwise or'd values from the +* XLLF_INT_*_MASK preprocessor symbols. +* +* @note +* C-style signature: +* void XLlFifo_IntClear(XLlFifo *InstancePtr, u32 Mask) +* +*****************************************************************************/ +#define XLlFifo_IntClear(InstancePtr, Mask) \ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET, \ + ((Mask) & XLLF_INT_ALL_MASK)) + +/****************************************************************************/ +/** +* +* XLlFifo_RxReset resets the receive channel of the FIFO specified by +* InstancePtr. XLlFifo_RxReset drops any bytes in the FIFO not yet +* retrieved. +* +* The calling software may want to test for the completion of the reset by +* reading the interrupt status (IS) register and testing for the Rx Reset +* complete (RRC) bit. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return N/A +* +* @note +* C-style signature: +* void XLlFifo_RxReset(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_RxReset(InstancePtr) \ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_RDFR_OFFSET, \ + XLLF_RDFR_RESET_MASK) + +/****************************************************************************/ +/** +* +* XLlFifo_IsRxEmpty returns true if the receive channel of the FIFO, specified +* by InstancePtr, is empty. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_IsRxEmpty returns TRUE when the receive channel of the +* FIFO is empty. Otherwise, XLlFifo_IsRxEmpty returns FALSE. +* +* @note +* C-style signature: +* int XLlFifo_IsRxEmpty(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_IsRxEmpty(InstancePtr) \ + ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_RDFO_OFFSET) == 0) \ + ? TRUE : FALSE) + + +/*****************************************************************************/ +/** +* +* XLlFifo_RxOccupancy returns the number of 32-bit words available (occupancy) to +* be read from the receive channel of the FIFO, specified by InstancePtr. +* +* The xps_ll_fifo core uses the same fifo to store data values and frame length +* values. Upon initialization, the XLlFifo_RxOccupancy will give the value of +* 1, which means one length value (a reserved fifo location) and no data +* values. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_RxOccupancy returns the occupancy count for the specified +* packet FIFO. +* +* @note +* +* C Signature: u32 XLlFifo_RxOccupancy(XLlFifo *InstancePtr) +* +******************************************************************************/ +#define XLlFifo_RxOccupancy(InstancePtr) \ + XStrm_RxOccupancy(&((InstancePtr)->RxStreamer)) + +/*****************************************************************************/ +/** +* +* XLlFifo_RxGetLen notifies the hardware that the program is ready to receive +* the next frame from the receive channel of the FIFO, specified by +* InstancePtr. +* +* Note that the program must first call XLlFifo_RxGetLen before pulling data +* out of the receive channel of the FIFO with XLlFifo_Read. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_RxGetLen returns the number of bytes available in the next +* frame. +* +* @note +* +* C Signature: u32 XLlFifo_RxGetLen(XLlFifo *InstancePtr) +* +******************************************************************************/ +#define XLlFifo_RxGetLen(InstancePtr) \ + XStrm_RxGetLen(&((InstancePtr)->RxStreamer)) + +/*****************************************************************************/ +/** +* +* XLlFifo_Read reads Bytes bytes from the receive channel of the FIFO +* referenced by InstancePtr to the block of memory, referenced by +* BufPtr. +* +* Care must be taken to ensure that the number of bytes read with one or more +* calls to XLlFifo_Read() does not exceed the number of bytes available given +* from the last call to XLlFifo_RxGetLen(). +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param BufPtr specifies the memory address to place the data read. +* +* @param Bytes specifies the number of bytes to read. +* +* @return N/A +* +* @note +* Error handling is handled through hardware exceptions and interrupts. +* +* C Signature: void XLlFifo_Read(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes) +* +******************************************************************************/ +#define XLlFifo_Read(InstancePtr, BufPtr, Bytes) \ + XStrm_Read(&((InstancePtr)->RxStreamer), (BufPtr), (Bytes)) + +/****************************************************************************/ +/** +* +* XLlFifo_TxReset resets the transmit channel of the FIFO specified by +* InstancePtr. XLlFifo_TxReset drops any bytes in the FIFO not yet +* transmitted. +* +* The calling software may want to test for the completion of the reset by +* reading the interrupt status (IS) register and testing for the Tx Reset +* complete (TRC) bit. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return N/A +* +* @note +* C-style signature: +* void XLlFifo_TxReset(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_TxReset(InstancePtr) \ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDFR_OFFSET, \ + XLLF_TDFR_RESET_MASK) + +/****************************************************************************/ +/** +* +* XLlFifo_IsTxDone returns true if the transmission in the transmit channel +* of the FIFO, specified by InstancePtr, is complete. XLlFifo_IsTxDone +* works only if the TC bit in the IS register is cleared before sending a +* frame. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_IsTxDone returns TRUE when the transmit channel of the +* FIFO is complete. Otherwise, XLlFifo_IsTxDone returns FALSE. +* +* @note +* C-style signature: +* int XLlFifo_IsTxDone(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_IsTxDone(InstancePtr) \ + ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) & \ + XLLF_INT_TC_MASK) \ + ? TRUE : FALSE) + +/****************************************************************************/ +/** +* +* XLlFifo_IsRxDone returns true if the reception in the receive channel +* of the FIFO, specified by InstancePtr, is complete. XLlFifo_IsRxDone +* works only if the RC bit in the ISR register is cleared before receiving a +* frame. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_IsRxDone returns TRUE when the receive channel of the +* FIFO is complete. Otherwise, XLlFifo_IsRxDone returns FALSE. +* +* @note +* C-style signature: +* int XLlFifo_IsRxDone(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_IsRxDone(InstancePtr) \ + ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) & \ + XLLF_INT_RC_MASK) \ + ? TRUE : FALSE) + +/****************************************************************************/ +/** +* +* XLlFifo_TxVacancy returns the number of unused 32 bit words available +* (vacancy) in the send channel of the FIFO specified by InstancePtr. +* +* The xps_ll_fifo core uses tXLLF_he same fifo to store data values and frame length +* values. Upon initialization, the XLlFifo_TxVacancy will give the value of +* FIFO_WIDTH - 1, which means one length value used (a reserved fifo location) +* and no data values yet present. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XLlFifo_TxVacancy returns the vacancy count in 32-bit words for +* the specified FIFO. +* +* @note +* C-style signature: +* u32 XLlFifo_TxVacancy(XLlFifo *InstancePtr) +* +*****************************************************************************/ +#define XLlFifo_TxVacancy(InstancePtr) \ + XStrm_TxVacancy(&((InstancePtr)->TxStreamer)) + +/*****************************************************************************/ +/** +* +* XLlFifo_TxSetLen begins a hardware transfer of Bytes bytes out of the +* transmit channel of the FIFO specified by InstancePtr. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param Bytes specifies the frame length in bytes. +* +* @return N/A +* +* @note +* +* C Signature: void XLlFifo_TxSetLen(XLlFifo *InstancePtr, u32 Bytes) +* +******************************************************************************/ +#define XLlFifo_TxSetLen(InstancePtr, Bytes) \ + XStrm_TxSetLen(&((InstancePtr)->TxStreamer), (Bytes)) + +/*****************************************************************************/ +/** +* +* XLlFifo_Write writes Bytes bytes of the block of memory, referenced by +* BufPtr, to the transmit channel of the FIFO referenced by +* InstancePtr. +* +* Care must be taken to ensure that the number of bytes written with one or +* more calls to XLlFifo_Write() matches the number of bytes given in the next +* call to XLlFifo_TxSetLen(). +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param BufPtr specifies the memory address of data to write. +* +* @param Bytes specifies the number of bytes to write. +* +* @return N/A +* +* @note +* Error handling is handled through hardware exceptions and interrupts. +* +* C Signature: void XLlFifo_Write(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes) +* +******************************************************************************/ +#define XLlFifo_Write(InstancePtr, BufPtr, Bytes) \ + XStrm_Write(&((InstancePtr)->TxStreamer), (BufPtr), (Bytes)) + + +/*****************************************************************************/ +/** +* +* XLlFifo_WriteTdr writes to the Transmit Destination Register (TDR) +* +* The TDR stores the destination address corresponding to the packet to be +* transmitted. When presenting a transmit packet to the AXI4-Stream FIFO core +* the following sequence should be followed +* - Write the destination address into TDR first, +* - Write the packet data to the Transmit Data FIFO next +* - Write the length of the packet into the Transmit Length Register. +* +* @param InstancePtr references the FIFO on which to operate. +* @param Tdest is the Transmit Destination address to be written to TDR. +* +* @return N/A +* +* @note C Signature: +* void XLlFifo_WriteTdr(XLlFifo *InstancePtr, u32 Tdest); +* +******************************************************************************/ +#define XLlFifo_WriteTdr(InstancePtr, Tdest) \ + XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDR_OFFSET, \ + Tdest & 0xF) + +/*****************************************************************************/ +/** +* +* XLlFifo_ReadTdr returns the contents of the Receive Destination Register(RDR). +* +* The RDR contains destination address corresponding to the valid packet that +* is received. The RDR should only be read when a receive packet is available +* for processing (the receive occupancy is not zero). +* Once the RDR is read, the receive packet data should be read from the receive +* data FIFO before the RDR is read again. The RDR values are stored in the +* receive data FIFO by the AXI4-Stream FIFO core with the data of each packet. +* The RDR value for the subsequent packet to be processed is moved to the RDR +* when the previous RDR value has been read. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return The Receive Destination address read from the RDR. +* +* @note C Signature: +* u32 XLlFifo_ReadRdr(XLlFifo *InstancePtr) +* +******************************************************************************/ +#define XLlFifo_ReadRdr(InstancePtr) \ + XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_RDR_OFFSET) + +/************************** Function Prototypes ******************************/ +/* + * Initialization functions xllfifo.c + */ +int XLlFifo_CfgInitialize(XLlFifo *InstancePtr, + XLlFifo_Config *Config, u32 EffectiveAddress); +void XLlFifo_Initialize(XLlFifo *InstancePtr, u32 BaseAddress); +XLlFifo_Config *XLlFfio_LookupConfig(u32 DeviceId); +u32 XLlFifo_iRxOccupancy(XLlFifo *InstancePtr); +u32 XLlFifo_iRxGetLen(XLlFifo *InstancePtr); +u32 XLlFifo_iTxVacancy(XLlFifo *InstancePtr); +void XLlFifo_iTxSetLen(XLlFifo *InstancePtr, u32 Bytes); +u32 XLlFifo_RxGetWord(XLlFifo *InstancePtr); +void XLlFifo_TxPutWord(XLlFifo *InstancePtr, u32 Word); + +#ifdef __cplusplus +} +#endif +#endif /* XLLFIFO_H end of preprocessor protection symbols */ diff --git a/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_g.c b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_g.c new file mode 100644 index 00000000..628a946e --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_g.c @@ -0,0 +1,66 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xtrafgen_g.c +* +* Provide a template for user to define their own hardware settings. +* +* If using XPS, this file will be automatically generated. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a adk 9/10/2013 initial release
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xllfifo.h" + +/************************** Constant Definitions *****************************/ + +XLlFifo_Config XLlFifo_ConfigTable[] = +{ + { + XPAR_AXI_FIFO_MM_S_1_DEVICE_ID, + XPAR_AXI_FIFO_MM_S_1_BASEADDR, + XPAR_AXI_FIFO_MM_S_1_AXI4_BASEADDR, + XPAR_AXI_FIFO_MM_S_1_DATA_INTERFACE_TYPE + } +}; diff --git a/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_hw.h b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_hw.h new file mode 100644 index 00000000..bb7fa206 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_hw.h @@ -0,0 +1,237 @@ +/****************************************************************************** +* +* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xllfifo_hw.h +* +* This header file contains identifiers and low-level driver functions (or +* macros) that can be used to access the xps_ll_fifo core. +* High-level driver functions are defined in xpfifo.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a jvb  10/16/06 First release.
+* 1.02a jz   12/04/09  Hal phase 1 support
+* 2.00a hbm  01/20/10  Hal phase 1 support, bump up major release
+* 2.03a asa  14/08/12  Added XLLF_TDR_OFFSET, XLLF_RDR_OFFSET
+*		       defines for the new registers, and XLLF_INT_TFPF_MASK,
+*		       XLLF_INT_TFPE_MASK, XLLF_INT_RFPF_MASK and
+*		       XLLF_INT_RFPE_MASK for the new version of the
+*		       AXI4-Stream FIFO core (v2.01a and later)
+* 
+* +******************************************************************************/ + +#ifndef XLLFIFO_HW_H /* prevent circular inclusions */ +#define XLLFIFO_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xdebug.h" +#include "xil_io.h" +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ + +/* Register offset definitions. Unless otherwise noted, register access is + * 32 bit. + */ + +/** @name Registers + * @{ + */ +#define XLLF_ISR_OFFSET 0x00000000 /**< Interrupt Status */ +#define XLLF_IER_OFFSET 0x00000004 /**< Interrupt Enable */ + +#define XLLF_TDFR_OFFSET 0x00000008 /**< Transmit Reset */ +#define XLLF_TDFV_OFFSET 0x0000000c /**< Transmit Vacancy */ +#define XLLF_TDFD_OFFSET 0x00000010 /**< Transmit Data */ +#define XLLF_TLF_OFFSET 0x00000014 /**< Transmit Length */ + +#define XLLF_RDFR_OFFSET 0x00000018 /**< Receive Reset */ +#define XLLF_RDFO_OFFSET 0x0000001c /**< Receive Occupancy */ +#define XLLF_RDFD_OFFSET 0x00000020 /**< Receive Data */ +#define XLLF_RLF_OFFSET 0x00000024 /**< Receive Length */ +#define XLLF_LLR_OFFSET 0x00000028 /**< Local Link Reset */ +#define XLLF_TDR_OFFSET 0x0000002C /**< Transmit Destination */ +#define XLLF_RDR_OFFSET 0x00000030 /**< Receive Destination */ + +/*@}*/ + +/* Register masks. The following constants define bit locations of various + * control bits in the registers. Constants are not defined for those registers + * that have a single bit field representing all 32 bits. For further + * information on the meaning of the various bit masks, refer to the HW spec. + */ + +/** @name Interrupt bits + * These bits are associated with the XLLF_IER_OFFSET and XLLF_ISR_OFFSET + * registers. + * @{ + */ +#define XLLF_INT_RPURE_MASK 0x80000000 /**< Receive under-read */ +#define XLLF_INT_RPORE_MASK 0x40000000 /**< Receive over-read */ +#define XLLF_INT_RPUE_MASK 0x20000000 /**< Receive underrun (empty) */ +#define XLLF_INT_TPOE_MASK 0x10000000 /**< Transmit overrun */ +#define XLLF_INT_TC_MASK 0x08000000 /**< Transmit complete */ +#define XLLF_INT_RC_MASK 0x04000000 /**< Receive complete */ +#define XLLF_INT_TSE_MASK 0x02000000 /**< Transmit length mismatch */ +#define XLLF_INT_TRC_MASK 0x01000000 /**< Transmit reset complete */ +#define XLLF_INT_RRC_MASK 0x00800000 /**< Receive reset complete */ +#define XLLF_INT_TFPF_MASK 0x00400000 /**< Tx FIFO Programmable Full, + * AXI FIFO MM2S Only */ +#define XLLF_INT_TFPE_MASK 0x00200000 /**< Tx FIFO Programmable Empty + * AXI FIFO MM2S Only */ +#define XLLF_INT_RFPF_MASK 0x00100000 /**< Rx FIFO Programmable Full + * AXI FIFO MM2S Only */ +#define XLLF_INT_RFPE_MASK 0x00080000 /**< Rx FIFO Programmable Empty + * AXI FIFO MM2S Only */ +#define XLLF_INT_ALL_MASK 0xfff80000 /**< All the ints */ +#define XLLF_INT_ERROR_MASK 0xf2000000 /**< Error status ints */ +#define XLLF_INT_RXERROR_MASK 0xe0000000 /**< Receive Error status ints */ +#define XLLF_INT_TXERROR_MASK 0x12000000 /**< Transmit Error status ints */ +/*@}*/ + +/** @name Reset register values + * These bits are associated with the XLLF_TDFR_OFFSET and XLLF_RDFR_OFFSET + * reset registers. + * @{ + */ +#define XLLF_RDFR_RESET_MASK 0x000000a5 /**< receive reset value */ +#define XLLF_TDFR_RESET_MASK 0x000000a5 /**< Transmit reset value */ +#define XLLF_LLR_RESET_MASK 0x000000a5 /**< Local Link reset value */ +/*@}*/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**** debug macros ****/ +#define XLlFifo_reg_name(RegOffset) \ + (((RegOffset) == XLLF_ISR_OFFSET) ? "ISR": \ + ((RegOffset) == XLLF_IER_OFFSET) ? "IER": \ + ((RegOffset) == XLLF_TDFR_OFFSET) ? "TDFR {tx reset}": \ + ((RegOffset) == XLLF_TDFV_OFFSET) ? "TDFV {tx vacancy}": \ + ((RegOffset) == XLLF_TDFD_OFFSET) ? "TDFD {tx data}": \ + ((RegOffset) == XLLF_TLF_OFFSET) ? "TLF {tx length}": \ + ((RegOffset) == XLLF_RDFR_OFFSET) ? "RDFR {rx reset}": \ + ((RegOffset) == XLLF_RDFO_OFFSET) ? "RDFO {rx occupancy}": \ + ((RegOffset) == XLLF_RDFD_OFFSET) ? "RDFD {rx data}": \ + ((RegOffset) == XLLF_RLF_OFFSET) ? "RLF {rx length}": \ + "unknown") + +#define XLlFifo_print_reg_o(BaseAddress, RegOffset, Value) \ + xdbg_printf(XDBG_DEBUG_FIFO_REG, "0x%08x -> %s(0x%08x)\n", (Value), \ + XLlFifo_reg_name(RegOffset), \ + (RegOffset) + (BaseAddress)) + +#define XLlFifo_print_reg_i(BaseAddress, RegOffset, Value) \ + xdbg_printf(XDBG_DEBUG_FIFO_REG, "%s(0x%08x) -> 0x%08x\n", \ + XLlFifo_reg_name(RegOffset), \ + (RegOffset) + (BaseAddress), (Value)) +/**** end debug macros ****/ + +/****************************************************************************/ +/** +* +* XLlFifo_ReadReg returns the value of the register at the offet, +* RegOffset, from the memory mapped base address, BaseAddress. +* +* @param BaseAddress specifies the base address of the device. +* +* @param RegOffset specifies the offset from BaseAddress. +* +* @return XLlFifo_ReadReg returns the value of the specified register. +* +* @note +* C-style signature: +* u32 XLlFifo_ReadReg(u32 BaseAddress, u32 RegOffset) +* +*****************************************************************************/ +#ifdef DEBUG +extern u32 _xllfifo_rr_value; +#define XLlFifo_ReadReg(BaseAddress, RegOffset) \ + ((((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \ + "XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \ + (RegOffset)) : 0), \ + _xllfifo_rr_value = Xil_In32((BaseAddress) + (RegOffset)), \ + XLlFifo_print_reg_i((BaseAddress), (RegOffset), _xllfifo_rr_value), \ + _xllfifo_rr_value) +#else +#define XLlFifo_ReadReg(BaseAddress, RegOffset) \ + (Xil_In32((BaseAddress) + (RegOffset))) +#endif + +/****************************************************************************/ +/** +* +* XLlFifo_WriteReg writes the value, Value, to the register at the +* offet, RegOffset, from the memory mapped base address, +* BaseAddress. +* +* @param BaseAddress specifies the base address of the device. +* +* @param RegOffset specifies the offset from BaseAddress. +* +* @param Value is value to write to the register. +* +* @return N/A +* +* @note +* C-style signature: +* void XLlFifo_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Value) +* +*****************************************************************************/ +#ifdef DEBUG +#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \ + (((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \ + "XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \ + (RegOffset)) : 0), \ + XLlFifo_print_reg_o((BaseAddress), (RegOffset), (Value)), \ + (Xil_Out32((BaseAddress) + (RegOffset), (Value))) +#else +#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \ + ((Xil_Out32((BaseAddress) + (RegOffset), (Value)))) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* XLLFIFO_HW_H end of protection macro */ diff --git a/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_sinit.c b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_sinit.c new file mode 100644 index 00000000..f6108ffb --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/src/xllfifo_sinit.c @@ -0,0 +1,85 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xtrafgen_sinit.c +* +* This file contains static initialzation functionality for Axi Streaming FIFO +* driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a adk 9/10/2013 initial release
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xllfifo.h" + +/*****************************************************************************/ +/** + * Look up the hardware configuration for a device instance + * + * @param DeviceId is the unique device ID of the device to lookup for + * + * @return + * The configuration structure for the device. If the device ID is + * not found,a NULL pointer is returned. + * + * @note None + * + ******************************************************************************/ +XLlFifo_Config *XLlFfio_LookupConfig(u32 DeviceId) +{ + extern XLlFifo_Config XLlFifo_ConfigTable[]; + XLlFifo_Config *CfgPtr; + u32 Index; + + CfgPtr = NULL; + + for (Index = 0; Index < XPAR_XLLFIFO_NUM_INSTANCES; Index++) { + if (XLlFifo_ConfigTable[Index].DeviceId == DeviceId) { + + CfgPtr = &XLlFifo_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} diff --git a/XilinxProcessorIPLib/drivers/llfifo/src/xstreamer.c b/XilinxProcessorIPLib/drivers/llfifo/src/xstreamer.c new file mode 100644 index 00000000..f619472e --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/src/xstreamer.c @@ -0,0 +1,513 @@ +/****************************************************************************** +* +* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/* +* @file xstreamer.c +* +* See xtreamer.h for a description on how to use this driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a jvb  10/13/06 First release - based on Robert McGee's streaming packet
+*                     fifo driver.
+* 1.02a jz   12/04/09  Hal phase 1 support
+* 2.00a hbm  01/20/10  Hal phase 1 support, bump up major release
+* 2.02a asa  12/28/11  The function XStrm_Read is changed to reset HeadIndex
+*		       to zero when all the bytes are read.
+* 
+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xstreamer.h" +#include "xil_assert.h" + +/* + * Implementation Notes + * + * --- Receive --- + * + * The basic algorithm for receiving bytes through this byte streamer copies a + * fifo key-hole width chunk from the fifo into a holding buffer and then doles + * out the bytes from the holding buffer. In some cases, when the buffer given + * happens to already be aligned in memory, this algorithm will bypass the + * holding buffer. + * + * Here is a picture to depict this process: + * + * Initial state: holding buffer + * +--------------+ + * | | + * +--------------+ + * ^ + * | + * index + * + * during XStrm_Read(): + * first holding buffer fill: holding buffer + * +--------------+ + * |////////| + * +--------------+ + * ^ + * | + * index + * + * first holding buffer read: holding buffer + * read unread + * +--------------+ + * | |///////| + * +--------------+ + * ^ + * | + * index + * + * ... + * + * last holding buffer read: holding buffer + * +--------------+ + * | | + * +--------------+ + * ^ + * | + * index + * + * repeat this process ^^^ + * + * + * --- Transmit --- + * + * The basic algorithm for transmitting bytes through this byte streamer copies + * bytes into a holding buffer and then writes the holding buffer into the fifo + * when it is full. In some cases, when the buffer given happens to already be + * aligned in memory, this algorithm will bypass the holding buffer. + * + * Here is a picture to depict this process: + * + * Initial state: holding buffer + * +--------------+ + * | | + * +--------------+ + * ^ + * | + * index + * + * during XStrm_Write(): + * first holding buffer write: holding buffer + * writen empty + * +--------------+ + * |//////| | + * +--------------+ + * ^ + * | + * index + * + * ... + * last holding buffer write: holding buffer + * +--------------+ + * |////////| + * +--------------+ + * ^ + * | + * index + * + * holding buffer flush: holding buffer + * +--------------+ + * | | + * +--------------+ + * ^ + * | + * index + * + * repeat this process ^^^ + */ + +#ifndef min +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +xdbg_stmnt(u32 _xstrm_ro_value;) +xdbg_stmnt(u32 _xstrm_buffered;) + +/*****************************************************************************/ +/* +* +* XStrm_RxInitialize initializes the XStrm_RxFifoStreamer object referenced by +* InstancePtr. +* +* @param InstancePtr references the tx streamer on which to operate. +* +* @param FifoWidth specifies the FIFO keyhole size in bytes. +* +* @param FifoInstance references the FIFO driver instance that this streamer +* object should use to transfer data into the the actual fifo. +* +* @param ReadFn specifies a routine to use to read data from the actual +* FIFO. It is assumed that this read routine will handle only reads +* from an aligned buffer. (Otherwise, why are we using this streamer +* driver?) +* +* @param GetLenFn specifies a routine to use to initiate a receive on the +* actual FIFO. +* +* @param GetOccupancyFn specifies a routine to use to retrieve the occupancy +* in the actual FIFO. The true occupancy value needs to come through +* this streamer driver becuase it holds some of the bytes. +* +* @return N/A +* +******************************************************************************/ +void XStrm_RxInitialize(XStrm_RxFifoStreamer *InstancePtr, unsigned FifoWidth, + void *FifoInstance, XStrm_XferFnType ReadFn, + XStrm_GetLenFnType GetLenFn, + XStrm_GetOccupancyFnType GetOccupancyFn) +{ + /* Verify arguments */ + Xil_AssertVoid(InstancePtr != NULL); + + InstancePtr->HeadIndex = FifoWidth; + InstancePtr->FifoWidth = FifoWidth; + InstancePtr->FifoInstance = FifoInstance; + InstancePtr->ReadFn = ReadFn; + InstancePtr->GetLenFn = GetLenFn; + InstancePtr->GetOccupancyFn = GetOccupancyFn; +} + +/*****************************************************************************/ +/* +* +* XStrm_TxInitialize initializes the XStrm_TxFifoStreamer object referenced by +* InstancePtr. +* +* @param InstancePtr references the tx streamer on which to operate. +* +* @param FifoWidth specifies the FIFO keyhole size in bytes. +* +* @param FifoInstance references the FIFO driver instance that this streamer +* object should use to transfer data into the the actual fifo. +* +* @param WriteFn specifies a routine to use to write data into the actual +* FIFO. It is assumed that this write routine will handle only writes +* from an aligned buffer. (Otherwise, why are we using this streamer +* driver?) +* +* @param SetLenFn specifies a routine to use to initiate a transmit on the +* actual FIFO. +* +* @param GetVacancyFn specifies a routine to use to retrieve the vacancy in +* the actual FIFO. The true vacancy value needs to come through this +* streamer driver becuase it holds some of the bytes. +* +* @return N/A +* +******************************************************************************/ +void XStrm_TxInitialize(XStrm_TxFifoStreamer *InstancePtr, unsigned FifoWidth, + void *FifoInstance, XStrm_XferFnType WriteFn, + XStrm_SetLenFnType SetLenFn, + XStrm_GetVacancyFnType GetVacancyFn) +{ + /* Verify arguments */ + Xil_AssertVoid(InstancePtr != NULL); + + InstancePtr->TailIndex = 0; + InstancePtr->FifoWidth = FifoWidth; + InstancePtr->FifoInstance = FifoInstance; + InstancePtr->WriteFn = WriteFn; + InstancePtr->SetLenFn = SetLenFn; + InstancePtr->GetVacancyFn = GetVacancyFn; +} + +/*****************************************************************************/ +/* +* +* XStrm_RxGetLen notifies the hardware that the program is ready to receive the +* next frame from the receive channel of the FIFO, specified by +* InstancePtr. +* +* Note that the program must first call XStrm_RxGetLen before pulling data +* out of the receive channel of the FIFO with XStrm_Read. +* +* @param InstancePtr references the FIFO on which to operate. +* +* @return XStrm_RxGetLen returns the number of bytes available in the next +* frame. +* +******************************************************************************/ +u32 XStrm_RxGetLen(XStrm_RxFifoStreamer *InstancePtr) +{ + u32 len; + + InstancePtr->HeadIndex = InstancePtr->FifoWidth; + len = (*InstancePtr->GetLenFn)(InstancePtr->FifoInstance); + InstancePtr->FrmByteCnt = len; + return len; +} + +/*****************************************************************************/ +/* +* +* XStrm_Read reads Bytes bytes from the FIFO specified by +* InstancePtr to the block of memory, referenced by BufPtr. +* +* Care must be taken to ensure that the number of bytes read with one or more +* calls to XStrm_Read() does not exceed the number of bytes available given +* from the last call to XStrm_RxGetLen(). +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param BufPtr specifies the memory address to place the data read. +* +* @param Bytes specifies the number of bytes to read. +* +* @return N/A +* +******************************************************************************/ +void XStrm_Read(XStrm_RxFifoStreamer *InstancePtr, void *BufPtr, + unsigned Bytes) +{ + u8 *DestPtr = (u8 *) BufPtr; + unsigned BytesRemaining = Bytes; + unsigned FifoWordsToXfer; + unsigned PartialBytes; + unsigned i; + + while (BytesRemaining) { + xdbg_printf(XDBG_DEBUG_FIFO_RX, "XStrm_Read: BytesRemaining: %d\n", BytesRemaining); + /* Case 1: There are bytes in the holding buffer + * + * 1) Read the bytes from the holding buffer to the target buffer. + * 2) Loop back around and handle the rest of the transfer. + */ + if (InstancePtr->HeadIndex != InstancePtr->FifoWidth) { + xdbg_printf(XDBG_DEBUG_FIFO_RX, "XStrm_Read: Case 1: InstancePtr->HeadIndex [%d] != InstancePtr->FifoWidth [%d]\n", + InstancePtr->HeadIndex, InstancePtr->FifoWidth); + i = InstancePtr->HeadIndex; + + PartialBytes = min(BytesRemaining, + InstancePtr->FifoWidth - + InstancePtr->HeadIndex); + InstancePtr->HeadIndex += PartialBytes; + BytesRemaining -= PartialBytes; + InstancePtr->FrmByteCnt -= PartialBytes; + while (PartialBytes--) { + *DestPtr = InstancePtr->AlignedBuffer.bytes[i]; + i++; + DestPtr++; + } + } + /* Case 2: There are no more bytes in the holding buffer and + * the target buffer is 32 bit aligned and + * the number of bytes remaining to transfer is greater + * than or equal to the fifo width. + * + * 1) We can go fast by reading a long string of fifo words right out + * of the fifo into the target buffer. + * 2) Loop back around to transfer the last few bytes. + */ + else if ((((unsigned)DestPtr & 3) == 0) && + (BytesRemaining >= InstancePtr->FifoWidth)) { + xdbg_printf(XDBG_DEBUG_FIFO_RX, "XStrm_Read: Case 2: DestPtr: %p, BytesRemaining: %d, InstancePtr->FifoWidth: %d\n", + DestPtr, BytesRemaining, InstancePtr->FifoWidth); + FifoWordsToXfer = + BytesRemaining / InstancePtr->FifoWidth; + + (*(InstancePtr->ReadFn)) (InstancePtr->FifoInstance, + DestPtr, FifoWordsToXfer); + DestPtr += FifoWordsToXfer * InstancePtr->FifoWidth; + BytesRemaining -= + FifoWordsToXfer * InstancePtr->FifoWidth; + InstancePtr->FrmByteCnt -= + FifoWordsToXfer * InstancePtr->FifoWidth; + } + /* Case 3: There are no more bytes in the holding buffer and + * the number of bytes remaining to transfer is less than + * the fifo width or + * things just don't line up. + * + * 1) Fill the holding buffer. + * 2) Loop back around and handle the rest of the transfer. + */ + else { + xdbg_printf(XDBG_DEBUG_FIFO_RX, "XStrm_Read: Case 3\n"); + /* + * At the tail end, read one fifo word into the local holding + * buffer and loop back around to take care of the transfer. + */ + (*InstancePtr->ReadFn) (InstancePtr->FifoInstance, + &(InstancePtr->AlignedBuffer. + bytes[0]), 1); + InstancePtr->HeadIndex = 0; + } + } + if ((InstancePtr->FrmByteCnt) == 0) { + InstancePtr->HeadIndex = 0; + } +} + +/*****************************************************************************/ +/* +* +* XStrm_TxSetLen flushes to the FIFO, specified by InstancePtr, any +* bytes remaining in internal buffers and begins a hardware transfer of data +* out of the transmit channel of the FIFO. Bytes specifies the number +* of bytes in the frame to transmit. +* +* @param InstancePtr references the FIFO Streamer on which to operate. +* +* @param Bytes specifies the frame length in bytes. +* +* @return N/A +* +******************************************************************************/ +void XStrm_TxSetLen(XStrm_TxFifoStreamer *InstancePtr, u32 Bytes) +{ + /* + * First flush what's in the holding buffer + */ + if (InstancePtr->TailIndex != 0) { + (*InstancePtr->WriteFn) (InstancePtr->FifoInstance, + &(InstancePtr->AlignedBuffer.bytes[0]), + 1); + InstancePtr->TailIndex = 0; + } + + /* + * Kick off the hw write + */ + (*(InstancePtr)->SetLenFn) (InstancePtr->FifoInstance, Bytes); +} + +/*****************************************************************************/ +/* +* +* XStrm_Write writes Bytes bytes of the block of memory, referenced by +* BufPtr, to the transmit channel of the FIFO referenced by +* InstancePtr. +* +* Care must be taken to ensure that the number of bytes written with one or +* more calls to XStrm_Write() matches the number of bytes given in the next +* call to XStrm_TxSetLen(). +* +* @param InstancePtr references the FIFO on which to operate. +* +* @param BufPtr specifies the memory address of data to write. +* +* @param Bytes specifies the number of bytes to write. +* +* @return N/A +* +******************************************************************************/ +void XStrm_Write(XStrm_TxFifoStreamer *InstancePtr, void *BufPtr, + unsigned Bytes) +{ + u8 *SrcPtr = (u8 *) BufPtr; + unsigned BytesRemaining = Bytes; + unsigned FifoWordsToXfer; + unsigned PartialBytes; + unsigned i; + + while (BytesRemaining) { + xdbg_printf(XDBG_DEBUG_FIFO_TX, + "XStrm_Write: BytesRemaining: %d\n", + BytesRemaining); + /* Case 1: The holding buffer is full + * + * 1) Write it to the fifo. + * 2) Fall through to transfer more bytes in this iteration. + */ + if (InstancePtr->TailIndex == InstancePtr->FifoWidth) { + xdbg_printf(XDBG_DEBUG_FIFO_TX, + "XStrm_Write: (case 1) TailIndex: %d; FifoWidth: %d; WriteFn: %p\n", + InstancePtr->TailIndex, InstancePtr->FifoWidth, + InstancePtr->WriteFn); + (*InstancePtr->WriteFn) (InstancePtr->FifoInstance, + &(InstancePtr->AlignedBuffer. + bytes[0]), 1); + InstancePtr->TailIndex = 0; + } + /* Case 2: There are no bytes in the holding buffer and + * the target buffer is 32 bit aligned and + * the number of bytes remaining to transfer is greater + * than or equal to the fifo width. + * + * 1) We can go fast by writing a long string of fifo words right out + * of the source buffer into the fifo. + * 2) Loop back around to transfer the last few bytes. + */ + if ((InstancePtr->TailIndex == 0) && + (BytesRemaining >= InstancePtr->FifoWidth) && + (((unsigned)SrcPtr & 3) == 0)) { + FifoWordsToXfer = + BytesRemaining / InstancePtr->FifoWidth; + + xdbg_printf(XDBG_DEBUG_FIFO_TX, "XStrm_Write: (case 2) TailIndex: %d; BytesRemaining: %d; FifoWidth: %d; SrcPtr: %p;\n InstancePtr: %p; WriteFn: %p ,\nFifoWordsToXfer: %d (BytesRemaining: %d)\n", + InstancePtr->TailIndex, BytesRemaining, + InstancePtr->FifoWidth, SrcPtr, + InstancePtr, InstancePtr->WriteFn, + FifoWordsToXfer, + BytesRemaining); + + (*InstancePtr->WriteFn) (InstancePtr->FifoInstance, + SrcPtr, FifoWordsToXfer); + SrcPtr += FifoWordsToXfer * InstancePtr->FifoWidth; + BytesRemaining -= + FifoWordsToXfer * InstancePtr->FifoWidth; + xdbg_printf(XDBG_DEBUG_FIFO_TX, "XStrm_Write: (end case 2) TailIndex: %d; BytesRemaining: %d; SrcPtr: %p\n", + InstancePtr->TailIndex, BytesRemaining, SrcPtr); + } + /* Case 3: The alignment of the "galaxies" didn't occur in + * Case 2 above, so we must pump the bytes through the + * holding buffer. + * + * 1) Write bytes from the source buffer to the holding buffer + * 2) Loop back around and handle the rest of the transfer. + */ + else { + i = InstancePtr->TailIndex; + + PartialBytes = + min(BytesRemaining, + InstancePtr->FifoWidth - + InstancePtr->TailIndex); + BytesRemaining -= PartialBytes; + InstancePtr->TailIndex += PartialBytes; + while (PartialBytes--) { + xdbg_printf(XDBG_DEBUG_FIFO_TX, "XStrm_Write: (case 3) PartialBytes: %d\n", + PartialBytes); + InstancePtr->AlignedBuffer.bytes[i] = *SrcPtr; + i++; + SrcPtr++; + } + } + } +} diff --git a/XilinxProcessorIPLib/drivers/llfifo/src/xstreamer.h b/XilinxProcessorIPLib/drivers/llfifo/src/xstreamer.h new file mode 100644 index 00000000..6250b73c --- /dev/null +++ b/XilinxProcessorIPLib/drivers/llfifo/src/xstreamer.h @@ -0,0 +1,330 @@ +/****************************************************************************** +* +* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/* + * + * @file xstreamer.h + * + * The Xilinx byte streamer for packet FIFOs. + * + *

Driver Description

+ * + * This driver enables higher layer software to access a hardware FIFO using + * any alignment in the data buffers while preserving alignment for the hardware + * FIFO access. + * + * This driver treats send and receive channels separately, using different + * types of instance objects for each. + * + * This driver makes use of another FIFO driver to access the specific FIFO + * hardware through use of the routines passed into the Tx/RxInitialize + * routines. + * + *

Initialization

+ * + * Send and receive channels are intialized separately. The receive channel is + * initiailzed using XStrm_RxInitialize(). The send channel is initialized + * using XStrm_TxInitialize(). + * + * + *

Usage

+ * It is fairly simple to use the API provided by this byte streamer + * driver. The only somewhat tricky part is that the calling code must + * correctly call a couple routines in the right sequence for receive and + * transmit. + * + * This sequence is described here. Check the routine functional + * descriptions for information on how to use a specific API routine. + * + *

Receive

+ * A frame is received by using the following sequence:
+ * 1) call XStrm_RxGetLen() to get the length of the next incoming frame.
+ * 2) call XStrm_Read() one or more times to read the number of bytes + * reported by XStrm_RxGetLen().
+ * + * For example: + *
+ * 	frame_len = XStrm_RxGetLen(&RxInstance);
+ * 	while (frame_len) {
+ * 		unsigned bytes = min(sizeof(buffer), frame_len);
+ * 		XStrm_Read(&RxInstance, buffer, bytes);
+ * 		// do something with buffer here
+ * 		frame_len -= bytes;
+ * 	}
+ * 
+ * + * Other restrictions on the sequence of API calls may apply depending on + * the specific FIFO driver used by this byte streamer driver. + * + *

Transmit

+ * A frame is transmittted by using the following sequence:
+ * 1) call XStrm_Write() one or more times to write all the of bytes in + * the next frame.
+ * 2) call XStrm_TxSetLen() to begin the transmission of frame just + * written.
+ * + * For example: + *
+ * 	frame_left = frame_len;
+ * 	while (frame_left) {
+ * 		unsigned bytes = min(sizeof(buffer), frame_left);
+ * 		XStrm_Write(&TxInstance, buffer, bytes);
+ * 		// do something here to refill buffer
+ * 	}
+ * 	XStrm_TxSetLen(&RxInstance, frame_len);
+ * 
+ * + * Other restrictions on the sequence of API calls may apply depending on + * the specific FIFO driver used by this byte streamer driver. + * + *
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  10/12/06 First release
+ * 1.02a jz   12/04/09  Hal phase 1 support
+ * 2.00a hbm  01/20/10  Hal phase 1 support, bump up major release
+ * 2.02a asa  12/28/11  The macro XStrm_IsRxInternalEmpty is changed to use
+ *			FrmByteCnt instead of HeadIndex.
+ * 
+ * + *****************************************************************************/ +#ifndef XSTREAMER_H /* prevent circular inclusions */ +#define XSTREAMER_H /* by using preprocessor symbols */ + +/* force C linkage */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "xenv.h" +#include "xdebug.h" +#include "xil_types.h" + +/* + * key hole size in 32 bit words + */ +#define LARGEST_FIFO_KEYHOLE_SIZE_WORDS 4 + +/* + * This union is used simply to force a 32bit alignment on the + * buffer. Only the 'bytes' member is really used. + */ +union XStrm_AlignedBufferType { + u32 _words[LARGEST_FIFO_KEYHOLE_SIZE_WORDS]; + char bytes[LARGEST_FIFO_KEYHOLE_SIZE_WORDS * 4]; +}; + +typedef int(*XStrm_XferFnType) (void *FifoInstance, void *BufPtr, + unsigned WordCount); +typedef u32 (*XStrm_GetLenFnType) (void *FifoInstance); +typedef void (*XStrm_SetLenFnType) (void *FifoInstance, + u32 ByteCount); +typedef u32 (*XStrm_GetOccupancyFnType) (void *FifoInstance); +typedef u32 (*XStrm_GetVacancyFnType) (void *FifoInstance); + +/** + * This typedef defines a run-time instance of a receive byte-streamer. + */ +typedef struct XStrm_RxFifoStreamer { + union XStrm_AlignedBufferType AlignedBuffer; + unsigned HeadIndex; /**< HeadIndex is the index to the AlignedBuffer + * as bytes. + */ + unsigned FifoWidth; /**< FifoWidth is the FIFO key hole width in bytes. + */ + unsigned FrmByteCnt; /**< FrmByteCnt is the number of bytes in the next + * Frame. + */ + void *FifoInstance; /**< FifoInstance is the FIFO driver instance to + * pass to ReadFn, GetLenFn, and GetOccupancyFn + * routines. + */ + XStrm_XferFnType ReadFn; /**< ReadFn is the routine the streamer + * uses to receive bytes from the Fifo. + */ + XStrm_GetLenFnType GetLenFn; /**< GetLenFn is the routine the streamer + * uses to initiate receive operations + * on the FIFO. + */ + XStrm_GetOccupancyFnType GetOccupancyFn; /**< GetOccupancyFn is the + * routine the streamer uses + * to get the occupancy from + * the FIFO. + */ +} XStrm_RxFifoStreamer; + +/** + * This typedef defines a run-time instance of a transmit byte-streamer. + */ +typedef struct XStrm_TxFifoStreamer { + union XStrm_AlignedBufferType AlignedBuffer; + unsigned TailIndex; /**< TailIndex is the index to the AlignedBuffer + * as bytes + */ + unsigned FifoWidth; /**< FifoWidth is the FIFO key hole width in bytes. + */ + + void *FifoInstance; /**< FifoInstance is the FIFO driver instance to + * pass to WriteFn, SetLenFn, and GetVacancyFn + * routines. + */ + XStrm_XferFnType WriteFn; /**< WriteFn is the routine the streamer + * uses to transmit bytes to the Fifo. + */ + XStrm_SetLenFnType SetLenFn; /**< SetLenFn is the routine the streamer + * uses to initiate transmit operations + * on the FIFO. + */ + XStrm_GetVacancyFnType GetVacancyFn; /**< GetVaccancyFn is the routine + * the streamer uses to get the + * vacancy from the FIFO. + */ +} XStrm_TxFifoStreamer; + +/*****************************************************************************/ +/* +* +* XStrm_TxVacancy returns the number of unused 32-bit words available (vacancy) +* between the streamer, specified by InstancePtr, and the FIFO this +* streamer is using. +* +* @param InstancePtr references the streamer on which to operate. +* +* @return XStrm_TxVacancy returns the vacancy count in number of 32 bit words. +* +* @note +* +* C Signature: u32 XStrm_TxVacancy(XStrm_TxFifoStreamer *InstancePtr) +* +* The amount of bytes in the holding buffer (rounded up to whole 32-bit words) +* is subtracted from the vacancy value of FIFO this streamer is using. This is +* to ensure the caller can write the number words given in the return value and +* not overflow the FIFO. +* +******************************************************************************/ +#define XStrm_TxVacancy(InstancePtr) \ + (((*(InstancePtr)->GetVacancyFn)((InstancePtr)->FifoInstance)) - \ + (((InstancePtr)->TailIndex + 3) / 4)) + +/*****************************************************************************/ +/* +* +* XStrm_RxOccupancy returns the number of 32-bit words available (occupancy) to +* be read from the streamer, specified by InstancePtr, and FIFO this +* steamer is using. +* +* @param InstancePtr references the streamer on which to operate. +* +* @return XStrm_RxOccupancy returns the occupancy count in number of 32 bit +* words. +* +* @note +* +* C Signature: u32 XStrm_RxOccupancy(XStrm_RxFifoStreamer *InstancePtr) +* +* The amount of bytes in the holding buffer (rounded up to whole 32-bit words) +* is added to the occupancy value of FIFO this streamer is using. This is to +* ensure the caller will get a little more accurate occupancy value. +* +******************************************************************************/ +#ifdef DEBUG +extern u32 _xstrm_ro_value; +extern u32 _xstrm_buffered; +#define XStrm_RxOccupancy(InstancePtr) \ + (_xstrm_ro_value = ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)), \ + xdbg_printf(XDBG_DEBUG_FIFO_RX, "reg: %d; frmbytecnt: %d\n", \ + _xstrm_ro_value, (InstancePtr)->FrmByteCnt), \ + (((InstancePtr)->FrmByteCnt) ? \ + _xstrm_buffered = ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \ + 0), \ + xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered_bytes: %d\n", _xstrm_buffered), \ + xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered (rounded): %d\n", _xstrm_buffered), \ + (_xstrm_ro_value + _xstrm_buffered)) +#else +#define XStrm_RxOccupancy(InstancePtr) \ + ( \ + ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)) + \ + ( \ + ((InstancePtr)->FrmByteCnt) ? \ + ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \ + 0 \ + ) \ + ) +#endif + +/****************************************************************************/ +/* +* +* XStrm_IsRxInternalEmpty returns true if the streamer, specified by +* InstancePtr, is not holding any bytes in it's internal buffers. Note +* that this routine does not reflect information about the state of the +* FIFO used by this streamer. +* +* @param InstancePtr references the streamer on which to operate. +* +* @return XStrm_IsRxInternalEmpty returns TRUE when the streamer is not +* holding any bytes in it's internal buffers. Otherwise, +* XStrm_IsRxInternalEmpty returns FALSE. +* +* @note +* C-style signature: +* int XStrm_IsRxInternalEmpty(XStrm_RxFifoStreamer *InstancePtr) +* +*****************************************************************************/ +#define XStrm_IsRxInternalEmpty(InstancePtr) \ + (((InstancePtr)->FrmByteCnt == 0) ? TRUE : FALSE) + +void XStrm_RxInitialize(XStrm_RxFifoStreamer *InstancePtr, + unsigned FifoWidth, void *FifoInstance, + XStrm_XferFnType ReadFn, + XStrm_GetLenFnType GetLenFn, + XStrm_GetOccupancyFnType GetOccupancyFn); + +void XStrm_TxInitialize(XStrm_TxFifoStreamer *InstancePtr, + unsigned FifoWidth, void *FifoInstance, + XStrm_XferFnType WriteFn, + XStrm_SetLenFnType SetLenFn, + XStrm_GetVacancyFnType GetVacancyFn); + +void XStrm_TxSetLen(XStrm_TxFifoStreamer *InstancePtr, u32 Bytes); +void XStrm_Write(XStrm_TxFifoStreamer *InstancePtr, void *BufPtr, + unsigned bytes); + +u32 XStrm_RxGetLen(XStrm_RxFifoStreamer *InstancePtr); +void XStrm_Read(XStrm_RxFifoStreamer *InstancePtr, void *BufPtr, + unsigned bytes); + +#ifdef __cplusplus +} +#endif +#endif /* XSTREAMER_H end of preprocessor protection symbols */