WARP Project Forums - Wireless Open-Access Research Platform

You are not logged in.

#1 2015-Nov-18 08:13:47

JayG8027
Member
Registered: 2015-Mar-05
Posts: 33

RF interface timing

Hello, I am studying WARPLab 7.5.0 and I am using  and one WARP v3 hardwares.

A WARP board has four RF interface by using FMC-RF-2X245 module.
Two RF interfaces are used as TX and one RF interface is used as RX. 
Two TX interfaces are connected to input of RF adder and one RX interface is connected to output of RF adder. 
In this case, I use one RF adder.  RFA, RFC are TX, RFB is RX.   

Code:

    wl_basebandCmd(nodes(1),[RFA], 'write_IQ', tx_vec_air(:));

    % Enable the Tx and Rx radios
    wl_interfaceCmd(nodes(1), RFA, 'tx_en');
    wl_interfaceCmd(nodes(1), RFB, 'rx_en');

    % Enable the Tx and Rx buffers
    wl_basebandCmd(nodes(1), RFA, 'tx_buff_en');
    wl_basebandCmd(nodes(1), RFB, 'rx_buff_en');

    
    wl_basebandCmd(nodes(1),[RFC], 'write_IQ', tx_vec_air2(:));

    % Enable the Tx and Rx radios
    wl_interfaceCmd(nodes(1),RFC, 'tx_en');
    wl_interfaceCmd(nodes(1),RFB, 'rx_en');

    % Enable the Tx and Rx buffers
    wl_basebandCmd(nodes(1),RFC, 'tx_buff_en');
    wl_basebandCmd(nodes(1),RFB, 'rx_buff_en');
    %%%%%%%%%%%%%%%%%%%%%%%%    
       
    % Trigger the Tx/Rx cycle at both nodes
    eth_trig.send();

    % Pause for the samples to be processed at the node
    pause(TX_NUM_SAMPS * 1/(40e6));

I expect sum of two TX signal, but result is only one side signal that positioned at below command.
the result of above code is same with result of tx_vec_air2.

If we change order command like below code, the result is same with result of  tx_vec_air.

Code:

   wl_basebandCmd(nodes(1),[RFC], 'write_IQ', tx_vec_air2(:));

    % Enable the Tx and Rx radios
    wl_interfaceCmd(nodes(1),RFC, 'tx_en');
    wl_interfaceCmd(nodes(1),RFB, 'rx_en');

    % Enable the Tx and Rx buffers
    wl_basebandCmd(nodes(1),RFC, 'tx_buff_en');
    wl_basebandCmd(nodes(1),RFB, 'rx_buff_en');

    wl_basebandCmd(nodes(1),[RFA], 'write_IQ', tx_vec_air(:));

    % Enable the Tx and Rx radios
    wl_interfaceCmd(nodes(1), RFA, 'tx_en');
    wl_interfaceCmd(nodes(1), RFB, 'rx_en');

    % Enable the Tx and Rx buffers
    wl_basebandCmd(nodes(1), RFA, 'tx_buff_en');
    wl_basebandCmd(nodes(1), RFB, 'rx_buff_en');

    
   
    %%%%%%%%%%%%%%%%%%%%%%%%    
       
    % Trigger the Tx/Rx cycle at both nodes
    eth_trig.send();

When I connect to RF adder, we try to use various combination of wire and wireless connection.   
When I connect RF cable, I use 30dB attenuation. Wire and wireless connection don't affect the result.

I want to know why this result occur.
The cause of this problem can be our RF adder hardware problem, different start transmission time of RF interface, and other WARP hardware features.
please help me, thank you.

Last edited by JayG8027 (2015-Nov-18 08:27:13)

Offline

 

#2 2015-Nov-18 08:55:34

welsh
Administrator
From: Mango Communications
Registered: 2013-May-15
Posts: 612

Re: RF interface timing

You are running into an issue with the 'tx_buff_en' command.

In WARPLab 7.5.0 and WARPLab 7.5.1, there is a bug in the 'tx_buff_en' and 'rx_buff_en' commands.  To change the value in the buffers core, the C code on the node uses macros wl_bb_set_tx_buffer_en(rf_sel) and wl_bb_set_rx_buffer_en(rf_sel).  You can see in the WARPLab 7.5.0 implementation, that the macros use the value passed in to set the register, overwriting the previous value.  This was fixed in WARPLab 7.6.0 such that the current value in the core is read and then the new value is ORed in. 

To fix this, you can either:
1) Update the macro in the WARPLab 7.5.0 C code to have the correct behavior.
2) Enable all interfaces when using the 'tx_buff_en' and 'rx_buff_en' commands:

Code:

    % Enable the Tx and Rx buffers
    wl_basebandCmd(nodes(1), RFA + RFC, 'tx_buff_en');
    wl_basebandCmd(nodes(1), RFB, 'rx_buff_en');

3) Update to WARPLab 7.6.0.  If you do so, please make sure you consult the porting guide.

Offline

 

#3 2015-Nov-19 20:54:56

JayG8027
Member
Registered: 2015-Mar-05
Posts: 33

Re: RF interface timing

Thank you for answer !

And I have another question. I am using wl_example_siso_ofdm_txrx.m example code.

Code:

%% WARPLab Tx/Rx
node_tx = node(1);
node_rx = node(2);
if(USE_WARPLAB_TXRX)
    wl_basebandCmd(node_tx,[RFA], 'write_IQ', tx_vec_air(:));

    % Enable the Tx and Rx radios
    wl_interfaceCmd(node_tx,RFA, 'tx_en');
    wl_interfaceCmd(node_tx,RFB, 'rx_en');

    % Enable the Tx and Rx buffers
    wl_basebandCmd(node_tx,RFA, 'tx_buff_en');
    wl_basebandCmd(node_tx,RFB, 'rx_buff_en');
    
    % Trigger the Tx/Rx cycle at both nodes
    eth_trig.send();

    % Pause for the samples to be processed at the node
    pause(TX_NUM_SAMPS * 1/(40e6));
    
    rx_vec_air_estH = wl_basebandCmd(node_tx,[RFB], 'read_IQ', 0, TX_NUM_SAMPS);  
    
    rx_vec_air_estH = rx_vec_air_estH(:).';
    
    % Disable the Tx/Rx radios and buffers
    wl_basebandCmd(nodes, 'RF_ALL', 'tx_rx_buff_dis');
    wl_interfaceCmd(nodes, 'RF_ALL', 'tx_rx_dis');
else
    % Sim-only mode: Apply wireless degradations here for sim (noise, fading, etc)

    % Perfect (ie. Rx=Tx):
    % rx_vec_air = tx_vec_air;

    % AWGN:
    rx_vec_air_estH = tx_vec_air + 1e-2*complex(randn(1,length(tx_vec_air)), randn(1,length(tx_vec_air)));
    
    % CFO:
    % rx_vec_air = tx_vec_air .* exp(-1i*2*pi*1e-4*[0:length(tx_vec_air)-1]);
end

if(USE_WARPLAB_TXRX)    
    % Write the Tx waveform to the Tx node
    wl_basebandCmd(node_rx,[RFA], 'write_IQ', tx_vec_air(:));

    % Enable the Tx and Rx radios
    wl_interfaceCmd(node_rx,RFA, 'tx_en');
    wl_interfaceCmd(node_tx,RFB, 'rx_en');

    % Enable the Tx and Rx buffers
    wl_basebandCmd(node_rx,RFA, 'tx_buff_en');
    wl_basebandCmd(node_tx,RFB, 'rx_buff_en');

    % Trigger the Tx/Rx cycle at both nodes
    eth_trig.send();

    % Pause for the samples to be processed at the node
    pause(TX_NUM_SAMPS * 1/(40e6));
    
    
    

    % Retrieve the received waveform from the Rx node
    rx_vec_air = wl_basebandCmd(node_tx,[RFB], 'read_IQ', 0, TX_NUM_SAMPS);  
    
    rx_vec_air = rx_vec_air(:).';
   
    % Disable the Tx/Rx radios and buffers
    wl_basebandCmd(nodes, 'RF_ALL', 'tx_rx_buff_dis');
    wl_interfaceCmd(nodes, 'RF_ALL', 'tx_rx_dis');
else
    % Sim-only mode: Apply wireless degradations here for sim (noise, fading, etc)

    % Perfect (ie. Rx=Tx):
    % rx_vec_air = tx_vec_air;

    % AWGN:
    rx_vec_air = tx_vec_air + 1e-2*complex(randn(1,length(tx_vec_air)), randn(1,length(tx_vec_air)));
    
    % CFO:
    % rx_vec_air = tx_vec_air .* exp(-1i*2*pi*1e-4*[0:length(tx_vec_air)-1]);
end

like above code, I try to transmit data from RFA of node_rx to RFB of node_tx after transmission from RFA of node_tx to RFB of node tx.
But data from RFA of node_rx to RFB of node_tx has many errors.
If we operate only  transmission from RFA of node_rx to RFB of node_tx, data doesn't have error.

I want to know cause of this phenomenon

Last edited by JayG8027 (2015-Nov-19 22:25:31)

Offline

 

#4 2015-Nov-20 09:59:13

welsh
Administrator
From: Mango Communications
Registered: 2013-May-15
Posts: 612

Re: RF interface timing

What kind of errors are you seeing? 

You need to try to isolate the problem.  See what happens when you perform the RF loopback (i.e. transmit from RFA to RFB) on node_rx as well as other transmission configurations between nodes (i.e. transmit from node_rx to node_tx and vice versa).  This will allow you to see if there is an antenna issue.  Another test would be to eliminate over-the-air affects by connecting the two nodes via an RF cable with greater than 30 dB of attenuation.  You can also just transmit a simple waveform between the nodes and then view it to see if everything is what you expect. 

I don't see any obvious errors in the code that you posted, so you will need to understand what else might be happening.  Also, you should make sure that the waveform processing is correct for both waveforms since there might be a post processing step that is causing the errors.

Offline

 

#5 2015-Nov-20 10:22:36

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 5159

Re: RF interface timing

See what happens when you perform the RF loopback (i.e. transmit from RFA to RFB)

Be sure to have >30dB attenuation between any Tx and Rx interface, even when using interfaces on the same node. Directly connecting Tx to Rx can damage the Rx circuits.

Offline

 

#6 2015-Nov-23 00:52:45

JayG8027
Member
Registered: 2015-Mar-05
Posts: 33

Re: RF interface timing

Errors mean result that calculated in wl_example_siso_ofdm_txrx.m code.
After plot figure of rx_syms(RX symbol matrix), I observed that errors occur in last part of rx_syms.
So, I reduced number of the number of OFDM symbols, and then errors become zero.

But, I don't know why this phenomenon still occurs.

Last edited by JayG8027 (2015-Nov-23 06:10:30)

Offline

 

#7 2015-Nov-23 08:13:11

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 5159

Re: RF interface timing

You need to be more specific about what parameters you're using, what you're changing, and exactly what you're observing. How many OFDM symbols are you transmitting? What does "last part of rx_syms" mean - the last X% of the waveform, for any length? Or any symbols beyond some length?

One possible source of errors is sampling frequency offset. This frequency offset manifests as a phase shift that increases with subcarrier index and time. The effect is very small- you will only observe degradation due to SFO for transmissions with thousands of OFDM symbols. The latest version of the SISO OFDM example (already in svn; to be included in WARPLab 7.7) includes estimation/correction for SFO.

Offline

 

#8 2015-Nov-24 02:59:16

JayG8027
Member
Registered: 2015-Mar-05
Posts: 33

Re: RF interface timing

Thank you for answer!
I am using wl_example_siso_ofdm_txrx.m code of WARPLab 7.5.0.

Code:

% Params:
USE_WARPLAB_TXRX        = 1;           % Enable WARPLab-in-the-loop (otherwise sim-only)
WRITE_PNG_FILES         = 0;           % Enable writing plots to PNG

% Waveform params
N_OFDM_SYMS             = 500;         % Number of OFDM symbols
MOD_ORDER               = 16;          % Modulation order (2/4/16 = BSPK/QPSK/16-QAM)
TX_SCALE                = 1.0;         % Scale for Tx waveform ([0:1])
INTERP_RATE             = 2;           % Interpolation rate (1 or 2)

% OFDM params
SC_IND_PILOTS           = [8 22 44 58];                           % Pilot subcarrier indices
SC_IND_DATA             = [2:7 9:21 23:27 39:43 45:57 59:64];     % Data subcarrier indices
N_SC                    = 64;                                     % Number of subcarriers
CP_LEN                  = 16;                                     % Cyclic prefix length
N_DATA_SYMS             = N_OFDM_SYMS * length(SC_IND_DATA);      % Number of data symbols (one per data-bearing subcarrier per OFDM symbol)

% Rx processing params
FFT_OFFSET              = 4;           % Number of CP samples to use in FFT (on average)
LTS_CORR_THRESH         = 0.8;         % Normalized threshold for LTS correlation
DO_APPLY_CFO_CORRECTION = 1;           % Enable CFO estimation/correction
USE_PILOT_TONES         = 1;           % Enable phase error correction
DECIMATE_RATE           = INTERP_RATE;

% WARPLab experiment params
USE_AGC                 = true;        % Use the AGC if running on WARP hardware
MAX_TX_LEN              = 2^17;          % Maximum number of samples to use for this experiment

I changed N_OFDM_SYMS parameter that means the number of OFDM symbols from 500 to 50,
because last 50% of received the waveform have errors.

Unchanged example code doesn't have error. But if I changed a part of example code like code in questions Nov-19, errors occur.

Last edited by JayG8027 (2015-Nov-24 03:00:20)

Offline

 

#9 2015-Nov-24 10:22:46

chunter
Administrator
From: Mango Communications
Registered: 2006-Aug-24
Posts: 1212

Re: RF interface timing

In Nov-19 post, the code snippet shows a node_tx RFA transmission to node_tx RFB. The result of that reception is stored in the variable "rx_vec_air_estH". Following this, there is then a node_rx RFA transmission to node_tx RFB. The result of that reception is stored in the variable "rx_vec_air". Is a correct rephrasing of the problem you are seeing that "rx_vec_air" (not "rx_vec_air_esth"), contains symbol errors near the tail end of the waveform only when the first transmission (resulting in rx_vec_air_estH) is enabled? Does "rx_vec_air_estH" play into the decoding of "rx_vec_air" in any way? Is this just a normal SISO Tx/Rx baseband like the example? Or are there extensions for some kind of cooperative scheme hinted at in your previous post.

It's not easy for us to decipher from your comments what exactly the test set up is here. Can you be more clear on what exactly the topology is and what kind of processing you are doing in MATLAB?

Offline

 

#10 2015-Nov-24 20:51:50

welsh
Administrator
From: Mango Communications
Registered: 2013-May-15
Posts: 612

Re: RF interface timing

We did some more investigation on this and we were able to replicate the behavior you were seeing.

In the code you provided on Nov-19, when you send the first Ethernet trigger, you have only configured buffers on node_tx, ie node_rx has all of its buffers disabled. The expected behavior of node_rx in this situation is:  When you trigger node_rx, nothing should happen at node_rx because all the buffers are disabled (i.e. the TX / RX state machines in the WARPLab buffers core should not run).  However, this expected behavior is not what happens at node_rx.  Instead, node_rx partially runs the TX / RX state machines and this is why you are seeing the errors in the receive waveform when you enable the buffers at node_rx and trigger the nodes a second time.

The reason you see the issue go away if you reduce the number of OFDM symbols is that the unexpected behavior only occurs when using large buffers (i.e. you have a TX / RX length greater than 2^15 samples).

To work around this issue there are two solutions:

1) Create multiple Ethernet triggers:

Since this unexpected behavior occurs when a node is triggered and all the buffers are disabled, you can create multiple Ethernet triggers such that only nodes with enabled buffers are triggered.  From the WARPLab 7.5.0 wl_example_siso_ofdm_txrx.m, instead of:

Code:

    % Create a UDP broadcast trigger and tell each node to be ready for it
    eth_trig = wl_trigger_eth_udp_broadcast;
    wl_triggerManagerCmd(nodes, 'add_ethernet_trigger', [eth_trig]);

create two Ethernet triggers and only add the second Ethernet trigger to node_tx:

Code:

    % Create a UDP broadcast trigger and tell each node to be ready for it
    eth_trig = wl_trigger_eth_udp_broadcast;
    wl_triggerManagerCmd(nodes, 'add_ethernet_trigger', [eth_trig]);

    % Create a second UDP broadcast trigger and tell node_tx to be ready for it
    eth_trig_tx_only = wl_trigger_eth_udp_broadcast;
    wl_triggerManagerCmd(nodes(1), 'add_ethernet_trigger', [eth_trig_tx_only]);

Then when you are doing your TX / RX (Note:  I use "..." to represent the other code so it is easier to see the changes):

Code:

%% WARPLab Tx/Rx
if(USE_WARPLAB_TXRX)
    wl_basebandCmd(node_tx,[RFA], 'write_IQ', tx_vec_air(:));
    ...
    % Trigger the Tx/Rx cycle at node_tx only
    eth_trig_tx_only.send();
    ...
    rx_vec_air_estH = wl_basebandCmd(node_tx,[RFB], 'read_IQ', 0, TX_NUM_SAMPS);  
   ...
end

if(USE_WARPLAB_TXRX)    
    % Write the Tx waveform to the Tx node
    wl_basebandCmd(node_rx,[RFA], 'write_IQ', tx_vec_air(:));
    ...
    % Trigger the Tx/Rx cycle at both nodes
    eth_trig.send();
    ...
    % Retrieve the received waveform from the Rx node
    rx_vec_air = wl_basebandCmd(node_tx,[RFB], 'read_IQ', 0, TX_NUM_SAMPS);  
    ...
end

2) Modify code in wl_baseband.c

If we look at the WARPLab 7.5.0 wl_baseband.c code, we need to ensure that nothing happens to the TX state machine when none of the buffers are enabled (the RX state machine does not need any modification).  To do this we add an if statement around most of the statements in the wl_buffers_core_tx_int_handler() function (Note:  There are two new lines of code that are marked with the comment "!!! NEW LINE OF CODE !!!"):

Code:

        // Get buffers core register values
        buff_en          = wl_bb_get_tx_buffer_en();
        tx_iq_status     = wl_bb_get_rf_tx_iq_status();
        continuous_tx    = ((wl_bb_get_config() & WL_BUF_REG_CONFIG_CONT_TX) == WL_BUF_REG_CONFIG_CONT_TX);

        // For the last write we need to prep the buffer for the next write IQ.  This means
        //   that we fill the temporary buffer completely.  For every other write, we need to
        //   transfer a threshold number of bytes to the buffer.
        //
        // ASSUMPTION:  We are going to assume that all TX buffers are the same size.
        //   In the future, this might not be true and the *_xfer_length calculations will need to be
        //   done per buffer.
        //

        if (buff_en) {    // <-- !!! NEW LINE OF CODE !!!

        if (tx_iq_status & WL_BUF_TX_IQ_STATUS_WR_DONE) {
            iq_write_offset  = 0x00000000;

            // If we are in continuous TX mode, the "done" means we need to start the TX waveform over,
            // but can't over-write what we are currently transmitting (ie only write half the buffer).
            if (continuous_tx) {
                iq_xfer_length   = (u32)(WARPLAB_IQ_TX_BUF_SIZE >> 1);
            } else {
                iq_xfer_length   = (u32)(WARPLAB_IQ_TX_BUF_SIZE);
            }
        } else {
            iq_write_offset  = (wl_bb_get_rf_tx_iq_buf_wr_byte_offset() & WL_BUF_TX_TRANSFER_BYTE_ALIGNMENT_MASK);
            iq_xfer_length   = (u32)(WARPLAB_IQ_TX_BUF_SIZE >> 1);
        }

        // Transfer the data
        populate_tmp_tx_buffers(buff_en, iq_write_offset, iq_xfer_length);

        // Update the write_offset in the buffers core
        wl_bb_set_rf_tx_iq_buf_wr_byte_offset(iq_write_offset + iq_xfer_length);

        }    // <-- !!! NEW LINE OF CODE !!!

NOTE:  I just added the lines and did not change the indentation of the other lines to show the minimum amount of code that needs to be modified. 

Unfortunately, this unexpected behavior exists in WARPLab 7.5.1 wl_baseband.c and WARPLab 7.6.0 wl_baseband.c.  However, you can make the same modification shown above to make sure that nothing happens to the TX state machine when none of the buffers are enabled.

Given this is unexpected behavior, we plan to release a new version of WARPLab that fixes this problem sometime next week after the Thanksgiving holiday.

Offline

 

#11 2015-Dec-07 20:40:04

JayG8027
Member
Registered: 2015-Mar-05
Posts: 33

Re: RF interface timing

Thank you for your answer !

I am have another question. I am using WARPLab 7.5.0 and two WARP v3 hardware boards.
And I test wl_example_siso_ofdm_txrx.m code of WARPLab 7.5.0.

When I operated program, lts_peaks value is not constant.

Code:

% Find all correlation peaks
lts_peaks = find(lts_corr > LTS_CORR_THRESH*max(lts_corr));

Other environment parameters are constant like a distance between two nodes.

What is the cause of this result? Is there causes of hardware such as clock module?

Last edited by JayG8027 (2015-Dec-07 20:42:17)

Offline

 

#12 2015-Dec-07 21:29:45

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 5159

Re: RF interface timing

The values in lts_peaks correspond to the Rx sample indexes of peaks in the LTS cross correlation. These sample indexes will reflect any difference in timing between the Tx node's transmission and Rx node's captured waveform. If you're using Ethernet triggers at both nodes there will definitely be jitter in the arrival of the trigger packets (the broadcast Ethernet frames) at the nodes. This jitter will manifest as a random offset between the Tx and Rx sample vectors. The Rx node might start before Tx (this is why the AGC trigger output is delayed, to assure the Rx node is mid-preamble before AGC starts) or Rx might start after Tx. The LTS correlator is designed to identify the absolute sample index of the preamble in the received waveform, whatever the Tx/Rx offset.

If your experiment requires a deterministic offset between the Tx and Rx sample vectors you must share a trigger between the Tx and Rx nodes. You can do this with wires between the WARP v3 debug headers or with CM-PLL modules. The WARPLab nodeSync example illustrates both options.

Offline

 

Board footer