blob: e32581e1e699b12af4c573212bc2127069135959 [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
Ericc0f78a32023-05-12 13:00:14 +020025#include <map>
Eric7d897cb2022-11-28 19:20:32 +010026#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
Ericc0f78a32023-05-12 13:00:14 +020030#include "bandmanager.h"
Eric7d897cb2022-11-28 19:20:32 +010031#include "radioDevice.h"
32#include "smpl_buf.h"
33
34extern "C" {
35#include <osmocom/gsm/gsm_utils.h>
36}
37
Eric7d897cb2022-11-28 19:20:32 +010038enum 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
Ericc0f78a32023-05-12 13:00:14 +020055/* Device parameter descriptor */
56struct dev_desc {
57 unsigned channels;
58 double mcr;
59 double rate;
60 double offset;
61 std::string desc_str;
62};
63
64using dev_key = std::tuple<blade_dev_type, int, int>;
65using dev_band_key = std::tuple<blade_dev_type, enum gsm_band>;
66using power_map_t = std::map<dev_band_key, dev_band_desc>;
67using dev_map_t = std::map<dev_key, dev_desc>;
68
69class blade_device : public RadioDevice, public band_manager<power_map_t, dev_map_t> {
Eric7d897cb2022-11-28 19:20:32 +010070 public:
Eric19e134a2023-05-10 23:50:38 +020071 blade_device(InterfaceType iface, const struct trx_cfg *cfg);
Eric7d897cb2022-11-28 19:20:32 +010072 ~blade_device();
73
Eric19e134a2023-05-10 23:50:38 +020074 int open();
Eric7d897cb2022-11-28 19:20:32 +010075 bool start();
76 bool stop();
77 bool restart();
78 enum TxWindowType getWindowType()
79 {
80 return tx_window;
81 }
82
83 int readSamples(std::vector<short *> &bufs, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun);
84
85 int writeSamples(std::vector<short *> &bufs, int len, bool *underrun, TIMESTAMP timestamp);
86
87 bool updateAlignment(TIMESTAMP timestamp);
88
89 bool setTxFreq(double wFreq, size_t chan);
90 bool setRxFreq(double wFreq, size_t chan);
91
92 TIMESTAMP initialWriteTimestamp();
93 TIMESTAMP initialReadTimestamp();
94
95 double fullScaleInputValue();
96 double fullScaleOutputValue();
97
98 double setRxGain(double db, size_t chan);
99 double getRxGain(size_t chan);
100 double maxRxGain(void)
101 {
102 return rx_gain_max;
103 }
104 double minRxGain(void)
105 {
106 return rx_gain_min;
107 }
108 double rssiOffset(size_t chan);
109
110 double setPowerAttenuation(int atten, size_t chan);
111 double getPowerAttenuation(size_t chan = 0);
112
113 int getNominalTxPower(size_t chan = 0);
114
115 double getTxFreq(size_t chan);
116 double getRxFreq(size_t chan);
117 double getRxFreq();
118
119 bool setRxAntenna(const std::string &ant, size_t chan)
120 {
121 return {};
122 };
123 std::string getRxAntenna(size_t chan)
124 {
125 return {};
126 };
127 bool setTxAntenna(const std::string &ant, size_t chan)
128 {
129 return {};
130 };
131 std::string getTxAntenna(size_t chan)
132 {
133 return {};
134 };
135
136 bool requiresRadioAlign();
137
138 GSM::Time minLatency();
139
140 inline double getSampleRate()
141 {
142 return tx_rate;
143 }
144
145 /** Receive and process asynchronous message
146 @return true if message received or false on timeout or error
147 */
148 bool recv_async_msg();
149
150 enum err_code {
151 ERROR_TIMING = -1,
152 ERROR_TIMEOUT = -2,
153 ERROR_UNRECOVERABLE = -3,
154 ERROR_UNHANDLED = -4,
155 };
156
157 protected:
158 struct bladerf *dev;
159 void *usrp_dev;
160
161 enum TxWindowType tx_window;
162 enum blade_dev_type dev_type;
163
164 double tx_rate, rx_rate;
165
166 double rx_gain_min, rx_gain_max;
167
168 std::vector<double> tx_gains, rx_gains;
169 std::vector<double> tx_freqs, rx_freqs;
Eric7d897cb2022-11-28 19:20:32 +0100170 size_t tx_spp, rx_spp;
171
172 bool started;
173 bool aligned;
174
175 size_t drop_cnt;
176 uint64_t prev_ts;
177
178 TIMESTAMP ts_initial, ts_offset;
179 std::vector<smpl_buf *> rx_buffers;
180 /* Sample buffers used to receive samples: */
181 std::vector<std::vector<short> > pkt_bufs;
182 /* Used to call UHD API: Buffer pointer of each elem in pkt_ptrs will
183 point to corresponding buffer of vector pkt_bufs. */
184 std::vector<short *> pkt_ptrs;
185
186 void init_gains();
187 void set_channels(bool swap);
188 void set_rates();
189 bool flush_recv(size_t num_pkts);
190
191 bool set_freq(double freq, size_t chan, bool tx);
Eric7d897cb2022-11-28 19:20:32 +0100192
193 Thread *async_event_thrd;
194 Mutex tune_lock;
195};