blob: 99eed432286543e555197e012e2aa1eb4fc5ec11 [file] [log] [blame]
Harald Welte940738e2018-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 Welte940738e2018-03-07 07:50:57 +010024#include <sys/time.h>
25#include <math.h>
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +020026#include <limits.h>
Harald Welte940738e2018-03-07 07:50:57 +010027#include <string>
28#include <iostream>
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +020029#include <lime/LimeSuite.h>
30
31#define LIMESDR_TX_AMPL 0.3
Harald Welte940738e2018-03-07 07:50:57 +010032
33/** A class to handle a LimeSuite supported device */
34class LMSDevice:public RadioDevice {
35
36private:
37
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +020038 static constexpr double masterClockRate = 52.0e6;
Harald Welte940738e2018-03-07 07:50:57 +010039
Pau Espin Pedrolc7a0bf12018-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
49 size_t sps, chans;
50 double actualSampleRate; ///< the actual USRP sampling rate
Harald Welte940738e2018-03-07 07:50:57 +010051
52 unsigned long long samplesRead; ///< number of samples read from LMS
53 unsigned long long samplesWritten; ///< number of samples sent to LMS
54
55 bool started; ///< flag indicates LMS has started
56 bool skipRx; ///< set if LMS is transmit-only.
57
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +020058 TIMESTAMP ts_initial, ts_offset;
59
60 double rxGain;
61
62 int get_ant_idx(const std::string & name, bool dir_tx, size_t chan);
63 bool flush_recv(size_t num_pkts);
Harald Welte940738e2018-03-07 07:50:57 +010064
65public:
66
67 /** Object constructor */
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +020068 LMSDevice(size_t sps, size_t chans);
Harald Welte940738e2018-03-07 07:50:57 +010069
70 /** Instantiate the LMS */
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +020071 int open(const std::string &args, int ref, bool swap_channels);
Harald Welte940738e2018-03-07 07:50:57 +010072
73 /** Start the LMS */
74 bool start();
75
76 /** Stop the LMS */
77 bool stop();
78
79 /** Set priority not supported */
80 void setPriority(float prio = 0.5) {
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +020081 }
82
83 enum TxWindowType getWindowType() {
Harald Welte940738e2018-03-07 07:50:57 +010084 return TX_WINDOW_LMS1;
85 }
86
87 /**
88 Read samples from the LMS.
89 @param buf preallocated buf to contain read result
90 @param len number of samples desired
91 @param overrun Set if read buffer has been overrun, e.g. data not being read fast enough
92 @param timestamp The timestamp of the first samples to be read
93 @param underrun Set if LMS does not have data to transmit, e.g. data not being sent fast enough
94 @param RSSI The received signal strength of the read result
95 @return The number of samples actually read
96 */
97 int readSamples(std::vector < short *>&buf, int len, bool * overrun,
98 TIMESTAMP timestamp = 0xffffffff, bool * underrun =
99 NULL, unsigned *RSSI = NULL);
100 /**
101 Write samples to the LMS.
102 @param buf Contains the data to be written.
103 @param len number of samples to write.
104 @param underrun Set if LMS does not have data to transmit, e.g. data not being sent fast enough
105 @param timestamp The timestamp of the first sample of the data buffer.
106 @param isControl Set if data is a control packet, e.g. a ping command
107 @return The number of samples actually written
108 */
109 int writeSamples(std::vector < short *>&bufs, int len, bool * underrun,
110 TIMESTAMP timestamp = 0xffffffff, bool isControl =
111 false);
112
113 /** Update the alignment between the read and write timestamps */
114 bool updateAlignment(TIMESTAMP timestamp);
115
116 /** Set the transmitter frequency */
117 bool setTxFreq(double wFreq, size_t chan = 0);
118
119 /** Set the receiver frequency */
120 bool setRxFreq(double wFreq, size_t chan = 0);
121
122 /** Returns the starting write Timestamp*/
123 TIMESTAMP initialWriteTimestamp(void) {
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +0200124 return ts_initial;
Harald Welte940738e2018-03-07 07:50:57 +0100125 }
126
127 /** Returns the starting read Timestamp*/
128 TIMESTAMP initialReadTimestamp(void) {
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +0200129 return ts_initial;
Harald Welte940738e2018-03-07 07:50:57 +0100130 }
131
132 /** returns the full-scale transmit amplitude **/
133 double fullScaleInputValue() {
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +0200134 return(double) SHRT_MAX * LIMESDR_TX_AMPL;
Harald Welte940738e2018-03-07 07:50:57 +0100135 }
136
137 /** returns the full-scale receive amplitude **/
138 double fullScaleOutputValue() {
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +0200139 return (double) SHRT_MAX;
Harald Welte940738e2018-03-07 07:50:57 +0100140 }
141
142 /** sets the receive chan gain, returns the gain setting **/
143 double setRxGain(double dB, size_t chan = 0);
144
145 /** get the current receive gain */
146 double getRxGain(size_t chan = 0) {
147 return rxGain;
148 }
149
150 /** return maximum Rx Gain **/
151 double maxRxGain(void);
152
153 /** return minimum Rx Gain **/
154 double minRxGain(void);
155
156 /** sets the transmit chan gain, returns the gain setting **/
157 double setTxGain(double dB, size_t chan = 0);
158
159 /** return maximum Tx Gain **/
160 double maxTxGain(void);
161
162 /** return minimum Rx Gain **/
163 double minTxGain(void);
164
165 /** sets the RX path to use, returns true if successful and false otherwise */
166 bool setRxAntenna(const std::string & ant, size_t chan = 0);
167
168 /* return the used RX path */
169 std::string getRxAntenna(size_t chan = 0);
170
171 /** sets the RX path to use, returns true if successful and false otherwise */
172 bool setTxAntenna(const std::string & ant, size_t chan = 0);
173
174 /* return the used RX path */
175 std::string getTxAntenna(size_t chan = 0);
176
Pau Espin Pedrolc7a0bf12018-04-25 12:17:10 +0200177 /** return whether user drives synchronization of Tx/Rx of USRP */
178 bool requiresRadioAlign();
179
180 /** return whether user drives synchronization of Tx/Rx of USRP */
181 virtual GSM::Time minLatency();
182
Harald Welte940738e2018-03-07 07:50:57 +0100183 /** Return internal status values */
184 inline double getTxFreq(size_t chan = 0) {
185 return 0;
186 }
187 inline double getRxFreq(size_t chan = 0) {
188 return 0;
189 }
190 inline double getSampleRate() {
191 return actualSampleRate;
192 }
193 inline double numberRead() {
194 return samplesRead;
195 }
196 inline double numberWritten() {
197 return samplesWritten;
198 }
199
200 std::vector < std::string > tx_paths, rx_paths;
201};
202
203#endif // _LMS_DEVICE_H_