SoDaRadio-5.0.3-master:8901fb5
USRPTuner.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 "USRPTuner.hxx"
30 #include "SoDaBase.hxx"
31 #include <uhd/utils/thread_priority.hpp>
32 #include <uhd/utils/safe_main.hpp>
33 #include <uhd/usrp/multi_usrp.hpp>
34 #include <uhd/usrp/multi_usrp.hpp>
35 #include <uhd/utils/msg.hpp>
36 #include <uhd/types/tune_request.hpp>
37 #include <uhd/types/tune_result.hpp>
38 #include <boost/format.hpp>
39 
40 SoDa::USRPTuner::USRPTuner * makeTuner(uhd::usrp::multi_usrp::sptr usrp,
41  double min_separation,
42  bool force_fracN,
43  bool force_simple)
44 {
45  bool choose_simple = force_simple;
46 
47 
48  if(!choose_simple) { // look at the module name
49 
50  }
51 
52  if(choose_simple) return new SimpleTuner(usrp);
53  else return IntNTuner(usrp, min_separation, force_fracN);
54 
55 }
56 
57 SoDa::USRPTuner::USRPTuner(uhd::usrp::multi_usrp::sptr _usrp, double _min_separation, std::string _unit_name) : Debug(_unit_name)
58 {
60  min_separation = _min_separation;
61  usrp = _usrp;
62 
63  std::vector<std::string> sensor_names = usrp->get_rx_sensor_names(0);
64  has_lock_detect = std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end();
65 }
66 
67 bool SoDa::IntNTuner::setRXFreq(double rx_freq, double avoid_freq, uhd::tune_result_t & tune_result)
68 {
69  double target_rx_freq = 100e3 * floor(rx_freq / 100.0e3);
70  while((rx_freq - target_rx_freq) < 100.0e3) {
71  target_rx_freq -= 100.0e3;
72  }
73 
74  uhd::tune_request_t rx_trequest(target_rx_freq);
75  rx_trequest.target_freq = target_rx_freq;
76  rx_trequest.rf_freq = target_rx_freq;
77  rx_trequest.rf_freq_policy = uhd::tune_request_t::POLICY_AUTO;
78  rx_trequest.dsp_freq_policy = uhd::tune_request_t::POLICY_AUTO;
79 
80  tune_result = usrp->set_rx_freq(rx_trequest);
81 
82  debugMsg(boost::format("USRPTuner: RX Tune RF_actual %lf DDC = %lf tuned = %lf target = %lf request rf = %lf request ddc = %lf\n")
83  % tune_result.actual_rf_freq
84  % tune_result.actual_dsp_freq
85  % rx_freq
86  % target_rx_freq
87  % rx_trequest.rf_freq
88  % rx_trequest.dsp_freq);
89 
90  return checkLock(rx_trequest, 'r', tune_result);
91 }
92 
93 bool SoDa::IntNTuner::setTXFreq(double tx_freq, double avoid_freq, uhd::tune_result_t & tune_result)
94 {
95  // On the transmit side, we're using a minimal IF rate and
96  // using the full range of the tuning hardware.
97 
98  // If the transmitter is off, we retune anyway to park the
99  // transmit LO as far away as possible. This is especially
100  // important for the UBX.
101 
102  uhd::tune_request_t tx_request(tx_freq);
103 
104  tx_request.rf_freq_policy = uhd::tune_request_t::POLICY_AUTO;
105 
106  debugMsg(boost::format("Tuning TX unit to new frequency %f (request = %f (%f %f))\n")
107  % tx_freq % tx_request.target_freq % tx_request.rf_freq % tx_request.dsp_freq);
108 
109  tune_result = usrp->set_tx_freq(tx_request);
110 
111  debugMsg(boost::format("Tuned TX unit to new frequency %g t.rf %g a.rf %g t.dsp %g a.dsp %g\n")
112  % tx_freq
113  % tune_result.target_rf_freq
114  % tune_result.actual_rf_freq
115  % tune_result.target_dsp_freq
116  % tune_result.actual_dsp_freq);
117 
118  return checkLock(tx_request, 't', tune_result);
119 }
120 
121 bool SoDa::USRPTuner::checkLock(uhd::tune_request_t & req,
122  char sel,
123  uhd::tune_result_t & cur)
124 {
125  int lock_itercount = 0;
126  uhd::tune_result_t ret = cur;
127 
128  // if we don't do lock, then return.
129  if(!has_lock_detect) return true;
130 
131  while(1) {
132  uhd::sensor_value_t lo_locked = (sel == 'r') ? usrp->get_rx_sensor("lo_locked",0) : usrp->get_tx_sensor("lo_locked",0);
133  if(lo_locked.to_bool()) break;
134  else usleep(1000);
135  if((lock_itercount & 0xfff) == 0) {
136  debugMsg(boost::format("Waiting for %c LO lock to freq = %f (%f:%f) count = %d\n")
137  % sel % req.target_freq % req.rf_freq % req.dsp_freq % lock_itercount);
138  if(sel == 'r') ret = usrp->set_rx_freq(req);
139  else ret = usrp->set_tx_freq(req);
140  }
141  lock_itercount++;
142  }
143 
144  return true;
145 }
146 
The Baseclass for all SoDa objects, and useful commonly used classes.
void debugMsg(const std::string &msg, unsigned int threshold=1)
Definition: Debug.hxx:64
virtual bool setTXFreq(double tx_freq, double avoid_freq, uhd::tune_result_t &tune_result)
setTXFreq set the TX 1st LO frequency.
Definition: USRPTuner.cxx:93
virtual bool 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: USRPTuner.cxx:121
double min_separation
Definition: USRPTuner.hxx:118
Class that encapsulates tuning functions for various daughter cards.
bool setRXFreq(double rx_freq, double avoid_freq, uhd::tune_result_t &tune_result)
setRXFreq set the RX 1st LO frequency.
Definition: USRPTuner.cxx:67
A simple base class to provide debug messaging from any derived class.
Definition: Debug.hxx:42
SoDa::USRPTuner::USRPTuner * makeTuner(uhd::usrp::multi_usrp::sptr usrp, double min_separation, bool force_fracN, bool force_simple)
Definition: USRPTuner.cxx:40
uhd::usrp::multi_usrp::sptr usrp
Definition: USRPTuner.hxx:119
USRPTuner(uhd::usrp::multi_usrp::sptr usrp, double min_separation, std::string unit_name=std::string("USRPTuner"))
Constructor –.
Definition: USRPTuner.cxx:57