Examples

This page provides working examples showing how to generate ADRV9002 profiles using the library. Each example creates a complete 2Rx/2Tx LTE 10 MHz configuration — a common starting point that you can modify for your application.

The general workflow is:

  1. Create configuration structures for RX channels, TX channels, radio settings, and clocks

  2. Call generate_profile() to produce the profile JSON and stream binary

  3. Write the outputs to files or load them directly onto hardware

C Example

A complete C example that configures a 2Rx/2Tx LTE 10 MHz profile:

#include <adrv9002_iio.h>
#include <stdio.h>
#include <stdlib.h>

// Same as ref_profile.json
adrv9002_config lte_lvs_3072_MHz_10() {
  rx_radio_channel_config rx1;
  rx1.enabled = 1;
  rx1.adc_high_performance_mode = true;
  rx1.frequency_offset_correction_enable = false;
  rx1.analog_filter_power_mode = 2; // High power/performance
  rx1.analog_filter_biquad = false;
  rx1.channel_bandwidth_hz = 18000000;
  rx1.sample_rate_hz = 30720000;
  rx1.nco_enable = false;
  rx1.nco_frequency_hz = 0;
  rx1.rf_port = 0; // RX-A

  // Copy rx1 to rx2
  rx_radio_channel_config rx2 = rx1;
  rx2.rf_port = 0; // RX-B

  // TX side
  tx_radio_channel_config tx1;
  tx1.enabled = 1;
  tx1.sample_rate_hz = 30720000;
  tx1.frequency_offset_correction_enable = false;
  tx1.analog_filter_power_mode = 2; // High power/performance
  tx1.channel_bandwidth_hz = 18000000;
  tx1.orx_enabled = true;
  tx1.elb_type = 2;

  // Copy tx1 to tx2
  tx_radio_channel_config tx2 = tx1;

  radio_config r_cfg;
  r_cfg.adc_rate_mode = 3; // High Performance
  r_cfg.fdd = false;
  r_cfg.lvds = true;
  r_cfg.ssi_lanes = 2;
  r_cfg.ddr = true;
  r_cfg.adc_rate_mode = 3; // High Performance
  r_cfg.short_strobe = true;
  r_cfg.rx_config[0] = rx1;
  r_cfg.rx_config[1] = rx2;
  r_cfg.tx_config[0] = tx1;
  r_cfg.tx_config[1] = tx2;

  clock_config clk_cfg;
  clk_cfg.device_clock_frequency_khz = 38400;
  clk_cfg.clock_pll_high_performance_enable = true;
  clk_cfg.clock_pll_power_mode = 2; // High power/performance
  clk_cfg.processor_clock_divider = 1;

  adrv9002_config adrv_cfg;
  adrv_cfg.clk_cfg = clk_cfg;
  adrv_cfg.radio_cfg = r_cfg;

  return adrv_cfg;
}

int main() {

  // Create configuration
  adrv9002_config adrv_cfg = lte_lvs_3072_MHz_10();

  // Generate profile and stream image
  char *profile;
  char *stream_image;
  size_t profile_size;
  size_t stream_image_size;

  int ret = adrv9002_generate_profile(&adrv_cfg, &profile, &profile_size,
                                      &stream_image, &stream_image_size);

  if (ret != 0) {
    printf("Error generating profile: %d\n", ret);
    return ret;
  }

  // Write stream and profile to files
  FILE *fp;
  fp = fopen("profile.json", "w");
  fwrite(profile, 1, profile_size, fp);
  fclose(fp);
  fp = fopen("stream_image.bin", "w");
  fwrite(stream_image, 1, stream_image_size, fp);
  fclose(fp);
}

Compiling

gcc -o gen_profile example.c -ladrv9002-iio -ladrv9001-profile-gen -ladrv9001-stream-gen -ladrv9001-filter-designer

Python Example

The same configuration using the Python bindings:

import adrv9002
import pprint
import copy

# Create profile configuration
rx1 = adrv9002.rx_radio_channel_config()
rx1.enabled = True
rx1.adc_high_performance_mode = True
rx1.frequency_offset_correction_enable = False
rx1.analog_filter_power_mode = 2  # High power/performance
rx1.analog_filter_biquad = False
rx1.analog_filter_bandwidth_hz = 18000000
rx1.channel_bandwidth_hz = 18000000
rx1.sample_rate_hz = 30720000
rx1.nco_enable = False
rx1.nco_frequency_hz = 0
rx1.rf_port = 0  # RX-A

rx2 = copy.deepcopy(rx1)

tx1 = adrv9002.tx_radio_channel_config()
tx1.enabled = True
tx1.sample_rate_hz = 30720000
tx1.frequency_offset_correction_enable = False
tx1.analog_filter_power_mode = 2  # High power/performance
tx1.channel_bandwidth_hz = 18000000
tx1.orx_enabled = True
tx1.elb_type = 2

tx2 = copy.deepcopy(tx1)

r_cfg = adrv9002.radio_config()
r_cfg.adc_rate_mode = 3  # High Performance
r_cfg.fdd = False
r_cfg.lvds = True
r_cfg.ssi_lanes = 2
r_cfg.ddr = True
r_cfg.adc_rate_mode = 3  # High Performance
r_cfg.short_strobe = True
r_cfg.rx_config[0] = rx1
r_cfg.rx_config[1] = rx2
r_cfg.tx_config[0] = tx1
r_cfg.tx_config[1] = tx2

clk_cfg = adrv9002.clock_config()
clk_cfg.device_clock_frequency_khz = 38400
clk_cfg.clock_pll_high_performance_enable = True
clk_cfg.clock_pll_power_mode = 2  # High power/performance
clk_cfg.processor_clock_divider = 1

adrv_cfg = adrv9002.adrv9002_config()
adrv_cfg.clk_cfg = clk_cfg
adrv_cfg.radio_cfg = r_cfg

# Generate profile and stream binary
profile, stream = adrv9002.generate_profile(adrv_cfg)

pprint.pprint(profile)

Loading Profiles to Hardware (IIO)

If built with IIO support, you can generate and load a profile in one call:

import adrv9002

cfg = adrv9002.adrv9002_config()
# ... configure cfg ...

# Generate and load directly to hardware
adrv9002.generate_load_profile_iio(cfg, "ip:192.168.2.1")

Configuration Reference

Radio Modes

adc_rate_mode

Description

0

Low Power

1

Medium Performance

2

High Performance

3

Ultra High Performance

Interface Options

Parameter

Values

Description

lvds

True/False

LVDS (True) or CMOS (False) interface

ssi_lanes

1, 2, 4

Number of SSI data lanes

ddr

True/False

Double data rate

short_strobe

True/False

Short strobe mode

fdd

True/False

Frequency Division Duplex mode

Clock Configuration

Parameter

Description

device_clock_frequency_khz

Device clock input (kHz)

clock_pll_high_performance_enable

PLL high-perf mode

processor_clock_divider

1, 2, 4, 8, 16, 32, 64, 128, 256