wiki:WARPLab/Porting

Version 7 (modified by murphpo, 11 years ago) (diff)

--

WARPLab 7: Porting Code from old WARPLab

The basic flow of an experiment is the same across all versions of WARPLab. However WARPLab 7 has been designed to simplify experiments utilizing multiple nodes, each with multiple RF interfaces. The code samples below illustrate equivalent processes in WARPLab 6 and WARPLab 7, emphasizing the more compact and portable syntax available in the WARPLab 7 framework.

The code on this page is not a complete example; please see the WARPLab 7 examples for ready-to-use scripts.


Initialization: WARPLab 7 provides a utility script wl_initNodes which simplifies the process of establishing a connection from MATLAB to multiple WARP nodes running the WARPLab reference design. The array returned by wl_initNodes replaces the individual socket handles used in WARPLab 6.

%WARPLab 6

%Load the many global variables for the framework
warplab_defines

%Initialize two WARP nodes
[socketHandles, packetNum] = warplab_initialize(2);

%Retrieve socket handles for the trigger and both nodes
udp_Sync = socketHandles(1);
udp_node1 = socketHandles(2);
udp_node2 = socketHandles(3);
%WARPLab 7

%Initialize two WARP nodes
nodes = wl_initNodes(2);

%Retrieve IDs for available RF interfaces
[RFA, RFB] = wl_getInterfaceIDs(nodes(1));

%Create an Ethernet trigger and assign it to both nodes
eth_trig = wl_trigger_eth_udp_broadcast;
wl_triggerManagerCmd(nodes, 'add_ethernet_trigger', eth_trig);


Setting Parameters: WARPLab 7 enables setting the same RF and baseband parameters as previous versions. However the syntax for sending commands to nodes has changed. The new syntax allows the same command to be sent to multiple nodes in one line. Each node can be assigned the same parameter value, or multiple values (one per node) can be passed as an array argument. The example below shows equivalent code for setting a few parameters for two nodes.

%WARPLab 6
warplab_writeRegister(udp_node1, TX_DELAY, 0);
warplab_writeRegister(udp_node1, TX_LENGTH, 2^14);

warplab_writeRegister(udp_node2, TX_DELAY, 0);
warplab_writeRegister(udp_node2, TX_LENGTH, 2^14);

warplab_setRadioParameter(udp_node1, CARRIER_CHANNEL, 11);
warplab_setRadioParameter(udp_node2, CARRIER_CHANNEL, 11);
%WARPLab 7
wl_basebandCmd(nodes, 'tx_delay', 0);
wl_basebandCmd(nodes, 'tx_length', 2^14);
wl_interfaceCmd(nodes, 'RF_ALL', 'channel', 2.4, 11);

Writing Samples: Vectors of samples are constructed in MATLAB and written to buffers assigned to specific RF interfaces on the WARP nodes. In WARPLab 7 the buffer selection is parametric, simplifying the processing of iterating over nodes and interfaces, switching interfaces programmatically, etc. The example below illustrates how different waveforms can be written to multiple interfaces in one line. For complete documentation of the write_iq command, refer to the command documentation.

%WARPLab 6

%Time vector (assumes 40MHz sampling rate)
t = (1/40e6) .* [0 : 2^14-1];

%Generate a 1MHz sinusoid
txSigA = exp(1i*2*pi*t*1e6);

%Generate a 2MHz sinusoid
txSigB = exp(1i*2*pi*t*2e6);

%Write the two signals to RF A and B on both nodes
warplab_writeSMWO(udp_node1, RADIO2_TXDATA, txSigA);
warplab_writeSMWO(udp_node1, RADIO3_TXDATA, txSigB);
warplab_writeSMWO(udp_node2, RADIO2_TXDATA, txSigA);
warplab_writeSMWO(udp_node2, RADIO3_TXDATA, txSigB);
%WARPLab 7

%Time column vector (assumes 40MHz sampling rate)
t = (1/40e6) .* [0 : 2^14-1].';

%Generate a 1MHz sinusoid
txSigA = exp(1i*2*pi*t*1e6);

%Generate a 2MHz sinusoid
txSigB = exp(1i*2*pi*t*2e6);

%Write the two signals to RF A and B on both nodes
% Use vector arguments for interface selection and per-interface signals
wl_basebandCmd(nodes, [RFA RFB], 'write_IQ', [txSigA txSigB]);


Tx/Rx Cycle: The basic flow of a Tx/Rx cycle in WARPLab 7 is unchanged:

  • Write samples to Tx buffers (see above)
  • Enable Tx radios and buffers
  • Enable Rx radios and buffers
  • Send trigger to Tx and Rx nodes
  • Disable Tx/Rx radios and buffers
  • Retrieve captured samples from Rx buffers (see below)

The code below illustrates the updated syntax for en/disabling radios and buffers and sending triggers.

%WARPLab 6

%Enable the RF transceivers
warplab_sendCmd(udp_node1, RADIO2_TXEN, packetNum);
warplab_sendCmd(udp_node1, RADIO3_TXEN, packetNum);
warplab_sendCmd(udp_node2, RADIO2_RXEN, packetNum);
warplab_sendCmd(udp_node2, RADIO3_RXEN, packetNum);

%Enable the Tx/Rx buffers
warplab_sendCmd(udp_node1, RADIO2TXBUFF_TXEN, packetNum);
warplab_sendCmd(udp_node1, RADIO3TXBUFF_TXEN, packetNum);
warplab_sendCmd(udp_node2, RADIO2RXBUFF_RXEN, packetNum);
warplab_sendCmd(udp_node2, RADIO3RXBUFF_RXEN, packetNum);

%Prepare nodes for trigger reception
warplab_sendCmd(udp_node1, TX_START, packetNum);
warplab_sendCmd(udp_node2, RX_START, packetNum);

% Send the trigger
warplab_sendSync(udp_Sync);

%Disable the RF transceivers
warplab_sendCmd(udp_node1, RADIO2_TXDIS, packetNum);
warplab_sendCmd(udp_node1, RADIO3_TXDIS, packetNum);
warplab_sendCmd(udp_node2, RADIO2_RXDIS, packetNum);
warplab_sendCmd(udp_node2, RADIO3_RXDIS, packetNum);

%Disable the Tx/Rx buffers
warplab_sendCmd(udp_node1, RADIO2TXBUFF_TXDIS, packetNum);
warplab_sendCmd(udp_node1, RADIO3TXBUFF_TXDIS, packetNum);
warplab_sendCmd(udp_node2, RADIO2RXBUFF_RXDIS, packetNum);
warplab_sendCmd(udp_node2, RADIO3RXBUFF_RXDIS, packetNum);


%WARPLab 7

%Enable the RF transceivers
wl_interfaceCmd(nodes(1), [RFA RFB], 'tx_en');
wl_interfaceCmd(nodes(2), [RFA RFB], 'rx_en');

%Enable the sample buffers
wl_basebandCmd(nodes(1), [RFA RFB], 'tx_buff_en');
wl_basebandCmd(nodes(2), [RFA RFB], 'rx_buff_en');

%Send the broadcast trigger
eth_trig.send();

%Disable the transceivers and buffers
wl_basebandCmd(nodes, 'RF_ALL', 'tx_rx_buff_dis');
wl_interfaceCmd(nodes, 'RF_ALL', 'tx_rx_dis');

%Retrieve the IQ and RSSI samples from the Rx node
rx_IQ = wl_basebandCmd(nodes(2), [RFA RFB], 'read_IQ', 0, 2^14);
rx_RSSI = wl_basebandCmd(nodes(2), [RFA RFB], 'read_RSSI', 0, 2^12);

Reading Samples: WARPLab 7 simplifies the process for reading samples from multiple nodes and multiple buffers. The example below illustrates reading IQ and RSSI samples from two interfaces (RFA and RFB) on one node.

%WARPLab 6

%Retrieve and format the IQ samples from RFA and RFB
[Node2_Radio2_RawRxData] = warplab_readSMRO(udp_node2, RADIO2_RXDATA, 2^14);
[Node2_Radio2_RxData] = warplab_processRawRxData(Node2_Radio2_RawRxData);
[Node2_Radio3_RawRxData] = warplab_readSMRO(udp_node2, RADIO3_RXDATA, 2^14);
[Node2_Radio3_RxData] = warplab_processRawRxData(Node2_Radio3_RawRxData);

%Retrieve and format the RSSI samples from RFA and RFB
[Node2_Radio2_RawRSSIData] = warplab_readSMRO(udp_node2, RADIO2_RSSIDATA, 2^12);
[Node2_Radio2_RSSIData] = warplab_processRawRSSIData(Node2_Radio2_RawRSSIData);
[Node2_Radio3_RawRSSIData] = warplab_readSMRO(udp_node2, RADIO3_RSSIDATA, 2^12);
[Node2_Radio3_RSSIData] = warplab_processRawRSSIData(Node2_Radio3_RawRSSIData);

%WARPLab 7

%Retrieve the IQ and RSSI samples from both interfaces on the Rx node
rx_IQ = wl_basebandCmd(nodes(2), [RFA RFB], 'read_IQ', 0, 2^14);
rx_RSSI = wl_basebandCmd(nodes(2), [RFA RFB], 'read_RSSI', 0, 2^12);