blob: 349efbb85531e7fef9e4b9e8660b7a03ae8479f1 [file] [log] [blame]
Harald Welte4a5484c2018-03-07 07:50:57 +01001/*
2* Copyright 2018 sysmocom - s.f.m.c. GmbH
3*
4* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
5*
6* This use of this software may be subject to additional restrictions.
7* See the LEGAL file in the main directory for details.
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.
12
13*/
14
15#ifndef _LMS_DEVICE_H_
16#define _LMS_DEVICE_H_
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include "radioDevice.h"
23
Harald Welte4a5484c2018-03-07 07:50:57 +010024#include <sys/time.h>
25#include <math.h>
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020026#include <limits.h>
Harald Welte4a5484c2018-03-07 07:50:57 +010027#include <string>
28#include <iostream>
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020029#include <lime/LimeSuite.h>
30
31#define LIMESDR_TX_AMPL 0.3
Harald Welte4a5484c2018-03-07 07:50:57 +010032
33/** A class to handle a LimeSuite supported device */
34class LMSDevice:public RadioDevice {
35
36private:
37
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020038 static constexpr double masterClockRate = 52.0e6;
Harald Welte4a5484c2018-03-07 07:50:57 +010039
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020040 lms_device_t *m_lms_dev;
41 std::vector<lms_stream_t> m_lms_stream_rx;
42 std::vector<lms_stream_t> m_lms_stream_tx;
43
44 std::vector<uint32_t> m_last_rx_underruns;
45 std::vector<uint32_t> m_last_rx_overruns;
46 std::vector<uint32_t> m_last_tx_underruns;
47 std::vector<uint32_t> m_last_tx_overruns;
48
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020049 double actualSampleRate; ///< the actual USRP sampling rate
Harald Welte4a5484c2018-03-07 07:50:57 +010050
51 unsigned long long samplesRead; ///< number of samples read from LMS
52 unsigned long long samplesWritten; ///< number of samples sent to LMS
53
54 bool started; ///< flag indicates LMS has started
55 bool skipRx; ///< set if LMS is transmit-only.
56
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020057 TIMESTAMP ts_initial, ts_offset;
58
59 double rxGain;
60
61 int get_ant_idx(const std::string & name, bool dir_tx, size_t chan);
62 bool flush_recv(size_t num_pkts);
Harald Welte4a5484c2018-03-07 07:50:57 +010063
64public:
65
66 /** Object constructor */
Harald Welte9939ccd2018-06-13 23:21:57 +020067 LMSDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t chans, double lo_offset,
Harald Welte66efb7c2018-06-13 21:55:09 +020068 const std::vector<std::string>& tx_paths,
69 const std::vector<std::string>& rx_paths);
Harald Welte4a5484c2018-03-07 07:50:57 +010070
71 /** Instantiate the LMS */
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020072 int open(const std::string &args, int ref, bool swap_channels);
Harald Welte4a5484c2018-03-07 07:50:57 +010073
74 /** Start the LMS */
75 bool start();
76
77 /** Stop the LMS */
78 bool stop();
79
80 /** Set priority not supported */
81 void setPriority(float prio = 0.5) {
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +020082 }
83
84 enum TxWindowType getWindowType() {
Harald Welte4a5484c2018-03-07 07:50:57 +010085 return TX_WINDOW_LMS1;
86 }
87
88 /**
89 Read samples from the LMS.
90 @param buf preallocated buf to contain read result
91 @param len number of samples desired
92 @param overrun Set if read buffer has been overrun, e.g. data not being read fast enough
93 @param timestamp The timestamp of the first samples to be read
94 @param underrun Set if LMS does not have data to transmit, e.g. data not being sent fast enough
95 @param RSSI The received signal strength of the read result
96 @return The number of samples actually read
97 */
98 int readSamples(std::vector < short *>&buf, int len, bool * overrun,
99 TIMESTAMP timestamp = 0xffffffff, bool * underrun =
100 NULL, unsigned *RSSI = NULL);
101 /**
102 Write samples to the LMS.
103 @param buf Contains the data to be written.
104 @param len number of samples to write.
105 @param underrun Set if LMS does not have data to transmit, e.g. data not being sent fast enough
106 @param timestamp The timestamp of the first sample of the data buffer.
107 @param isControl Set if data is a control packet, e.g. a ping command
108 @return The number of samples actually written
109 */
110 int writeSamples(std::vector < short *>&bufs, int len, bool * underrun,
111 TIMESTAMP timestamp = 0xffffffff, bool isControl =
112 false);
113
114 /** Update the alignment between the read and write timestamps */
115 bool updateAlignment(TIMESTAMP timestamp);
116
117 /** Set the transmitter frequency */
118 bool setTxFreq(double wFreq, size_t chan = 0);
119
120 /** Set the receiver frequency */
121 bool setRxFreq(double wFreq, size_t chan = 0);
122
123 /** Returns the starting write Timestamp*/
124 TIMESTAMP initialWriteTimestamp(void) {
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +0200125 return ts_initial;
Harald Welte4a5484c2018-03-07 07:50:57 +0100126 }
127
128 /** Returns the starting read Timestamp*/
129 TIMESTAMP initialReadTimestamp(void) {
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +0200130 return ts_initial;
Harald Welte4a5484c2018-03-07 07:50:57 +0100131 }
132
133 /** returns the full-scale transmit amplitude **/
134 double fullScaleInputValue() {
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +0200135 return(double) SHRT_MAX * LIMESDR_TX_AMPL;
Harald Welte4a5484c2018-03-07 07:50:57 +0100136 }
137
138 /** returns the full-scale receive amplitude **/
139 double fullScaleOutputValue() {
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +0200140 return (double) SHRT_MAX;
Harald Welte4a5484c2018-03-07 07:50:57 +0100141 }
142
143 /** sets the receive chan gain, returns the gain setting **/
144 double setRxGain(double dB, size_t chan = 0);
145
146 /** get the current receive gain */
147 double getRxGain(size_t chan = 0) {
148 return rxGain;
149 }
150
151 /** return maximum Rx Gain **/
152 double maxRxGain(void);
153
154 /** return minimum Rx Gain **/
155 double minRxGain(void);
156
157 /** sets the transmit chan gain, returns the gain setting **/
158 double setTxGain(double dB, size_t chan = 0);
159
160 /** return maximum Tx Gain **/
161 double maxTxGain(void);
162
163 /** return minimum Rx Gain **/
164 double minTxGain(void);
165
166 /** sets the RX path to use, returns true if successful and false otherwise */
167 bool setRxAntenna(const std::string & ant, size_t chan = 0);
168
169 /* return the used RX path */
170 std::string getRxAntenna(size_t chan = 0);
171
172 /** sets the RX path to use, returns true if successful and false otherwise */
173 bool setTxAntenna(const std::string & ant, size_t chan = 0);
174
175 /* return the used RX path */
176 std::string getTxAntenna(size_t chan = 0);
177
Pau Espin Pedrolcdbe1e72018-04-25 12:17:10 +0200178 /** return whether user drives synchronization of Tx/Rx of USRP */
179 bool requiresRadioAlign();
180
181 /** return whether user drives synchronization of Tx/Rx of USRP */
182 virtual GSM::Time minLatency();
183
Harald Welte4a5484c2018-03-07 07:50:57 +0100184 /** Return internal status values */
185 inline double getTxFreq(size_t chan = 0) {
186 return 0;
187 }
188 inline double getRxFreq(size_t chan = 0) {
189 return 0;
190 }
191 inline double getSampleRate() {
192 return actualSampleRate;
193 }
194 inline double numberRead() {
195 return samplesRead;
196 }
197 inline double numberWritten() {
198 return samplesWritten;
199 }
Harald Welte4a5484c2018-03-07 07:50:57 +0100200};
201
202#endif // _LMS_DEVICE_H_