SoDaRadio-5.0.3-master:8901fb5
USRPCtrl.cxx
Go to the documentation of this file.
1 /*
2  Copyright (c) 2012, Matthew H. Reilly (kb1vc)
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include "USRPCtrl.hxx"
30 #include "SoDaBase.hxx"
31 #include "USRPFrontEnd.hxx"
32 #include <uhd/utils/thread_priority.hpp>
33 #include <uhd/utils/safe_main.hpp>
34 #include <uhd/usrp/multi_usrp.hpp>
35 #include <uhd/usrp/multi_usrp.hpp>
36 #include <uhd/utils/msg.hpp>
37 #include <uhd/types/tune_request.hpp>
38 #include <uhd/types/tune_result.hpp>
39 #include <boost/format.hpp>
40 #include <boost/property_tree/exceptions.hpp>
41 
42 
43 // Mac OSX doesn't have a clock_gettime, it has
44 // the microsecond resolution gettimeofday.
45 #include <sys/time.h>
46 
47 const unsigned int SoDa::USRPCtrl::TX_RELAY_CTL = 0x1000;
48 const unsigned int SoDa::USRPCtrl::TX_RELAY_MON = 0x0800;
49 
50 const double SoDa::USRPCtrl::rxmode_offset = 1.0e6;
51 
52 
54 
55 SoDa::USRPCtrl::USRPCtrl(Params * _params, CmdMBox * _cmd_stream) : SoDa::SoDaThread("USRPCtrl")
56 {
57  // point to myself....
58  SoDa::USRPCtrl::singleton_ctrl_obj = this;
59 
60  // setup a normal message handler that doesn't babble
61  // so much.
62  uhd::msg::register_handler(normal_message_handler);
63 
64  // initialize variables
65  last_rx_req_freq = 0.0; // at least this is a number...
66  tx_on = false;
67  first_gettime = 0.0;
68  rx_rf_gain = 0.0;
69  tx_rf_gain = 0.0;
70  tx_freq = 0.0;
72  tx_samp_rate = 625000;
73  tx_ant = std::string("TX");
74  motherboard_name = std::string("UNKNOWN_MB");
75 
76  cmd_stream = _cmd_stream;
77  params = _params;
78 
79  // subscribe to the command stream.
81 
82  // make the device.
83  usrp = uhd::usrp::multi_usrp::make(params->getRadioArgs());
84 
85  if(usrp == NULL) {
86  throw SoDaException((boost::format("Unable to allocate USRP unit with arguments = [%]\n") % params->getRadioArgs()).str(), this);
87  }
88 
89  // We need to find out if this is a B2xx or something like it -- they don't
90  // have daughter cards and there are other things to watch out for....
91  PropTree tree(usrp, getObjName());
92 
93  motherboard_name = tree.getStringProp("name", "unknown");
94 
95  if((motherboard_name == "B200") || (motherboard_name == "B210")) {
96  // B2xx needs a master clock rate of 50 MHz to generate a sample rate of 625 kS/s.
97  // B2xx needs a master clock rate of 25 MHz to generate a sample rate of 625 kS/s.
98  usrp->set_master_clock_rate(25.0e6);
99  debugMsg(boost::format("Initial setup %s") % usrp->get_pp_string());
100  is_B2xx = true;
101  is_B210 = (motherboard_name == "B210");
102  }
103  else {
104  is_B2xx = false;
105  is_B210 = false;
106  }
107 
108  // we need to setup the subdevices
109  if(is_B2xx) {
110  usrp->set_rx_subdev_spec(std::string("A:A"), 0);
111  std::cerr << "DISABLING TVRT LO" << std::endl;
112  if(0 && is_B210) {
113  debugMsg("Setup two subdevices -- TVRT_LO Capable");
114  usrp->set_tx_subdev_spec(std::string("A:A A:B"), 0);
115  tvrt_lo_capable = true;
116  }
117  else {
118  debugMsg("Setup one subdevice -- NOT TVRT_LO Capable");
119  usrp->set_tx_subdev_spec(std::string("A:A"), 0);
120  tvrt_lo_capable = false;
121  }
122  }
123  else {
124  debugMsg("Setup one subdevice -- NOT TVRT_LO Capable");
125  tvrt_lo_capable = false;
126  }
127 
128  first_gettime = 0.0;
129  double tmp = getTime();
130  // truncate to whole number of seconds -- paranoia
131  first_gettime = floor(tmp);
132 
133  // get the tx front end subtree
134  tx_fe_has_enable = false;
135  tx_fe_subtree = getUSRPFrontEnd(tree, 'T');
136 
137  // do we care? If the tx_fe_subtree doesn't have an enable property,
138  // we want to avoid setting and getting it....
139  if(tx_fe_subtree != NULL) {
141 #if 0
142  std::cerr << "Testing for tx power_mode prop." << std::endl;
143  if(tx_fe_subtree->hasProperty("power_mode")) {
144  std::cerr << "Found for tx power_mode prop." << std::endl;
145  tx_fe_subtree->setStringProp("power_mode/value","powersave"); // "performance");
146  }
147 #endif
148  }
149 
150 
151  // get the rx front end subtree
152  rx_fe_has_enable = false;
153  rx_fe_subtree = getUSRPFrontEnd(tree, 'R');
154 
155  // do we care? If the rx_fe_subtree doesn't have an enable property,
156  // we want to avoid setting and getting it....
157  if(rx_fe_subtree != NULL) {
159 #if 0
160  if(rx_fe_subtree->hasProperty("power_mode")) {
161  std::cerr << "*****Setting power save mode for RX front end.******" << std::endl;
162  // powersave may be the right choice, see
163  // http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/2016-April/019784.html
164  rx_fe_subtree->setStringProp("power_mode/value","powersave"); // "performance");
165  }
166 #endif
167  }
168  if(rx_fe_has_enable) rx_fe_subtree->setBoolProp("enabled",true);
169 
170 
171  // do we have lock sensors?
172  std::vector<std::string> rx_snames, tx_snames;
173  rx_snames = usrp->get_rx_sensor_names(0);
174  tx_snames = usrp->get_tx_sensor_names(0);
175  rx_has_lo_locked_sensor = std::find(rx_snames.begin(), rx_snames.end(), "lo_locked") != rx_snames.end();
176  tx_has_lo_locked_sensor = std::find(tx_snames.begin(), tx_snames.end(), "lo_locked") != tx_snames.end();
177 
178 
179  // find the gain ranges
180  rx_rf_gain_range = usrp->get_rx_gain_range();
181  tx_rf_gain_range = usrp->get_tx_gain_range();
182 
183  // find the frequency ranges
184  rx_rf_freq_range = usrp->get_rx_freq_range();
185  tx_rf_freq_range = usrp->get_tx_freq_range();
186 
187  // set the sample rates
188  usrp->set_rx_rate(params->getRXRate());
189  usrp->set_tx_rate(params->getTXRate());
190 
191  // setup the control IO pins (for TX/RX external relay)
192  // Note that there are no GPIOs available for the B2xx right now.
193  initControlGPIO();
194 
195  // setup a widget to control external devices
197 
198  // turn off the transmitter
199  setTXEna(false);
200 
201  // turn of the LO
202  tvrt_lo_mode = false;
203 
204  // if we are in integer-N mode, setup the step table.
206 }
207 
208 
210 {
211  uhd::set_thread_priority_safe();
212  // now do the event loop. we watch
213  // for commands and responses on the command stream.
214 
215  // do the initial commands
217  params->getRXRate()));
219  params->getTXRate()));
220 
222  params->getRXAnt()));
223  debugMsg(boost::format("Sending TX_ANT as [%s]\n") % params->getTXAnt());
225  params->getTXAnt()));
227  params->getClockSource()));
228 
231 
233 
234  // transmitter is off
235  tx_on = false;
237 
238  bool exitflag = false;
239  unsigned int cmds_processed = 0;
240  unsigned int loopcount = 0;
241  while(!exitflag) {
242  loopcount++;
243  Command * cmd = cmd_stream->get(subid);
244  if(cmd == NULL) {
245  boost::this_thread::sleep(boost::posix_time::milliseconds(50));
246  }
247  else {
248  // process the command.
249  if((cmds_processed & 0xff) == 0) {
250  debugMsg(boost::format("USRPCtrl processed %d commands") % cmds_processed);
251  }
252  cmds_processed++;
253  execCommand(cmd);
254  exitflag |= (cmd->target == Command::STOP);
255  cmd_stream->free(cmd);
256  }
257  }
258 }
259 
261 {
262  double ret;
263  struct timeval tv;
264  gettimeofday(&tv, NULL);
265  ret = (((double) tv.tv_sec) - first_gettime) + 1.0e-6*((double) tv.tv_usec);
266  return ret;
267 }
268 
270 {
271  switch (cmd->cmd) {
272  case Command::GET:
273  execGetCommand(cmd);
274  break;
275  case Command::SET:
276  execSetCommand(cmd);
277  break;
278  case Command::REP:
279  execRepCommand(cmd);
280  break;
281  default:
282  break;
283  }
284 }
285 
286 uhd::tune_result_t SoDa::USRPCtrl::checkLock(uhd::tune_request_t & req, char sel, uhd::tune_result_t & cur)
287 {
288  int lock_itercount = 0;
289  uhd::tune_result_t ret = cur;
290 
291  // not all front ends even have LOs....
292  if(!((sel == 'r') ? rx_has_lo_locked_sensor : tx_has_lo_locked_sensor)) {
293  return cur;
294  }
295 
296  while(1) {
297  uhd::sensor_value_t lo_locked = (sel == 'r') ? usrp->get_rx_sensor("lo_locked",0) : usrp->get_tx_sensor("lo_locked",0);
298  if(lo_locked.to_bool()) break;
299  else usleep(1000);
300  if((lock_itercount & 0xfff) == 0) {
301  debugMsg(boost::format("Waiting for %c LO lock to freq = %f (%f:%f) count = %d\n")
302  % sel % req.target_freq % req.rf_freq % req.dsp_freq % lock_itercount);
303  if(sel == 'r') ret = usrp->set_rx_freq(req);
304  else ret = usrp->set_tx_freq(req);
305  }
306  lock_itercount++;
307  }
308 
309  return ret;
310 }
311 
312 void SoDa::USRPCtrl::set1stLOFreq(double freq, char sel, bool set_if_freq)
313 {
314  // select "r" for rx and "t" for tx.
315  // We only want to tune for one band :: 2m 144 to 148.
316  // well... not really... I'd like to tune to 432 as well.
317  // well.... this really should be made to work for all freqs.
318  //
319 
320  double target_rx_freq;
321 
322 
323  if(sel == 'r') {
324  // we round the target frequency to a point that puts the
325  // baseband between 150 and 250 KHz below the requested
326  // frequency. and an even 100kHz multiple.
327 
328  // we need to fiddle this a bit, as we can hang the radio if
329  // the requested frequency is out of range...
330  if(freq < rx_rf_freq_range.start()) freq = rx_rf_freq_range.start();
331  if(freq > rx_rf_freq_range.stop()) freq = rx_rf_freq_range.stop();
332 
333  target_rx_freq = freq;
334 
335  target_rx_freq = 100e3 * floor(freq / 100e3);
336  debugMsg(boost::format("freq = %lf 1st target = %lf\n") % freq % target_rx_freq);
337  while((freq - target_rx_freq) < 100e3) {
338  target_rx_freq -= 100.0e3;
339  debugMsg(boost::format("\tfreq = %lf new target = %lf\n") % freq % target_rx_freq);
340  }
341 
346  uhd::tune_request_t rx_trequest(target_rx_freq);
347  if(supports_IntN_Mode) {
348  // look for a good target RX freq that doesn't cause inband/nearband spurs...
349  applyTargetFreqCorrection(target_rx_freq, target_rx_freq, &rx_trequest);
350  debugMsg(boost::format("\t*****target_rx_freq = %lf corrected to %lf\n")
351  % target_rx_freq % rx_trequest.rf_freq);
352  }
353  else {
354  // just use the vanilla tuning....
355  rx_trequest.target_freq = target_rx_freq;
356  rx_trequest.rf_freq = target_rx_freq;
357  rx_trequest.rf_freq_policy = uhd::tune_request_t::POLICY_AUTO;
358  rx_trequest.dsp_freq_policy = uhd::tune_request_t::POLICY_AUTO;
359  }
360 
361  last_rx_tune_result = usrp->set_rx_freq(rx_trequest);
363  debugMsg(boost::format("RX Tune RF_actual %lf DDC = %lf tuned = %lf target = %lf request rf = %lf request ddc = %lf\n")
364  % last_rx_tune_result.actual_rf_freq
365  % last_rx_tune_result.actual_dsp_freq
366  % freq
367  % target_rx_freq
368  % rx_trequest.rf_freq
369  % rx_trequest.dsp_freq);
370  }
371  else {
372  // On the transmit side, we're using a minimal IF rate and
373  // using the full range of the tuning hardware.
374 
375  // If the transmitter is off, we retune anyway to park the
376  // transmit LO as far away as possible. This is especially
377  // important for the UBX.
378  if(freq < tx_rf_freq_range.start()) freq = tx_rf_freq_range.start();
379  if(freq > tx_rf_freq_range.stop()) freq = tx_rf_freq_range.stop();
380 
381 
382  uhd::tune_request_t tx_request(freq);
383 
384  if(tvrt_lo_mode) {
385  tx_request.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
386  tx_request.rf_freq = tvrt_lo_fe_freq;
387  }
388  else if(supports_IntN_Mode) {
389  applyTargetFreqCorrection(freq, last_rx_req_freq, &tx_request);
390  }
391  else {
392  tx_request.rf_freq_policy = uhd::tune_request_t::POLICY_AUTO;
393  }
394 
395  debugMsg(boost::format("Tuning TX unit to new frequency %f (request = %f (%f %f))\n")
396  % freq % tx_request.target_freq % tx_request.rf_freq % tx_request.dsp_freq);
397 
398  last_tx_tune_result = usrp->set_tx_freq(tx_request);
399 
400  debugMsg(boost::format("Tuned TX unit to new frequency %g t.rf %g a.rf %g t.dsp %g a.dsp %g\n")
401  % freq
402  % last_tx_tune_result.target_rf_freq
403  % last_tx_tune_result.actual_rf_freq
404  % last_tx_tune_result.target_dsp_freq
405  % last_tx_tune_result.actual_dsp_freq);
406 
408 
409  double txfreqs[2];
410  txfreqs[0] = usrp->get_tx_freq(0);
411  if(tvrt_lo_mode) {
412  txfreqs[1] = usrp->get_tx_freq(1);
413  debugMsg(boost::format("TX LO = %g TVRT LO = %g\n") % txfreqs[0] % txfreqs[1]);
414  }
415  }
416 
417  // If we are setting the RX mode, then we need to send
418  // a message to the USRPRX to tell it what its IF freq should be.
419  if((sel == 'r') && set_if_freq) {
421  freq - target_rx_freq));
422  }
423 }
424 
448 {
449  double freq, fdiff;
450  if(cmd->cmd != Command::SET) {
451  std::cerr << "execSetCommand got a non-set command! " << cmd->toString() << std::endl;
452  return;
453  }
454  double tmp;
455  switch (cmd->target) {
457  last_rx_req_freq = cmd->dparms[0];
458  freq = cmd->dparms[0];
459  fdiff = freq - (last_rx_tune_result.actual_rf_freq - last_rx_tune_result.actual_dsp_freq);
460 
461  debugMsg(boost::format("Got RX RETUNE request -- frequency %f diff = %f last actual_rf %f dsp %f\n")
462  % freq % fdiff % last_rx_tune_result.actual_rf_freq % last_rx_tune_result.actual_dsp_freq);
463 
464  if((fdiff < 200e3) && (fdiff > 100e3)) {
467  last_rx_tune_result.actual_rf_freq - last_rx_tune_result.actual_dsp_freq));
468  break;
469  }
470  // else -- treat this as a RX_TUNE_FREQ request.
471  case Command::RX_TUNE_FREQ:
472  case Command::RX_FE_FREQ:
473  last_rx_req_freq = cmd->dparms[0];
474  set1stLOFreq(cmd->dparms[0], 'r', cmd->target != Command::RX_TUNE_FREQ);
475  // now adjust the 3rd lo (missing in int-N mode redo....)
476  fdiff = freq - (last_rx_tune_result.actual_rf_freq - last_rx_tune_result.actual_dsp_freq);
479  last_rx_tune_result.actual_rf_freq - last_rx_tune_result.actual_dsp_freq));
480  break;
481 
482  case Command::LO_CHECK:
483  if(cmd->dparms[0] == 0.0) {
484  set1stLOFreq(last_rx_req_freq, 'r', false);
485  }
486  else {
487  debugMsg(boost::format("setting lo check freq to %lf\n") % cmd->dparms[0]);
488  usrp->set_rx_freq(cmd->dparms[0]);
489  // now send a GET lo offset command
491  }
492  break;
493 
496  case Command::TX_FE_FREQ:
497  set1stLOFreq(cmd->dparms[0] + tx_freq_rxmode_offset, 't', false);
498  tx_freq = cmd->dparms[0];
500  last_tx_tune_result.actual_rf_freq + last_tx_tune_result.actual_dsp_freq));
501  break;
502 
504  usrp->set_rx_rate(cmd->dparms[0]);
506  usrp->get_rx_rate()));
507  break;
509  tx_samp_rate = cmd->dparms[0];
510  usrp->set_tx_rate(cmd->dparms[0]);
512  usrp->get_tx_rate()));
513  break;
514 
515  case Command::RX_RF_GAIN:
516  // dparameters ranges from 0 to 100... normalize this
517  // to the actual range;
518  rx_rf_gain = rx_rf_gain_range.start() + cmd->dparms[0] * 0.01 * (rx_rf_gain_range.stop() - rx_rf_gain_range.start());
519  if(!tx_on) {
520  usrp->set_rx_gain(rx_rf_gain);
522  usrp->get_rx_gain()));
523  }
524  break;
525  case Command::TX_RF_GAIN:
526  tx_rf_gain = tx_rf_gain_range.start() + cmd->dparms[0] * 0.01 * (tx_rf_gain_range.stop() - tx_rf_gain_range.start());
527  tmp = cmd->dparms[0];
528  debugMsg(boost::format("Setting TX gain to %lg from power %lg") % tx_rf_gain % tmp);
529  if(tx_on) {
530  usrp->set_tx_gain(tx_rf_gain);
532  usrp->get_tx_gain()));
533  }
534  break;
535  case SoDa::Command::TX_STATE: // SET TX_ON
536  debugMsg(boost::format("TX_STATE arg = %d\n") % cmd->iparms[0]);
537  if(cmd->iparms[0] == 1) {
538  // set the txgain to where it is supposed to be.
539  tx_on = true;
540  usrp->set_rx_gain(0.0);
541  usrp->set_tx_gain(tx_rf_gain);
543  usrp->get_tx_gain()));
544  // to move a birdie away, we bumped the TX LO,, move it back.
545  tx_freq_rxmode_offset = 0.0; // so tuning works.
546 
547  // enable the transmit relay
548  debugMsg(boost::format("Enabling TX\nCurrent TXENA %d\n") % tx_fe_subtree->getBoolProp("enabled"));
549  if(supports_tx_gpio) {
550  debugMsg(boost::format("Current GPIO = %x ") %
551  dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX));
552  }
553  setTXEna(true);
554 
555  debugMsg(boost::format("New TXENA %d\n") % tx_fe_subtree->getBoolProp("enabled"));
556  if(supports_tx_gpio) {
557  debugMsg(boost::format("New GPIO = %x ") % dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX));
558  }
559  // and tell the TX unit to turn on the TX
560  // This avoids the race between CTRL and TX/RX units for setup and teardown....
562  3));
563  }
564  if(cmd->iparms[0] == 0) {
565  tx_on = false;
566  // set txgain to zero
567  usrp->set_tx_gain(0.0);
568  usrp->set_rx_gain(rx_rf_gain);
569  // tune the TX unit 1MHz away from where we want to be.
570  tx_freq_rxmode_offset = rxmode_offset; // so tuning works.
572 
573  // turn off the transmit relay and the TX chain.
574  // This also turns off the TX LO on a WBX module, so
575  // the above tx_freq_rxmode trick may not be necessary
576  // We keep the rxmode_offset here in case other modules
577  // leave the TXLO on.
578  setTXEna(false);
579  debugMsg(boost::format("Disabling TX -- Got TXENA %d") % tx_fe_subtree->getBoolProp("enabled"));
580  if(supports_tx_gpio) {
581  debugMsg(boost::format("Got GPIO = %x ") %
582  dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX));
583  }
584  // and tell the RX unit to turn on the RX
585  // This avoids the race between CTRL and TX/RX units for setup and teardown....
587  2));
588  }
589  break;
590 
592  if((cmd->iparms[0] & 1) == 1) {
593  debugMsg("Setting reference to external");
594  usrp->set_clock_source(std::string("external"));
595  }
596  else {
597  debugMsg("Setting reference to internal");
598  usrp->set_clock_source(std::string("internal"));
599  }
600  break;
601 
602  case Command::RX_ANT:
603  setAntenna(cmd->sparm, 'r');
604  debugMsg(boost::format("Got RX antenna as [%s]\n") % usrp->get_rx_antenna());
605  cmd_stream->put(new Command(Command::REP, Command::RX_ANT, usrp->get_rx_antenna()));
606  break;
607 
608  case Command::TX_ANT:
609  tx_ant = cmd->sparm;
610  setAntenna(cmd->sparm, 't');
611  debugMsg(boost::format("Got TX antenna as [%s]\n") % usrp->get_tx_antenna());
612  cmd_stream->put(new Command(Command::REP, Command::TX_ANT, usrp->get_tx_antenna()));
613  break;
614 
616  setTransverterLOFreqPower(cmd->dparms[0], cmd->dparms[1]);
617  break;
618 
620  debugMsg("Enable Transverter LO");
622  break;
623 
625  debugMsg("Disable Transverter LO");
627  break;
628 
629  default:
630  break;
631  }
632 }
633 
635 {
636  int res;
637 
638 
639  switch (cmd->target) {
640  case Command::RX_FE_FREQ:
642  last_rx_tune_result.actual_rf_freq,
643  last_rx_tune_result.actual_dsp_freq));
644  break;
645  case Command::TX_FE_FREQ:
647  last_tx_tune_result.actual_rf_freq,
648  last_tx_tune_result.actual_dsp_freq));
649  break;
650 
653  usrp->get_rx_rate()));
654  break;
657  usrp->get_tx_rate()));
658  break;
659 
661  res = 0;
662  if(usrp->get_clock_source(0) == std::string("external")) {
663  res = 2;
664  }
665 
666  if (1) {
667  // is it locked?
668  uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked", 0);
669  if(ref_locked.to_bool()) {
670  res |= 1;
671  }
672  }
673 
675  res));
676  break;
677 
678  case Command::HWMB_REP:
680  (boost::format("%s\t%6.1f to %6.1f MHz")
682  % (rx_rf_freq_range.start() * 1e-6)
683  % (rx_rf_freq_range.stop() * 1e-6)).str()));
684  reportAntennas();
685  reportModes();
686  reportAFFilters();
688  break;
689  default:
690  break;
691  }
692 }
693 
695 {
696  switch (cmd->target) {
697  default:
698  break;
699  }
700 }
701 
703 {
704  supports_tx_gpio = true;
705 
706  // now, find the daughtercard, if it exists
707  try {
708  dboard = usrp->get_tx_dboard_iface();
709  }
710  catch (uhd::lookup_error & v) {
711  std::cerr << "No daughterboard interface found..." << std::endl;
712  dboard == NULL;
713  supports_tx_gpio = false;
714  }
715 
716  if(supports_tx_gpio) {
717 
718  // now get the old version of the GPIO enable mask.
719  unsigned short dir = dboard->get_gpio_ddr(uhd::usrp::dboard_iface::UNIT_TX);
720  unsigned short ctl = dboard->get_pin_ctrl(uhd::usrp::dboard_iface::UNIT_TX);
721  unsigned short out = dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX);
722 
723  // and print it.
724  debugMsg(boost::format("TX GPIO direction = %04x control = %04x output = %04x ctlmask = %04x monmask = %04x") % dir % ctl % out % TX_RELAY_CTL % TX_RELAY_MON);
725 
726 
727  // now set the direction to OUT for the CTL bit
728  dboard->set_gpio_ddr(uhd::usrp::dboard_iface::UNIT_TX,
730 
731  // and control it from the GPIO write
732  dboard->set_pin_ctrl(uhd::usrp::dboard_iface::UNIT_TX,
733  0, TX_RELAY_CTL);
734 
735  // and make sure the txena is OFF
736  dboard->set_gpio_out(uhd::usrp::dboard_iface::UNIT_TX,
737  0, TX_RELAY_CTL);
738  }
739  else {
740  std::cerr << "GPIO control of TX relay is disabled.\n"
741  << "This is normal if this radio is a B2xx.\n";
742  }
743 }
744 
746 {
747  unsigned short enabits = val ? TX_RELAY_CTL : 0;
748  if(supports_tx_gpio) {
749  dboard->set_gpio_out(uhd::usrp::dboard_iface::UNIT_TX,
750  enabits, TX_RELAY_CTL);
751  }
752 
753  // switch the relay BEFORE transmit on....
754  if(val) {
755  tr_control->setTXOn();
756  }
757 
758  // if the front end has an enable property, set it.
759  setTXFrontEndEnable(val);
760 
761  // if we're enabling, set the power, freq, and other stuff
762  if(val) {
763  usleep(400);
764  // set the tx antenna
765  setAntenna(tx_ant, 't');
766  // set the tx gain.
767  usrp->set_tx_gain(tx_rf_gain);
768  // tx freq
770 
771  double r = usrp->get_tx_rate();
772  debugMsg(boost::format("TX rate = %g\n") % r);
773  }
774 
775  if(!val) {
776  tr_control->setTXOff();
777  }
778 
779 }
780 
782 {
783  if(!tx_fe_has_enable) return;
784 
785  // enable the transmitter (or disable it)
786  tx_fe_subtree->setBoolProp("enabled", val);
787 
788  debugMsg(boost::format("Got %d from call to en/dis TX with val = %d")
789  % tx_fe_subtree->getBoolProp("enabled") % val);
790  if(rx_fe_has_enable) {
791  debugMsg(boost::format("Got rx_fe enabled = %d from call to en/dis TX with val = %d")
792  % rx_fe_subtree->getBoolProp("enabled") % val);
793  }
794 }
795 
797 {
798  unsigned int enabits = 0;
799  if(supports_tx_gpio) {
800  enabits = dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX);
801  }
802 
803  return ((enabits & TX_RELAY_CTL) != 0);
804 }
805 
806 
808 {
809  unsigned int enabits = 0;
810  if(supports_tx_gpio) {
811  enabits = dboard->read_gpio(uhd::usrp::dboard_iface::UNIT_TX);
812  }
813 
814  return ((enabits & TX_RELAY_MON) != 0);
815 }
816 
817 void SoDa::USRPCtrl::setTransverterLOFreqPower(double freq, double power)
818 {
819  uhd::gain_range_t tx_gain_range = usrp->get_tx_gain_range(1);
820  double plo = tx_gain_range.start();
821  double phi = tx_gain_range.stop();
822  tvrt_lo_gain = plo + power * (phi - plo);
823  tvrt_lo_freq = freq;
824 
825  debugMsg(boost::format("Setting Transverter LO freq = %10lg power = %g gain = %g\n") % tvrt_lo_freq % power % tvrt_lo_gain);
826 
827  debugMsg("About to report Transverter LO setting.");
828  cmd_stream->put(new Command(Command::REP, Command::TVRT_LO_CONFIG, tvrt_lo_freq, power));
829 
830 }
831 
833 {
834  if(!tvrt_lo_capable) {
835  tvrt_lo_mode = false;
836  return;
837  }
838 
839  debugMsg("Enabling transverter LO\n");
840  usrp->set_tx_antenna("TX2", 1);
841 
842  usrp->set_tx_gain(tvrt_lo_gain, 1);
843  // tune the first LO 4MHz below the target, and let the DDC make up the rest.
844  uhd::tune_request_t lo_freq_req(tvrt_lo_freq, -4.0e6);
845  uhd::tune_result_t tres = usrp->set_tx_freq(lo_freq_req, 1);
846 
847  tvrt_lo_mode = true;
848 
849  debugMsg(boost::format("LO frequency = %10lg power %g number of channels = %d target_rf %g actual rf %g target dsp %g actual dsp %g\n")
850  % usrp->get_tx_freq(1) % usrp->get_tx_gain(1) % usrp->get_tx_num_channels()
851  % tres.target_rf_freq % tres.actual_rf_freq % tres.target_dsp_freq % tres.actual_dsp_freq);
852 
853  tvrt_lo_fe_freq = tres.target_rf_freq;
854 }
855 
857 {
858  tvrt_lo_mode = false;
859  if(!tvrt_lo_capable) return;
860  usrp->set_tx_gain(0.0, 1);
861  usrp->set_tx_freq(100.0e6, 1);
862 }
863 
864 void SoDa::USRPCtrl::applyTargetFreqCorrection(double target_freq, double avoid_freq, uhd::tune_request_t * treq)
865 {
866  debugMsg(boost::format("###### aTFC(%lf...)") % target_freq);
867 
868  // if we can't find a really good answer, at least setup a "correct" answer...
869  treq->dsp_freq_policy = uhd::tune_request_t::POLICY_AUTO;
870  treq->target_freq = target_freq;
871  // default
872  treq->rf_freq = target_freq;
873  treq->rf_freq_policy = uhd::tune_request_t::POLICY_AUTO;
874  treq->args = uhd::device_addr_t("");
875 
876  // try three step sizes.
877  double steps[] = {12.5e6, 10.0e6, 50.0e6/3.0};
878  int i;
879  if(target_freq < 10.0e6) {
880  // take the default...
881  debugMsg("\t\treturns default request\n");
882  return;
883  }
884 
885  double N;
886 
887  // now look for a good integer N setting that puts the reference spurs
888  // at least 1MHz away from our "avoid" frequency...
889  for(i = 0; i < 3; i++) {
890  N = round(target_freq / steps[i]);
891 
892  double rf_freq = N * steps[i];
893  debugMsg(boost::format("\t\tTRY rf_freq = %lf step = %lf\n") % rf_freq % steps[i]);
894  if(fabs(rf_freq - avoid_freq) > 1.0e6) {
895  // this is an OK choice.
896  debugMsg(boost::format("\t\tACCEPT rf_freq = %lf step = %lf\n") % rf_freq % steps[i]);
897  treq->rf_freq = rf_freq;
898  treq->rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
899  treq->args = uhd::device_addr_t((boost::format("mode_n=integer,int_n_step=%lf") % steps[i]).str());
900  return;
901  }
902  }
903 
904  // if we get here, we're probably a multiple of 50 MHz.... tough point to make....
905  // there are no good answers...
906  N = round(target_freq / steps[0]);
907  double rf_freq = N * steps[0];
908  debugMsg(boost::format("\t\tTRY rf_freq = %lf step = %lf\n") % rf_freq % steps[0]);
909  if(fabs(rf_freq - avoid_freq) < 1.0e6) {
910  if(rf_freq > avoid_freq) N = N - 1.0;
911  else N = N + 1.0;
912  rf_freq = N * steps[0];
913  }
914  // this is an OK choice.
915  debugMsg(boost::format("\t\tGRUDGINGLY ACCEPT rf_freq = %lf step = %lf\n") % rf_freq % steps[0]);
916  treq->rf_freq = rf_freq;
917  treq->rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
918  treq->args = uhd::device_addr_t((boost::format("mode_n=integer,int_n_step=%lf") % steps[0]).str());
919 
920 
921 }
922 
923 
924 
925 void SoDa::USRPCtrl::normal_message_handler(uhd::msg::type_t type, const std::string & msg)
926 {
927  switch (type) {
928  case uhd::msg::error:
929  std::cerr << "UHD ERROR: " << msg << std::flush;
930  break;
931  case uhd::msg::warning:
932  std::cerr << "UHD WARNING: " << msg << std::flush;
933  break;
934  default:
935  SoDa::USRPCtrl::singleton_ctrl_obj->debugMsg(msg);
936  break;
937  }
938 }
939 
940 void SoDa::USRPCtrl::testIntNMode(bool force_int_N, bool force_frac_N)
941 {
942  uhd::tune_result_t tunres_int, tunres_frac;
943 
944  debugMsg("In testIntNMode\n");
945 
946  supports_IntN_Mode = false;
947  if(force_int_N) {
948  debugMsg("Forced IntN Tuning support ON.");
949  supports_IntN_Mode = true;
950  }
951  else if(force_frac_N) {
952  debugMsg("Forced IntN Tuning support OFF.");
953  supports_IntN_Mode = false;
954  }
955  else if(is_B2xx) {
956  supports_IntN_Mode = false;
957  return;
958  }
959  else {
960  // first, do we have this capability?
961  // LFTX/LFRX/BASICRX/BASICTX don't. Check the RX/RF front end name
962  // if it contains LFRX or BASICRX then we don't support intN mode.
963  // get the db name for the rx
964  std::string dbname;
965  dbname = rx_fe_subtree->getStringProp("name");
966 
967  std::string lfrx("LFRX");
968  std::string basrx("BASICRX");
969  if((dbname.compare(0, lfrx.length(), lfrx) == 0) ||
970  (dbname.compare(0, basrx.length(), basrx) == 0)) {
971  std::cerr << boost::format("This is a simple front end -- no front-end LO. [%s]\n")
972  % dbname;
973  supports_IntN_Mode = false;
974  return;
975  }
976 
977  // if we get here, the front end has an LO
978  // pick a frequency halfway between the min and max freq for this MB.
979  double tf = (rx_rf_freq_range.stop() + rx_rf_freq_range.start()) * 0.5;
980  // Now bump it by some silly amount
981  tf += 123456.789;
982 
983  debugMsg(boost::format("got tf = %g\n") % tf);
984 
985  // and tune with and without intN
986  uhd::tune_request_t tunreq_int(tf);
987  uhd::tune_request_t tunreq_frac(tf);
988  tunreq_int.args = uhd::device_addr_t("mode_n=integer,int_n_step=12.5e6");
989  debugMsg("About to tune int...\n");
990  tunres_int = usrp->set_rx_freq(tunreq_int);
991  debugMsg("About to tune frac...\n");
992  tunres_frac = usrp->set_rx_freq(tunreq_frac);
993 
994  // are there differences?
995  if(tunres_int.actual_rf_freq != tunres_frac.actual_rf_freq) {
996  supports_IntN_Mode = true;
997  }
998 
999  debugMsg(boost::format("int rf = %g frac rf = %g tf = %g\n")
1000  % tunres_int.actual_rf_freq % tunres_frac.actual_rf_freq % tf);
1001  }
1002 
1003 
1004 
1005  if(supports_IntN_Mode) {
1006  debugMsg("Supports INT_N tuning mode.\n");
1007  }
1008  else {
1009  debugMsg("Does not support INT_N tuning mode.\n");
1010  }
1011 
1012  return;
1013 }
1014 
1016 {
1018  "CW_U", ((int) SoDa::Command::CW_U)));
1020  "USB", ((int) SoDa::Command::USB)));
1022  "CW_L", ((int) SoDa::Command::CW_L)));
1024  "LSB", ((int) SoDa::Command::LSB)));
1026  "AM", ((int) SoDa::Command::AM)));
1028  "WBFM", ((int) SoDa::Command::WBFM)));
1030  "NBFM", ((int) SoDa::Command::NBFM)));
1031 }
1032 
1034 {
1036  "100", ((int) SoDa::Command::BW_100)));
1038  "500", ((int) SoDa::Command::BW_500)));
1040  "2000", ((int) SoDa::Command::BW_2000)));
1042  "6000", ((int) SoDa::Command::BW_6000)));
1044  "PASS", ((int) SoDa::Command::BW_PASS)));
1045 
1046 }
1047 
1049 {
1050  std::vector<std::string> rx_ants = usrp->get_rx_antennas();
1051  BOOST_FOREACH(std::string ant, rx_ants) {
1052  debugMsg(boost::format("Sending RX antenna list element [%s]\n") % ant);
1054  ant));
1055 
1056  }
1057  std::vector<std::string> tx_ants = usrp->get_tx_antennas();
1058  BOOST_FOREACH(std::string ant, tx_ants) {
1059  debugMsg(boost::format("Sending TX antenna list element [%s]\n") % ant);
1061  ant));
1062 
1063  }
1064 }
1065 
1066 
1067 void SoDa::USRPCtrl::setAntenna(const std::string & ant, char sel)
1068 {
1069  std::vector<std::string> ants;
1070 
1071  ants = (sel == 'r') ? usrp->get_rx_antennas() : usrp->get_tx_antennas();
1072 
1073  std::string choice = ants[0];
1074 
1075  BOOST_FOREACH(std::string a, ants) {
1076  if (ant == a) {
1077  choice = ant;
1078  break;
1079  }
1080  }
1081 
1082  if(sel == 'r') {
1083  usrp->set_rx_antenna(choice);
1084  }
1085  if(sel == 't') {
1086  usrp->set_tx_antenna(choice);
1087  }
1088 
1089  return;
1090 }
uhd::usrp::multi_usrp::sptr usrp
to which USRP unit is this connected?
Definition: USRPCtrl.hxx:165
bool rx_fe_has_enable
can we access rx_fe_subtree/enabled ?
Definition: USRPCtrl.hxx:175
The Baseclass for all SoDa objects, and useful commonly used classes.
On receipt of a TVRT_LO_DISABLE command, turn the LO output on TX2 off.
Definition: Command.hxx:391
Not many choices for TX ant, just TX.
Definition: Command.hxx:154
SoDa::PropTree * tx_fe_subtree
property tree from daughtercard module
Definition: USRPCtrl.hxx:168
static SoDa::USRPCtrl * singleton_ctrl_obj
This is a singleton object – the last (and only, we hope) such object to be created sets a static po...
Definition: USRPCtrl.hxx:91
bool is_B2xx
The B200 and B210 need some special handling, as they don&#39;t have frontend lock indications (as of 3...
Definition: USRPCtrl.hxx:99
The Thread baseclass for all SoDa thread objects.
Definition: SoDaBase.hxx:284
void debugMsg(const std::string &msg, unsigned int threshold=1)
Definition: Debug.hxx:64
turn transmitter on and off.
Definition: Command.hxx:197
Sample rate for RX is typically 600 KHz or better to allow a reasonable span for the waterfall and pe...
Definition: Command.hxx:132
RX audio gain setting.
Definition: Command.hxx:175
T * get(unsigned int subscriber_id)
Definition: MultiMBox.hxx:110
double tvrt_lo_fe_freq
the frequency of the second transmit channel front-end oscillator
Definition: USRPCtrl.hxx:253
Sample rate for TX needs to be fast enough for reasonable FM We set it to 625000 just because there d...
Definition: Command.hxx:141
std::string & getObjName()
get the name of this object
Definition: SoDaBase.hxx:182
SoDa::TRControl * tr_control
external control widget for TR switching and other things.
Definition: USRPCtrl.hxx:282
uhd::tune_result_t last_tx_tune_result
TX tune result.
Definition: USRPCtrl.hxx:217
Set the TX final amplifier.
Definition: Command.hxx:167
bool tx_has_lo_locked_sensor
does the tx frond end have an lo_locked sensor?
Definition: USRPCtrl.hxx:176
Set the RX front end attenuator/amp.
Definition: Command.hxx:161
void disableTransverterLO()
Definition: USRPCtrl.cxx:856
PropTree * getUSRPFrontEnd(PropTree *tree, char tr_choice)
return a pointer to a PropTree object for the first "T" or "R" front end that provides an IQ or QI st...
This is an LO check command - use it for finding the actual microwave LO frequency.
Definition: Command.hxx:299
Though libuhd is designed to be re-entrant, there are some indications that all control functions (se...
Definition: USRPCtrl.hxx:68
std::string motherboard_name
The model name of the USRP unit.
Definition: USRPCtrl.hxx:246
void setBoolProp(const std::string &propname, const bool val=false)
Definition: PropTree.hxx:152
void execGetCommand(Command *cmd)
Dispatch an incoming GET command.
Definition: USRPCtrl.cxx:634
int iparms[4]
integer parameters
Definition: Command.hxx:668
static const double rxmode_offset
tx offset when in RX mode
Definition: USRPCtrl.hxx:241
double tx_samp_rate
sample rate to USRP TX chain.
Definition: USRPCtrl.hxx:243
Set the RX front end (1st LO, the 2nd IF LO), and the 3rd LO in a more-or-less optimal way to positio...
Definition: Command.hxx:68
bool getTXRelayOn()
get the state of the TX relay confirm bit
Definition: USRPCtrl.cxx:807
void enableTransverterLO()
Definition: USRPCtrl.cxx:832
uhd::freq_range_t tx_rf_freq_range
property of the device – what is the min/maximum TX frequency?
Definition: USRPCtrl.hxx:230
This class handles command line parameters and built-ins.
Definition: Params.hxx:42
The SoDa Exception class.
Definition: SoDaBase.hxx:217
double rx_rf_gain
rf gain for RX front end amp/attenuator
Definition: USRPCtrl.hxx:223
Report the motherboard name (the model name of the USRP)
Definition: Command.hxx:362
std::string getTXAnt() const
which port is the TX channel?
Definition: Params.hxx:76
PropTree class encapsulates the USRP property tree functions to allow better trap and error recovery ...
Definition: PropTree.hxx:44
bool supports_IntN_Mode
if true, this unit can tune the front-end LO
Definition: USRPCtrl.hxx:276
CmdTarget target
the thing we&#39;re touching
Definition: Command.hxx:673
virtual bool setTXOn()=0
activate external controls to enable transmit mode.
bool tvrt_lo_capable
if true, this unit can implement a local transverter oscillator.
Definition: USRPCtrl.hxx:249
void setStringProp(const std::string &propname, const std::string val=std::string("None"))
Definition: PropTree.hxx:137
Report a string/name pair for modulation mode.
Definition: Command.hxx:450
double getTime()
get the number of seconds since the "Epoch"
Definition: USRPCtrl.cxx:260
indicate to GUI that we&#39;ve sent all the initial configuration information
Definition: Command.hxx:460
double getRXRate() const
Sample rates and all that other stuff are fixed.
Definition: Params.hxx:98
bool tx_on
if true, we are transmitting.
Definition: USRPCtrl.hxx:233
uhd::tune_result_t last_rx_tune_result
RX tune result – actual LO and DSP freq.
Definition: USRPCtrl.hxx:216
bool getBoolProp(const std::string &propname, const bool defval=false)
Definition: PropTree.hxx:132
void set1stLOFreq(double freq, char sel, bool set_if_freq=false)
Set the front-end (LO + DDS) frequency to &#39;freq&#39; This includes setting the PLL front end synthesizer ...
Definition: USRPCtrl.cxx:312
static void normal_message_handler(uhd::msg::type_t type, const std::string &msg)
This is the more permanent message handler...
Definition: USRPCtrl.cxx:925
void reportAntennas()
report the antennas that are available, send the report on cmd_stream
Definition: USRPCtrl.cxx:1048
double tx_freq
remember current tx freq
Definition: USRPCtrl.hxx:239
On receipt of a STOP command, all threads should exit their run loop.
Definition: Command.hxx:371
void setTXEna(bool val)
turn TX on/off
Definition: USRPCtrl.cxx:745
This is a list of all the commands that can "do something" to one or more components in the SoDa radi...
Definition: Command.hxx:47
void applyTargetFreqCorrection(double target_freq, double avoid_freq, uhd::tune_request_t *tune_req)
applyTargetFreqCorrection adjusts the requested frequency, if necessary, to avoid a birdie caused by ...
Definition: USRPCtrl.cxx:864
Same effect as TX_TUNE_FREQ.
Definition: Command.hxx:115
double tx_rf_gain
rf gain for final TX amp
Definition: USRPCtrl.hxx:224
virtual bool setTXOff()=0
activate external controls to disable transmit mode.
double tx_freq_rxmode_offset
when in RX mode, move tx off frequency to put the tx birdie out of band, when in TX mode...
Definition: USRPCtrl.hxx:240
bool forceIntN()
Definition: Params.hxx:113
char sparm[64]
a buffer holding the string
Definition: Command.hxx:670
bool tx_fe_has_enable
can we access tx_fe_subtree/enabled ?
Definition: USRPCtrl.hxx:174
void setTransverterLOFreqPower(double freq, double power)
set the transverter LO frequency and power This code does not work for libUHD after 3...
Definition: USRPCtrl.cxx:817
uhd::gain_range_t tx_rf_gain_range
property of the device – what is the min/maximum TX gain setting?
Definition: USRPCtrl.hxx:227
void reportAFFilters()
report the audio filters that are implemented, send the report on cmd_stream
Definition: USRPCtrl.cxx:1033
std::string getStringProp(const std::string &propname, const std::string defval=std::string("None"))
Definition: PropTree.hxx:117
double getTXRate() const
TX rate will always be 625K.
Definition: Params.hxx:102
Set the RX front end 1st LO and the 2nd IF LO.
Definition: Command.hxx:79
bool supports_tx_gpio
does this unit support GPIO signals? (B2xx does not as of 3.7.0)
Definition: USRPCtrl.hxx:181
Report TX antenna choice (asciiz string, uint tag)
Definition: Command.hxx:444
bool getTXEna()
get the state of the TXEna bit
Definition: USRPCtrl.cxx:796
void free(T *m)
Definition: MultiMBox.hxx:118
std::string getRXAnt() const
which port is the RX channel?
Definition: Params.hxx:71
RX ant choices are TX/RX, and RX2.
Definition: Command.hxx:148
uhd::usrp::dboard_iface::sptr dboard
the daughterboard we&#39;re controlling
Definition: USRPCtrl.hxx:166
double first_gettime
timestamps are relative to the first timestamp.
Definition: USRPCtrl.hxx:220
std::string getRadioArgs() const
return args that point to a particular USRP unit
Definition: Params.hxx:56
bool forceFracN()
Definition: Params.hxx:112
static const unsigned int TX_RELAY_MON
mask for RELAY sense bit
Definition: USRPCtrl.hxx:214
CmdType cmd
the command type (SET, GET, REP)
Definition: Command.hxx:672
void initControlGPIO()
Initialize the GPIO control registers to set the direction and enables for the TX/RX relay output and...
Definition: USRPCtrl.cxx:702
double dparms[4]
double float parameters
Definition: Command.hxx:669
void testIntNMode(bool force_int_N, bool force_frac_N)
Test for support for integer-N synthesis.
Definition: USRPCtrl.cxx:940
double last_rx_req_freq
remember the last setting – useful for "calibration check"
Definition: USRPCtrl.hxx:235
Thread class that owns the USRP control channel and functions.
Params * params
Definition: USRPCtrl.hxx:94
The master clock oscillator source Reference oscilator selector set to 1 for external, 0 for internal rep = 1 for internal lock, 0 for unlock 3 for external lock, 2 for external unlocked.
Definition: Command.hxx:291
void reportModes()
report the modulation modes that are implemented, send the report on cmd_stream
Definition: USRPCtrl.cxx:1015
Tune the 3rd LO, if the current FE frequency is such that the desired frequency is between RX_FE_FREQ...
Definition: Command.hxx:89
static const unsigned int TX_RELAY_CTL
we use TX_IO bit 12 to turn on the TX relay we use TX_IO bit 11 to monitor the TX relay ...
Definition: USRPCtrl.hxx:213
bool tvrt_lo_mode
if true, set the transmit frequency, with some knowledge of the tvrt LO.
Definition: USRPCtrl.hxx:250
void setTXFrontEndEnable(bool val)
set TX enable property on front-end module – not present in all daughtercards... ...
Definition: USRPCtrl.cxx:781
Tune the 3rd LO (in SoDa::USRPRX).
Definition: Command.hxx:96
double tvrt_lo_freq
the frequency of the second transmit channel oscillator
Definition: USRPCtrl.hxx:252
unsigned int subid
subscriber ID for this thread&#39;s connection to the command channel
Definition: USRPCtrl.hxx:162
bool rx_has_lo_locked_sensor
does the rx frond end have an lo_locked sensor?
Definition: USRPCtrl.hxx:177
Set the TX front end (1st LO, the 2nd IF LO), and the 3rd LO in a more-or-less optimal way to positio...
Definition: Command.hxx:108
double tvrt_lo_gain
output power for the second transmit channel (used for transverter LO)
Definition: USRPCtrl.hxx:251
uhd::freq_range_t rx_rf_freq_range
property of the device – what is the min/maximum RX frequency?
Definition: USRPCtrl.hxx:229
std::string tx_ant
TX antenna choice (usually has to be TX or TX/RX1?
Definition: USRPCtrl.hxx:244
Report a string/name pair for AF filter bandwidth.
Definition: Command.hxx:455
Report RX antenna choice (asciiz string, uint tag)
Definition: Command.hxx:439
void run()
start the thread
Definition: USRPCtrl.cxx:209
void put(T *m)
Definition: MultiMBox.hxx:97
On receipt of a TVRT_LO_ENABLE command dump a perpetual constant IF stream of (1.0, 0.0) into the tx2 channel to get a steady output.
Definition: Command.hxx:381
Manage front end settings for Ettus USRP devices Functions that return a property tree corresponding ...
CmdMBox * cmd_stream
command stream channel
Definition: USRPCtrl.hxx:161
bool hasProperty(const std::string &propname)
does the property tree have this property name as a child?
Definition: PropTree.hxx:100
static TRControl * makeTRControl(uhd::usrp::multi_usrp::sptr usrp, int mboard=0)
make the appropriate TR control widget given a pointer to a USRP device.
Definition: TRControl.cxx:45
On receipt of a TVRT_LO_CONFIG command , set the TX2 channel frequency to dparam[0] and the TX2 outpu...
Definition: Command.hxx:404
SoDa::PropTree * rx_fe_subtree
property tree from daughtercard module
Definition: USRPCtrl.hxx:170
Same effect as TX_TUNE_FREQ.
Definition: Command.hxx:122
USRPCtrl(Params *params, CmdMBox *_cmd_stream)
Constructor Build a USRPCtrl thread.
Definition: USRPCtrl.cxx:55
uhd::gain_range_t rx_rf_gain_range
property of the device – what is the min/maximum RX gain setting?
Definition: USRPCtrl.hxx:226
std::string getClockSource() const
where does the reference come from?
Definition: Params.hxx:64
void execRepCommand(Command *cmd)
Dispatch an incoming REPort command.
Definition: USRPCtrl.cxx:694
std::string toString() const
return a string that displays the command
Definition: Command.cxx:230
void setAntenna(const std::string &ant, char sel)
Set the antenna choice.
Definition: USRPCtrl.cxx:1067
void execSetCommand(Command *cmd)
Dispatch an incoming SET command.
Definition: USRPCtrl.cxx:447
this is a GET/REP command – BaseBandRX takes FFT centered around 0 and reports largest peak within 5...
Definition: Command.hxx:305
uhd::tune_result_t checkLock(uhd::tune_request_t &req, char sel, uhd::tune_result_t &cur)
is the identified (rx or tx) front-end LO locked? If not, set the tuning frequency to "the right thin...
Definition: USRPCtrl.cxx:286
void execCommand(Command *cmd)
Parse an incoming command and dispatch.
Definition: USRPCtrl.cxx:269
bool is_B210
the B210 has two tx channels – use the second for a Transverter LO – see USRPLO ...
Definition: USRPCtrl.hxx:100