[[TracNav(WARPLab/TOC)]] = Changes in WARPLab 7.6 = WARPLab 7.6 adopts a new, cleaner syntax for handling the numeric IDs of RF interfaces and trigger inputs/outputs. The previous syntax is still supported in WARPLab 7.6 but will be removed in future releases. Refer to the code snippets below for details. All [wiki:../Examples WARPLab examples] have been updated with the new syntax. Refer to the reference design user guide for details of the new structures returned by the [wiki:../Reference/Node#wl_getInterfaceIDs wl_getInterfaceIDs()], [wiki:../Reference/Node#wl_getTriggerInputIDs wl_getTriggerInputIDs()], and [wiki:../Reference/Node#wl_getTriggerOutputIDs wl_getTriggerOutputIDs()] methods. '''Old WARPLab 7.5 Syntax''' {{{ #!text/matlab % WARPLab 7.5 % Read Trigger IDs into workspace [T_IN_ETH_A, T_IN_ENERGY, T_IN_AGCDONE, T_IN_REG, T_IN_D0, T_IN_D1, T_IN_D2, T_IN_D3, T_IN_ETH_B] = wl_getTriggerInputIDs(nodes(1)); [T_OUT_BASEBAND, T_OUT_AGC, T_OUT_D0, T_OUT_D1, T_OUT_D2, T_OUT_D3] = wl_getTriggerOutputIDs(nodes(1)); % Connect the ETH_A trigger input to the BASEBAND and AGC trigger outputs wl_triggerManagerCmd(nodes, 'output_config_input_selection', [T_OUT_BASEBAND, T_OUT_AGC], [T_IN_ETH_A]); % Read RF interface IDs into the workspace [RFA,RFB] = wl_getInterfaceIDs(nodes(1)); % Call some interface commands wl_interfaceCmd(nodes, RFA, 'channel', 2.4, 11); wl_interfaceCmd(nodes, RFB, 'channel', 2.4, 6); wl_interfaceCmd(nodes, 'RF_ALL', 'tx_gains', 3, 20); }}} '''New WARPLab 7.6 Syntax''' {{{ #!text/matlab % WARPLab 7.6 % Read Trigger IDs into workspace trig_in_ids = wl_getTriggerInputIDs(nodes(1)); trig_out_ids = wl_getTriggerOutputIDs(nodes(1)); % Connect the ETH_A trigger input to the BASEBAND and AGC trigger outputs wl_triggerManagerCmd(nodes, 'output_config_input_selection', [trig_out_ids.BASEBAND, trig_out_ids.AGC], [trig_in_ids.ETH_A]); % Read RF interface IDs into the workspace ifc_ids = wl_getInterfaceIDs(nodes(1)); wl_interfaceCmd(nodes, ifc_ids.RF_A, 'channel', 2.4, 11); wl_interfaceCmd(nodes, ifc_ids.RF_B, 'channel', 2.4, 6); wl_interfaceCmd(nodes, ifc_ids.RF_ALL, 'tx_gains', 3, 20); }}} ---- = Changes in WARPLab 7.5 = WARPLab 7.5 was designed to be fully compatible with unmodified WARPLab 7.4 scripts. Some syntax and behaviors from WARPLab 7.4 will be deprecated in future WARPLab releases. WARPLab 7.5 will print warnings when these features are encountered. In this documentation, we describe this deprecated behavior and explain the small changes required to adopt the new syntax. Users should adopt these conventions in their current scripts as the deprecated commands may be removed in a future release of WARPLab. ---- '''Choosing a Transmission Length:''' In our previous WARPLab examples, we adopted the convention of building a transmission waveform whose length was equal to the maximum buffer length the board could support. As of WARPLab 7.5, this number can be [wiki:WARPLab/BufferSizes extremely large]. We have updated all of our example scripts with the following change. {{{#!html
}}} {{{ #!text/matlab % WARPLab 7.4 % We will use the transmitter's I/Q buffer length to determine % how long our transmission can be % % node_tx - WARPLab node object for the transmitter txLength = node_tx.baseband.txIQLen; wl_basebandCmd(node_tx, 'tx_length', txLength); }}} {{{#!html }}} {{{ #!text/matlab % WARPLab 7.5 % We will read the transmitter's maximum I/Q buffer length % and assign that value to a temporary variable. % % node_tx - WARPLab node object for the transmitter % RF_TX - index of RF interface used for transmission maximum_buffer_len = wl_basebandCmd(node_tx, RF_TX, 'tx_buff_max_num_samples'); % Our transmission length for this example does not need % to fill the entire transmit buffer, so we will use the smaller % of two values: the maximum buffer length the board % can support or an arbitrary value defined by this script txLength = min(32768, maximum_buffer_len); wl_basebandCmd(node_tx, 'tx_length', txLength); }}} {{{#!html
}}} In WARPLab 7.5, the {{{txIQLen}}} parameter of a node object still exists and defaults to 32 kSamp for WARP v3 hardware and 16 kSamp for WARP v2 hardware. Attempting to read this parameter will work, but it will print a deprecation warning to the MATLAB console. Instead, users should use the new {{{tx_buff_max_num_samples}}} baseband command to determine the maximum number of samples that the transmit buffers can support. ---- '''Choosing a Reception Length:''' In our previous WARPLab examples, we never bothered to tell the board to capture a certain number of samples. Because the overall buffer size was small, we just let the board capture and fill the entire receive buffer. This is no longer appropriate in WARPLab 7.5 because the maximum receive buffer size can be very large. {{{#!html
}}} {{{ #!text/matlab % WARPLab 7.4 % Trigger of transmission and reception % % eth_trig - UDP broadcast trigger object eth_trig.send(); % Read samples from the receive buffer % % node_rx - WARPLab node object for the receiver % RF_TX - index of RF interface used for transmission % rxLength - number of samples to read rx_IQ = wl_basebandCmd(node_rx, [RF_RX], 'read_IQ', 0, rxLength); }}} {{{#!html }}} {{{ #!text/matlab % WARPLab 7.5 % Set the number of samples that should be captured % % node_rx - WARPLab node object for the receiver % rxLength - number of samples to receive wl_basebandCmd(node_rx, 'rx_length', rxLength); % Trigger of transmission and reception % % eth_trig - UDP broadcast trigger object eth_trig.send(); % Read samples from the receive buffer % % node_rx - WARPLab node object for the receiver % RF_TX - index of RF interface used for transmission % rxLength - number of samples to read rx_IQ = wl_basebandCmd(node_rx, [RF_RX], 'read_IQ', 0, rxLength); }}} {{{#!html
}}} Without the {{{rx_length}}} command, the board will default to capturing 32 kSamp in WARP v3 hardware and 16 kSamp in WARP v2 hardware. Using this command will explicitly tell the board to capture the given number of samples. Note: the value of {{{rxLength}}} should not exceed the maximum receive buffer size the board can support. To determine this value, use the {{{rx_buff_max_num_samples}}} command. ---- = Porting Code from WARPLab 6 = 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 [wiki:../Examples the WARPLab 7 examples] for ready-to-use scripts. ---- '''Initialization''': WARPLab 7 provides a utility script [wiki:../Reference/Utility#wl_initNodes 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. {{{#!html
}}} {{{ #!text/matlab %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); }}} {{{#!html }}} {{{ #!text/matlab %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); }}} {{{#!html
}}} ---- '''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. {{{#!html
}}} {{{ #!text/matlab %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); }}} {{{#!html }}} {{{ %WARPLab 7 wl_basebandCmd(nodes, 'tx_delay', 0); wl_basebandCmd(nodes, 'tx_length', 2^14); wl_interfaceCmd(nodes, 'RF_ALL', 'channel', 2.4, 11); }}} {{{#!html
}}} ---- '''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 [wiki:../Reference/Baseband/Buffers#write_iq command documentation]. {{{#!html
}}} {{{ #!text/matlab %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); }}} {{{#!html }}} {{{ #!text/matlab %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]); }}} {{{#!html
}}} ---- '''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. {{{#!html
}}} {{{ #!text/matlab %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); }}} {{{#!html }}} {{{ #!text/matlab %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'); }}} {{{#!html
}}} ---- '''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. {{{#!html
}}} {{{ #!text/matlab %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); }}} {{{#!html }}} {{{ #!text/matlab %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); }}} {{{#!html
}}}