ADRV904x no-OS Example Project
See projects/adrv904x (doxygen) for the Doxygen documentation.
Supported Evaluation Boards
Overview
The ADRV904x family is a software-defined radio (SDR) transceiver family from Analog Devices. The ADRV9040 is an integrated quad RF transceiver capable of simultaneous multi-band operation. The device integrates four transmit channels, four receive channels, an observation receiver, and an integrated frequency synthesizer with phase-locked loop (PLL), covering frequencies from 650 MHz to 6 GHz. The transceiver supports 5G NR, LTE, and multi-standard radio applications.
The JESD204C-based digital interface connects to an FPGA host platform. On-chip
features include digital predistortion (DPD), crest factor reduction (CFR), an
ARM Cortex-A55 application processor for running on-chip firmware, and integrated
3 Gbps JESD204C SerDes lanes. The device requires the Koror vendor API, bundled
under drivers/rf-transceiver/koror/, for initialization and control.
Applications
5G New Radio (NR) base stations
Multi-standard radio (MSR) systems
Wireless backhaul and fronthaul
Software-defined radio (SDR) platforms
Military and defense communications
Test and measurement
Hardware Specifications
Power Supply Requirements
The ADRV904x evaluation board is powered through the FMC connector of the carrier board (ZCU102). The ZCU102 supplies the required voltages to the evaluation board over the high-pin-count FMC2 connector. Ensure the ZCU102 power supply is rated for the full evaluation board current draw.
On-board Connectors
Connector |
Function |
|---|---|
FMC2 (HPC) |
High-speed digital interface to carrier (JESD204C lanes, SPI, GPIO, clocks) |
SMA RF ports |
Transmit (Tx) and Receive (Rx) RF signal connectors |
Connect the ADRV904x evaluation board to the FMC2 connector on the ZCU102 before powering the system.
No-OS Supported Examples
This project is organized around the no-OS variant based build flow.
Selecting a variant at build time (--variant <name>) chooses which
application is compiled. The platform main() is a thin dispatcher that
calls example_main(), provided by the selected example. Shared
initialization data is defined in
src/common,
and platform-specific macros and extra init parameters are in
src/platform.
Basic Example
The basic example initializes the ADRV904x transceiver via the Koror vendor API, brings up the JESD204C RX/TX links using the AXI JESD204, AXI ADC core, AXI DAC core, and AXI DMAC IP cores, and enables the default DDS waveform on Tx. Runtime status messages (link rates, SYSREF alignment, deframer status) are printed over UART. This is the recommended starting point for board bring-up.
Select this variant with --variant basic_example.
The output from a successful initialization looks like:
rx_adxcvr: Using QPLL with previously defined settings.
Firmware file: ADRV9040_FW.bin
Gain Table file: RxGainTable.csv
Streams file: stream_image.bin
Device Profile file: DeviceProfileTest.bin
DFE file: ADRV9040_DFE_CALS_FW.bin
adrv904x_setup()
adrv904x-phy Rev 0, API version: 2.10.0.4 found
adrv904x-device revision: 0xa0
Using the Profile Init and PostMcsInit Structures
tx_dac: Successfully initialized (491564941 Hz)
tx_adxcvr: OK (16220160 kHz)
rx_adxcvr: OK (16220160 kHz)
tx_jesd status:
Link is enabled
Measured Link Clock: 245.782 MHz
Reported Link Clock: 245.760 MHz
Lane rate: 16220.160 MHz
Lane rate / 66: 245.760 MHz
LEMC rate: 7.680 MHz
Link status: DATA
SYSREF captured: Yes
SYSREF alignment error: No
rx_jesd status:
Link is enabled
...
Link status: DATA
SYSREF captured: Yes
SYSREF alignment error: No
DMA Example
The DMA example sends a sinewave on the Tx channels using DMA from an in-memory lookup table. When a Tx channel is physically looped back to an Rx channel via an electrical wire, the received data can be read from its memory address. After the link initialization output, the application prints the memory addresses:
DMA_EXAMPLE Tx: address=0x434800 samples=8192 channels=16 bits=32
DMA_EXAMPLE Rx: address=0x43c800 samples=262144 channels=16 bits=16
The Xilinx xsct tool can retrieve data from memory and save it to CSV files:
xsct tools/scripts/platform/xilinx/capture.tcl ZYNQ_PSU 0x43c800 262144 16 16
The resulting CSV files can be visualized using the plot.py script:
python tools/scripts/platform/xilinx/plot.py 16
More information about the DMA data format is available at no-OS DAC DMA example.
Select this variant with --variant dma_example.
IIO Example
The IIO example launches an IIOD server on the ZCU102 so that a host IIO client
can connect via the serial backend. The AXI ADC and AXI DAC cores are exposed
through the IIO framework (iio_axi_adc and iio_axi_dac), enabling
host-side data capture and playback using IIO-Oscilloscope or libiio tools.
If you are not familiar with ADI IIO Application, please take a look at: IIO No-OS
If you are not familiar with ADI IIO-Oscilloscope Client, please take a look at: IIO Oscilloscope
After the JESD link is established, the application prints:
Running IIOD server...
If successful, you may connect an IIO client application by:
1. Disconnecting the serial terminal you use to view this message.
2. Connecting the IIO client application using the serial backend configured as shown:
Baudrate: 921600
Data size: 8 bits
Parity: none
Stop bits: 1
Flow control: none
Connect to the IIOD server using a serial-backend enabled iio-oscilloscope with the settings printed at the serial terminal.
Select this variant with --variant iio_example.
No-OS Supported Platforms
Xilinx
Used Hardware
Connections
Connect the ADRV904x evaluation board to the FMC2 (HPC) connector on the ZCU102 before powering the system.
The UART console appears on the ZCU102 USB-UART adapter (/dev/ttyUSB0 or
/dev/ttyUSB1 on Linux, COMx on Windows) at 115200 baud, 8N1.
Build Command
The Xilinx platform uses the CMake/Ninja build system via the
no_os_build.py helper script. Available variants: basic_example,
dma_example, iio_example. Available boards: zcu102.
A Xilinx hardware description file (.xsa) generated from the matching HDL
design is required. The HDL design name for all variants is adrv904x (see
CONFIG_XILINX_HDL_DESIGN in each .conf file). Obtain the pre-built
adrv904x_zcu102/system_top.xsa from the ADI HDL repository releases, or
build it yourself by following the
Building HDL guide.
For toolchain setup and prerequisites, see the Xilinx CMake build guide.
# source the Vitis environment (adjust path to your Vitis install)
source ~/.xilinx/2025.1/Vitis/settings64.sh
# PowerShell (Windows) equivalent:
# & "$env:USERPROFILE\.xilinx\2025.1\Vitis\settings64.bat"
cd no-OS
# build the basic example on the ZCU102
python tools/scripts/no_os_build.py build \
--project adrv904x --variant basic_example --board zcu102 \
--hardware /path/to/adrv904x_zcu102/system_top.xsa
# build and flash (requires a connected debug probe)
python tools/scripts/no_os_build.py build \
--project adrv904x --variant basic_example --board zcu102 \
--hardware /path/to/adrv904x_zcu102/system_top.xsa \
--probe openocd --flash
Replace basic_example with dma_example or iio_example to build
the corresponding variant.
Note
After programming, the Vitis IDE may require manual heap size adjustment
to 0x800000 and adding the math library (-lm) to the GCC linker flags.