PYNQ Framework for ANTSDR

PYNQ Framework for ANTSDR

alt tag

This project was inspired by PYNQ and PlutoSDR. There are already many SDR platforms based on ZYNQ and AD9361, so does ANTSDR.

When we saw the PYNQ_RFSOC, we thought PYNQ might also be a good SDR Framework. Due to the high price of RFSOC, we think we can make a product with similar functions based on ANTSDR.

Finally, we transplanted PYNQ framework into ANTSDR successfully. Through the python binding of libiio and python interface pyadi-iio provided by ADI, we can use PYNQ to interact with AD9361. Although the performance of ZYNQ7020+AD9361 may not be the same as RFSoC, it is also a good attempt for us.

Build instruction

In this section, I will briefly introduce how to make PYNQ SD card Image for ANTSDR. For detail information, please refer to PYNQ SD card.

  • Pre-conditions:

    • Host computer: Ubuntu16.04 LTS ( this is the tested version)
    • Vivado 2018.3 (install path /opt/Xilinx)
    • petalinux 2018.3 (install path /opt/pkg/petalinux/2018.3)
    • PYNQ branch image_v2.4

    You should install the required software into the corresponding path .

  • Set up the host

     git clone --recursive https://github.com/MicroPhase/antsdr-pynq.git
     cd antsdr-pynq/pynq/sdbuild/scripts/
     ./setup_host.sh

    This will take a few minutes to setup the host environment. After it finished, you will the the quem and crosstool-ng folder in /opt .

     [email protected]:/opt$ ls -l /opt/
     total 32
     drwxr-xr-x 6 root root 4096 1月   7  2020 crosstool-ng
     drwxr-xr-x 3 wcc  wcc  4096 1月   4  2020 pkg
     drwxr-xr-x 6 root root 4096 1月   7  2020 qemu
     drwxrwxrwx 6 wcc  wcc  4096 1月   7  2020 Xilinx
  • Build the SD card Image

    Now you can build the image from scratch, you can either build from source code or build from offline root file system. I would recommend the second way.

    • Build from offline rootfs You can download the offline PYNQ rootfs from this link: https://www.xilinx.com/member/forms/download/xef.html?filename=pynq_rootfs_arm_v2.4.zip. You can unzip this file to a folder and start to build the image. For example
      mkdir sdbuild/prebuilt
      unzip -d  sdbuild/prebuilt  pynq_rootfs_arm_v2.4.zip
      cd sdbuild
      cp -r  ../../antsdr  ../boards/
      make BOARDS=antsdr  PREBUILT=./prebuilt/bionic.arm.2.4.img
    • Build from source code
      cd sdbuild
      make BOARDS=antsdr

    You can find the output image antsdr-2.4.img in the sdbuild/output folder.

  • Trouble shutting

    • if the result returns a environment error, this could be caused by the petalinux environment settings.
      you should configure the dash.
      sudo dpkg-reconfigure dash    
      (then choose no)
    

Setup the PYNQ for antsdr

Once you have finished building the image, you can let ANTSDR to become a PYNQ SDR.

  • Burn the image into a SD card

    • In linux
       sudo dd if=sdbuild/output/ANTSDR-2.4.img of=/dev/sdb bs=4M
    • In windows you can use win32diskmanger or other software to burn the sd card.
  • Boot up antsdr

You should insert the SD card into antsdr, connect antsdr to the router with a network cable(the antsdr needs to acess to the internet for building libiio from source), connect to the serial port of antsdr and computer with usb, and power on.

antsdr connection

From the serial port terminal, you can see the printed information about PYNQ startup.

Once the PYNQ boot up, you can interact with antsdr through serial port.

[email protected]:~$ ls
jupyter_notebooks  pynq  REVISION
xi[email protected]:~$ ifconfig
eth0: flags=4163
   
      mtu 1500
        inet 192.168.3.226  netmask 255.255.255.0  broadcast 192.168.3.255
        ether 6a:c7:37:d0:cd:8a  txqueuelen 1000  (Ethernet)
        RX packets 4305  bytes 3915132 (3.9 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2803  bytes 240798 (240.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 29  base 0xb000

eth0:1: flags=4163
    
       mtu 1500
        inet 192.168.2.99  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 6a:c7:37:d0:cd:8a  txqueuelen 1000  (Ethernet)
        device interrupt 29  base 0xb000

lo: flags=73
     
        mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 726  bytes 74719 (74.7 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 726  bytes 74719 (74.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[email protected]:~$

     
    
   

You need to connect the ethernet cable to a router, the following steps will needs antsdr to have an access to network.

Python bonding for libiio

You can refer this link to build the python bonding for libiio: python bonding for libiio

NOTE: these instructions below will be running on antsdr. The password for sudo is xilinx

  • Install Prerequisites/Dependencies

    sudo apt-get update
    sudo apt-get install build-essential
    sudo apt-get install libxml2-dev bison flex libcdk5-dev cmake
    sudo apt-get install libaio-dev libusb-1.0-0-dev
    sudo apt-get install libserialport-dev libavahi-client-dev
    sudo apt-get install doxygen graphviz
    sudo apt-get install python3 python3-pip python3-setuptools
  • Install to Read local context attributes from /etc/libiio.ini

    git clone https://github.com/pcercuei/libini.git
    cd libini
    mkdir build && cd build && cmake ../ && make && sudo make install
    cd ~
  • Install libiio and pylibiio

    git clone https://github.com/analogdevicesinc/libiio.git
    cd libiio
    cmake ./
    make all -j$(nproc)
    sudo make install
    sudo ldconfig
    cd bindings/python/
    sudo python3 setup.py.cmakein install
    cd ~

    If the libiio is installed, you can use iio_info to get the information of iio devices.

    [email protected]:~$ iio_info
    Library version: 0.23 (git tag: c14a0f8)
    Compiled with backends: local xml ip usb
    IIO context created with local backend.
    Backend version: 0.23 (git tag: c14a0f8)
    Backend description string: Linux pynq 4.14.0-xilinx- #1 SMP PREEMPT Thu Sep 2 06:07:03 UTC 2021 armv7l
    IIO context has 2 attributes:
            local,kernel: 4.14.0-xilinx-
            uri: local:
    IIO context has 5 devices:
            iio:device0: ad9361-phy
    ......
    ......
    ......
    
  • clone pyadi-iio and move adi folder into jupter note book

    git clone https://github.com/analogdevicesinc/pyadi-iio.git
    cp -r pyadi-iio/adi jupyter_notebooks

Interact AD9361 using jupyter_notebooks

Now, open your web browser and acess to the antsdr. First, let's get the ip address of antsdr.

eth0: flags=4163
   
      mtu 1500
        inet 192.168.3.226  netmask 255.255.255.0  broadcast 192.168.3.255
        ether 6a:c7:37:d0:cd:8a  txqueuelen 1000  (Ethernet)
        RX packets 27542  bytes 34260194 (34.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 19276  bytes 1545616 (1.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 29  base 0xb000

eth0:1: flags=4163
    
       mtu 1500
        inet 192.168.2.99  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 6a:c7:37:d0:cd:8a  txqueuelen 1000  (Ethernet)
        device interrupt 29  base 0xb000

lo: flags=73
     
        mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 765  bytes 77367 (77.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 765  bytes 77367 (77.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

     
    
   

As you can see, there are 2 ip address for the ethernet port, the first one is the dynamic IP address if antsdr are connected to a router. The second one is the static IP address for antsdr.

If you use the first ip address to access the antsdr, you should type the ip address in your browser. for example:192.168.3.229:9090 for dynamic IP. or 192.168.2.99 for static IP(ethernet cable should connect directly to the computer).

By default, the password is xilinx. pynq_login

Then we can see the jupyter notebook, we need a little modifications to use the adi package.change the adi/_init_.py file. comment other package besides ad936x.

file init_py

from adi.ad936x import ad9361, ad9363, ad9364, Pluto

from adi.fmcomms5 import FMComms5

# from adi.ad9371 import ad9371

# from adi.adrv9002 import adrv9002

# from adi.adrv9009 import adrv9009

# from adi.adrv9009_zu11eg import adrv9009_zu11eg

# from adi.adrv9009_zu11eg_multi import adrv9009_zu11eg_multi

# from adi.adrv9009_zu11eg_fmcomms8 import adrv9009_zu11eg_fmcomms8

# from adi.ad9081 import ad9081

# from adi.ad9081_mc import ad9081_mc, QuadMxFE

# from adi.ad9083 import ad9083

# from adi.ad9094 import ad9094

# from adi.ad9680 import ad9680

# from adi.ad9136 import ad9136

# from adi.ad9144 import ad9144

# from adi.ad9152 import ad9152

# from adi.cn0532 import cn0532

# from adi.daq2 import DAQ2

# from adi.daq3 import DAQ3

# from adi.adis16460 import adis16460

# from adi.adis16507 import adis16507

# from adi.ad7124 import ad7124

# from adi.adxl345 import adxl345

# from adi.adxrs290 import adxrs290

# from adi.fmclidar1 import fmclidar1

# from adi.ad5686 import ad5686

# from adi.adar1000 import adar1000, adar1000_array

# from adi.ltc2983 import ltc2983

# from adi.one_bit_adc_dac import one_bit_adc_dac

# from adi.ltc2314_14 import ltc2314_14

# from adi.ad7606 import ad7606

# from adi.ad7799 import ad7799

# from adi.ad7746 import ad7746

# from adi.adpd410x import adpd410x

# from adi.ad7689 import ad7689

# from adi.adf4371 import adf4371

# from adi.adpd188 import adpd188

try:
    from adi.jesd import jesd
except ImportError:
    pass

__version__ = "0.0.9"
name = "Analog Devices Hardware Interfaces"

Example to interact with ad9361

Now we can, write a simple script to interact with ad9361. This demo is originally from PySDR

import numpy as np
import adi
import matplotlib.pyplot as plt

sample_rate = 1e6 # Hz
center_freq = 915e6 # Hz
num_samps = 100000 # number of samples per call to rx()
tx_gain = 100

sdr = adi.ad9361(uri="local:")
sdr.sample_rate = int(sample_rate)

fc = 3000000
N = 1024
ts = 1 / 30000000.0
t = np.arange(0, N * ts, ts)
i = np.cos(2 * np.pi * t * fc) * 2 ** 14
q = np.sin(2 * np.pi * t * fc) * 2 ** 14
iq = i + 1j * q

sdr.sample_rate = int(sample_rate)
sdr.tx_lo = int(center_freq)
sdr.tx_hardware_gain_chan0 = tx_gain
sdr.tx_enabled_channels = [0]

# Config Rx
sdr.rx_lo = int(center_freq)
sdr.rx_rf_bandwidth = int(sample_rate)
sdr.rx_buffer_size = num_samps
sdr.gain_control_mode_chan0 = 'slow_attack'
sdr.rx_enabled_channels = [0]
# sdr.rx_hardwaregain_chan0 = -10.0 # dB, increase to increase the receive gain, but be careful not to saturate the ADC

sdr.tx_cyclic_buffer = True
# Send data cyclically
sdr.tx(iq)

# Clear buffer just to be safe
for i in range (0, 10):
    raw_data = sdr.rx()

# Receive samples
rx_samples = sdr.rx()
print(rx_samples)

# Stop transmitting
sdr.tx_destroy_buffer()

# Calculate power spectral density (frequency domain version of signal)
psd = np.abs(np.fft.fftshift(np.fft.fft(rx_samples)))**2
psd_dB = 10*np.log10(psd)
f = np.linspace(sample_rate/-2, sample_rate/2, len(psd))

# Plot time domain
plt.figure(0)
plt.plot(np.real(rx_samples[:200:1]))
plt.plot(np.imag(rx_samples[:200:1]))
plt.xlabel("Time")

# Plot freq domain
plt.figure(1)
plt.plot(f/1e6, psd_dB)
plt.xlabel("Frequency [MHz]")
plt.ylabel("PSD")
plt.show()

result

Work to be done

This is the first open source PYNQ project to control AD9361, as you can see, there are still a lot of thins need to do. I am waiting for your contribution.

  • TODO
    • libiio package build into the pynq image
    • python code for pynq demo
    • RF performance measurement
    • HDL project and devicetree improvement.(The hdl project is mainly based on fmcomms2/3/4+zed)

Licenses

PYNQ License : BSD 3-Clause License

Xilinx Embedded SW License : Multiple License File

Digilent IP License: MIT License

ADI meta layer License: MIT License

ADI hdl License: Multiple License File

Similar Resources

Framework for Enterprise Application Development in c++, HTTP1/HTTP2/HTTP3 compliant, Supports multiple server backends

The ffead-cpp Framework ffead-cpp is a web-framework, application framework, utilities all bundled into one. It also provides an embedded HTTP/Web-Soc

Nov 26, 2022

JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.

JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.

JUCE is an open-source cross-platform C++ application framework used for rapidly developing high quality desktop and mobile applications, including VS

Dec 1, 2022

An eventing framework for building high performance and high scalability systems in C.

NOTE: THIS PROJECT HAS BEEN DEPRECATED AND IS NO LONGER ACTIVELY MAINTAINED As of 2019-03-08, this project will no longer be maintained and will be ar

Nov 20, 2022

An Open Source Machine Learning Framework for Everyone

An Open Source Machine Learning Framework for Everyone

Documentation TensorFlow is an end-to-end open source platform for machine learning. It has a comprehensive, flexible ecosystem of tools, libraries, a

Nov 26, 2022

header only, dependency-free deep learning framework in C++14

header only, dependency-free deep learning framework in C++14

The project may be abandoned since the maintainer(s) are just looking to move on. In the case anyone is interested in continuing the project, let us k

Nov 30, 2022

a unified framework for modeling chemically reactive systems

Reaktoro Reaktoro is a unified framework for modeling chemically reactive systems. It provides methods for chemical equilibrium and kinetic calculatio

Nov 21, 2022

Async++ concurrency framework for C++11

Async++ Async++ is a lightweight concurrency framework for C++11. The concept was inspired by the Microsoft PPL library and the N3428 C++ standard pro

Dec 1, 2022

A task scheduling framework designed for the needs of game developers.

Intel Games Task Scheduler (GTS) To the documentation. Introduction GTS is a C++ task scheduling framework for multi-processor platforms. It is design

Nov 20, 2022

An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.

An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.

What is SObjectizer? What distinguishes SObjectizer? SObjectizer is not like TBB, taskflow or HPX Show me the code! HelloWorld example Ping-Pong examp

Nov 15, 2022

Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Nov 21, 2022

A unit testing framework for C

Check Table of Contents About Installing Linking Packaging About Check is a unit testing framework for C. It features a simple interface for defining

Nov 27, 2022

The fastest feature-rich C++11/14/17/20 single-header testing framework

The fastest feature-rich C++11/14/17/20 single-header testing framework

master branch Windows All dev branch Windows All doctest is a new C++ testing framework but is by far the fastest both in compile times (by orders of

Nov 23, 2022

A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)

A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)

Catch2 v3 is being developed! You are on the devel branch, where the next major version, v3, of Catch2 is being developed. As it is a significant rewo

Nov 25, 2022

A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)

A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)

Catch2 v3 is being developed! You are on the devel branch, where the next major version, v3, of Catch2 is being developed. As it is a significant rewo

Nov 24, 2022

C++ Benchmark Authoring Library/Framework

Celero C++ Benchmarking Library Copyright 2017-2019 John Farrier Apache 2.0 License Community Support A Special Thanks to the following corporations f

Nov 24, 2022

CppUTest unit testing and mocking framework for C/C++

CppUTest CppUTest unit testing and mocking framework for C/C++ More information on the project page Slack channel: Join if link not expired Getting St

Nov 26, 2022

A testing micro framework for creating function test doubles

Fake Function Framework (fff) A Fake Function Framework for C Hello Fake World! Capturing Arguments Return Values Resetting a Fake Call History Defaul

Dec 1, 2022

Googletest - Google Testing and Mocking Framework

GoogleTest OSS Builds Status Announcements Release 1.10.x Release 1.10.x is now available. Coming Soon Post 1.10.x googletest will follow Abseil Live

Nov 25, 2022

Minimal unit testing framework for C

MinUnit Minunit is a minimal unit testing framework for C/C++ self-contained in a single header file. It provides a way to define and configure test s

Nov 18, 2022
Comments
  • AD9363 support

    AD9363 support

    I see the AD9363's E310s are available, but perhaps AD9361's are out of stock ...

    Is it possible to port 9361 examples / sdcard image to the AD9363 rev or is this too much work?

    image https://www.aliexpress.com/item/1005003181244737.html

  • Missing antsdr board folder or spec file

    Missing antsdr board folder or spec file

    From the README steps, is there a missing folder called "antsdr" at the toplevel? I want to try rebuilding, but image building would need that folder. Please let me know if I'm missing a step.

    mkdir sdbuild/prebuilt
    unzip -d  sdbuild/prebuilt  pynq_rootfs_arm_v2.4.zip
    cd sdbuild
    make BOARDS=../../antsdr  PREBUILT=./prebuilt/bionic.arm.2.4.img  #### ../../antsdr does not exist?
    
Framework for Enterprise Application Development in c++, HTTP1/HTTP2/HTTP3 compliant, Supports multiple server backends

The ffead-cpp Framework ffead-cpp is a web-framework, application framework, utilities all bundled into one. It also provides an embedded HTTP/Web-Soc

Nov 26, 2022
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.

JUCE is an open-source cross-platform C++ application framework used for rapidly developing high quality desktop and mobile applications, including VS

Dec 1, 2022
An eventing framework for building high performance and high scalability systems in C.

NOTE: THIS PROJECT HAS BEEN DEPRECATED AND IS NO LONGER ACTIVELY MAINTAINED As of 2019-03-08, this project will no longer be maintained and will be ar

Nov 20, 2022
🔥 bhook(aka ByteHook) is a PLT hook framework for Android app.

?? bhook(aka ByteHook) is a PLT hook framework for Android app. Most of ByteDance's Android apps use bhook as the PLT hook solution online.

Nov 28, 2022
Idle is an asynchronous and hot-reloadable C++ dynamic component framework
Idle is an asynchronous and hot-reloadable C++ dynamic component framework

Idle is an asynchronous, hot-reloadable, and highly reactive dynamic component framework similar to OSGI that is: ?? Modular: Your program logic is en

Nov 29, 2022
Kigs framework is a C++ modular multipurpose cross platform framework.
Kigs framework is a C++ modular multipurpose cross platform framework.

Kigs framework is a C++ modular multi-purpose cross-platform framework. It was used as a basis for many professionnal projects. The main goal was to b

Nov 28, 2022
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.

Cutelyst - The Qt Web Framework A Web Framework built on top of Qt, using the simple and elegant approach of Catalyst (Perl) framework. Qt's meta obje

Nov 25, 2022
TreeFrog Framework : High-speed C++ MVC Framework for Web Application

Small but Powerful and Efficient TreeFrog Framework is a high-speed and full-stack web application framework based on C++ and Qt, which supports HTTP

Nov 24, 2022
Cute Framework (CF for short) is the cutest framework available for making 2D games in C/C++
Cute Framework (CF for short) is the cutest framework available for making 2D games in C/C++

Cute Framework (CF for short) is the cutest framework available for making 2D games in C/C++. CF comprises of different features, where the various features avoid inter-dependencies. In this way using CF is about picking and choosing which pieces are needed for your game

Nov 25, 2022
TengineGst is a streaming media analytics framework, based on GStreamer multimedia framework, for creating varied complex media analytics pipelines.
TengineGst is a streaming media analytics framework, based on GStreamer multimedia framework, for creating varied complex media analytics pipelines.

TengineGst is a streaming media analytics framework, based on GStreamer multimedia framework, for creating varied complex media analytics pipelines. It ensures pipeline interoperability and provides optimized media, and inference operations using Tengine Toolkit Inference Engine backend, across varied architecture - CPU, iGPU and VPU.

Nov 22, 2022