Digilent provides a set of libraries supporting Zmod modules on both Linux and baremetal (standalone) platforms.
The Zmod Base Library implements functionality common to all Zmods. For each Zmod, separate libraries are implemented, based on Zmod Base Library.
This document describes the Zmod Base Library structure and also addresses issues common to all Zmods.
These instructions / demos are provided for the Zmods attached to an Eclypse board, still Zmods can be attached to any Zynq board having a SYZYGY connector.
Note: At the time of writing, the ZmodADC1410 library only supports the Zmod Scope 1410-105 (formerly known as the Zmod ADC 1410.
The following block diagram shows the overall structure of Zmod Libraries.
The Zmod libraries run in the Zynq PS (processing system).
The Zmod is physically attached on the SYZYGY connector of the development board (Eclypse).
In the Zynq PL (FPGA) there is an IP core specific to each Zmod. This IP core can be accessed from the Zynq PS through its registers. The IP core is able to communicate with the memory over the AXI DMA data bus. Each Zmod has associated one particular instance of AXI DMA IP core.
Communication over the AXI DMA is mastered by the Zmod libraries.
The Zmod libraries contain two layers. The base layer is called Zmod Base Library and is described under this page. It mainly deals with the functionality common to all Zmods and provides the platform abstraction layer, ensuring consistent implementation for the two supported platforms (Linux, Baremetal), hiding under it all the platform related functionality.
On the higher level there is a Zmod specific library. It is based on the Zmod Base library and implements only the Zmod specific functionality and definitions.
The Zmod Libraries ensure the following objectives are met:
The above mentioned topics are detailed and described in the next section Implementation Details.
The Zmod Base Library implementation consists of a C++ class called ZMOD Class which is the base class for inherited classes used for each particular Zmod.
Also, the Zmod Base Library implementation contains two separate folders: Linux and Baremetal.
Consult the table in the right in order to proceed to the Environment Setup section.
Download the git files indicated below in order to access the Projects Files and Demos for the two Zmods: ADC1410 and DAC1411, together with the Base library files.
Download source files:
Library and Demo files | ZmodADC1410 Demo Files | DAC1411 Demo Files |
---|---|---|
Base Zmod Library | ZMODADC1410 Demo | ZMODDAC1411 Demo |
Shortcut to Projects Setup section:
Clone the git repository containing the libraries and demos using the below command:
git clone --recursive https://github.com/Digilent/Eclypse-Z7-SW.git -b zmod_adc_dac/master
Similar command for the Zmod specific demos.
For details on the Zmod specific libraries see the following documents:
For details on the Zmod API, see the following document:
The ZMOD Class calls Zmod IP Cores related functionality, AXI DMA related functionality and Flash related functionality which are implemented differently on Linux and Baremetal. The platform abstraction layer provides a common API for both platforms.
The Zmod folder contains these header files: reg.h, dma.h and flash.h which contain declarations for the platform dependent functions corresponding to IP Core registers, AXI DMA and Flash. The functions prototypes are common for both platforms while their implementation resides in the Baremetal and Linux folders.
The project level definition LINUX_APP ensures each function is implemented exactly once (all the Linux platform projects must define LINUX_APP).
Under the Linux and Baremetal folders there is a separate folder for each interface: reg, dma, flash, and intc (for Baremetal only).
For more details, read the functionality described below in this section.
The IP core related functionality provides access to the registers of the IP core corresponding to a particular Zmod.
This functionality allows:
This functionality is platform dependent, as explained in the Platform Abstraction Layer.
The prototype of these functions is placed in the Zmod/reg.h file and is common to both Linux and Baremetal platforms. The implementation of these functions is in Zmod/linux/reg.c and Zmod/baremetal/reg.c respectively, exclusively depending on the project level definition LINUX_APP.
The Linux implementation uses UIO mapping to access the IP registers.
The Baremetal implementation uses Xil_Out32 and Xil_In32 to access the IP registers.
The Baremetal uses the Xilinx interrupt controller XIntc. The interrupt related implementation is implemented in Zmod/intc folder.
The initialization function takes the IP base address and the IP interrupt number as parameters.
On Linux, the IP base address is stored in /sys/class/uio/uio<uio number>/maps/map<map number>/addr file. The <uio number> and <map number> are usually '0'. For Linux the IP core interrupt is not implemented, so -1 is used.
For baremetal, the IP base address and the IP interrupt number are specified in xparameters.h (in the bsp include files). For example, XPAR_AXI_ZMODADC1410_0_S00_AXI_BASEADDR and XPAR_FABRIC_AXI_ZMODADC1410_0_IRQ_OUT_INTR.
The IP core related functionality is mainly called from IP Cores Register Access Functions of ZMOD Class.
The AXI DMA related functionality provides the ability to transfer data over AXI DMA.
The functionality allows:
This functionality is platform dependent, as explained in the Platform Abstraction Layer.
The prototype of these functions is placed in the Zmod/dma.h file and is common to both Linux and baremetal platforms. The implementation of these functions is in Zmod/linux/dma.c and Zmod/baremetal/dma.c respectively, exclusively depending on the project level definition LINUX_APP.
The Linux implementation uses libaxidma devices for each AXIDMA instance.
The Baremetal implementation uses the XAxiDma driver for each AXIDMA instance.
The initialization function takes the AXI DMA base address and the AXI DMA interrupt number as parameters.
For Linux, the AXI DMA base address can be found in the /sys/class/uio/uio<uio number>/maps/map<map number>/addr file. The <uio number> and <map number> are usually '0'.
The AXI DMA interrupt is implemented inside libaxidma, so -1 value can be provided for the AXI DMA interrupt number.
For Baremetal, the AXI DMA base address and the AXI DMA interrupt number are specified in xparameters.h file (in the bsp include files). For example XPAR_AXI_DMA_0_BASEADDR and XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR.
The Zmod implementation uses one way AXI DMA transfers (S2MM or MM2S), so the transfer direction is set in the initialization function.
The AXI DMA related functionality is mainly called from AXI DMA Transfer Functions of ZMOD Class.
The Flash related functionality provides access to the persistent memory (flash) placed on each Zmod. These functions handle calibration values.
Their functionality allows:
This functionality is platform dependent, as explained in the Platform Abstraction Layer.
The prototype of these functions is placed in the Zmod/flash.h file and is common to both Linux and Baremetal platforms. The implementation of these functions is in the Zmod/linux/flash.c and Zmod/baremetal/flash.c respectively, exclusively depending on the project level definition LINUX_APP.
The Linux implementation uses /dev/i2c-0 device.
The Baremetal implementation uses XIicPs driver.
The initialization function takes the Flash base address as a parameter.
For Linux, the Flash base address can be found in the /sys/bus/i2c/devices/i2c-<i2c number>/name file by parsing its content for the address. The <i2c number> is usually '0'. For example, the content of /sys/bus/i2c/devices/i2c-0/name is “Cadence I2C at e0005000”, e0005000 being the needed Flash base address.
For Baremetal Flash base address is specified in xparameters.h (in the bsp include files). For example XPAR_PS7_I2C_1_BASEADDR.
The initialization function also requires the address of slave I2C device corresponding to the Zmod connector.
For Eclypse, the addresses of slave I2C devices are: 0x30 (corresponding to ZMOD A connector) and 0x31 (corresponding to ZMOD B connector).
The Flash related functionality is mainly called from Calibrations Functions of ZMOD Class.
This is the base class for individual Zmod classes (for example ZMODADC1410 class or ZMODDAC1411 class). It implements the functionality common to all Zmods and all the functionality needed to access hardware resources, abstracting these details from the derived classes. It implements the following function members:
The ZMOD class constructor initializes the hardware interfaces. It takes the following parameters:
The ZMOD class destructor calls the destroy functions for the hardware interfaces, also freeing the dynamically allocated calibration data.
The ZMOD class provides initialization of the IP core related module, and access to IP core registers.
To access IP core related functionality, the ZMOD class calls functions from the platform abstraction layer (see IP Core Related Functionality).
Thus read/write register and read/write register field functions are provided, both in signed and unsigned versions: readReg, writeReg, readRegFld, writeRegFld, readSignedRegFld and writeSignedRegFld.
A register's bit field designates a number of contiguous bits inside an IP core register and is defined as a triplet of IP core register address, start bit, and end bit. Some register's bit fields can be common to all ZMODS (defined in the base class header file zmod.h) or specific to an individual Zmod (defined in the specific library header file, ZMODADC1410/zmodadc1410.h for example). The register's bit fields definitions can be found on each specific Zmod library user guide.
The ZMOD class also provides functions that allow sending and receiving commands to / from the chip on the specific ZMOD (for example sending commands to the ADC device on the ZmodADC1410 or to the DAC device on the ZmodDAC1411): sendCommand and receiveCommand functions.
To access AXI DMA related functionality, the ZMOD class calls functions from the platform abstraction layer (see AXI DMA Related Functionality).
The ZMOD class provides initialization and one way AXI DMA transfer functions.
Also, ZMOD class provides data buffer allocation / de-allocation functions: allocDMABuffer and freeDMABuffer.
The setTransferSize function allows setting the AXI DMA transfer size (in bytes).
The startDMATransfer function starts an uni-directional (one way) AXI DMA transfer.
The isDMATransferComplete function informs when a transfer is complete.
To access the flash memory functionality, ZMOD class calls functions from the platform abstraction layer (see Flash Related Functionality).
The ZMOD class provides flash initialization and flash transfer functions.
These functions are used to manage calibration values specific to each Zmod. They are computed during the Zmod manufacturing process and are stored in the Zmod persistent memory (flash) at specific addresses.
The meaning of the content stored in flash memory is specific to each Zmod type, still there are common features:
The initCalib function initializes the calibration related data. It is normally called from the classes derived from ZMOD class, providing as parameter the Zmod ID and the length of the calibration area. The function allocates an array of bytes that will be used as calibration image. The classes derived from ZMOD class will interpret this image as specific calibration structure.
The readUserCalib function reads from flash an array of bytes from the flash address corresponding to the user calibration. The length of this array is the length of the calibration area. It returns specific errors if the first byte is different than the expected Zmod ID and if the last byte does not match the checksum of the previous bytes.
The restoreFactoryCalib function reads an array of bytes from the flash address corresponding to the factory calibration and writes the array of bytes to the flash address corresponding to the user calibration.
The writeUserCalib function writes an array of bytes to the flash address corresponding to the user calibration. Prior to writing, it fills the first byte with the Zmod ID and it computes the checksum on the last byte of the array of bytes to be written.
The base library and demos are delivered as a 2019.1 Xilinx Vivado SDK workspace and the structure is presented below:
Under each of the above described demos, the zmodlib folder can be found, having the following structure:
This section contains the steps for setting the environment for Baremetal project setup and Linux project setup for both Zmod ADC and Zmod DAC. Depending on the user needs, one can either use the projects we deliver in their own development process or use the libraries in their projects. If the second case is considered, the user should apply the below described settings to his project, in order to be able to build it.
The steps below need to be followed in order to obtain a complete SDK workspace and to be able to build and run any of the projects, in either Linux or Baremetal platforms.
The ZmodADC1410_Demo_Linux and ZmodDAC1411_Demo_Linux are run from Xilinx SDK.
This step by step tutorial roughly follows the How to debug Linux Application in SDK 2019.1 by Xilinx, with some changes due to our Debian 10 rootfs.
The following steps are for the Eclypse Z7 board. If a Zmod ADC is used, it should be attached to the Eclypse Z7's ZMOD A port. If a Zmod DAC is used, it should be attached to the Eclypse Z7's ZMOD B port.
git clone --recursive https://github.com/Digilent/Eclypse-Z7-SW.git -b zmod_adc_dac/master
NOTE: If you choose to download the repository as ZIP, the folder zmodlib will not be populated and you will have to populate it manually.
dd if=/path/to/extracted/image/eclypse-debian-buster-armhf-rfs.img of=/dev/(sdX or mmcblkX} && sync
ip a
git clone --recursive https://github.com/Digilent/Eclypse-Z7-SW.git -b zmod_adc_dac/master
NOTE: If you choose to download the repository as ZIP, the folder zmodlib will not be populated and you will have to populate it manually.
This use case is needed when an SDK workspace is created by the user. The steps below need to be followed in order to obtain a complete SDK workspace and to be able to build and run any of the projects, in either Linux or Baremetal platforms.
It is assumed that Zmod and specific folders for Zmods (ZmodADC1410 for example) are placed in the SDK workspace root folder, as provided by Digilent (see Delivery Structure).
--sysroot=${SYSROOT}
Note: In Petalinux 2019.1 in order to build the sysroot image is necessary to run the following command:
petalinux-build -c build-sysroots
It is assumed that Zmod and specific folders for Zmods (ZmodADC1410 for example) are placed in the SDK workspace root folder, as provided by Digilent (see Delivery Structure).