Private LTE with Analog ADALM-PLUTO v0.38 Update

|

Introduction

Previously I got the open source LTE stack srsRAN working with the low cost Analog ADALM-PLUTO.

At the time the additional functionality was added to their 0.37 release. They’ve recently release v0.38, so I figured I’d give it the same treatment.

Changes

It appears the main changes between v0.37 and v0.38 are:

  • Linux kernel 5.10 -> 5.15
  • Buildroot 2022.02.3 -> 2023.02.5
  • Xilinx tools 2021.2 -> 2022.2

Analog have added some new logic within the FPGA design which appears to improve support AD636x RF transceiver’s Time Division Duplexing (TDD) mode.

As with my previous custom firmware, without timestamping enabled the firmware *should* behave identically to the official firmware. As such the new TDD module is included, however it currently conflicts with timestamping support.

The timestamping module and new TDD module share a common signal to the internal DMA controller. When timestamping is enabled it will make use of the shared line, in preference to the TDD controller. When disabled the TDD controller will make use of the line as in the official Analog firmware. Essentially this comes down to TDD + timestamping using the new module isn’t likely possible at present with the current timestamping arrangement at least.

For more information on Analog’s new TDD support see HDL support for AD9361 TDD mode and Generic Time-Division Duplexing Controller.

Pre-Built Images

If you’re just looking to try, I’ve released some pre-built images on GitHub. These can be installed and configured using the instructions from my original post.

Building

If you’d prefer to build from source, the following notes are adapted from Analog’s wiki. They’ve made a few tweaks to their build process, as such the following is subtly different from the previous v0.37 release.

Building the ADALM-PLUTO’s firmware requires installation of Xilinx’s Vivado Design Suite 2022.2. After which the firmware may be cloned and build as follows:

git clone --branch v0.38_timestamp --recurse-submodules --shallow-submodules https://github.com/pgreenland/plutosdr-fw.git
cd plutosdr-fw
make

Once complete (it takes a while) build artefacts will be available in the build directory. The two key images being pluto.dfu the RAM bootable image and pluto.frm the firmware update image.

Was this article helpful?
YesNo
, , , , , ,

24 responses to “Private LTE with Analog ADALM-PLUTO v0.38 Update”

  1. amit malaghan avatar
    amit malaghan

    hi , i am getting this error when i try to install plutosdr-fw in pc

    rm -f
    rm -rf build/*
    make -C buildroot ARCH=arm zynq_pluto_defconfig
    make[1]: Entering directory ‘/home/student/Documents/5gcache/plutosdr-fw/buildroot’
    make[1]: *** No rule to make target ‘zynq_pluto_defconfig’. Stop.
    make[1]: Leaving directory ‘/home/student/Documents/5gcache/plutosdr-fw/buildroot’
    Makefile:62: recipe for target ‘TOOLCHAIN’ failed
    make: *** [TOOLCHAIN] Error 2

    1. Phil Greenland avatar
      Phil Greenland

      Hey Amit,

      Have you got the submodules cloned and checked out? The buildoot directory contains files?

      Thanks,

      Phil

  2. Alejandro avatar

    Hi Phil, We are planning to access the timestamping interface via the soapy module from the embedded processor in pluto, i.e. using the “local:” URI.
    Should we expect it to work as it is working via the USB? Or will it need further adaptations?

    1. Phil Greenland avatar
      Phil Greenland

      Hi Alejandro,

      It won’t work with the branch I reference for the LTE simulation, which supports USB (for the Pluto and Pluto+) and now IP (via another special interface) for the Pluto+.

      However I did adapt the native IIO interface to support timestamping. It wasn’t fast enough over the USB connection for LTE. It should work fine locally, as you’re planning though.

      I’ve just rebased and pushed the “IIO enabled” version here: https://github.com/pgreenland/SoapyPlutoSDR/tree/sdr_gadget_timestamping_with_iio_support

      I haven’t built it or tried it recently though I’m afraid.

      If you give it a go, there’s a python and C version of a loopback test (see the support directory) which you could run on the Pluto itself….presumably cross compiling the C version would be easiest?. If the output of those look sensible (no warnings or reports of missing packets) you should be in business.

      Happy to provide support where I can, let me know how you get on!

      Thanks,

      Phil

      1. Alejandro avatar

        Hi Phil, thank you very much for the clues. I already cross compiled it for Cortex-A9 and installed it in the sysroot-v0.38. It needed only some minor modifications of the CMakeLists.txt and a few changes because we installed not the latest version of boost in the sysroot.
        We will be testing it in the following days, and write you back with the results.
        Many thanks and best regards! Alejandro.

  3. Alejandro avatar

    Hi Phil, we recompiled plutosd-fw 0.38_timestamp branch in order to access the timestamping interface through the local iio uri.
    Everything goes ok except for the hdl compilation which is failing with the following error:
    ERROR: [BD 41-74] Exec TCL: Please specify VLNV when creating IP cell cpack_timestamp
    ERROR: [BD 5-7] Error: running create_bd_cell -type ip -name cpack_timestamp .
    ERROR: [Common 17-39] ‘create_bd_cell’ failed due to earlier errors.
    while executing
    “create_bd_cell -type ip -vlnv [get_ipdefs -all -filter “VLNV =~ :${i_ip}: && design_tool_contexts =~ IPI && UPGRADE_VERSIONS == “””] ${i_name}”
    (procedure “ad_ip_instance” line 3)
    invoked from within
    “ad_ip_instance util_cpack2_timestamp cpack_timestamp”
    (file “system_bd.tcl” line 241)

    Any Ideas how we could overcome this?

    Best regards, Alejandro.

    1. Phil Greenland avatar
      Phil Greenland

      I’ve not seen that one myself before. Are you running the same version as Vivado as Analog are using for the v0.38 build, 2022.2?

      Thanks,

      Phil

      1. Alejandro avatar

        Yes, Vivado 2022.2 (installed together with Vitis).
        Thanks and best regards, Alejandro.

        1. Phil Greenland avatar
          Phil Greenland

          Ah ok, I wasn’t sure if a later / earlier version might cause issues.

          I’ve kicked a fresh build off in the background, following my own instructions from the post.

          If it completes and you’re not worried about building the HDL yourself at the moment, I can drop you the hardware export. I believe this can be used by the firmware build, in place of performing the full synthesis yourself.

          Thanks,

          Phil

          1. Dim avatar
            Dim

            Hi Phil, will you be able to upload the IIO supported image to git that I can run this script > test_timestamp_loopback.py? Does it need to be using SoapySDR? Can I use pyadi-iio and still get timestamping? Does it require a special version of pyadi-iio or pylibiio?

            Thanks

          2. Phil Greenland avatar
            Phil Greenland

            Hey,

            There are images supporting the timestamping on Github – https://github.com/pgreenland/plutosdr-fw/releases/tag/v0.38_with_timestamping they should install like a regular PlutoSDR update.

            The script was written specifically for SoapySDR unfortunately. Using a modified version of PlutoSDR plugin, to prove out the communication before srsRAN used SoapySDR to communicate with the Pluto.

            In terms of using other libraries, assuming they support timestamps they could be made aware of the timestamping but wouldn’t have any idea out of the box.

            The operation of the timestamping is relatively simple so could potentially be implemented yourself, directly in software. Although extending the appropriate library may be cleaner.

            Essentially samples arrive from and are sent to the RF hardware in blocks. The modified FPGA code is told to expect or insert a timestamp every x samples. The SoapySDR driver informs the FPGA of the block size, such that a timestamp will be inserted at the start of each received block and expected at the start of each transmitted one.

            Setting the timestamp every property can be seen here: https://github.com/pgreenland/SoapyPlutoSDR/blob/sdr_gadget_timestamping_with_iio_support/PlutoSDR_TimestampEvery.hpp

            When receiving RF data, the timestamp is extracted from the start of each block, as seen here: https://github.com/pgreenland/SoapyPlutoSDR/blob/c16932b646d8d5e31e869ec3e064d95a0c45202a/PlutoSDR_Streaming.cpp#L465

            When sending RF data, the timestamp is injected at the start of each block, as seen here: https://github.com/pgreenland/SoapyPlutoSDR/blob/c16932b646d8d5e31e869ec3e064d95a0c45202a/PlutoSDR_Streaming.cpp#L863

            If you were using the IIO libraries directly, with one channel enabled and say a block size of 1000 samples. From memory you’ll be receiving 16-bit I and 16-bit Q samples. You’d set timestamp every to 1000 and set the IIO buffer size to 1002. Which is 1000 data samples + 2 more data samples for the timestamp. With each IQ pair occupying 32-bits, in the single channel config 2 samples would be required to provide space for the 64-bit timestamp. Likewise if you were using a dual channel setup, only 1 extra sample would be required.

            If you were to give it a go I’d be tempted to test with SoapySDR first, then move to a custom solution.

            Hope that helps,

            Regards,

            Phil

  4.  avatar
    Anonymous

    I’d love to see the timestamping working with openbts or another 2G BTS software. 2G no longer exists where I live sadly.

  5. Deniz Ömer Çalış avatar
    Deniz Ömer Çalış

    Hi Phil!

    Is there any chance that you can further explain how to flash program ADALM-PLUTO. I tried to flash program it via Vitis 2022.2., flashing completes succesfully but when I disconnect and reconnect my custom program is gone. Is there any way that you know how to fix this issue?

    1. Phil Greenland avatar
      Phil Greenland

      Hey Deniz,

      Take a look at my original post https://www.quantulum.co.uk/blog/private-lte-with-analog-adalm-pluto/#booting_upgrade which covers a few options on either launching the software on the unit for testing without flashing it. Or flashing it to become the default. I’ve extracted these notes from Analog’s website. I’ve struggled to find the original RAM booting notes. But the firwmare updating notes were adapted from here: https://wiki.analog.com/university/tools/pluto/users/firmware#dfu_update

      Thanks,

      Phil

  6. Alphan Sahin avatar

    Hi Phil,

    I am using v39. When I remove the ADI’s TDD block from the original HDL code, Pluto does not show up as a drive on Windows. Do you have any recommendations to address this issue? Maybe you also noticed the same issue in your implementation. I think the issue happens because of the drivers regarding TDD and Phaser. Do you have any specific recommendations? Thank you.

    Best regards,

    Alphan

    1. Phil Greenland avatar
      Phil Greenland

      Hey Alphan,

      I believe the TDD block arrived with the v0.38 release, as it broke the integration of some of my logic.

      I ended up not removing it but either adding a mux around it or sharing a control line with it. I may have sidestepped the issue you’re having. I was aiming to keep things functionally identical to the original pluto software + my additions.

      Are you looking to get the LTE timestamping working with the v0.39 release or are working on something else entirely?

      Thanks,

      Phil

      1. Alphan Sahin avatar

        I plan to introduce some additional blocks regarding the synchronization . However, since the FPGA is quite small, I need to remove some existing blocks to gain some resources. I had done some similar changes to the earlier releases (https://github.com/alphansahin/Wireless-Federated-Learning-with-Non-coherent-Over-the-Air-Computation). It was not a problem at that time. However, with this current release, it seems it does not like the HDL changes. I believe it is related to Linux drivers. I believe I need to handle the device trees.

        1. Phil Greenland avatar
          Phil Greenland

          Aah very cool, I didn’t realise the TDD interface had an AXI connection but reading the links I left in the post it seems it does.

          The revc pluto device tree for the v0.39 release is here: https://github.com/analogdevicesinc/linux/blob/f3da30df60047dc5a0b8fa8c640be774e0f784d9/arch/arm/boot/dts/zynq-pluto-sdr-revc.dts#L36 – I’d expect you’d need to remove the axi_tdd_0 and iio_axi_tdd_0 device entries, or disable them. I haven’t checked if there are references to these elsewhere though, may be worth searching for those names a little.

          Phil

  7. Alphan Sahin avatar

    Hi Phil, yes, you are right. I commented out the TDD portion on the DTS file (zynq-pluto-sdr-revc.dts). I have just compiled it. It works now!

    1. Phil Greenland avatar
      Phil Greenland

      Jolly good!, thanks for the update 🙂

  8. Dim avatar
    Dim

    I tried used this – test_timestamp_loopback.py with some small modification to get it going but i got the error
    [INFO] Using format CS16.
    [INFO] Auto setting Buffer Size: 32768
    [INFO] Set MTU Size: 32768
    [INFO] Using format CS16.
    MTU – TX: 4096, RX: 32768
    [INFO] Has direct TX copy: 0
    Start test…
    [INFO] Has direct RX copy: 0
    Buffer: 0 – Samples: 32768, Flags: 0, Time: 0, TimeDiff: 0
    Buffer: 1 – Samples: 32768, Flags: 0, Time: 0, TimeDiff: 0
    Buffer: 2 – Samples: 32768, Flags: 0, Time: 0, TimeDiff: 0
    Buffer: 3 – Samples: 32768, Flags: 0, Time: 0, TimeDiff: 0 error – Traceback (most recent call last):
    File “C:/Users/ABC/PycharmProjects/pythonProject5/3.py”, line 257, in
    main()
    File “C:/Users/ABC/PycharmProjects/pythonProject5/3.py”, line 139, in main
    raise Exception(‘transmit failed %s’ % str(res))
    Exception: transmit failed ret=4, flags=4, timeNs=0 waht is changed was this – def main():
    “””Perform timestamp test”””

    # Always use USB URI
    args = dict(driver=”plutosdr”, uri=”usb:”, direct=”1″, timestamp_every=”1920″, loopback=”1″)

    # Enumerate devices using arguments as a search string
    results = SoapySDR.Device.enumerate(args)
    for result in results:
    print(f”Found device: {result}”)

    # Create device
    sdr = SoapySDR.Device(args)

    # Apply settings
    sdr.setSampleRate(SOAPY_SDR_RX, 0, 1.92e6)
    sdr.setFrequency(SOAPY_SDR_RX, 0, 800.0e6)
    sdr.setSampleRate(SOAPY_SDR_TX, 0, 1.92e6)
    sdr.setFrequency(SOAPY_SDR_TX, 0, 800.0e6)

    # Setup a stream (signed int16’s)
    channels = [0, 1] # [0] or [0, 1]
    rxStream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels)
    txStream = sdr.setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, channels)

    # Get stream MTUs
    rx_mtu = int(sdr.getStreamMTU(rxStream))
    tx_mtu = int(sdr.getStreamMTU(txStream))
    print(“MTU – TX: {}, RX: {}”.format(tx_mtu, rx_mtu))
    # Commenting out the MTU mismatch check
    # if (tx_mtu != rx_mtu):
    # raise Exception(“MTU mismatch”) any pointers to fix this ?
    Thank you and appreciate your time

    1. Phil Greenland avatar
      Phil Greenland

      That looks pretty good to me.

      You’ve installed the timestamping enabled firmware on the pluto? and built the associated updated plutosdr plugin?

      Regards,

      Phil

      1. Dim avatar
        Dim

        You’ve installed the timestamping enabled firmware on the pluto – yes – It was showing 1t1r first. i changes it to 2t2r. now shows –
        v0.38_with_timestamping
        https://wiki.analog.com/university/tools/pluto
        #

        and built the associated updated plutosdr plugin? – no, i installed the regular one – conda install -c conda-forge soapysdr-module-plutosdr.Do I need to build from here ? – https://github.com/pgreenland/SoapyPlutoSDR/tree/sdr_gadget_timestamping_with_iio_support or there is a different way of doing this ?
        Thankyou

        1. Phil Greenland avatar
          Phil Greenland

          Firmware install and configuration sounds good.

          The custom plutosdr plugin is required unfortunately, it understands how to do the timestamping from the host side. Either branch is good, the original one was https://github.com/pgreenland/SoapyPlutoSDR/tree/sdr_gadget_timestamping the _iio_support one allows for the test to be run on the pluto itself, although it was mainly for larger Zynq platforms using the same Analog codebase.

          One thing you may run into while installing the plugin. I haven’t tried to build it on Windows I’m afraid, you may well be the first.

          Thanks,

          Phil

Leave a Reply

Your email address will not be published. Required fields are marked *