blob: a440125a3aa3f00081b78ec12b51b01b09125faa [file] [log] [blame]
Ericb7253c62022-11-28 19:21:08 +01001#pragma once
2/*
3 * (C) 2022 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
4 * All Rights Reserved
5 *
6 * Author: Eric Wild <ewild@sysmocom.de>
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 *
21 */
22
23#include "itrq.h"
24#include <atomic>
25#include <complex>
26#include <cstdint>
27#include <functional>
28#include <iostream>
29#include <cassert>
30#include <cstring>
31
32#include <libbladeRF.h>
33#include <Timeval.h>
34#include <unistd.h>
Eric Wild238891f2024-03-20 19:39:05 +010035extern "C" {
36#include "mssdr_vty.h"
37}
Ericb7253c62022-11-28 19:21:08 +010038
39const size_t BLADE_BUFFER_SIZE = 1024 * 1;
40const size_t BLADE_NUM_BUFFERS = 32 * 1;
41const size_t NUM_TRANSFERS = 16 * 2;
42const int SAMPLE_SCALE_FACTOR = 15; // actually 16 but sigproc complains about clipping..
43
44// see https://en.cppreference.com/w/cpp/language/parameter_pack "Brace-enclosed initializers" example
Eric2e6c3622023-05-02 14:34:49 +020045template <typename Arg, typename... Args>
46void expand_args(std::ostream &out, Arg &&arg, Args &&...args)
Ericb7253c62022-11-28 19:21:08 +010047{
48 out << '(' << std::forward<Arg>(arg);
49 (void)(int[]){ 0, (void((out << "," << std::forward<Args>(args))), 0)... };
50 out << ')' << std::endl;
51}
52
Eric2e6c3622023-05-02 14:34:49 +020053template <class R, class... Args>
54using RvalFunc = R (*)(Args...);
Ericb7253c62022-11-28 19:21:08 +010055
56template <class R, class... Args>
57R exec_and_check(RvalFunc<R, Args...> func, const char *fname, const char *finame, const char *funcname, int line,
58 Args... args)
59{
60 R rval = func(std::forward<Args>(args)...);
61 if (rval != 0) {
62 std::cerr << ((rval >= 0) ? "OK:" : bladerf_strerror(rval)) << ':' << finame << ':' << line << ':'
63 << funcname << ':' << fname;
64 expand_args(std::cerr, args...);
65 }
66 return rval;
67}
68
69// only macros can pass a func name string
70#define blade_check(func, ...) exec_and_check(func, #func, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
71
72#pragma pack(push, 1)
73using blade_sample_type = std::complex<int16_t>;
74enum class blade_speed_buffer_type { HS, SS };
Eric2e6c3622023-05-02 14:34:49 +020075template <blade_speed_buffer_type T>
76struct blade_usb_message {
Ericb7253c62022-11-28 19:21:08 +010077 uint32_t reserved;
78 uint64_t ts;
79 uint32_t meta_flags;
80 blade_sample_type d[(T == blade_speed_buffer_type::SS ? 512 : 256) - 4];
81};
82
83static_assert(sizeof(blade_usb_message<blade_speed_buffer_type::SS>) == 2048, "blade buffer mismatch!");
84static_assert(sizeof(blade_usb_message<blade_speed_buffer_type::HS>) == 1024, "blade buffer mismatch!");
Eric2e6c3622023-05-02 14:34:49 +020085template <unsigned int SZ, blade_speed_buffer_type T>
86struct blade_otw_buffer {
Ericb7253c62022-11-28 19:21:08 +010087 static_assert((SZ >= 2 && !(SZ % 2)), "min size is 2x usb buffer!");
88 blade_usb_message<T> m[SZ];
89 int actual_samples_per_msg()
90 {
91 return sizeof(blade_usb_message<T>::d) / sizeof(typeof(blade_usb_message<T>::d[0]));
92 }
93 int actual_samples_per_buffer()
94 {
95 return SZ * actual_samples_per_msg();
96 }
97 int samples_per_buffer()
98 {
99 return SZ * sizeof(blade_usb_message<T>) / sizeof(typeof(blade_usb_message<T>::d[0]));
100 }
101 int num_msgs_per_buffer()
102 {
103 return SZ;
104 }
105 auto get_first_ts()
106 {
107 return m[0].ts;
108 }
109 constexpr auto *getsampleoffset(int ofs)
110 {
111 auto full = ofs / actual_samples_per_msg();
112 auto rem = ofs % actual_samples_per_msg();
113 return &m[full].d[rem];
114 }
115 int readall(blade_sample_type *outaddr)
116 {
117 blade_sample_type *addr = outaddr;
118 for (unsigned int i = 0; i < SZ; i++) {
119 memcpy(addr, &m[i].d[0], actual_samples_per_msg() * sizeof(blade_sample_type));
120 addr += actual_samples_per_msg();
121 }
122 return actual_samples_per_buffer();
123 }
124 int read_n(blade_sample_type *outaddr, int start, int num)
125 {
126 assert((start + num) <= actual_samples_per_buffer());
127 assert(start >= 0);
128
129 if (!num)
130 return 0;
131
132 // which buffer?
133 int start_buf_idx = (start > 0) ? start / actual_samples_per_msg() : 0;
134 // offset from actual buffer start
135 auto start_offset_in_buf = (start - (start_buf_idx * actual_samples_per_msg()));
136 auto samp_rem_in_first_buf = actual_samples_per_msg() - start_offset_in_buf;
137 auto remaining_first_buf = num > samp_rem_in_first_buf ? samp_rem_in_first_buf : num;
138
139 memcpy(outaddr, &m[start_buf_idx].d[start_offset_in_buf],
140 remaining_first_buf * sizeof(blade_sample_type));
141 outaddr += remaining_first_buf;
142
143 auto remaining = num - remaining_first_buf;
144
145 if (!remaining)
146 return num;
147
148 start_buf_idx++;
149
150 auto rem_full_bufs = remaining / actual_samples_per_msg();
151 remaining -= rem_full_bufs * actual_samples_per_msg();
152
153 for (int i = 0; i < rem_full_bufs; i++) {
154 memcpy(outaddr, &m[start_buf_idx++].d[0], actual_samples_per_msg() * sizeof(blade_sample_type));
155 outaddr += actual_samples_per_msg();
156 }
157
158 if (remaining)
159 memcpy(outaddr, &m[start_buf_idx].d[0], remaining * sizeof(blade_sample_type));
160 return num;
161 }
162 int write_n_burst(blade_sample_type *in, int num, uint64_t first_ts)
163 {
164 assert(num <= actual_samples_per_buffer());
165 int len_rem = num;
166 for (unsigned int i = 0; i < SZ; i++) {
167 m[i] = {};
168 m[i].ts = first_ts + i * actual_samples_per_msg();
169 if (len_rem) {
170 int max_to_copy =
171 len_rem > actual_samples_per_msg() ? actual_samples_per_msg() : len_rem;
172 memcpy(&m[i].d[0], in, max_to_copy * sizeof(blade_sample_type));
173 len_rem -= max_to_copy;
174 in += actual_samples_per_msg();
175 }
176 }
177 return num;
178 }
179};
180#pragma pack(pop)
181
Eric2e6c3622023-05-02 14:34:49 +0200182template <unsigned int SZ, blade_speed_buffer_type T>
183struct blade_otw_buffer_helper {
Ericb7253c62022-11-28 19:21:08 +0100184 static_assert((SZ >= 1024 && ((SZ & (SZ - 1)) == 0)), "only buffer size multiples of 1024 allowed!");
185 static blade_otw_buffer<SZ / 512, T> x;
186};
187
188using dev_buf_t = typeof(blade_otw_buffer_helper<BLADE_BUFFER_SIZE, blade_speed_buffer_type::SS>::x);
Ericb7253c62022-11-28 19:21:08 +0100189using bh_fn_t = std::function<int(dev_buf_t *)>;
190
Eric2e6c3622023-05-02 14:34:49 +0200191template <typename T>
192struct blade_hw {
Ericb7253c62022-11-28 19:21:08 +0100193 struct bladerf *dev;
194 struct bladerf_stream *rx_stream;
195 struct bladerf_stream *tx_stream;
Ericc3e515a2023-05-08 12:56:56 +0200196 using tx_buf_q_type = spsc_cond_timeout<BLADE_NUM_BUFFERS, dev_buf_t *, true, false>;
Ericb7253c62022-11-28 19:21:08 +0100197 const unsigned int rxFullScale, txFullScale;
198 const int rxtxdelay;
Eric Wild238891f2024-03-20 19:39:05 +0100199 bool use_agc;
Ericb7253c62022-11-28 19:21:08 +0100200
Eric40978042023-05-23 10:59:58 +0200201 static std::atomic<bool> stop_lower_threads_flag;
Ericc0f0a612023-05-02 15:34:19 +0200202 double rxfreq_cache, txfreq_cache;
Ericb7253c62022-11-28 19:21:08 +0100203
204 struct ms_trx_config {
205 int tx_freq;
206 int rx_freq;
207 int sample_rate;
208 int bandwidth;
Eric Wild238891f2024-03-20 19:39:05 +0100209 float rxgain;
210 float txgain;
Ericb7253c62022-11-28 19:21:08 +0100211
212 public:
Eric Wild238891f2024-03-20 19:39:05 +0100213 ms_trx_config()
214 : tx_freq(881e6), rx_freq(926e6), sample_rate(((1625e3 / 6) * 4)), bandwidth(1e6), rxgain(30),
215 txgain(30)
Ericb7253c62022-11-28 19:21:08 +0100216 {
217 }
218 } cfg;
219
220 struct buf_mgmt {
221 void **rx_samples;
222 void **tx_samples;
223 tx_buf_q_type bufptrqueue;
224
225 } buf_mgmt;
226
227 virtual ~blade_hw()
228 {
229 close_device();
230 }
Eric Wild238891f2024-03-20 19:39:05 +0100231 blade_hw(struct mssdr_cfg *cfgdata)
232 : rxFullScale(2047), txFullScale(2047), rxtxdelay(-60), use_agc(cfgdata->use_agc), rxfreq_cache(0),
Ericc0f0a612023-05-02 15:34:19 +0200233 txfreq_cache(0)
Ericb7253c62022-11-28 19:21:08 +0100234 {
Eric Wild238891f2024-03-20 19:39:05 +0100235 cfg.tx_freq = cfgdata->overrides.ul_freq;
236 cfg.rx_freq = cfgdata->overrides.dl_freq;
237 cfg.rxgain = cfgdata->overrides.dl_gain;
238 cfg.txgain = cfgdata->overrides.ul_gain;
Ericb7253c62022-11-28 19:21:08 +0100239 }
240
241 void close_device()
242 {
243 if (dev) {
244 if (tx_stream) {
245 bladerf_deinit_stream(tx_stream);
246 }
247
248 if (rx_stream) {
249 bladerf_deinit_stream(rx_stream);
250 }
251
252 bladerf_enable_module(dev, BLADERF_MODULE_RX, false);
253 bladerf_enable_module(dev, BLADERF_MODULE_TX, false);
254
255 bladerf_close(dev);
256 dev = NULL;
257 }
258 }
259
260 int init_device(bh_fn_t rxh, bh_fn_t txh)
261 {
262 struct bladerf_rational_rate rate = { 0, static_cast<uint64_t>((1625e3 * 4)) * 64, 6 * 64 }, actual;
Eric Wild238891f2024-03-20 19:39:05 +0100263 std::cerr << "cfg: ul " << cfg.tx_freq << " dl " << cfg.rx_freq << std::endl;
Ericb7253c62022-11-28 19:21:08 +0100264
265 bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_DEBUG);
266 bladerf_set_usb_reset_on_open(true);
Ericb52650f2023-11-03 20:37:51 +0100267
Ericb7253c62022-11-28 19:21:08 +0100268 blade_check(bladerf_open, &dev, "");
269 if (!dev) {
270 std::cerr << "open failed, device missing?" << std::endl;
271 exit(0);
272 }
273 if (bladerf_device_speed(dev) != bladerf_dev_speed::BLADERF_DEVICE_SPEED_SUPER) {
274 std::cerr << "open failed, only superspeed (usb3) supported!" << std::endl;
275 return -1;
276 }
277
278 blade_check(bladerf_set_tuning_mode, dev, bladerf_tuning_mode::BLADERF_TUNING_MODE_FPGA);
279
280 bool is_locked;
281 blade_check(bladerf_set_pll_enable, dev, true);
Eric Wild8f19df32024-03-18 16:16:17 +0100282 uint64_t refclock = 10000000UL;
283 blade_check(bladerf_set_pll_refclk, dev, refclock);
Ericb7253c62022-11-28 19:21:08 +0100284 for (int i = 0; i < 20; i++) {
285 usleep(50 * 1000);
286 bladerf_get_pll_lock_state(dev, &is_locked);
287
288 if (is_locked)
289 break;
290 }
291 if (!is_locked) {
292 std::cerr << "unable to lock refclk!" << std::endl;
293 return -1;
294 }
295
296 blade_check(bladerf_set_rational_sample_rate, dev, BLADERF_CHANNEL_RX(0), &rate, &actual);
297 blade_check(bladerf_set_rational_sample_rate, dev, BLADERF_CHANNEL_TX(0), &rate, &actual);
298
299 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_RX(0), (bladerf_frequency)cfg.rx_freq);
300 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_TX(0), (bladerf_frequency)cfg.tx_freq);
301
302 blade_check(bladerf_set_bandwidth, dev, BLADERF_CHANNEL_RX(0), (bladerf_bandwidth)cfg.bandwidth,
303 (bladerf_bandwidth *)NULL);
304 blade_check(bladerf_set_bandwidth, dev, BLADERF_CHANNEL_TX(0), (bladerf_bandwidth)cfg.bandwidth,
305 (bladerf_bandwidth *)NULL);
306
Eric Wild238891f2024-03-20 19:39:05 +0100307 blade_check(bladerf_set_gain_mode, dev, BLADERF_CHANNEL_RX(0),
308 use_agc ? BLADERF_GAIN_AUTOMATIC : BLADERF_GAIN_MGC);
309 setRxGain(cfg.rxgain, 0);
310 setTxGain(cfg.txgain, 0);
Ericb7253c62022-11-28 19:21:08 +0100311 usleep(1000);
Ericb3157b92023-05-23 11:32:34 +0200312
313 bladerf_set_stream_timeout(dev, BLADERF_TX, 10);
314 bladerf_set_stream_timeout(dev, BLADERF_RX, 10);
315
Ericb7253c62022-11-28 19:21:08 +0100316 blade_check(bladerf_init_stream, &rx_stream, dev, getrxcb(rxh), &buf_mgmt.rx_samples, BLADE_NUM_BUFFERS,
317 BLADERF_FORMAT_SC16_Q11_META, BLADE_BUFFER_SIZE, NUM_TRANSFERS, (void *)this);
318
319 blade_check(bladerf_init_stream, &tx_stream, dev, gettxcb(txh), &buf_mgmt.tx_samples, BLADE_NUM_BUFFERS,
320 BLADERF_FORMAT_SC16_Q11_META, BLADE_BUFFER_SIZE, NUM_TRANSFERS, (void *)this);
321
322 for (unsigned int i = 0; i < BLADE_NUM_BUFFERS; i++) {
323 auto cur_buffer = reinterpret_cast<tx_buf_q_type::elem_t *>(buf_mgmt.tx_samples);
324 buf_mgmt.bufptrqueue.spsc_push(&cur_buffer[i]);
325 }
326
Ericb7253c62022-11-28 19:21:08 +0100327 return 0;
328 }
329
Ericb3157b92023-05-23 11:32:34 +0200330 void actually_enable_streams()
331 {
332 blade_check(bladerf_enable_module, dev, BLADERF_MODULE_RX, true);
333 usleep(1000);
334 blade_check(bladerf_enable_module, dev, BLADERF_MODULE_TX, true);
335 }
336
Ericb7253c62022-11-28 19:21:08 +0100337 bool tuneTx(double freq, size_t chan = 0)
338 {
Ericc0f0a612023-05-02 15:34:19 +0200339 if (txfreq_cache == freq)
340 return true;
Ericb7253c62022-11-28 19:21:08 +0100341 msleep(15);
342 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_TX(0), (bladerf_frequency)freq);
Ericc0f0a612023-05-02 15:34:19 +0200343 txfreq_cache = freq;
Ericb7253c62022-11-28 19:21:08 +0100344 msleep(15);
345 return true;
346 };
347 bool tuneRx(double freq, size_t chan = 0)
348 {
Ericc0f0a612023-05-02 15:34:19 +0200349 if (rxfreq_cache == freq)
350 return true;
Ericb7253c62022-11-28 19:21:08 +0100351 msleep(15);
352 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_RX(0), (bladerf_frequency)freq);
Ericc0f0a612023-05-02 15:34:19 +0200353 rxfreq_cache = freq;
Ericb7253c62022-11-28 19:21:08 +0100354 msleep(15);
355 return true;
356 };
357 bool tuneRxOffset(double offset, size_t chan = 0)
358 {
359 return true;
360 };
361
362 double setRxGain(double dB, size_t chan = 0)
363 {
Eric Wild238891f2024-03-20 19:39:05 +0100364 cfg.rxgain = dB;
Ericb7253c62022-11-28 19:21:08 +0100365 msleep(15);
366 blade_check(bladerf_set_gain, dev, BLADERF_CHANNEL_RX(0), (bladerf_gain)dB);
367 msleep(15);
368 return dB;
369 };
370 double setTxGain(double dB, size_t chan = 0)
371 {
Eric Wild238891f2024-03-20 19:39:05 +0100372 cfg.txgain = dB;
Ericb7253c62022-11-28 19:21:08 +0100373 msleep(15);
374 blade_check(bladerf_set_gain, dev, BLADERF_CHANNEL_TX(0), (bladerf_gain)dB);
375 msleep(15);
376 return dB;
377 };
378 int setPowerAttenuation(int atten, size_t chan = 0)
379 {
380 return atten;
381 };
382
383 static void check_timestamp(dev_buf_t *rcd)
384 {
385 static bool first = true;
386 static uint64_t last_ts;
387 if (first) {
388 first = false;
389 last_ts = rcd->m[0].ts;
390 } else if (last_ts + rcd->actual_samples_per_buffer() != rcd->m[0].ts) {
391 std::cerr << "RX Overrun!" << last_ts << " " << rcd->actual_samples_per_buffer() << " "
392 << last_ts + rcd->actual_samples_per_buffer() << " " << rcd->m[0].ts << std::endl;
393 last_ts = rcd->m[0].ts;
394 } else {
395 last_ts = rcd->m[0].ts;
396 }
397 }
398
399 bladerf_stream_cb getrxcb(bh_fn_t rxbh)
400 {
401 // C cb -> no capture!
402 static auto rxbhfn = rxbh;
403 return [](struct bladerf *dev, struct bladerf_stream *stream, struct bladerf_metadata *meta,
404 void *samples, size_t num_samples, void *user_data) -> void * {
405 // struct blade_hw *trx = (struct blade_hw *)user_data;
406 static int to_skip = 0;
407 dev_buf_t *rcd = (dev_buf_t *)samples;
408
Eric40978042023-05-23 10:59:58 +0200409 if (stop_lower_threads_flag)
Ericb7253c62022-11-28 19:21:08 +0100410 return BLADERF_STREAM_SHUTDOWN;
411
412 if (to_skip < 120) // prevents weird overflows on startup
413 to_skip++;
414 else {
415 check_timestamp(rcd);
416 rxbhfn(rcd);
417 }
418
419 return samples;
420 };
421 }
422 bladerf_stream_cb gettxcb(bh_fn_t txbh)
423 {
424 // C cb -> no capture!
425 static auto txbhfn = txbh;
426 return [](struct bladerf *dev, struct bladerf_stream *stream, struct bladerf_metadata *meta,
427 void *samples, size_t num_samples, void *user_data) -> void * {
428 struct blade_hw *trx = (struct blade_hw *)user_data;
429 auto ptr = reinterpret_cast<tx_buf_q_type::elem_t>(samples);
430
431 if (samples) // put buffer address back into queue, ready to be reused
432 trx->buf_mgmt.bufptrqueue.spsc_push(&ptr);
433
Eric40978042023-05-23 10:59:58 +0200434 if (stop_lower_threads_flag)
Ericb7253c62022-11-28 19:21:08 +0100435 return BLADERF_STREAM_SHUTDOWN;
436
437 return BLADERF_STREAM_NO_DATA;
438 };
439 }
440
441 auto get_rx_burst_handler_fn(bh_fn_t burst_handler)
442 {
Eric989fe752023-10-06 16:06:13 +0200443 using thist = decltype(this);
444 auto fn = [](void *args) -> void * {
445 thist t = reinterpret_cast<thist>(args);
Ericb3157b92023-05-23 11:32:34 +0200446 int status = 0;
Eric40978042023-05-23 10:59:58 +0200447 if (!stop_lower_threads_flag)
Eric989fe752023-10-06 16:06:13 +0200448 status = bladerf_stream(t->rx_stream, BLADERF_RX_X1);
Ericb7253c62022-11-28 19:21:08 +0100449 if (status < 0)
450 std::cerr << "rx stream error! " << bladerf_strerror(status) << std::endl;
451
452 return 0;
453 };
454 return fn;
455 }
456 auto get_tx_burst_handler_fn(bh_fn_t burst_handler)
457 {
Eric989fe752023-10-06 16:06:13 +0200458 using thist = decltype(this);
459 auto fn = [](void *args) -> void * {
460 thist t = reinterpret_cast<thist>(args);
Ericb3157b92023-05-23 11:32:34 +0200461 int status = 0;
Eric40978042023-05-23 10:59:58 +0200462 if (!stop_lower_threads_flag)
Eric989fe752023-10-06 16:06:13 +0200463 status = bladerf_stream(t->tx_stream, BLADERF_TX_X1);
Ericb7253c62022-11-28 19:21:08 +0100464 if (status < 0)
465 std::cerr << "rx stream error! " << bladerf_strerror(status) << std::endl;
466
467 return 0;
468 };
469 return fn;
470 }
471
472 void submit_burst_ts(blade_sample_type *buffer, int len, uint64_t ts)
473 {
Ericb7253c62022-11-28 19:21:08 +0100474 tx_buf_q_type::elem_t rcd;
475
Ericb3157b92023-05-23 11:32:34 +0200476 // exit by submitting a dummy buffer to assure the libbladerf stream mutex is happy (thread!)
477 if (!buffer) {
478 bladerf_submit_stream_buffer(tx_stream, (void *)BLADERF_STREAM_SHUTDOWN, 1000);
479 return;
480 }
481
482 //get empty bufer from list
Ericb7253c62022-11-28 19:21:08 +0100483 while (!buf_mgmt.bufptrqueue.spsc_pop(&rcd))
484 buf_mgmt.bufptrqueue.spsc_prep_pop();
485 assert(rcd != nullptr);
486
487 rcd->write_n_burst(buffer, len, ts + rxtxdelay); // blade xa4 specific delay!
488 blade_check(bladerf_submit_stream_buffer_nb, tx_stream, (void *)rcd);
489 }
490};