blob: 07b7d6ad0cad0d8b59c5bb90fca2ea197b03ebd3 [file] [log] [blame]
Eric7d897cb2022-11-28 19:20:32 +01001/*
2 * Copyright 2022 sysmocom - s.f.m.c. GmbH
3 *
4 * Author: Eric Wild <ewild@sysmocom.de>
5 *
6 * SPDX-License-Identifier: AGPL-3.0+
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * See the COPYING file in the main directory for details.
21 */
22
23#pragma once
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include "radioDevice.h"
30#include "smpl_buf.h"
31
32extern "C" {
33#include <osmocom/gsm/gsm_utils.h>
34}
35
36#include <bladerf.h>
37
38enum class blade_dev_type { BLADE1, BLADE2 };
39
40struct dev_band_desc {
41 /* Maximum UHD Tx Gain which can be set/used without distorting the
42 output signal, and the resulting real output power measured when that
43 gain is used. Correct measured values only provided for B210 so far. */
44 double nom_uhd_tx_gain; /* dB */
45 double nom_out_tx_power; /* dBm */
46 /* Factor used to infer base real RSSI offset on the Rx path based on current
47 configured RxGain. The resulting rssiOffset is added to the per burst
48 calculated energy in upper layers. These values were empirically
49 found and may change based on multiple factors, see OS#4468.
50 rssiOffset = rxGain + rxgain2rssioffset_rel;
51 */
52 double rxgain2rssioffset_rel; /* dB */
53};
54
55class blade_device : public RadioDevice {
56 public:
57 blade_device(size_t tx_sps, size_t rx_sps, InterfaceType type, size_t chan_num, double offset,
58 const std::vector<std::string> &tx_paths, const std::vector<std::string> &rx_paths);
59 ~blade_device();
60
61 int open(const std::string &args, int ref, bool swap_channels);
62 bool start();
63 bool stop();
64 bool restart();
65 enum TxWindowType getWindowType()
66 {
67 return tx_window;
68 }
69
70 int readSamples(std::vector<short *> &bufs, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun);
71
72 int writeSamples(std::vector<short *> &bufs, int len, bool *underrun, TIMESTAMP timestamp);
73
74 bool updateAlignment(TIMESTAMP timestamp);
75
76 bool setTxFreq(double wFreq, size_t chan);
77 bool setRxFreq(double wFreq, size_t chan);
78
79 TIMESTAMP initialWriteTimestamp();
80 TIMESTAMP initialReadTimestamp();
81
82 double fullScaleInputValue();
83 double fullScaleOutputValue();
84
85 double setRxGain(double db, size_t chan);
86 double getRxGain(size_t chan);
87 double maxRxGain(void)
88 {
89 return rx_gain_max;
90 }
91 double minRxGain(void)
92 {
93 return rx_gain_min;
94 }
95 double rssiOffset(size_t chan);
96
97 double setPowerAttenuation(int atten, size_t chan);
98 double getPowerAttenuation(size_t chan = 0);
99
100 int getNominalTxPower(size_t chan = 0);
101
102 double getTxFreq(size_t chan);
103 double getRxFreq(size_t chan);
104 double getRxFreq();
105
106 bool setRxAntenna(const std::string &ant, size_t chan)
107 {
108 return {};
109 };
110 std::string getRxAntenna(size_t chan)
111 {
112 return {};
113 };
114 bool setTxAntenna(const std::string &ant, size_t chan)
115 {
116 return {};
117 };
118 std::string getTxAntenna(size_t chan)
119 {
120 return {};
121 };
122
123 bool requiresRadioAlign();
124
125 GSM::Time minLatency();
126
127 inline double getSampleRate()
128 {
129 return tx_rate;
130 }
131
132 /** Receive and process asynchronous message
133 @return true if message received or false on timeout or error
134 */
135 bool recv_async_msg();
136
137 enum err_code {
138 ERROR_TIMING = -1,
139 ERROR_TIMEOUT = -2,
140 ERROR_UNRECOVERABLE = -3,
141 ERROR_UNHANDLED = -4,
142 };
143
144 protected:
145 struct bladerf *dev;
146 void *usrp_dev;
147
148 enum TxWindowType tx_window;
149 enum blade_dev_type dev_type;
150
151 double tx_rate, rx_rate;
152
153 double rx_gain_min, rx_gain_max;
154
155 std::vector<double> tx_gains, rx_gains;
156 std::vector<double> tx_freqs, rx_freqs;
157 bool band_ass_curr_sess; /* true if "band" was set after last POWEROFF */
158 enum gsm_band band;
159 struct dev_band_desc band_desc;
160 size_t tx_spp, rx_spp;
161
162 bool started;
163 bool aligned;
164
165 size_t drop_cnt;
166 uint64_t prev_ts;
167
168 TIMESTAMP ts_initial, ts_offset;
169 std::vector<smpl_buf *> rx_buffers;
170 /* Sample buffers used to receive samples: */
171 std::vector<std::vector<short> > pkt_bufs;
172 /* Used to call UHD API: Buffer pointer of each elem in pkt_ptrs will
173 point to corresponding buffer of vector pkt_bufs. */
174 std::vector<short *> pkt_ptrs;
175
176 void init_gains();
177 void set_channels(bool swap);
178 void set_rates();
179 bool flush_recv(size_t num_pkts);
180
181 bool set_freq(double freq, size_t chan, bool tx);
182 void get_dev_band_desc(dev_band_desc &desc);
183 bool set_band(enum gsm_band req_band);
184 void assign_band_desc(enum gsm_band req_band);
185
186 Thread *async_event_thrd;
187 Mutex tune_lock;
188};