blob: d31ea295541528ce563ee0eb8d2ed039d85d95f5 [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);
189// using buf_in_use = blade_otw_buffer<2, blade_speed_buffer_type::SS>;
190using bh_fn_t = std::function<int(dev_buf_t *)>;
191
Eric2e6c3622023-05-02 14:34:49 +0200192template <typename T>
193struct blade_hw {
Ericb7253c62022-11-28 19:21:08 +0100194 struct bladerf *dev;
195 struct bladerf_stream *rx_stream;
196 struct bladerf_stream *tx_stream;
197 // using pkt2buf = blade_otw_buffer<2, blade_speed_buffer_type::SS>;
Ericc3e515a2023-05-08 12:56:56 +0200198 using tx_buf_q_type = spsc_cond_timeout<BLADE_NUM_BUFFERS, dev_buf_t *, true, false>;
Ericb7253c62022-11-28 19:21:08 +0100199 const unsigned int rxFullScale, txFullScale;
200 const int rxtxdelay;
Eric Wild238891f2024-03-20 19:39:05 +0100201 bool use_agc;
Ericb7253c62022-11-28 19:21:08 +0100202
Eric40978042023-05-23 10:59:58 +0200203 static std::atomic<bool> stop_lower_threads_flag;
Ericc0f0a612023-05-02 15:34:19 +0200204 double rxfreq_cache, txfreq_cache;
Ericb7253c62022-11-28 19:21:08 +0100205
206 struct ms_trx_config {
207 int tx_freq;
208 int rx_freq;
209 int sample_rate;
210 int bandwidth;
Eric Wild238891f2024-03-20 19:39:05 +0100211 float rxgain;
212 float txgain;
Ericb7253c62022-11-28 19:21:08 +0100213
214 public:
Eric Wild238891f2024-03-20 19:39:05 +0100215 ms_trx_config()
216 : tx_freq(881e6), rx_freq(926e6), sample_rate(((1625e3 / 6) * 4)), bandwidth(1e6), rxgain(30),
217 txgain(30)
Ericb7253c62022-11-28 19:21:08 +0100218 {
219 }
220 } cfg;
221
222 struct buf_mgmt {
223 void **rx_samples;
224 void **tx_samples;
225 tx_buf_q_type bufptrqueue;
226
227 } buf_mgmt;
228
229 virtual ~blade_hw()
230 {
231 close_device();
232 }
Eric Wild238891f2024-03-20 19:39:05 +0100233 blade_hw(struct mssdr_cfg *cfgdata)
234 : rxFullScale(2047), txFullScale(2047), rxtxdelay(-60), use_agc(cfgdata->use_agc), rxfreq_cache(0),
Ericc0f0a612023-05-02 15:34:19 +0200235 txfreq_cache(0)
Ericb7253c62022-11-28 19:21:08 +0100236 {
Eric Wild238891f2024-03-20 19:39:05 +0100237 cfg.tx_freq = cfgdata->overrides.ul_freq;
238 cfg.rx_freq = cfgdata->overrides.dl_freq;
239 cfg.rxgain = cfgdata->overrides.dl_gain;
240 cfg.txgain = cfgdata->overrides.ul_gain;
Ericb7253c62022-11-28 19:21:08 +0100241 }
242
243 void close_device()
244 {
245 if (dev) {
246 if (tx_stream) {
247 bladerf_deinit_stream(tx_stream);
248 }
249
250 if (rx_stream) {
251 bladerf_deinit_stream(rx_stream);
252 }
253
254 bladerf_enable_module(dev, BLADERF_MODULE_RX, false);
255 bladerf_enable_module(dev, BLADERF_MODULE_TX, false);
256
257 bladerf_close(dev);
258 dev = NULL;
259 }
260 }
261
262 int init_device(bh_fn_t rxh, bh_fn_t txh)
263 {
264 struct bladerf_rational_rate rate = { 0, static_cast<uint64_t>((1625e3 * 4)) * 64, 6 * 64 }, actual;
Eric Wild238891f2024-03-20 19:39:05 +0100265 std::cerr << "cfg: ul " << cfg.tx_freq << " dl " << cfg.rx_freq << std::endl;
Ericb7253c62022-11-28 19:21:08 +0100266
267 bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_DEBUG);
268 bladerf_set_usb_reset_on_open(true);
Ericb52650f2023-11-03 20:37:51 +0100269
Ericb7253c62022-11-28 19:21:08 +0100270 blade_check(bladerf_open, &dev, "");
271 if (!dev) {
272 std::cerr << "open failed, device missing?" << std::endl;
273 exit(0);
274 }
275 if (bladerf_device_speed(dev) != bladerf_dev_speed::BLADERF_DEVICE_SPEED_SUPER) {
276 std::cerr << "open failed, only superspeed (usb3) supported!" << std::endl;
277 return -1;
278 }
279
280 blade_check(bladerf_set_tuning_mode, dev, bladerf_tuning_mode::BLADERF_TUNING_MODE_FPGA);
281
282 bool is_locked;
283 blade_check(bladerf_set_pll_enable, dev, true);
Eric Wild8f19df32024-03-18 16:16:17 +0100284 uint64_t refclock = 10000000UL;
285 blade_check(bladerf_set_pll_refclk, dev, refclock);
Ericb7253c62022-11-28 19:21:08 +0100286 for (int i = 0; i < 20; i++) {
287 usleep(50 * 1000);
288 bladerf_get_pll_lock_state(dev, &is_locked);
289
290 if (is_locked)
291 break;
292 }
293 if (!is_locked) {
294 std::cerr << "unable to lock refclk!" << std::endl;
295 return -1;
296 }
297
298 blade_check(bladerf_set_rational_sample_rate, dev, BLADERF_CHANNEL_RX(0), &rate, &actual);
299 blade_check(bladerf_set_rational_sample_rate, dev, BLADERF_CHANNEL_TX(0), &rate, &actual);
300
301 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_RX(0), (bladerf_frequency)cfg.rx_freq);
302 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_TX(0), (bladerf_frequency)cfg.tx_freq);
303
304 blade_check(bladerf_set_bandwidth, dev, BLADERF_CHANNEL_RX(0), (bladerf_bandwidth)cfg.bandwidth,
305 (bladerf_bandwidth *)NULL);
306 blade_check(bladerf_set_bandwidth, dev, BLADERF_CHANNEL_TX(0), (bladerf_bandwidth)cfg.bandwidth,
307 (bladerf_bandwidth *)NULL);
308
Eric Wild238891f2024-03-20 19:39:05 +0100309 blade_check(bladerf_set_gain_mode, dev, BLADERF_CHANNEL_RX(0),
310 use_agc ? BLADERF_GAIN_AUTOMATIC : BLADERF_GAIN_MGC);
311 setRxGain(cfg.rxgain, 0);
312 setTxGain(cfg.txgain, 0);
Ericb7253c62022-11-28 19:21:08 +0100313 usleep(1000);
Ericb3157b92023-05-23 11:32:34 +0200314
315 bladerf_set_stream_timeout(dev, BLADERF_TX, 10);
316 bladerf_set_stream_timeout(dev, BLADERF_RX, 10);
317
Ericb7253c62022-11-28 19:21:08 +0100318 blade_check(bladerf_init_stream, &rx_stream, dev, getrxcb(rxh), &buf_mgmt.rx_samples, BLADE_NUM_BUFFERS,
319 BLADERF_FORMAT_SC16_Q11_META, BLADE_BUFFER_SIZE, NUM_TRANSFERS, (void *)this);
320
321 blade_check(bladerf_init_stream, &tx_stream, dev, gettxcb(txh), &buf_mgmt.tx_samples, BLADE_NUM_BUFFERS,
322 BLADERF_FORMAT_SC16_Q11_META, BLADE_BUFFER_SIZE, NUM_TRANSFERS, (void *)this);
323
324 for (unsigned int i = 0; i < BLADE_NUM_BUFFERS; i++) {
325 auto cur_buffer = reinterpret_cast<tx_buf_q_type::elem_t *>(buf_mgmt.tx_samples);
326 buf_mgmt.bufptrqueue.spsc_push(&cur_buffer[i]);
327 }
328
Ericb7253c62022-11-28 19:21:08 +0100329 return 0;
330 }
331
Ericb3157b92023-05-23 11:32:34 +0200332 void actually_enable_streams()
333 {
334 blade_check(bladerf_enable_module, dev, BLADERF_MODULE_RX, true);
335 usleep(1000);
336 blade_check(bladerf_enable_module, dev, BLADERF_MODULE_TX, true);
337 }
338
Ericb7253c62022-11-28 19:21:08 +0100339 bool tuneTx(double freq, size_t chan = 0)
340 {
Ericc0f0a612023-05-02 15:34:19 +0200341 if (txfreq_cache == freq)
342 return true;
Ericb7253c62022-11-28 19:21:08 +0100343 msleep(15);
344 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_TX(0), (bladerf_frequency)freq);
Ericc0f0a612023-05-02 15:34:19 +0200345 txfreq_cache = freq;
Ericb7253c62022-11-28 19:21:08 +0100346 msleep(15);
347 return true;
348 };
349 bool tuneRx(double freq, size_t chan = 0)
350 {
Ericc0f0a612023-05-02 15:34:19 +0200351 if (rxfreq_cache == freq)
352 return true;
Ericb7253c62022-11-28 19:21:08 +0100353 msleep(15);
354 blade_check(bladerf_set_frequency, dev, BLADERF_CHANNEL_RX(0), (bladerf_frequency)freq);
Ericc0f0a612023-05-02 15:34:19 +0200355 rxfreq_cache = freq;
Ericb7253c62022-11-28 19:21:08 +0100356 msleep(15);
357 return true;
358 };
359 bool tuneRxOffset(double offset, size_t chan = 0)
360 {
361 return true;
362 };
363
364 double setRxGain(double dB, size_t chan = 0)
365 {
Eric Wild238891f2024-03-20 19:39:05 +0100366 cfg.rxgain = dB;
Ericb7253c62022-11-28 19:21:08 +0100367 msleep(15);
368 blade_check(bladerf_set_gain, dev, BLADERF_CHANNEL_RX(0), (bladerf_gain)dB);
369 msleep(15);
370 return dB;
371 };
372 double setTxGain(double dB, size_t chan = 0)
373 {
Eric Wild238891f2024-03-20 19:39:05 +0100374 cfg.txgain = dB;
Ericb7253c62022-11-28 19:21:08 +0100375 msleep(15);
376 blade_check(bladerf_set_gain, dev, BLADERF_CHANNEL_TX(0), (bladerf_gain)dB);
377 msleep(15);
378 return dB;
379 };
380 int setPowerAttenuation(int atten, size_t chan = 0)
381 {
382 return atten;
383 };
384
385 static void check_timestamp(dev_buf_t *rcd)
386 {
387 static bool first = true;
388 static uint64_t last_ts;
389 if (first) {
390 first = false;
391 last_ts = rcd->m[0].ts;
392 } else if (last_ts + rcd->actual_samples_per_buffer() != rcd->m[0].ts) {
393 std::cerr << "RX Overrun!" << last_ts << " " << rcd->actual_samples_per_buffer() << " "
394 << last_ts + rcd->actual_samples_per_buffer() << " " << rcd->m[0].ts << std::endl;
395 last_ts = rcd->m[0].ts;
396 } else {
397 last_ts = rcd->m[0].ts;
398 }
399 }
400
401 bladerf_stream_cb getrxcb(bh_fn_t rxbh)
402 {
403 // C cb -> no capture!
404 static auto rxbhfn = rxbh;
405 return [](struct bladerf *dev, struct bladerf_stream *stream, struct bladerf_metadata *meta,
406 void *samples, size_t num_samples, void *user_data) -> void * {
407 // struct blade_hw *trx = (struct blade_hw *)user_data;
408 static int to_skip = 0;
409 dev_buf_t *rcd = (dev_buf_t *)samples;
410
Eric40978042023-05-23 10:59:58 +0200411 if (stop_lower_threads_flag)
Ericb7253c62022-11-28 19:21:08 +0100412 return BLADERF_STREAM_SHUTDOWN;
413
414 if (to_skip < 120) // prevents weird overflows on startup
415 to_skip++;
416 else {
417 check_timestamp(rcd);
418 rxbhfn(rcd);
419 }
420
421 return samples;
422 };
423 }
424 bladerf_stream_cb gettxcb(bh_fn_t txbh)
425 {
426 // C cb -> no capture!
427 static auto txbhfn = txbh;
428 return [](struct bladerf *dev, struct bladerf_stream *stream, struct bladerf_metadata *meta,
429 void *samples, size_t num_samples, void *user_data) -> void * {
430 struct blade_hw *trx = (struct blade_hw *)user_data;
431 auto ptr = reinterpret_cast<tx_buf_q_type::elem_t>(samples);
432
433 if (samples) // put buffer address back into queue, ready to be reused
434 trx->buf_mgmt.bufptrqueue.spsc_push(&ptr);
435
Eric40978042023-05-23 10:59:58 +0200436 if (stop_lower_threads_flag)
Ericb7253c62022-11-28 19:21:08 +0100437 return BLADERF_STREAM_SHUTDOWN;
438
439 return BLADERF_STREAM_NO_DATA;
440 };
441 }
442
443 auto get_rx_burst_handler_fn(bh_fn_t burst_handler)
444 {
Eric989fe752023-10-06 16:06:13 +0200445 using thist = decltype(this);
446 auto fn = [](void *args) -> void * {
447 thist t = reinterpret_cast<thist>(args);
Ericb3157b92023-05-23 11:32:34 +0200448 int status = 0;
Eric40978042023-05-23 10:59:58 +0200449 if (!stop_lower_threads_flag)
Eric989fe752023-10-06 16:06:13 +0200450 status = bladerf_stream(t->rx_stream, BLADERF_RX_X1);
Ericb7253c62022-11-28 19:21:08 +0100451 if (status < 0)
452 std::cerr << "rx stream error! " << bladerf_strerror(status) << std::endl;
453
454 return 0;
455 };
456 return fn;
457 }
458 auto get_tx_burst_handler_fn(bh_fn_t burst_handler)
459 {
Eric989fe752023-10-06 16:06:13 +0200460 using thist = decltype(this);
461 auto fn = [](void *args) -> void * {
462 thist t = reinterpret_cast<thist>(args);
Ericb3157b92023-05-23 11:32:34 +0200463 int status = 0;
Eric40978042023-05-23 10:59:58 +0200464 if (!stop_lower_threads_flag)
Eric989fe752023-10-06 16:06:13 +0200465 status = bladerf_stream(t->tx_stream, BLADERF_TX_X1);
Ericb7253c62022-11-28 19:21:08 +0100466 if (status < 0)
467 std::cerr << "rx stream error! " << bladerf_strerror(status) << std::endl;
468
469 return 0;
470 };
471 return fn;
472 }
473
474 void submit_burst_ts(blade_sample_type *buffer, int len, uint64_t ts)
475 {
Ericb7253c62022-11-28 19:21:08 +0100476 tx_buf_q_type::elem_t rcd;
477
Ericb3157b92023-05-23 11:32:34 +0200478 // exit by submitting a dummy buffer to assure the libbladerf stream mutex is happy (thread!)
479 if (!buffer) {
480 bladerf_submit_stream_buffer(tx_stream, (void *)BLADERF_STREAM_SHUTDOWN, 1000);
481 return;
482 }
483
484 //get empty bufer from list
Ericb7253c62022-11-28 19:21:08 +0100485 while (!buf_mgmt.bufptrqueue.spsc_pop(&rcd))
486 buf_mgmt.bufptrqueue.spsc_prep_pop();
487 assert(rcd != nullptr);
488
489 rcd->write_n_burst(buffer, len, ts + rxtxdelay); // blade xa4 specific delay!
490 blade_check(bladerf_submit_stream_buffer_nb, tx_stream, (void *)rcd);
491 }
492};