Statistics
| Branch: | Tag: | Revision:

root / host / include / uhd / usrp / multi_usrp.hpp @ 45a40a0f

History | View | Annotate | Download (27.9 KB)

1
//
2
// Copyright 2010-2011 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
#ifndef INCLUDED_UHD_USRP_MULTI_USRP_HPP
19
#define INCLUDED_UHD_USRP_MULTI_USRP_HPP
20

    
21
//define API capabilities for compile time detection of new features
22
#define UHD_USRP_MULTI_USRP_REF_SOURCES_API
23
#define UHD_USRP_MULTI_USRP_GET_RATES_API
24
#define UHD_USRP_MULTI_USRP_DC_OFFSET_API
25
#define UHD_USRP_MULTI_USRP_CORRECTION_API
26

    
27
#include <uhd/config.hpp>
28
#include <uhd/device.hpp>
29
#include <uhd/deprecated.hpp>
30
#include <uhd/types/ranges.hpp>
31
#include <uhd/types/stream_cmd.hpp>
32
#include <uhd/types/tune_request.hpp>
33
#include <uhd/types/tune_result.hpp>
34
#include <uhd/types/sensors.hpp>
35
#include <uhd/usrp/subdev_spec.hpp>
36
#include <uhd/usrp/dboard_iface.hpp>
37
#include <uhd/usrp/mboard_iface.hpp>
38
#include <boost/shared_ptr.hpp>
39
#include <boost/utility.hpp>
40
#include <complex>
41
#include <string>
42
#include <vector>
43

    
44
namespace uhd{ namespace usrp{
45

    
46
/*!
47
 * The Multi-USRP device class:
48
 *
49
 * This class facilitates ease-of-use for most use-case scenarios.
50
 * The wrapper provides convenience functions to tune the devices,
51
 * set the dboard gains, antennas, filters, and other properties.
52
 * This class can be used to interface with a single USRP with
53
 * one or more channels, or multiple USRPs in a homogeneous setup.
54
 * All members take an optional parameter for board number or channel number.
55
 * In the single device, single channel case, these parameters can be unspecified.
56
 *
57
 * When using a single device with multiple channels:
58
 *  - Channel mapping is determined by the subdevice specifications
59
 *  - All channels share a common RX sample rate
60
 *  - All channels share a common TX sample rate
61
 *
62
 * When using multiple devices in a configuration:
63
 *  - Channel mapping is determined by the device address arguments
64
 *  - All boards share a common RX sample rate
65
 *  - All boards share a common TX sample rate
66
 *  - All boards share a common RX subdevice specification size
67
 *  - All boards share a common TX subdevice specification size
68
 *  - All boards must have synchronized times (see the set_time_*() calls)
69
 *
70
 * Example to setup channel mapping for multiple devices:
71
 * <pre>
72
 *
73
 * //create a multi_usrp with two boards in the configuration
74
 * device_addr_t dev_addr;
75
 * dev_addr["addr0"] = "192.168.10.2"
76
 * dev_addr["addr1"] = "192.168.10.3";
77
 * multi_usrp::sptr dev = multi_usrp::make(dev_addr);
78
 *
79
 * //set the board on 10.2 to use the A RX subdevice (RX channel 0)
80
 * dev->set_rx_subdev_spec("A:A", 0);
81
 *
82
 * //set the board on 10.3 to use the B RX subdevice (RX channel 1)
83
 * dev->set_rx_subdev_spec("A:B", 1);
84
 *
85
 * //set both boards to use the AB TX subdevice (TX channels 0 and 1)
86
 * dev->set_tx_subdev_spec("A:AB", multi_usrp::ALL_MBOARDS);
87
 *
88
 * //now that all the channels are mapped, continue with configuration...
89
 *
90
 * </pre>
91
 */
92
class UHD_API multi_usrp : boost::noncopyable{
93
public:
94
    typedef boost::shared_ptr<multi_usrp> sptr;
95

    
96
    //! A wildcard motherboard index
97
    static const size_t ALL_MBOARDS = size_t(~0);
98

    
99
    //! A wildcard channel index
100
    static const size_t ALL_CHANS = size_t(~0);
101

    
102
    //! A wildcard gain element name
103
    static const std::string ALL_GAINS;
104

    
105
    /*!
106
     * Make a new multi usrp from the device address.
107
     * \param dev_addr the device address
108
     * \return a new single usrp object
109
     */
110
    static sptr make(const device_addr_t &dev_addr);
111

    
112
    /*!
113
     * Get the underlying device object.
114
     * This is needed to get access to the streaming API and properties.
115
     * \return the device object within this single usrp
116
     */
117
    virtual device::sptr get_device(void) = 0;
118

    
119
    //! Convenience method to get a RX streamer
120
    rx_streamer::sptr get_rx_stream(const stream_args_t &args){
121
        return this->get_device()->get_rx_stream(args);
122
    }
123

    
124
    //! Convenience method to get a TX streamer
125
    tx_streamer::sptr get_tx_stream(const stream_args_t &args){
126
        return this->get_device()->get_tx_stream(args);
127
    }
128

    
129
    /*******************************************************************
130
     * Mboard methods
131
     ******************************************************************/
132

    
133
    /*!
134
     * Set the master clock rate.
135
     * This controls the rate of the clock that feeds the FPGA DSP.
136
     * On some devices, this re-tunes the clock to the specified rate.
137
     * If the specified rate is not available, this method will throw.
138
     * On other devices, this method notifies the software of the rate,
139
     * but requires the the user has made the necessary hardware change.
140
     * \param rate the new master clock rate in Hz
141
     * \param mboard the motherboard index 0 to M-1
142
     */
143
    virtual void set_master_clock_rate(double rate, size_t mboard = ALL_MBOARDS) = 0;
144

    
145
    /*!
146
     * Get the master clock rate.
147
     * \param mboard the motherboard index 0 to M-1
148
     * \return the master clock rate in Hz.
149
     */
150
    virtual double get_master_clock_rate(size_t mboard = 0) = 0;
151

    
152
    /*!
153
     * Get a printable summary for this USRP configuration.
154
     * \return a printable string
155
     */
156
    virtual std::string get_pp_string(void) = 0;
157

    
158
    /*!
159
     * Get canonical name for this USRP motherboard.
160
     * \param mboard which motherboard to query
161
     * \return a string representing the name
162
     */
163
    virtual std::string get_mboard_name(size_t mboard = 0) = 0;
164

    
165
    /*!
166
     * Get the current time in the usrp time registers.
167
     * \param mboard which motherboard to query
168
     * \return a timespec representing current usrp time
169
     */
170
    virtual time_spec_t get_time_now(size_t mboard = 0) = 0;
171

    
172
    /*!
173
     * Get the time when the last pps pulse occured.
174
     * \param mboard which motherboard to query
175
     * \return a timespec representing the last pps
176
     */
177
    virtual time_spec_t get_time_last_pps(size_t mboard = 0) = 0;
178

    
179
    /*!
180
     * Sets the time registers on the usrp immediately.
181
     *
182
     * If only one MIMO master is present in your configuration, set_time_now is
183
     * safe to use because the slave's time automatically follows the master's time.
184
     * Otherwise, this call cannot set the time synchronously across multiple devices.
185
     * Please use the set_time_next_pps or set_time_unknown_pps calls with a PPS signal.
186
     *
187
     * \param time_spec the time to latch into the usrp device
188
     * \param mboard the motherboard index 0 to M-1
189
     */
190
    virtual void set_time_now(const time_spec_t &time_spec, size_t mboard = ALL_MBOARDS) = 0;
191

    
192
    /*!
193
     * Set the time registers on the usrp at the next pps tick.
194
     * The values will not be latched in until the pulse occurs.
195
     * It is recommended that the user sleep(1) after calling to ensure
196
     * that the time registers will be in a known state prior to use.
197
     *
198
     * Note: Because this call sets the time on the "next" pps,
199
     * the seconds in the time spec should be current seconds + 1.
200
     *
201
     * \param time_spec the time to latch into the usrp device
202
     */
203
    virtual void set_time_next_pps(const time_spec_t &time_spec) = 0;
204

    
205
    /*!
206
     * Synchronize the times across all motherboards in this configuration.
207
     * Use this method to sync the times when the edge of the PPS is unknown.
208
     *
209
     * Ex: Host machine is not attached to serial port of GPSDO
210
     * and can therefore not query the GPSDO for the PPS edge.
211
     *
212
     * This is a 2-step process, and will take at most 2 seconds to complete.
213
     * Upon completion, the times will be synchronized to the time provided.
214
     *
215
     * - Step1: wait for the last pps time to transition to catch the edge
216
     * - Step2: set the time at the next pps (synchronous for all boards)
217
     *
218
     * \param time_spec the time to latch at the next pps after catching the edge
219
     */
220
    virtual void set_time_unknown_pps(const time_spec_t &time_spec) = 0;
221

    
222
    /*!
223
     * Are the times across all motherboards in this configuration synchronized?
224
     * Checks that all time registers are approximately close but not exact,
225
     * given that the RTT may varying for a control packet transaction.
226
     * \return true when all motherboards time registers are in sync
227
     */
228
    virtual bool get_time_synchronized(void) = 0;
229

    
230
    /*!
231
     * Issue a stream command to the usrp device.
232
     * This tells the usrp to send samples into the host.
233
     * See the documentation for stream_cmd_t for more info.
234
     *
235
     * With multiple devices, the first stream command in a chain of commands
236
     * should have a time spec in the near future and stream_now = false;
237
     * to ensure that the packets can be aligned by their time specs.
238
     *
239
     * \param stream_cmd the stream command to issue
240
     * \param chan the channel index 0 to N-1
241
     */
242
    virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan = ALL_CHANS) = 0;
243

    
244
    /*!
245
     * Set the clock configuration for the usrp device.
246
     * DEPRECATED in favor of set time and clock source calls.
247
     * This tells the usrp how to get a 10Mhz reference and PPS clock.
248
     * See the documentation for clock_config_t for more info.
249
     * \param clock_config the clock configuration to set
250
     * \param mboard which motherboard to set the config
251
     */
252
    virtual void set_clock_config(const clock_config_t &clock_config, size_t mboard = ALL_MBOARDS) = 0;
253

    
254
    /*!
255
     * Set the time source for the usrp device.
256
     * This sets the method of time synchronization,
257
     * typically a pulse per second or an encoded time.
258
     * Typical options for source: external, MIMO.
259
     * \param source a string representing the time source
260
     * \param mboard which motherboard to set the config
261
     */
262
    virtual void set_time_source(const std::string &source, const size_t mboard = ALL_MBOARDS) = 0;
263

    
264
    /*!
265
     * Get the currently set time source.
266
     * \param mboard which motherboard to get the config
267
     * \return the string representing the time source
268
     */
269
    virtual std::string get_time_source(const size_t mboard) = 0;
270

    
271
    /*!
272
     * Get a list of possible time sources.
273
     * \param mboard which motherboard to get the list
274
     * \return a vector of strings for possible settings
275
     */
276
    virtual std::vector<std::string> get_time_sources(const size_t mboard) = 0;
277

    
278
    /*!
279
     * Set the clock source for the usrp device.
280
     * This sets the source for a 10 Mhz reference clock.
281
     * Typical options for source: internal, external, MIMO.
282
     * \param source a string representing the clock source
283
     * \param mboard which motherboard to set the config
284
     */
285
    virtual void set_clock_source(const std::string &source, const size_t mboard = ALL_MBOARDS) = 0;
286

    
287
    /*!
288
     * Get the currently set clock source.
289
     * \param mboard which motherboard to get the config
290
     * \return the string representing the clock source
291
     */
292
    virtual std::string get_clock_source(const size_t mboard) = 0;
293

    
294
    /*!
295
     * Get a list of possible clock sources.
296
     * \param mboard which motherboard to get the list
297
     * \return a vector of strings for possible settings
298
     */
299
    virtual std::vector<std::string> get_clock_sources(const size_t mboard) = 0;
300

    
301
    /*!
302
     * Get the number of USRP motherboards in this configuration.
303
     */
304
    virtual size_t get_num_mboards(void) = 0;
305

    
306
    /*!
307
     * Get a motherboard sensor value.
308
     * \param name the name of the sensor
309
     * \param mboard the motherboard index 0 to M-1
310
     * \return a sensor value object
311
     */
312
    virtual sensor_value_t get_mboard_sensor(const std::string &name, size_t mboard = 0) = 0;
313

    
314
    /*!
315
     * Get a list of possible motherboard sensor names.
316
     * \param mboard the motherboard index 0 to M-1
317
     * \return a vector of sensor names
318
     */
319
    virtual std::vector<std::string> get_mboard_sensor_names(size_t mboard = 0) = 0;
320
    
321
    /*!
322
     * Get a handle to the mboard_iface object which controls peripheral access.
323
     * \return a mboard_iface::sptr object
324
     */
325
    virtual mboard_iface::sptr get_mboard_iface(size_t mboard) = 0;
326

    
327
    /*******************************************************************
328
     * RX methods
329
     ******************************************************************/
330
    /*!
331
     * Set the RX subdevice specification:
332
     * The subdev spec maps a physical part of a daughter-board to a channel number.
333
     * Set the subdev spec before calling into any methods with a channel number.
334
     * The subdev spec must be the same size across all motherboards.
335
     * \param spec the new subdevice specification
336
     * \param mboard the motherboard index 0 to M-1
337
     */
338
    virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0;
339

    
340
    /*!
341
     * Get the RX subdevice specification.
342
     * \param mboard the motherboard index 0 to M-1
343
     * \return the subdevice specification in use
344
     */
345
    virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(size_t mboard = 0) = 0;
346

    
347
    /*!
348
     * Get the number of RX channels in this configuration.
349
     * This is the number of USRPs times the number of RX channels per board,
350
     * where the number of RX channels per board is homogeneous among all USRPs.
351
     */
352
    virtual size_t get_rx_num_channels(void) = 0;
353

    
354
    /*!
355
     * Get the name of the RX subdevice.
356
     * \param chan the channel index 0 to N-1
357
     * \return the subdevice name
358
     */
359
    virtual std::string get_rx_subdev_name(size_t chan = 0) = 0;
360

    
361
    /*!
362
     * Set the RX sample rate.
363
     * \param rate the rate in Sps
364
     * \param chan the channel index 0 to N-1
365
     */
366
    virtual void set_rx_rate(double rate, size_t chan = ALL_CHANS) = 0;
367

    
368
    /*!
369
     * Gets the RX sample rate.
370
     * \param chan the channel index 0 to N-1
371
     * \return the rate in Sps
372
     */
373
    virtual double get_rx_rate(size_t chan = 0) = 0;
374

    
375
    /*!
376
     * Get a range of possible RX rates.
377
     * \param chan the channel index 0 to N-1
378
     * \return the meta range of rates
379
     */
380
    virtual meta_range_t get_rx_rates(size_t chan = 0) = 0;
381

    
382
    /*!
383
     * Set the RX center frequency.
384
     * \param tune_request tune request instructions
385
     * \param chan the channel index 0 to N-1
386
     * \return a tune result object
387
     */
388
    virtual tune_result_t set_rx_freq(
389
        const tune_request_t &tune_request, size_t chan = 0
390
    ) = 0;
391

    
392
    /*!
393
     * Get the RX center frequency.
394
     * \param chan the channel index 0 to N-1
395
     * \return the frequency in Hz
396
     */
397
    virtual double get_rx_freq(size_t chan = 0) = 0;
398

    
399
    /*!
400
     * Get the RX center frequency range.
401
     * \param chan the channel index 0 to N-1
402
     * \return a frequency range object
403
     */
404
    virtual freq_range_t get_rx_freq_range(size_t chan = 0) = 0;
405

    
406
    /*!
407
     * Set the RX gain value for the specified gain element.
408
     * For an empty name, distribute across all gain elements.
409
     * \param gain the gain in dB
410
     * \param name the name of the gain element
411
     * \param chan the channel index 0 to N-1
412
     */
413
    virtual void set_rx_gain(double gain, const std::string &name, size_t chan = 0) = 0;
414

    
415
    //! A convenience wrapper for setting overall RX gain
416
    void set_rx_gain(double gain, size_t chan = 0){
417
        return this->set_rx_gain(gain, ALL_GAINS, chan);
418
    }
419

    
420
    /*!
421
     * Get the RX gain value for the specified gain element.
422
     * For an empty name, sum across all gain elements.
423
     * \param name the name of the gain element
424
     * \param chan the channel index 0 to N-1
425
     * \return the gain in dB
426
     */
427
    virtual double get_rx_gain(const std::string &name, size_t chan = 0) = 0;
428

    
429
    //! A convenience wrapper for getting overall RX gain
430
    double get_rx_gain(size_t chan = 0){
431
        return this->get_rx_gain(ALL_GAINS, chan);
432
    }
433

    
434
    /*!
435
     * Get the RX gain range for the specified gain element.
436
     * For an empty name, calculate the overall gain range.
437
     * \param name the name of the gain element
438
     * \param chan the channel index 0 to N-1
439
     * \return a gain range object
440
     */
441
    virtual gain_range_t get_rx_gain_range(const std::string &name, size_t chan = 0) = 0;
442

    
443
    //! A convenience wrapper for getting overall RX gain range
444
    gain_range_t get_rx_gain_range(size_t chan = 0){
445
        return this->get_rx_gain_range(ALL_GAINS, chan);
446
    }
447

    
448
    /*!
449
     * Get the names of the gain elements in the RX chain.
450
     * Gain elements are ordered from antenna to FPGA.
451
     * \param chan the channel index 0 to N-1
452
     * \return a vector of gain element names
453
     */
454
    virtual std::vector<std::string> get_rx_gain_names(size_t chan = 0) = 0;
455

    
456
    /*!
457
     * Select the RX antenna on the subdevice.
458
     * \param ant the antenna name
459
     * \param chan the channel index 0 to N-1
460
     */
461
    virtual void set_rx_antenna(const std::string &ant, size_t chan = 0) = 0;
462

    
463
    /*!
464
     * Get the selected RX antenna on the subdevice.
465
     * \param chan the channel index 0 to N-1
466
     * \return the antenna name
467
     */
468
    virtual std::string get_rx_antenna(size_t chan = 0) = 0;
469

    
470
    /*!
471
     * Get a list of possible RX antennas on the subdevice.
472
     * \param chan the channel index 0 to N-1
473
     * \return a vector of antenna names
474
     */
475
    virtual std::vector<std::string> get_rx_antennas(size_t chan = 0) = 0;
476

    
477
    /*!
478
     * Get the locked status of the LO on the subdevice.
479
     * \param chan the channel index 0 to N-1
480
     * \return true for locked
481
     */
482
    UHD_DEPRECATED bool get_rx_lo_locked(size_t chan = 0){
483
        return this->get_rx_sensor("lo_locked", chan).to_bool();
484
    }
485

    
486
    /*!
487
     * Set the RX bandwidth on the subdevice.
488
     * \param bandwidth the bandwidth in Hz
489
     * \param chan the channel index 0 to N-1
490
     */
491
    virtual void set_rx_bandwidth(double bandwidth, size_t chan = 0) = 0;
492

    
493
    /*!
494
     * Get the RX bandwidth on the subdevice.
495
     * \param chan the channel index 0 to N-1
496
     * \return the bandwidth in Hz
497
     */
498
    virtual double get_rx_bandwidth(size_t chan = 0) = 0;
499

    
500
    /*!
501
     * Read the RSSI value on the RX subdevice.
502
     * \param chan the channel index 0 to N-1
503
     * \return the rssi in dB
504
     * \throw exception if RSSI readback not supported
505
     */
506
    UHD_DEPRECATED double read_rssi(size_t chan = 0){
507
        return this->get_rx_sensor("rssi", chan).to_real();
508
    }
509

    
510
    /*!
511
     * Get the dboard interface object for the RX subdevice.
512
     * The dboard interface gives access to GPIOs, SPI, I2C, low-speed ADC and DAC.
513
     * Use at your own risk!
514
     * \param chan the channel index 0 to N-1
515
     * \return the dboard interface sptr
516
     */
517
    virtual dboard_iface::sptr get_rx_dboard_iface(size_t chan = 0) = 0;
518

    
519
    /*!
520
     * Get an RX subdevice sensor value.
521
     * \param name the name of the sensor
522
     * \param chan the channel index 0 to N-1
523
     * \return a sensor value object
524
     */
525
    virtual sensor_value_t get_rx_sensor(const std::string &name, size_t chan = 0) = 0;
526

    
527
    /*!
528
     * Get a list of possible RX subdevice sensor names.
529
     * \param chan the channel index 0 to N-1
530
     * \return a vector of sensor names
531
     */
532
    virtual std::vector<std::string> get_rx_sensor_names(size_t chan = 0) = 0;
533

    
534
    /*!
535
     * Enable/disable the automatic RX DC offset correction.
536
     * The automatic correction subtracts out the long-run average.
537
     *
538
     * When disabled, the averaging option operation is halted.
539
     * Once halted, the average value will be held constant
540
     * until the user re-enables the automatic correction
541
     * or overrides the value by manually setting the offset.
542
     *
543
     * \param enb true to enable automatic DC offset correction
544
     * \param chan the channel index 0 to N-1
545
     */
546
    virtual void set_rx_dc_offset(const bool enb, size_t chan = ALL_CHANS) = 0;
547

    
548
    /*!
549
     * Set a constant RX DC offset value.
550
     * The value is complex to control both I and Q.
551
     * Only set this when automatic correction is disabled.
552
     * \param offset the dc offset (1.0 is full-scale)
553
     * \param chan the channel index 0 to N-1
554
     */
555
    virtual void set_rx_dc_offset(const std::complex<double> &offset, size_t chan = ALL_CHANS) = 0;
556

    
557
    /*!
558
     * Set the RX frontend IQ imbalance and gain correction.
559
     * Use this to adjust the magnitude and phase of I and Q.
560
     *
561
     * \param correction the complex correction value
562
     * \param chan the channel index 0 to N-1
563
     */
564
    virtual void set_rx_correction(const std::complex<double> &correction, size_t chan = ALL_CHANS) = 0;
565

    
566
    /*******************************************************************
567
     * TX methods
568
     ******************************************************************/
569
    /*!
570
     * Set the TX subdevice specification:
571
     * The subdev spec maps a physical part of a daughter-board to a channel number.
572
     * Set the subdev spec before calling into any methods with a channel number.
573
     * The subdev spec must be the same size across all motherboards.
574
     * \param spec the new subdevice specification
575
     * \param mboard the motherboard index 0 to M-1
576
     */
577
    virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0;
578

    
579
    /*!
580
     * Get the TX subdevice specification.
581
     * \param mboard the motherboard index 0 to M-1
582
     * \return the subdevice specification in use
583
     */
584
    virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(size_t mboard = 0) = 0;
585

    
586
    /*!
587
     * Get the number of TX channels in this configuration.
588
     * This is the number of USRPs times the number of TX channels per board,
589
     * where the number of TX channels per board is homogeneous among all USRPs.
590
     */
591
    virtual size_t get_tx_num_channels(void) = 0;
592

    
593
    /*!
594
     * Get the name of the TX subdevice.
595
     * \param chan the channel index 0 to N-1
596
     * \return the subdevice name
597
     */
598
    virtual std::string get_tx_subdev_name(size_t chan = 0) = 0;
599

    
600
    /*!
601
     * Set the TX sample rate.
602
     * \param rate the rate in Sps
603
     * \param chan the channel index 0 to N-1
604
     */
605
    virtual void set_tx_rate(double rate, size_t chan = ALL_CHANS) = 0;
606

    
607
    /*!
608
     * Gets the TX sample rate.
609
     * \param chan the channel index 0 to N-1
610
     * \return the rate in Sps
611
     */
612
    virtual double get_tx_rate(size_t chan = 0) = 0;
613

    
614
    /*!
615
     * Get a range of possible TX rates.
616
     * \param chan the channel index 0 to N-1
617
     * \return the meta range of rates
618
     */
619
    virtual meta_range_t get_tx_rates(size_t chan = 0) = 0;
620

    
621
    /*!
622
     * Set the TX center frequency.
623
     * \param tune_request tune request instructions
624
     * \param chan the channel index 0 to N-1
625
     * \return a tune result object
626
     */
627
    virtual tune_result_t set_tx_freq(
628
        const tune_request_t &tune_request, size_t chan = 0
629
    ) = 0;
630

    
631
    /*!
632
     * Get the TX center frequency.
633
     * \param chan the channel index 0 to N-1
634
     * \return the frequency in Hz
635
     */
636
    virtual double get_tx_freq(size_t chan = 0) = 0;
637

    
638
    /*!
639
     * Get the TX center frequency range.
640
     * \param chan the channel index 0 to N-1
641
     * \return a frequency range object
642
     */
643
    virtual freq_range_t get_tx_freq_range(size_t chan = 0) = 0;
644

    
645
    /*!
646
     * Set the TX gain value for the specified gain element.
647
     * For an empty name, distribute across all gain elements.
648
     * \param gain the gain in dB
649
     * \param name the name of the gain element
650
     * \param chan the channel index 0 to N-1
651
     */
652
    virtual void set_tx_gain(double gain, const std::string &name, size_t chan = 0) = 0;
653

    
654
    //! A convenience wrapper for setting overall TX gain
655
    void set_tx_gain(double gain, size_t chan = 0){
656
        return this->set_tx_gain(gain, ALL_GAINS, chan);
657
    }
658

    
659
    /*!
660
     * Get the TX gain value for the specified gain element.
661
     * For an empty name, sum across all gain elements.
662
     * \param name the name of the gain element
663
     * \param chan the channel index 0 to N-1
664
     * \return the gain in dB
665
     */
666
    virtual double get_tx_gain(const std::string &name, size_t chan = 0) = 0;
667

    
668
    //! A convenience wrapper for getting overall TX gain
669
    double get_tx_gain(size_t chan = 0){
670
        return this->get_tx_gain(ALL_GAINS, chan);
671
    }
672

    
673
    /*!
674
     * Get the TX gain range for the specified gain element.
675
     * For an empty name, calculate the overall gain range.
676
     * \param name the name of the gain element
677
     * \param chan the channel index 0 to N-1
678
     * \return a gain range object
679
     */
680
    virtual gain_range_t get_tx_gain_range(const std::string &name, size_t chan = 0) = 0;
681

    
682
    //! A convenience wrapper for getting overall TX gain range
683
    gain_range_t get_tx_gain_range(size_t chan = 0){
684
        return this->get_tx_gain_range(ALL_GAINS, chan);
685
    }
686

    
687
    /*!
688
     * Get the names of the gain elements in the TX chain.
689
     * Gain elements are ordered from antenna to FPGA.
690
     * \param chan the channel index 0 to N-1
691
     * \return a vector of gain element names
692
     */
693
    virtual std::vector<std::string> get_tx_gain_names(size_t chan = 0) = 0;
694

    
695
    /*!
696
     * Select the TX antenna on the subdevice.
697
     * \param ant the antenna name
698
     * \param chan the channel index 0 to N-1
699
     */
700
    virtual void set_tx_antenna(const std::string &ant, size_t chan = 0) = 0;
701

    
702
    /*!
703
     * Get the selected TX antenna on the subdevice.
704
     * \param chan the channel index 0 to N-1
705
     * \return the antenna name
706
     */
707
    virtual std::string get_tx_antenna(size_t chan = 0) = 0;
708

    
709
    /*!
710
     * Get a list of possible TX antennas on the subdevice.
711
     * \param chan the channel index 0 to N-1
712
     * \return a vector of antenna names
713
     */
714
    virtual std::vector<std::string> get_tx_antennas(size_t chan = 0) = 0;
715

    
716
    /*!
717
     * Get the locked status of the LO on the subdevice.
718
     * \param chan the channel index 0 to N-1
719
     * \return true for locked
720
     */
721
    UHD_DEPRECATED bool get_tx_lo_locked(size_t chan = 0){
722
        return this->get_tx_sensor("lo_locked", chan).to_bool();
723
    }
724

    
725
    /*!
726
     * Set the TX bandwidth on the subdevice.
727
     * \param bandwidth the bandwidth in Hz
728
     * \param chan the channel index 0 to N-1
729
     */
730
    virtual void set_tx_bandwidth(double bandwidth, size_t chan = 0) = 0;
731

    
732
    /*!
733
     * Get the TX bandwidth on the subdevice.
734
     * \param chan the channel index 0 to N-1
735
     * \return the bandwidth in Hz
736
     */
737
    virtual double get_tx_bandwidth(size_t chan = 0) = 0;
738

    
739
    /*!
740
     * Get the dboard interface object for the TX subdevice.
741
     * The dboard interface gives access to GPIOs, SPI, I2C, low-speed ADC and DAC.
742
     * Use at your own risk!
743
     * \param chan the channel index 0 to N-1
744
     * \return the dboard interface sptr
745
     */
746
    virtual dboard_iface::sptr get_tx_dboard_iface(size_t chan = 0) = 0;
747

    
748
    /*!
749
     * Get an TX subdevice sensor value.
750
     * \param name the name of the sensor
751
     * \param chan the channel index 0 to N-1
752
     * \return a sensor value object
753
     */
754
    virtual sensor_value_t get_tx_sensor(const std::string &name, size_t chan = 0) = 0;
755

    
756
    /*!
757
     * Get a list of possible TX subdevice sensor names.
758
     * \param chan the channel index 0 to N-1
759
     * \return a vector of sensor names
760
     */
761
    virtual std::vector<std::string> get_tx_sensor_names(size_t chan = 0) = 0;
762

    
763
    /*!
764
     * Set a constant TX DC offset value.
765
     * The value is complex to control both I and Q.
766
     * \param offset the dc offset (1.0 is full-scale)
767
     * \param chan the channel index 0 to N-1
768
     */
769
    virtual void set_tx_dc_offset(const std::complex<double> &offset, size_t chan = ALL_CHANS) = 0;
770

    
771
    /*!
772
     * Set the TX frontend IQ imbalance and gain correction.
773
     * Use this to adjust the magnitude and phase of I and Q.
774
     *
775
     * \param correction the complex correction value
776
     * \param chan the channel index 0 to N-1
777
     */
778
    virtual void set_tx_correction(const std::complex<double> &correction, size_t chan = ALL_CHANS) = 0;
779

    
780
};
781

    
782
}}
783

    
784
#endif /* INCLUDED_UHD_USRP_MULTI_USRP_HPP */