1
|
/*
|
2
|
* Copyright 2014 Free Software Foundation, Inc.
|
3
|
*
|
4
|
* This software is distributed under multiple licenses; see the COPYING file in
|
5
|
* the main directory for licensing information for this specific distribuion.
|
6
|
*
|
7
|
* This use of this software may be subject to additional restrictions.
|
8
|
* See the LEGAL file in the main directory for details.
|
9
|
*
|
10
|
* This program is distributed in the hope that it will be useful,
|
11
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
13
|
*
|
14
|
**/
|
15
|
|
16
|
#ifndef _BLADERF_DEVICE_H_
|
17
|
#define _BLADERF_DEVICE_H_
|
18
|
|
19
|
#include <libbladeRF.h>
|
20
|
|
21
|
#ifdef HAVE_CONFIG_H
|
22
|
#include "config.h"
|
23
|
#endif
|
24
|
|
25
|
#include "radioDevice.h"
|
26
|
#include <sys/time.h>
|
27
|
#include <math.h>
|
28
|
#include <string>
|
29
|
#include <iostream>
|
30
|
#include "bytesex.h"
|
31
|
|
32
|
// Timestamped data includes a header that overlaps the start of buffer
|
33
|
// The header takes 16 octets = 4 samples of (real part: 2 octets, imaginary: 2 octets)
|
34
|
// Timestamp is in half sample components; a full buffer increments it by 1016
|
35
|
#define PKT_SAMPLES_SUPER_RAW 512
|
36
|
#define PKT_SAMPLES_SUPER_USE (PKT_SAMPLES_SUPER_RAW - 4)
|
37
|
#define PKT_SAMPLES_HIGH_RAW 256
|
38
|
#define PKT_SAMPLES_HIGH_USE (PKT_SAMPLES_HIGH_RAW - 4)
|
39
|
#define PKT_BUFFERS 4
|
40
|
|
41
|
struct bladerf_timestamp {
|
42
|
uint32_t rsvd;
|
43
|
uint32_t time_lo;
|
44
|
uint32_t time_hi;
|
45
|
uint32_t flags;
|
46
|
};
|
47
|
|
48
|
struct bladerf_highspeed_timestamp {
|
49
|
struct bladerf_timestamp header;
|
50
|
int16_t samples[PKT_SAMPLES_HIGH_USE * 2];
|
51
|
};
|
52
|
|
53
|
struct bladerf_superspeed_timestamp {
|
54
|
struct bladerf_timestamp header;
|
55
|
int16_t samples[PKT_SAMPLES_SUPER_USE * 2];
|
56
|
};
|
57
|
|
58
|
/** A class to handle a bladeRF device */
|
59
|
class bladeRFDevice: public RadioDevice {
|
60
|
|
61
|
private:
|
62
|
double desiredSampleRate; ///< the desired sampling rate
|
63
|
double actualSampleRate; ///< the actual bladeRF sampling rate
|
64
|
unsigned int decimRate; ///< the bladeRF decimation rate
|
65
|
|
66
|
int sps_rx; // RX oversampling
|
67
|
int sps_tx; // TX oversampling
|
68
|
|
69
|
unsigned long long samplesRead; ///< number of samples read from bladeRF
|
70
|
unsigned long long samplesWritten; ///< number of samples sent to bladeRF
|
71
|
|
72
|
bool skipRx; ///< set if bladeRF is transmit-only.
|
73
|
|
74
|
static const unsigned int currDataSize_log2 = 21;
|
75
|
static const unsigned long currDataSize = (1 << currDataSize_log2);
|
76
|
short *data;
|
77
|
struct bladerf *bdev;
|
78
|
|
79
|
Mutex writeLock;
|
80
|
|
81
|
double rxGain;
|
82
|
int mRxGain1;
|
83
|
int mRxHealth;
|
84
|
int mTxHealth;
|
85
|
|
86
|
bool isSuperSpeed;
|
87
|
union {
|
88
|
struct bladerf_highspeed_timestamp highSpeed[PKT_BUFFERS];
|
89
|
struct bladerf_superspeed_timestamp superSpeed[PKT_BUFFERS];
|
90
|
} rxBuffer;
|
91
|
union {
|
92
|
struct bladerf_highspeed_timestamp highSpeed;
|
93
|
struct bladerf_superspeed_timestamp superSpeed;
|
94
|
} txBuffer;
|
95
|
int rxBufIndex;
|
96
|
int rxBufCount;
|
97
|
int rxConsumed;
|
98
|
int txBuffered;
|
99
|
TIMESTAMP rxTimestamp;
|
100
|
TIMESTAMP txTimestamp;
|
101
|
TIMESTAMP rxResyncCandidate;
|
102
|
|
103
|
/** Rx DC offsets correction */
|
104
|
bool mDcCorrect;
|
105
|
int mRxMaxOffset;
|
106
|
int mRxCorrectionI;
|
107
|
int mRxCorrectionQ;
|
108
|
int mRxAverageI;
|
109
|
int mRxAverageQ;
|
110
|
|
111
|
/** debug mode control */
|
112
|
int pulseMode;
|
113
|
int rxShowInfo;
|
114
|
int txShowInfo;
|
115
|
bool spammy;
|
116
|
|
117
|
/** Number of raw samples in current mode */
|
118
|
inline int rawSamples() const
|
119
|
{ return isSuperSpeed ? PKT_SAMPLES_SUPER_RAW : PKT_SAMPLES_HIGH_RAW; }
|
120
|
|
121
|
/** Number of usable samples in current mode */
|
122
|
inline int useSamples() const
|
123
|
{ return isSuperSpeed ? PKT_SAMPLES_SUPER_USE : PKT_SAMPLES_HIGH_USE; }
|
124
|
|
125
|
/** Adjust health variable, terminate transceiver if excessive errors */
|
126
|
static void checkHealth(int& health, bool ok);
|
127
|
|
128
|
/** Set the transmission frequency */
|
129
|
bool tx_setFreq(double freq, double *actual_freq);
|
130
|
|
131
|
/** Set the receiver frequency */
|
132
|
bool rx_setFreq(double freq, double *actual_freq);
|
133
|
|
134
|
/** Set the RAD1 style VCTCXO*/
|
135
|
bool setVCTCXOrad1(unsigned int adj);
|
136
|
|
137
|
/** Set the RX DAC correction offsets */
|
138
|
bool setRxOffsets(int corrI, int corrQ);
|
139
|
|
140
|
/** Set the TX DAC correction offsets */
|
141
|
bool setTxOffsets(int corrI, int corrQ);
|
142
|
|
143
|
/** Set loopback mode */
|
144
|
bool setLoopback(bladerf_loopback loopback);
|
145
|
|
146
|
public:
|
147
|
|
148
|
/** Object constructor */
|
149
|
bladeRFDevice (int sps_rx, int sps_tx, bool skipRx = false);
|
150
|
|
151
|
/** Instantiate the bladeRF */
|
152
|
int open(const std::string &args = "", bool extref = false);
|
153
|
|
154
|
/** Start the bladeRF */
|
155
|
bool start();
|
156
|
|
157
|
/** Stop the bladeRF */
|
158
|
bool stop();
|
159
|
|
160
|
/**
|
161
|
Read samples from the bladeRF.
|
162
|
@param buf preallocated buf to contain read result
|
163
|
@param len number of samples desired
|
164
|
@param overrun Set if read buffer has been overrun, e.g. data not being read fast enough
|
165
|
@param timestamp The timestamp of the first samples to be read
|
166
|
@param underrun Set if bladeRF does not have data to transmit, e.g. data not being sent fast enough
|
167
|
@param RSSI The received signal strength of the read result
|
168
|
@return The number of samples actually read
|
169
|
*/
|
170
|
int readSamples(std::vector<short *> &bufs, int len, bool *overrun,
|
171
|
TIMESTAMP timestamp, bool *underrun, unsigned *RSSI);
|
172
|
|
173
|
/**
|
174
|
Write samples to the bladeRF.
|
175
|
@param buf Contains the data to be written.
|
176
|
@param len number of samples to write.
|
177
|
@param underrun Set if bladeRF does not have data to transmit, e.g. data not being sent fast enough
|
178
|
@param timestamp The timestamp of the first sample of the data buffer.
|
179
|
@param isControl Set if data is a control packet, e.g. a ping command
|
180
|
@return The number of samples actually written
|
181
|
*/
|
182
|
int writeSamples(std::vector<short *> &bufs, int len, bool *underrun,
|
183
|
TIMESTAMP timestamp, bool isControl);
|
184
|
|
185
|
/** The bladeRF never goes out of alignment */
|
186
|
bool updateAlignment(TIMESTAMP timestamp) { return true; }
|
187
|
|
188
|
/** Set the VCTCXO offset*/
|
189
|
bool setVCTCXO(unsigned int wAdjFreq = 0);
|
190
|
|
191
|
/** Set the transmitter frequency */
|
192
|
bool setTxFreq(double wFreq, size_t chan);
|
193
|
|
194
|
/** Set the receiver frequency */
|
195
|
bool setRxFreq(double wFreq, size_t chan);
|
196
|
|
197
|
/** Returns the starting write Timestamp*/
|
198
|
TIMESTAMP initialWriteTimestamp(void) { return 1; }
|
199
|
|
200
|
/** Returns the starting read Timestamp*/
|
201
|
TIMESTAMP initialReadTimestamp(void) { return 1; }
|
202
|
|
203
|
// FIXME: 2^12?
|
204
|
/** returns the full-scale transmit amplitude **/
|
205
|
double fullScaleInputValue() {return 2040.0;}
|
206
|
|
207
|
/** returns the full-scale receive amplitude **/
|
208
|
double fullScaleOutputValue() {return 2040.0;}
|
209
|
|
210
|
/** sets the receive chan gain, returns the gain setting **/
|
211
|
double setRxGain(double dB, size_t chan);
|
212
|
|
213
|
/** get the current receive gain */
|
214
|
double getRxGain(size_t chan) {return rxGain;}
|
215
|
|
216
|
/** return maximum Rx Gain **/
|
217
|
double maxRxGain(void) {return BLADERF_RXVGA2_GAIN_MAX;}
|
218
|
|
219
|
/** return minimum Rx Gain **/
|
220
|
double minRxGain(void) {return BLADERF_RXVGA2_GAIN_MIN;}
|
221
|
|
222
|
/** sets the transmit chan gain, returns the gain setting **/
|
223
|
double setTxGain(double dB, size_t chan);
|
224
|
|
225
|
/** return maximum Tx Gain **/
|
226
|
double maxTxGain(void) {return BLADERF_TXVGA2_GAIN_MAX;}
|
227
|
|
228
|
/** return minimum Rx Gain **/
|
229
|
double minTxGain(void) {return BLADERF_TXVGA2_GAIN_MIN;}
|
230
|
|
231
|
|
232
|
/** Return internal status values: FIXME */
|
233
|
inline double getTxFreq(size_t chan) { return 0;}
|
234
|
inline double getRxFreq(size_t chan) { return 0;}
|
235
|
inline double getSampleRate() {printf(">>getsamplerate %f\n", actualSampleRate); return actualSampleRate;}
|
236
|
inline double numberRead() { return samplesRead; }
|
237
|
inline double numberWritten() { return samplesWritten;}
|
238
|
|
239
|
/** return factory settings */
|
240
|
unsigned int getFactoryValue(const std::string &name);
|
241
|
|
242
|
bool runCustom(const std::string &command);
|
243
|
|
244
|
enum TxWindowType getWindowType() { return TX_WINDOW_FIXED; }
|
245
|
void setPriority(float prio) {};
|
246
|
};
|
247
|
|
248
|
#endif // _BLADERF_DEVICE_H_
|