blob: 0b57ba48575550e4292cbf09f779e47b9349957a [file] [log] [blame]
Pau Espin Pedrol7bef2342019-04-29 17:23:21 +02001/*
2 * Device support for Ettus Research UHD driver
3 *
4 * Copyright 2010,2011 Free Software Foundation, Inc.
5 * Copyright (C) 2015 Ettus Research LLC
6 * Copyright 2019 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
7 *
8 * Author: Tom Tsou <tom.tsou@ettus.com>
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
19 *
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * See the COPYING file in the main directory for details.
23 */
24
25#pragma once
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include "radioDevice.h"
32#include "smpl_buf.h"
33
34#include <uhd/version.hpp>
35#include <uhd/property_tree.hpp>
36#include <uhd/usrp/multi_usrp.hpp>
37
38
39enum uhd_dev_type {
40 USRP1,
41 USRP2,
42 B100,
43 B200,
44 B210,
45 B2XX_MCBTS,
46 E1XX,
47 E3XX,
48 X3XX,
49 UMTRX,
50 LIMESDR,
51};
52
53/*
54 uhd_device - UHD implementation of the Device interface. Timestamped samples
55 are sent to and received from the device. An intermediate buffer
56 on the receive side collects and aligns packets of samples.
57 Events and errors such as underruns are reported asynchronously
58 by the device and received in a separate thread.
59*/
60class uhd_device : public RadioDevice {
61public:
62 uhd_device(size_t tx_sps, size_t rx_sps, InterfaceType type,
63 size_t chans, double offset,
64 const std::vector<std::string>& tx_paths,
65 const std::vector<std::string>& rx_paths);
66 ~uhd_device();
67
68 int open(const std::string &args, int ref, bool swap_channels);
69 bool start();
70 bool stop();
71 bool restart();
72 void setPriority(float prio);
73 enum TxWindowType getWindowType() { return tx_window; }
74
75 int readSamples(std::vector<short *> &bufs, int len, bool *overrun,
76 TIMESTAMP timestamp, bool *underrun, unsigned *RSSI);
77
78 int writeSamples(std::vector<short *> &bufs, int len, bool *underrun,
79 TIMESTAMP timestamp, bool isControl);
80
81 bool updateAlignment(TIMESTAMP timestamp);
82
83 bool setTxFreq(double wFreq, size_t chan);
84 bool setRxFreq(double wFreq, size_t chan);
85
86 TIMESTAMP initialWriteTimestamp();
87 TIMESTAMP initialReadTimestamp();
88
89 double fullScaleInputValue();
90 double fullScaleOutputValue();
91
92 double setRxGain(double db, size_t chan);
93 double getRxGain(size_t chan);
94 double maxRxGain(void) { return rx_gain_max; }
95 double minRxGain(void) { return rx_gain_min; }
96
97 double setTxGain(double db, size_t chan);
98 double maxTxGain(void) { return tx_gain_max; }
99 double minTxGain(void) { return tx_gain_min; }
100
101 double getTxFreq(size_t chan);
102 double getRxFreq(size_t chan);
103 double getRxFreq();
104
105 bool setRxAntenna(const std::string &ant, size_t chan);
106 std::string getRxAntenna(size_t chan);
107 bool setTxAntenna(const std::string &ant, size_t chan);
108 std::string getTxAntenna(size_t chan);
109
110 bool requiresRadioAlign();
111
112 GSM::Time minLatency();
113
114 inline double getSampleRate() { return tx_rate; }
Pau Espin Pedrol7bef2342019-04-29 17:23:21 +0200115
116 /** Receive and process asynchronous message
117 @return true if message received or false on timeout or error
118 */
119 bool recv_async_msg();
120
121 enum err_code {
122 ERROR_TIMING = -1,
123 ERROR_TIMEOUT = -2,
124 ERROR_UNRECOVERABLE = -3,
125 ERROR_UNHANDLED = -4,
126 };
127
128private:
129 uhd::usrp::multi_usrp::sptr usrp_dev;
130 uhd::tx_streamer::sptr tx_stream;
131 uhd::rx_streamer::sptr rx_stream;
132 enum TxWindowType tx_window;
133 enum uhd_dev_type dev_type;
134
135 double tx_rate, rx_rate;
136
137 double tx_gain_min, tx_gain_max;
138 double rx_gain_min, rx_gain_max;
139
140 std::vector<double> tx_gains, rx_gains;
141 std::vector<double> tx_freqs, rx_freqs;
142 size_t tx_spp, rx_spp;
143
144 bool started;
145 bool aligned;
146
Pau Espin Pedrol7bef2342019-04-29 17:23:21 +0200147 size_t drop_cnt;
148 uhd::time_spec_t prev_ts;
149
150 TIMESTAMP ts_initial, ts_offset;
151 std::vector<smpl_buf *> rx_buffers;
Pau Espin Pedrolef192d32019-04-30 18:51:00 +0200152 /* Sample buffers used to receive samples from UHD: */
153 std::vector<std::vector<short> > pkt_bufs;
154 /* Used to call UHD API: Buffer pointer of each elem in pkt_ptrs will
155 point to corresponding buffer of vector pkt_bufs. */
156 std::vector<short *> pkt_ptrs;
Pau Espin Pedrol7bef2342019-04-29 17:23:21 +0200157
158 void init_gains();
159 void set_channels(bool swap);
160 void set_rates();
161 bool parse_dev_type();
162 bool flush_recv(size_t num_pkts);
163 int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls);
164
165 std::string str_code(uhd::rx_metadata_t metadata);
166 std::string str_code(uhd::async_metadata_t metadata);
167
168 uhd::tune_request_t select_freq(double wFreq, size_t chan, bool tx);
169 bool set_freq(double freq, size_t chan, bool tx);
170
171 Thread *async_event_thrd;
172 Mutex tune_lock;
173};