blob: 4db256947b8857d9dc5ced1465e779b129ecf11f [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:
Eric19e134a2023-05-10 23:50:38 +020057 blade_device(InterfaceType iface, const struct trx_cfg *cfg);
Eric7d897cb2022-11-28 19:20:32 +010058 ~blade_device();
59
Eric19e134a2023-05-10 23:50:38 +020060 int open();
Eric7d897cb2022-11-28 19:20:32 +010061 bool start();
62 bool stop();
63 bool restart();
64 enum TxWindowType getWindowType()
65 {
66 return tx_window;
67 }
68
69 int readSamples(std::vector<short *> &bufs, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun);
70
71 int writeSamples(std::vector<short *> &bufs, int len, bool *underrun, TIMESTAMP timestamp);
72
73 bool updateAlignment(TIMESTAMP timestamp);
74
75 bool setTxFreq(double wFreq, size_t chan);
76 bool setRxFreq(double wFreq, size_t chan);
77
78 TIMESTAMP initialWriteTimestamp();
79 TIMESTAMP initialReadTimestamp();
80
81 double fullScaleInputValue();
82 double fullScaleOutputValue();
83
84 double setRxGain(double db, size_t chan);
85 double getRxGain(size_t chan);
86 double maxRxGain(void)
87 {
88 return rx_gain_max;
89 }
90 double minRxGain(void)
91 {
92 return rx_gain_min;
93 }
94 double rssiOffset(size_t chan);
95
96 double setPowerAttenuation(int atten, size_t chan);
97 double getPowerAttenuation(size_t chan = 0);
98
99 int getNominalTxPower(size_t chan = 0);
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 {
107 return {};
108 };
109 std::string getRxAntenna(size_t chan)
110 {
111 return {};
112 };
113 bool setTxAntenna(const std::string &ant, size_t chan)
114 {
115 return {};
116 };
117 std::string getTxAntenna(size_t chan)
118 {
119 return {};
120 };
121
122 bool requiresRadioAlign();
123
124 GSM::Time minLatency();
125
126 inline double getSampleRate()
127 {
128 return tx_rate;
129 }
130
131 /** Receive and process asynchronous message
132 @return true if message received or false on timeout or error
133 */
134 bool recv_async_msg();
135
136 enum err_code {
137 ERROR_TIMING = -1,
138 ERROR_TIMEOUT = -2,
139 ERROR_UNRECOVERABLE = -3,
140 ERROR_UNHANDLED = -4,
141 };
142
143 protected:
144 struct bladerf *dev;
145 void *usrp_dev;
146
147 enum TxWindowType tx_window;
148 enum blade_dev_type dev_type;
149
150 double tx_rate, rx_rate;
151
152 double rx_gain_min, rx_gain_max;
153
154 std::vector<double> tx_gains, rx_gains;
155 std::vector<double> tx_freqs, rx_freqs;
156 bool band_ass_curr_sess; /* true if "band" was set after last POWEROFF */
157 enum gsm_band band;
158 struct dev_band_desc band_desc;
159 size_t tx_spp, rx_spp;
160
161 bool started;
162 bool aligned;
163
164 size_t drop_cnt;
165 uint64_t prev_ts;
166
167 TIMESTAMP ts_initial, ts_offset;
168 std::vector<smpl_buf *> rx_buffers;
169 /* Sample buffers used to receive samples: */
170 std::vector<std::vector<short> > pkt_bufs;
171 /* Used to call UHD API: Buffer pointer of each elem in pkt_ptrs will
172 point to corresponding buffer of vector pkt_bufs. */
173 std::vector<short *> pkt_ptrs;
174
175 void init_gains();
176 void set_channels(bool swap);
177 void set_rates();
178 bool flush_recv(size_t num_pkts);
179
180 bool set_freq(double freq, size_t chan, bool tx);
181 void get_dev_band_desc(dev_band_desc &desc);
182 bool set_band(enum gsm_band req_band);
183 void assign_band_desc(enum gsm_band req_band);
184
185 Thread *async_event_thrd;
186 Mutex tune_lock;
187};