Logo
OpenCPI Release: v2.4.9

OpenCPI System Support Packages (OSPs)

  • LibreSDR OSP
    • OpenCPI LibreSDR Getting Started Guide
      • Document Revision History
      • How to Use This Document
      • Overview
      • Installation Prerequisites
      • Installation Steps for Platforms
        • Required Downloads for Installing the Platform
        • Details for Installing the RCC Platform
        • Details for Installing the HDL Platform
      • Setting up the LibreSDR After its Platforms are Installed
        • Details for Establishing a Serial Console Connection
        • Details for Configuring the Runtime Environment on the Embedded System
  • PlutoSDR OSP
    • OpenCPI Analog Devices PlutoSDR Getting Started Guide
      • Document Revision History
      • How to Use This Document
      • Overview
      • Installation Summary
      • Enabling PlutoSDR Modes of Operation
        • Enabling PlutoSDR-as-Device Mode
        • Enabling PlutoSDR-as-Host Mode
      • Updating the PlutoSDR Firmware
      • Issues Regarding Storage
      • Setting up the PlutoSDR After its Platforms are Installed
        • Details for Establishing a Serial Console Connection for the PlutoSDR
        • Details for Configuring the Runtime Environment for the PlutoSDR
  • Xilinx OSP
    • Getting Started Guides
      • OpenCPI Xilinx ZC706 Getting Started Guide
        • Document Revision History
        • How to Use This Document
        • Overview
        • Installation Prerequisites
        • Installation Steps for Platforms
        • Setting up the ZC706 After its Platforms are Installed
      • OpenCPI Xilinx ZCU102 Getting Started Guide
        • Document Revision History
        • How to Use This Document
        • Overview
        • Installation Prerequisites
        • Installation Summary
        • Setting up the ZCU102 Hardware
        • Enabling OpenCPI Development for the ZCU102
      • OpenCPI Xilinx ZCU111 Getting Started Guide
        • Document Revision History
        • How to Use This Document
        • Overview
        • Installation Prerequisites
        • Installation Summary
        • Setting up the ZCU111 Hardware
        • Enabling OpenCPI Development for the ZCU111

Component Projects

  • OpenCPI Haifuraiya
    • Applications
      • DVB-S2 Downlink ACI (downlink_aci)
        • Description
        • Hardware Portability
        • Execution
        • Verification
        • Troubleshooting
        • Worker Properties
      • DVB-S2 Downlink + Spectrum Monitor ACI (haifuraiya_aci)
        • Description
        • Hardware Portability
        • Prebuilt SD Card Images
        • Execution
        • Verification
        • Troubleshooting
        • Worker Properties
        • Receiving the Signal
      • DVB-S2 Downlink + OPV 64-Channel Receiver ACI (haifuraiya_opv)
        • Description
        • Execution
        • Verification
      • Log Power FFT (log_power_fft_app)
        • Description
        • Hardware Portability
        • Execution
        • Verification
        • Troubleshooting
      • Log-Power FFT UDP Viewer (log_power_fft_udp_app)
        • Description
        • Hardware Portability
        • Execution
        • Verification
        • Troubleshooting
      • Log Power FFT Web Sockets (log_power_fft_ws)
        • Description
        • Hardware Portability
        • Execution
        • Verification
        • Troubleshooting
    • Components Component Library
      • Windower (windower_xs_4k)
        • Design
        • Interface
        • Implementations
        • Example Application
        • Dependencies
        • Limitations
        • Testing
      • Windower Proxy (windower_xs_proxy)
        • Design
        • Interface
        • Implementations
        • Example Application
        • Dependencies
        • Limitations
        • Testing
      • DVB-S2 Encoder (dvbs2_encoder)
        • Function
        • Interface
        • Implementations
        • Example Application
        • Dependencies
        • Limitations
        • Testing
      • Xilinx Fast Fourier Transform (xilinx_fft)
        • Function
        • Implementations
        • Example Application
        • Dependencies
        • Limitations
        • Testing
  • OpenCPI Opulent-Voice
    • Opulent Voice Component Library
      • Chan Select (chan_select)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • 16-Channel Folded Carrier Recovery (cr_x16)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Decimate-by-N (decimate3)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Differential Soft Decision, 16-Channel Folded (dsd_x16)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Frame Merge 4 (frame_merge4)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Framer 16 (framer16)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Frame Synchronizer, 16-Channel Folded (fs_x16)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • MSK Decode x16 Back-End (msk_decode_x16)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • MSK Demod x16 (msk_demod_x16)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Tag Select (tag_select)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • 16-Channel Folded Symbol Timing Recovery (ted_x16)
        • Design
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Burst Detect x16 (bd_x16)
        • Function
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • Polyphase Channelizer (channelizer)
        • Function
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • MSK Demodulator (msk_demod)
        • Function
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
      • MSK Modulator (msk_mod)
        • Function
        • Interface
        • Implementations
        • Dependencies
        • Limitations
        • Testing
    • Primitives
      • Dsp Primitive Library
    • Applications
      • Transmit
      • Receive
      • Simulation / bring-up
        • SKELETON NAME (msk_ber)
OpenCPI assets
  • OpenCPI Haifuraiya
  • Applications
  • DVB-S2 Downlink + Spectrum Monitor ACI (haifuraiya_aci)

DVB-S2 Downlink + Spectrum Monitor ACI (haifuraiya_aci)

Transmit IP network traffic over a DVB-S2 RF link while simultaneously capturing receive-side spectrum snapshots and embedding them in the downlink.

Description

haifuraiya_aci combines the DVB-S2 downlink transmitter with an FPGA-based spectrum monitor. IP packets arriving on a Linux TUN virtual network interface are encapsulated using Generic Stream Encapsulation (GSE, ETSI TS 102 606), packed into DVB-S2 Baseband (BB) frames, and streamed to the on-board FPGA DVB-S2 encoder via the OpenCPI Application Control Interface (ACI). In parallel, the application periodically captures a 4096-point FFT spectrum snapshot from the receive path, formats it as JSON, and sends it as a UDP datagram routed through the same TUN interface — so the spectrum data is itself encapsulated and transmitted over the DVB-S2 carrier.

The application uses a three-thread architecture:

  • TUN reader thread — reads IP packets from the TUN device (including the spectrum UDP packets produced by the FFT thread), fragments them into GSE packets sized to fit the BB frame data field, and pushes complete BB frames onto a bounded queue.

  • FFT UDP thread — triggers the FPGA triggered-sampler to capture a single spectrum snapshot once per second, computes log-power (dB) from the complex FFT output, serialises the result as a JSON object, and sends it as a UDP datagram to a configurable destination address/port via tun0.

  • Main thread — blocks on getOutputBuffer until the FPGA encoder has a free DMA buffer, then dequeues and sends the next BB frame. If the queue is empty (no IP traffic), a pre-built GSE null-packet padding frame is sent instead to keep the encoder fed.

The FPGA application (haifuraiya_aci.xml) connects:

  1. The external bbframe_input port to the dvbs2_encoder worker input (TX path).

  2. The dvbs2_encoder output to the Digital Radio Controller (DRC) TX port.

  3. The DRC RX port through a triggered_sampler_xs → windower_xs_4k_proxy (Blackman-Harris) → xilinx_fft pipeline to the external fft_out port (RX/spectrum path).

Default DVB-S2 parameters (compile-time constants in haifuraiya_aci.cc):

Parameter

Value

Frame type

Long frame (FECFRAME = 64 800 bits)

Constellation

QPSK

Code rate

9/10

Pilots

Disabled

MATYPE1

0x72 (GSE mode, roll-off 0.20)

BB frame size

7153 bytes (derived from DVB-S2 ETSI EN 302 307 tables)

DRC TX configuration (haifuraiya_aci.xml):

Parameter

Value

Center frequency

400.0 MHz

Bandwidth

20 MHz

Sample rate

4.0 MSPS

Gain

−50 dB (manual)

DRC RX configuration (haifuraiya_aci.xml):

Parameter

Value

Center frequency

98.5 MHz

Bandwidth

20 MHz

Sample rate

20 MSPS

Gain

60 dB (auto)

FFT parameters:

Parameter

Value

FFT size

4096 points

Window function

Blackman-Harris

Capture mode

Single-shot (triggered once per second)

Output format

JSON object {"s": [dB, dB, …]} sent as UDP

Hardware Portability

This application is designed to run on the following platforms:

Hardware

RCC Platform

HDL Platform

ADALM-PLUTOSDR

adi_plutosdr0_39

plutosdr

LibreSDR

xilinx24_1_aarch32

libresdr

Xilinx ZC706

xilinx24_1_aarch32

zc706

Xilinx ZCU102

xilinx24_1_aarch64

zcu102

Prebuilt SD Card Images

Prebuilt SD card images are available for download from GitLab CI. These contain the OpenCPI runtime, bitstream, and haifuraiya_aci configured to autostart on boot — no build environment required.

Platform

Download Link

LibreSDR

build_libresdr

Xilinx ZC706

build_zc706

Xilinx ZCU102

build_zcu102

These links always point to artifacts from the latest successful CI pipeline on the main branch.

SD Card Setup

  1. Download the artifact archive for your platform and extract it.

  2. Format an SD card with a FAT32 partition (or use an existing one).

  3. Copy the extracted files to the FAT32 boot partition.

  4. Insert the SD card into the target board and power on.

haifuraiya_aci will autostart on boot and begin transmitting on the DVB-S2 downlink. This serves as the TX portion of the end-to-end link described in the Receiving the Signal section below.

Execution

Prerequisites

  1. Build the project for the target RCC and HDL platforms.

  2. Deploy the bitstream and application artifacts to the target hardware.

  3. Ensure the OpenCPI runtime is available on the target.

  4. The application opens /dev/net/tun and requires either root privileges or CAP_NET_ADMIN on the target system.

Command(s)

Run the application on the target hardware:

./haifuraiya_aci [fft_dest_ip [fft_dest_port]]

Argument

Default

Description

fft_dest_ip

10.0.0.2

IP address (reachable via tun0) to receive spectrum JSON datagrams

fft_dest_port

5005

UDP port for spectrum data

The application prints the name of the TUN interface it allocates (e.g. tun0) and the commands needed to bring it up:

sudo ip link set tun0 up
sudo ip addr add 10.0.0.1/24 dev tun0

After running those commands, any IP traffic routed to the 10.0.0.1/24 subnet will be encapsulated and transmitted over the DVB-S2 RF link. Spectrum data will be sent as UDP to the configured destination, routed through tun0 and embedded in the downlink.

Verification

  • The application prints Running: DVB-S2 TX active, spectrum → tun0 → downlink once the encoder and FFT threads are started.

  • The FFT thread prints FFT thread: sending spectrum UDP to <ip>:<port> (via tun0 → DVB-S2 downlink) confirming the spectrum path is active.

  • Sending a ping from the host to 10.0.0.2 will produce GSE encapsulation debug output on stdout showing the fragment structure and CRC-32 of each GSE packet.

  • A spectrum analyzer or DVB-S2 receiver tuned to 400 MHz should detect the QPSK signal.

  • A UDP listener on the receiver side at the configured port should receive JSON objects containing the log-power spectrum array.

Troubleshooting

  • Cannot open /dev/net/tun — the process lacks CAP_NET_ADMIN; run as root or grant the capability.

  • Cannot ioctl TUNSETIFF — the tun kernel module is not loaded; run modprobe tun.

  • app failed: … — an OpenCPI runtime error occurred (bitstream not loaded, DRC initialization failure, etc.). Check that the correct bitstream is programmed and that the DRC worker is available for the target platform.

  • BB queue full, dropping oldest frame — the FPGA encoder cannot consume frames as fast as IP traffic arrives. Reduce traffic rate or verify that the encoder bitstream is running at the expected sample rate.

  • FFT thread: failed to create UDP socket — the system could not create a UDP socket; check that networking is available on the target.

  • FFT thread: invalid destination address — the fft_dest_ip argument is not a valid IPv4 address.

Worker Properties

The dvbs2_encoder worker (instance enc) exposes a regs array property used at startup to configure the QPSK constellation mapper:

Register offset

Value written

Description

0x110 + 0

(+I, +Q)

QPSK symbol (+1, +1)

0x110 + 4

(+I, −Q)

QPSK symbol (+1, −1)

0x110 + 8

(−I, +Q)

QPSK symbol (−1, +1)

0x110 + 12

(−I, −Q)

QPSK symbol (−1, −1)

Each 32-bit register packs the I sample in the upper 16 bits and the Q sample in the lower 16 bits. The magnitude used is 32 000 (out of a signed 16-bit range of ±32 767).

Receiving the Signal

To receive the DVB-S2 downlink produced by haifuraiya_aci you need a MiniTiouner (or compatible DVB-S2 USB tuner) running the LongMynd software, together with the gse-rx application to decode the GSE stream back into IP packets.

The receive-side data flow is:

RF → MiniTiouner → LongMynd (UDP BB frames) → gse-rx → TUN interface → host network

LongMynd Setup

LongMynd is an open-source DVB-S/S2 demodulator for the MiniTiouner hardware. It outputs BB frames as UDP datagrams and also provides a status stream and an optional web interface.

The easiest way to run LongMynd is to edit the example-run.sh script included in the LongMynd source tree. Set the frequency and symbol rate to match the haifuraiya_aci transmitter:

# In example-run.sh — key parameters to set:
FREQ=400000      # frequency in kHz (400 MHz)
SR=10000         # symbol rate in ks/s

The script configures the following defaults which work with gse-rx:

Parameter

Default

Description

TS_HOST / TS_PORT

127.0.0.1:9002

UDP destination for BB frame data (consumed by gse-rx)

STATUS_HOST / STATUS_PORT

127.0.0.1:9003

UDP destination for receiver status messages

WEB_PORT

9004

HTTP port for the LongMynd web interface

POL

v

LNB polarisation (sets LNB voltage)

TS_TIMEOUT

5000

Milliseconds without data before receiver reset

Then run the script:

cd /path/to/longmynd
./example-run.sh

LongMynd will lock onto the QPSK signal transmitted by haifuraiya_aci and forward raw BB frame data as UDP packets to 127.0.0.1:9002. The web interface at http://localhost:9004 can be used to monitor lock status, signal strength, and MER.

gse-rx Setup

gse-rx is a standalone Linux application that receives the BB frame UDP stream from LongMynd, synchronises and parses the BB frames, decodes GSE packets, reassembles fragmented IP packets, and injects the recovered IP traffic into a Linux TUN interface.

Build gse-rx (requires CMake 3.14+ and a C++17 compiler):

cd /home/aaron/git/gse-rx
cmake -B build
cmake --build build

Run gse-rx (requires root or CAP_NET_ADMIN):

sudo ./build/gse-rx

The program creates a TUN interface and prints the commands to bring it up:

sudo ip link set tun0 up
sudo ip addr add 10.0.0.2/24 dev tun0

Once the TUN interface is up, recovered IP packets from the DVB-S2 downlink are injected into the host network stack. This includes the spectrum JSON UDP datagrams sent by the haifuraiya_aci FFT thread — they will appear on UDP port 5005 (or whichever port was configured on the transmit side) and can be consumed by a spectrum viewer application.

gse-rx listens on 127.0.0.1:9002 by default. These values are compile-time constants in src/main.cc (LONGMYND_ADDR and LONGMYND_PORT).

fft-display Setup

fft-display is a standalone web-based spectrum display that sits downstream of gse-rx. It listens for the log-power FFT JSON UDP datagrams recovered from the DVB-S2 downlink and serves a live spectrum visualisation in a web browser. It has no OpenCPI dependency and can run on any Linux host.

The application has two components:

  • UDP receiver (main thread) — binds to a UDP port and receives the {"s": [dB, …]} JSON datagrams that gse-rx delivers to the host network stack via the TUN interface.

  • HTTP/WebSocket server (server thread, using uWebSockets) — serves static HTML/CSS/JS from a public/ directory and forwards each received spectrum JSON to all connected WebSocket clients in real time.

On initial WebSocket connection the server sends a configuration message with the center frequency and span: {"center": 98500000, "span": 20000000}.

Clone and build fft-display (requires CMake 3.14+, a C++20 compiler, and zlib):

git clone --recurse-submodules git@gitlab.com:aolivarez/fft-display.git
cd fft-display
cmake -B build
cmake --build build

Run the display application on the receive host:

./build/fft-display [udp_port [http_port]]

Argument

Default

Description

udp_port

5005

UDP port to listen on for spectrum JSON datagrams

http_port

3000

HTTP port for the web-based spectrum viewer

Then open http://localhost:3000 (or the appropriate host address) in a browser to view the live spectrum display.

End-to-End Summary

A complete link requires two machines (or two terminals on the same host with an RF loopback):

TX side:
  haifuraiya_aci (FPGA) → tun0 → DVB-S2 RF

RX side:
  RF → MiniTiouner → LongMynd (UDP) → gse-rx → tun0 → fft-display → browser

Side

Steps

TX

  1. Run haifuraiya_aci on the FPGA target.

  2. Bring up tun0 with 10.0.0.1/24.

  3. Route desired traffic through the TUN interface.

RX

  1. Start LongMynd pointed at the MiniTiouner, tuned to 400 MHz.

  2. Run gse-rx to decode BB frames and create the receive TUN.

  3. Bring up the receive tun0 with 10.0.0.2/24.

  4. Run fft-display to receive the spectrum UDP datagrams on port 5005 and serve the web viewer on port 3000.

  5. Open http://localhost:3000 in a browser to view the live spectrum display.

Previous Next

Last updated on 24 June 2026.