Project

General

Profile

Bug #5425 » bladerf_source_c_fix.cc

aoweis, 01/28/2022 06:32 PM

 
1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2013-2017 Nuand LLC
4
 * Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
5
 *
6
 * GNU Radio is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3, or (at your option)
9
 * any later version.
10
 *
11
 * GNU Radio is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GNU Radio; see the file COPYING.  If not, write to
18
 * the Free Software Foundation, Inc., 51 Franklin Street,
19
 * Boston, MA 02110-1301, USA.
20
 */
21

    
22
/*
23
 * config.h is generated by configure.  It contains the results
24
 * of probing for features, options etc.  It should be the first
25
 * file included in your .cc file.
26
 */
27
#ifdef HAVE_CONFIG_H
28
#include "config.h"
29
#endif
30

    
31
#include <iostream>
32

    
33
#include <boost/assign.hpp>
34
#include <boost/format.hpp>
35
#include <boost/lexical_cast.hpp>
36

    
37
#include <gnuradio/io_signature.h>
38

    
39
#include <volk/volk.h>
40

    
41
#include "arg_helpers.h"
42
#include "bladerf_source_c.h"
43
#include "osmosdr/source.h"
44

    
45
using namespace boost::assign;
46

    
47
/******************************************************************************
48
 * Functions
49
 ******************************************************************************/
50

    
51
/*
52
 * Create a new instance of bladerf_source_c and return
53
 * a boost shared_ptr.  This is effectively the public constructor.
54
 */
55
bladerf_source_c_sptr make_bladerf_source_c(const std::string &args)
56
{
57
  return gnuradio::get_initial_sptr(new bladerf_source_c(args));
58
}
59

    
60
/******************************************************************************
61
 * Private methods
62
 ******************************************************************************/
63

    
64
/*
65
 * The private constructor
66
 */
67
bladerf_source_c::bladerf_source_c(const std::string &args) :
68
  gr::sync_block( "bladerf_source_c",
69
                  gr::io_signature::make(0, 0, 0),
70
                  args_to_io_signature(args)),
71
  _16icbuf(NULL),
72
  _32fcbuf(NULL),
73
  _running(false),
74
  _agcmode(BLADERF_GAIN_DEFAULT)
75
{
76
  int status;
77

    
78
  dict_t dict = params_to_dict(args);
79

    
80
  /* Perform src/sink agnostic initializations */
81
  init(dict, BLADERF_RX);
82

    
83
  /* Handle setting of sampling mode */
84
  if (dict.count("sampling")) {
85
    bladerf_sampling sampling = BLADERF_SAMPLING_UNKNOWN;
86

    
87
    if (dict["sampling"] == "internal") {
88
      sampling = BLADERF_SAMPLING_INTERNAL;
89
    } else if (dict["sampling"] == "external") {
90
      sampling = BLADERF_SAMPLING_EXTERNAL;
91
    } else {
92
      BLADERF_WARNING("Invalid sampling mode: " + dict["sampling"]);
93
    }
94

    
95
    if (sampling != BLADERF_SAMPLING_UNKNOWN) {
96
      status = bladerf_set_sampling(_dev.get(), sampling);
97
      if (status != 0) {
98
        BLADERF_WARNING("Problem while setting sampling mode: " <<
99
                        bladerf_strerror(status));
100
      }
101
    }
102
  }
103

    
104
  /* Bias tee */
105
  if (dict.count("biastee")) {
106
    set_biastee_mode(dict["biastee"]);
107
  }
108

    
109
  /* Loopback */
110
  set_loopback_mode(dict.count("loopback") ? dict["loopback"] : "none");
111

    
112
  /* RX Mux */
113
  set_rx_mux_mode(dict.count("rxmux") ? dict["rxmux"] : "baseband");
114

    
115
  /* AGC mode */
116
  if (dict.count("agc_mode")) {
117
    set_agc_mode(dict["agc_mode"]);
118
  }
119

    
120
  /* Specify initial gain mode */
121
  if (dict.count("agc")) {
122
    for (size_t i = 0; i < get_max_channels(); ++i) {
123
      set_gain_mode(boost::lexical_cast<bool>(dict["agc"]), BLADERF_CHANNEL_RX(i));
124
      BLADERF_INFO(boost::str(boost::format("%s gain mode set to '%s'")
125
                    % channel2str(BLADERF_CHANNEL_RX(i))
126
                    % get_gain_mode(BLADERF_CHANNEL_RX(i))));
127
    }
128
  }
129

    
130
  /* Warn user about using an old FPGA version, as we no longer strip off the
131
   * markers that were pressent in the pre-v0.0.1 FPGA */
132
  {
133
    struct bladerf_version fpga_version;
134

    
135
    if (bladerf_fpga_version(_dev.get(), &fpga_version) != 0) {
136
      BLADERF_WARNING("Failed to get FPGA version");
137
    } else if (fpga_version.major <= 0 &&
138
               fpga_version.minor <= 0 &&
139
               fpga_version.patch < 1) {
140
      BLADERF_WARNING("Warning: FPGA version v0.0.1 or later is required. "
141
                      "Using an earlier FPGA version will result in "
142
                      "misinterpeted samples.");
143
    }
144
  }
145

    
146
  /* Initialize channel <-> antenna map */
147
  BOOST_FOREACH(std::string ant, get_antennas()) {
148
    _chanmap[str2channel(ant)] = -1;
149
  }
150

    
151
  /* Bounds-checking output signature depending on our underlying hardware */
152
  if (get_num_channels() > get_max_channels()) {
153
    BLADERF_WARNING("Warning: number of channels specified on command line ("
154
                    << get_num_channels() << ") is greater than the maximum "
155
                    "number supported by this device (" << get_max_channels()
156
                    << "). Resetting to " << get_max_channels() << ".");
157

    
158
    set_output_signature(gr::io_signature::make(get_max_channels(),
159
                                                get_max_channels(),
160
                                                sizeof(gr_complex)));
161
  }
162

    
163
  /* Set up constraints */
164
  int const alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
165
  set_alignment(std::max(1,alignment_multiple));
166
  set_max_noutput_items(_samples_per_buffer);
167
  set_output_multiple(get_num_channels());
168

    
169
  /* Set channel layout */
170
  _layout = (get_num_channels() > 1) ? BLADERF_RX_X2 : BLADERF_RX_X1;
171

    
172
  /* Initial wiring of antennas to channels */
173
  for (size_t ch = 0; ch < get_num_channels(); ++ch) {
174
    set_channel_enable(BLADERF_CHANNEL_RX(ch), true);
175
    _chanmap[BLADERF_CHANNEL_RX(ch)] = ch;
176
  }
177

    
178
  BLADERF_DEBUG("initialization complete");
179
}
180

    
181
bool bladerf_source_c::is_antenna_valid(const std::string &antenna)
182
{
183
  BOOST_FOREACH(std::string ant, get_antennas()) {
184
    if (antenna == ant) {
185
      return true;
186
    }
187
  }
188

    
189
  return false;
190
}
191

    
192
/******************************************************************************
193
 * Public methods
194
 ******************************************************************************/
195

    
196
std::string bladerf_source_c::name()
197
{
198
  return "bladeRF receiver";
199
}
200

    
201
std::vector<std::string> bladerf_source_c::get_devices()
202
{
203
  return bladerf_common::devices();
204
}
205

    
206
size_t bladerf_source_c::get_max_channels()
207
{
208
  return bladerf_common::get_max_channels(BLADERF_RX);
209
}
210

    
211
size_t bladerf_source_c::get_num_channels()
212
{
213
  return output_signature()->max_streams();
214
}
215

    
216
bool bladerf_source_c::start()
217
{
218
  int status;
219

    
220
  BLADERF_DEBUG("starting source");
221

    
222
  gr::thread::scoped_lock guard(d_mutex);
223

    
224
  status = bladerf_sync_config(_dev.get(), _layout, _format, _num_buffers,
225
                               _samples_per_buffer, _num_transfers,
226
                               _stream_timeout);
227
  if (status != 0) {
228
    BLADERF_THROW_STATUS(status, "bladerf_sync_config failed");
229
  }
230

    
231
  for (size_t ch = 0; ch < get_max_channels(); ++ch) {
232
    bladerf_channel brfch = BLADERF_CHANNEL_RX(ch);
233
    if (get_channel_enable(brfch)) {
234
      status = bladerf_enable_module(_dev.get(), brfch, true);
235
      if (status != 0) {
236
        BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
237
      }
238
    }
239
  }
240

    
241
  /* Allocate memory for conversions in work() */
242
  size_t alignment = volk_get_alignment();
243

    
244
  _16icbuf = reinterpret_cast<int16_t *>(volk_malloc(4*_samples_per_buffer*sizeof(int16_t), alignment));
245
  _32fcbuf = reinterpret_cast<gr_complex *>(volk_malloc(2*_samples_per_buffer*sizeof(gr_complex), alignment));
246

    
247
  _running = true;
248

    
249
  return true;
250
}
251

    
252
bool bladerf_source_c::stop()
253
{
254
  int status;
255

    
256
  BLADERF_DEBUG("stopping source");
257

    
258
  gr::thread::scoped_lock guard(d_mutex);
259

    
260
  if (!_running) {
261
    BLADERF_WARNING("source already stopped, nothing to do here");
262
    return true;
263
  }
264

    
265
  _running = false;
266

    
267
  for (size_t ch = 0; ch < get_max_channels(); ++ch) {
268
    bladerf_channel brfch = BLADERF_CHANNEL_RX(ch);
269
    if (get_channel_enable(brfch)) {
270
      status = bladerf_enable_module(_dev.get(), brfch, false);
271
      if (status != 0) {
272
        BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
273
      }
274
    }
275
  }
276

    
277
  /* Deallocate conversion memory */
278
  volk_free(_16icbuf);
279
  volk_free(_32fcbuf);
280
  _16icbuf = NULL;
281
  _32fcbuf = NULL;
282

    
283
  return true;
284
}
285

    
286
int bladerf_source_c::work(int noutput_items,
287
                          gr_vector_const_void_star &input_items,
288
                          gr_vector_void_star &output_items)
289
{
290
  int status;
291
  struct bladerf_metadata meta;
292
  struct bladerf_metadata *meta_ptr = NULL;
293
  size_t nstreams = num_streams(_layout);
294

    
295
  gr::thread::scoped_lock guard(d_mutex);
296

    
297
  // if we aren't running, nothing to do here
298
  if (!_running) {
299
    return 0;
300
  }
301

    
302
  // set up metadata
303
  if (BLADERF_FORMAT_SC16_Q11_META == _format) {
304
    memset(&meta, 0, sizeof(meta));
305
    meta.flags = BLADERF_META_FLAG_RX_NOW;
306
    meta_ptr = &meta;
307
  }
308

    
309
  // grab samples into temp buffer
310
  if(nstreams > 1)
311
    status = bladerf_sync_rx(_dev.get(), static_cast<void *>(_16icbuf), 2 * noutput_items, meta_ptr, _stream_timeout);
312
  else
313
    status = bladerf_sync_rx(_dev.get(), static_cast<void *>(_16icbuf), noutput_items, meta_ptr, _stream_timeout);
314

    
315
  if (status != 0) {
316
    BLADERF_WARNING(boost::str(boost::format("bladerf_sync_rx error: %s")
317
                    % bladerf_strerror(status)));
318
    ++_failures;
319

    
320
    if (_failures >= MAX_CONSECUTIVE_FAILURES) {
321
      BLADERF_WARNING("Consecutive error limit hit. Shutting down.");
322
      return WORK_DONE;
323
    }
324
  } else {
325
    _failures = 0;
326
  }
327

    
328
  // convert from int16_t to float
329
  // output_items is gr_complex (2x float), so num_points is 2*noutput_items
330
  volk_16i_s32f_convert_32f(reinterpret_cast<float *>(_32fcbuf), _16icbuf, SCALING_FACTOR, 4*noutput_items);
331

    
332
  // copy the samples into output_items
333
  gr_complex **out = reinterpret_cast<gr_complex **>(&output_items[0]);
334

    
335
  if (nstreams > 1) {
336
    // we need to deinterleave the multiplex as we copy
337
    gr_complex const *deint_in = _32fcbuf;
338

    
339
    for (size_t i = 0; i < noutput_items; ++i) {
340
      for (size_t n = 0; n < nstreams; ++n) {
341
        memcpy(out[n]++, deint_in++, sizeof(gr_complex));
342
      }
343
    }
344
  } else {
345
    // no deinterleaving to do: simply copy everything
346
    memcpy(out[0], _32fcbuf, sizeof(gr_complex) * noutput_items);
347
  }
348

    
349
  return noutput_items;
350
}
351

    
352
osmosdr::meta_range_t bladerf_source_c::get_sample_rates()
353
{
354
  return sample_rates(chan2channel(BLADERF_RX, 0));
355
}
356

    
357
double bladerf_source_c::set_sample_rate(double rate)
358
{
359
  return bladerf_common::set_sample_rate(rate, chan2channel(BLADERF_RX, 0));
360
}
361

    
362
double bladerf_source_c::get_sample_rate()
363
{
364
  return bladerf_common::get_sample_rate(chan2channel(BLADERF_RX, 0));
365
}
366

    
367
osmosdr::freq_range_t bladerf_source_c::get_freq_range(size_t chan)
368
{
369
  return bladerf_common::freq_range(chan2channel(BLADERF_RX, chan));
370
}
371

    
372
double bladerf_source_c::set_center_freq(double freq, size_t chan)
373
{
374
  return bladerf_common::set_center_freq(freq, chan2channel(BLADERF_RX, chan));
375
}
376

    
377
double bladerf_source_c::get_center_freq(size_t chan)
378
{
379
  return bladerf_common::get_center_freq(chan2channel(BLADERF_RX, chan));
380
}
381

    
382
double bladerf_source_c::set_freq_corr(double ppm, size_t chan)
383
{
384
  /* TODO: Write the VCTCXO with a correction value (also changes TX ppm value!) */
385
  BLADERF_WARNING("Frequency correction is not implemented.");
386
  return get_freq_corr(chan2channel(BLADERF_RX, chan));
387
}
388

    
389
double bladerf_source_c::get_freq_corr(size_t chan)
390
{
391
  /* TODO: Return back the frequency correction in ppm */
392
  return 0;
393
}
394

    
395
std::vector<std::string> bladerf_source_c::get_gain_names(size_t chan)
396
{
397
  return bladerf_common::get_gain_names(chan2channel(BLADERF_RX, chan));
398
}
399

    
400
osmosdr::gain_range_t bladerf_source_c::get_gain_range(size_t chan)
401
{
402
  return bladerf_common::get_gain_range(chan2channel(BLADERF_RX, chan));
403
}
404

    
405
osmosdr::gain_range_t bladerf_source_c::get_gain_range(const std::string &name,
406
                                                       size_t chan)
407
{
408
  return bladerf_common::get_gain_range(name, chan2channel(BLADERF_RX, chan));
409
}
410

    
411
bool bladerf_source_c::set_gain_mode(bool automatic, size_t chan)
412
{
413
  return bladerf_common::set_gain_mode(automatic,
414
                                       chan2channel(BLADERF_RX, chan),
415
                                       _agcmode);
416
}
417

    
418
bool bladerf_source_c::get_gain_mode(size_t chan)
419
{
420
  return bladerf_common::get_gain_mode(chan2channel(BLADERF_RX, chan));
421
}
422

    
423
double bladerf_source_c::set_gain(double gain, size_t chan)
424
{
425
  return bladerf_common::set_gain(gain, chan2channel(BLADERF_RX, chan));
426
}
427

    
428
double bladerf_source_c::set_gain(double gain, const std::string &name,
429
                                  size_t chan)
430
{
431
  return bladerf_common::set_gain(gain, name, chan2channel(BLADERF_RX, chan));
432
}
433

    
434
double bladerf_source_c::get_gain(size_t chan)
435
{
436
  return bladerf_common::get_gain(chan2channel(BLADERF_RX, chan));
437
}
438

    
439
double bladerf_source_c::get_gain(const std::string &name, size_t chan)
440
{
441
  return bladerf_common::get_gain(name, chan2channel(BLADERF_RX, chan));
442
}
443

    
444
std::vector<std::string> bladerf_source_c::get_antennas(size_t chan)
445
{
446
  return bladerf_common::get_antennas(BLADERF_RX);
447
}
448

    
449
std::string bladerf_source_c::set_antenna(const std::string &antenna,
450
                                          size_t chan)
451
{
452
  bool _was_running = _running;
453

    
454
  if (_was_running) {
455
    stop();
456
  }
457

    
458
  bladerf_common::set_antenna(BLADERF_RX, chan, antenna);
459

    
460
  if (_was_running) {
461
    start();
462
  }
463

    
464
  return get_antenna(chan);
465
}
466

    
467
std::string bladerf_source_c::get_antenna(size_t chan)
468
{
469
  return channel2str(chan2channel(BLADERF_RX, chan));
470
}
471

    
472
void bladerf_source_c::set_dc_offset_mode(int mode, size_t chan)
473
{
474
  if (osmosdr::source::DCOffsetOff == mode) {
475
    //_src->set_auto_dc_offset( false, chan );
476
    /* reset to default for off-state */
477
    set_dc_offset(std::complex<double>(0.0, 0.0), chan);
478
  } else if (osmosdr::source::DCOffsetManual == mode) {
479
    /* disable auto mode, but keep correcting with last known values */
480
    //_src->set_auto_dc_offset( false, chan );
481
  } else if (osmosdr::source::DCOffsetAutomatic == mode) {
482
    //_src->set_auto_dc_offset( true, chan );
483
    BLADERF_WARNING("Automatic DC correction mode is not implemented.");
484
  }
485
}
486

    
487
void bladerf_source_c::set_dc_offset(const std::complex<double> &offset,
488
                                     size_t chan)
489
{
490
  int status;
491

    
492
  status = bladerf_common::set_dc_offset(offset, chan2channel(BLADERF_RX, chan));
493

    
494
  if (status != 0) {
495
    BLADERF_THROW_STATUS(status, "could not set dc offset");
496
  }
497
}
498

    
499
void bladerf_source_c::set_iq_balance_mode(int mode, size_t chan)
500
{
501
  if (osmosdr::source::IQBalanceOff == mode) {
502
    //_src->set_auto_iq_balance( false, chan );
503
    /* reset to default for off-state */
504
    set_iq_balance(std::complex<double>(0.0, 0.0), chan);
505
  } else if (osmosdr::source::IQBalanceManual == mode) {
506
    /* disable auto mode, but keep correcting with last known values */
507
    //_src->set_auto_iq_balance( false, chan );
508
  } else if (osmosdr::source::IQBalanceAutomatic == mode) {
509
    //_src->set_auto_iq_balance( true, chan );
510
    BLADERF_WARNING("Automatic IQ correction mode is not implemented.");
511
  }
512
}
513

    
514
void bladerf_source_c::set_iq_balance(const std::complex<double> &balance,
515
                                      size_t chan)
516
{
517
  int status;
518

    
519
  status = bladerf_common::set_iq_balance(balance, chan2channel(BLADERF_RX, chan));
520

    
521
  if (status != 0) {
522
    BLADERF_THROW_STATUS(status, "could not set iq balance");
523
  }
524
}
525

    
526
osmosdr::freq_range_t bladerf_source_c::get_bandwidth_range(size_t chan)
527
{
528
  return filter_bandwidths(chan2channel(BLADERF_RX, chan));
529
}
530

    
531
double bladerf_source_c::set_bandwidth(double bandwidth, size_t chan)
532
{
533
  return bladerf_common::set_bandwidth(bandwidth,
534
                                       chan2channel(BLADERF_RX, chan));
535
}
536

    
537
double bladerf_source_c::get_bandwidth(size_t chan)
538
{
539
  return bladerf_common::get_bandwidth(chan2channel(BLADERF_RX, chan));
540
}
541

    
542
std::vector<std::string> bladerf_source_c::get_clock_sources(size_t mboard)
543
{
544
  return bladerf_common::get_clock_sources(mboard);
545
}
546

    
547
void bladerf_source_c::set_clock_source(const std::string &source,
548
                                        size_t mboard)
549
{
550
  bladerf_common::set_clock_source(source, mboard);
551
}
552

    
553
std::string bladerf_source_c::get_clock_source(size_t mboard)
554
{
555
  return bladerf_common::get_clock_source(mboard);
556
}
557

    
558
void bladerf_source_c::set_biastee_mode(const std::string &mode)
559
{
560
  int status;
561
  bool enable;
562

    
563
  if (mode == "on" || mode == "1" || mode == "rx") {
564
    enable = true;
565
  } else {
566
    enable = false;
567
  }
568

    
569
  status = bladerf_set_bias_tee(_dev.get(), BLADERF_CHANNEL_RX(0), enable);
570
  if (BLADERF_ERR_UNSUPPORTED == status) {
571
    // unsupported, but not worth crashing out
572
    BLADERF_WARNING("Bias-tee not supported by device");
573
  } else if (status != 0) {
574
    BLADERF_THROW_STATUS(status, "Failed to set bias-tee");
575
  }
576
}
577

    
578
void bladerf_source_c::set_loopback_mode(const std::string &loopback)
579
{
580
  int status;
581
  bladerf_loopback mode;
582

    
583
  if (loopback == "bb_txlpf_rxvga2") {
584
    mode = BLADERF_LB_BB_TXLPF_RXVGA2;
585
  } else if (loopback == "bb_txlpf_rxlpf") {
586
    mode = BLADERF_LB_BB_TXLPF_RXLPF;
587
  } else if (loopback == "bb_txvga1_rxvga2") {
588
    mode = BLADERF_LB_BB_TXVGA1_RXVGA2;
589
  } else if (loopback == "bb_txvga1_rxlpf") {
590
    mode = BLADERF_LB_BB_TXVGA1_RXLPF;
591
  } else if (loopback == "rf_lna1") {
592
    mode = BLADERF_LB_RF_LNA1;
593
  } else if (loopback == "rf_lna2") {
594
    mode = BLADERF_LB_RF_LNA2;
595
  } else if (loopback == "rf_lna3") {
596
    mode = BLADERF_LB_RF_LNA3;
597
  } else if (loopback == "firmware") {
598
    mode = BLADERF_LB_FIRMWARE;
599
  } else if (loopback == "rfic_bist") {
600
    mode = BLADERF_LB_RFIC_BIST;
601
  } else if (loopback == "none") {
602
    mode = BLADERF_LB_NONE;
603
  } else {
604
    BLADERF_THROW("Unknown loopback mode: " + loopback);
605
  }
606

    
607
  status = bladerf_set_loopback(_dev.get(), mode);
608
  if (BLADERF_ERR_UNSUPPORTED == status) {
609
    // unsupported, but not worth crashing out
610
    BLADERF_WARNING("Loopback mode not supported by device: " + loopback);
611
  } else if (status != 0) {
612
    BLADERF_THROW_STATUS(status, "Failed to set loopback mode");
613
  }
614
}
615

    
616
void bladerf_source_c::set_rx_mux_mode(const std::string &rxmux)
617
{
618
  int status;
619
  bladerf_rx_mux mode;
620

    
621
  if (rxmux == "baseband") {
622
    mode = BLADERF_RX_MUX_BASEBAND;
623
  } else if (rxmux == "12bit") {
624
    mode = BLADERF_RX_MUX_12BIT_COUNTER;
625
  } else if (rxmux == "32bit") {
626
    mode = BLADERF_RX_MUX_32BIT_COUNTER;
627
  } else if (rxmux == "digital") {
628
    mode = BLADERF_RX_MUX_DIGITAL_LOOPBACK;
629
  } else {
630
    BLADERF_THROW("Unknown RX mux mode: " + rxmux);
631
  }
632

    
633
  status = bladerf_set_rx_mux(_dev.get(), mode);
634
  if (BLADERF_ERR_UNSUPPORTED == status) {
635
    // unsupported, but not worth crashing out
636
    BLADERF_WARNING("RX mux mode not supported by device: " + rxmux);
637
  } else if (status != 0) {
638
    BLADERF_THROW_STATUS(status, "Failed to set RX mux mode");
639
  }
640
}
641

    
642
void bladerf_source_c::set_agc_mode(const std::string &agcmode)
643
{
644
#ifndef BLADERF_COMPATIBILITY
645
  int status;
646
  bladerf_gain_mode mode;
647
  bool ok = false;
648
  struct bladerf_gain_modes const *modes = NULL;
649

    
650
  /* Get the list of AGC modes */
651
  status = bladerf_get_gain_modes(_dev.get(), BLADERF_CHANNEL_RX(0), &modes);
652
  if (status < 0) {
653
    BLADERF_THROW_STATUS(status, "failed to get gain modes");
654
  }
655

    
656
  size_t count = status;
657

    
658
  /* Compare... */
659
  for (size_t i = 0; i < count; ++i) {
660
    if (agcmode == std::string(modes[i].name)) {
661
      mode = modes[i].mode;
662
      ok = true;
663
      BLADERF_DEBUG("Setting gain mode to " << mode << " (" << agcmode << ")");
664
      break;
665
    }
666
  }
667

    
668
  if (!ok) {
669
    BLADERF_WARNING("Unknown gain mode \"" << agcmode << "\"");
670
    return;
671
  }
672

    
673
  _agcmode = mode;
674

    
675
  for (size_t i = 0; i < get_num_channels(); ++i) {
676
    if (bladerf_common::get_gain_mode(BLADERF_CHANNEL_RX(i))) {
677
      /* Refresh this */
678
      bladerf_common::set_gain_mode(true, BLADERF_CHANNEL_RX(i), _agcmode);
679
    }
680
  }
681
#endif
682
}
(1-1/2)
Add picture from clipboard (Maximum size: 48.8 MB)