RENEW Project Documentation

Version 1.0

Reconfigurable Ecosystem for Next-generation End-to-end Wireless

Driver in Matlab

This driver is written for TDD SISO communication between two Iris boards. It is assumed that the communication between the boards is done through block ram transmission mode where a whole block of data (packet) is transmitted and received at slots allocated for these two functionalities. Note that block ram transmission corresponds to a P (pilot transmission) in the TDD scheduling map.

Click here for the complete code.

Class Definition

We begin by defining the iris_py class which will be the interface between the Matlab script that calls the Matlab driver and the underlying Python driver and object. The list of properties include parameters such as sample rate, transmitter gain, and frequency, receiver gain and frequency, number of samples of the packet. A variable sdr_params will be used to receive the experiment’s values for the aforementioned parameters and py_obj will contain the Python object created through the Python Driver’s object class corresponding to an Iris node.

Note that we must zero-pad our data to account for the analog path and over-the-air delays. Example values for zero-padding are given in the tutorial scripts that follow. Also, it is important that the number of samples to be transmitted is below 4096 including zero-padding. This is due to the size of the Iris board ram that we use for bursty transmission.

 classdef iris_py < handle

    properties
        sdr_params;
        py_obj;         %pyhton object
        
        % Parameters to feed python (pun very intended!)
        serial_id;
		sample_rate;
		tx_freq;
		rx_freq;
		bw;
		tx_gain;
		rx_gain;
		n_samp;
        tdd_sched;
        n_zpad_samp;    %number of zero-padding samples
        
    end 

Matlab Object Constructor

The constructor initializes the experiment’s parameters received from the caller Matlab script(s), creates a python object and assigns it to the variable py_obj, and passes the parameters to that Python object.

 function obj = iris_py(sdr_params)
            if nargin > 0
                obj.sdr_params = sdr_params;
                
                obj.serial_id = sdr_params.id;
                obj.sample_rate = sdr_params.sample_rate;
                obj.tx_freq = sdr_params.txfreq;
                obj.rx_freq = sdr_params.rxfreq;
                obj.tx_gain = sdr_params.txgain;
                obj.rx_gain = sdr_params.rxgain;
                obj.n_samp = sdr_params.n_samp;
                obj.tdd_sched = sdr_params.tdd_sched;
                obj.n_zpad_samp = sdr_params.n_zpad_samp;
        
                obj.py_obj = py.iris_py.Iris_py( pyargs('serial_id',obj.serial_id,...
                    'tx_freq', obj.tx_freq, 'rx_freq', obj.rx_freq,...
                    'tx_gain',obj.tx_gain,'rx_gain',obj.rx_gain,...
                    'sample_rate',obj.sample_rate, 'n_samp',obj.n_samp,'n_zpad_samp',obj.n_zpad_samp) ); 
            end
        end
    end 

Function List

The functions below are a bridge between the Matlab experiment scripts and the underlying Python Driver and objects. They translate calls from the scripts to calls on the Python objects.

Set the trigger

Generate a trigger signal to start the frame count. Used in the chained mode where the boards are chained together and exchange control commands directly and off the air.

 function sdrtrigger(obj, trig)
            obj.py_obj.set_trigger(pyargs('trig',trig)); 
        end 

Synchronize delays

In the chained mode, used by the node assumed to be the base station to synchronize the delays between itself and the UE node. In the unchained mode, it resets the correlator on the UE node to start trying to find the beginning of the frame by correlating with a known sequence, i.e., the beacon.

 function sdrsync(obj, is_bs)
            obj.py_obj.sync_delays(pyargs('is_bs', is_bs)); 
         end 

Set up the correlator

Called to setup the correlator on the UE node.

 function sdr_setcorr(obj)
            obj.py_obj.set_corr(); 
         end 

Transmission control gain

This function will turn on the gain control on the transmitter side.

 function sdr_txgainctrl(obj)
            obj.py_obj.tx_gain_ctrl(); 
         end 

Start transmitting the beacon

In the unchained mode, by calling the function below, the base station node will burn the beacon sequence onto the base station' ram to be transmitted at each pilot slot in the scheduling frame.

 function sdr_txbeacon(obj, prefix_len)
             obj.py_obj.burn_beacon( pyargs('prefix_len', prefix_len) );
         end 

Set the frame schedule

Configure the scheduling frame on an Iris node. If in chained mode, the same functionality is expected by both the UE and the base station nodes. Otherwise, the UE needs to configure the trigger_out parameter.

 function set_config(obj, chained_mode, is_bs, trigger_out)
             if chained_mode
                obj.py_obj.config_sdr_tdd_chained(pyargs('tdd_sched', obj.tdd_sched));        
             else
                obj.py_obj.config_sdr_tdd( pyargs('tdd_sched', obj.tdd_sched, 'is_bs', is_bs, 'trigger_out', trigger_out));
                
             end
         end 

Set up and activate the reading stream

These functions set the receiver streams up and activate them.

 function sdrrxsetup(obj)
           obj.py_obj.setup_stream_rx();
        end
    function sdr_activate_rx(obj)
           obj.py_obj.activate_stream_rx();
        end 

Block ram transmission

The data packet received from the caller Matlab script are burnt onto the node’s ram memory.

 function sdrtx(obj, data)
            re = real(data);   
            im = imag(data);
            obj.py_obj.burn_data( pyargs('data_r', re, 'data_i', im) );
        end 

Read the data

This function reads the recieved data sent from the Python driver, turns them into complex floats and sends them back to the caller Matlab script.

 function [data, len] = sdrrx(obj)
            rcv_data = obj.py_obj.recv_stream_tdd();
            data = double( py.array.array( 'd',py.numpy.nditer( py.numpy.real(rcv_data) ) ) ) + ...
                1i*double( py.array.array( 'd',py.numpy.nditer( py.numpy.imag(rcv_data) ) ) );
            len = length(data);
        end 

Close and clean up

Finally, using the function bellow, the opened streams are closed and the Iris boards are reset.

 function sdr_close(obj)
            obj.py_obj.close();
            delete(obj.py_obj);
        end 

Last updated on 9 Feb 2020 / Published on 18 Mar 2019