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> 58 SoDa::USRPCtrl::singleton_ctrl_obj =
this;
73 tx_ant = std::string(
"TX");
98 usrp->set_master_clock_rate(25.0e6);
99 debugMsg(boost::format(
"Initial setup %s") %
usrp->get_pp_string());
110 usrp->set_rx_subdev_spec(std::string(
"A:A"), 0);
111 std::cerr <<
"DISABLING TVRT LO" << std::endl;
113 debugMsg(
"Setup two subdevices -- TVRT_LO Capable");
114 usrp->set_tx_subdev_spec(std::string(
"A:A A:B"), 0);
118 debugMsg(
"Setup one subdevice -- NOT TVRT_LO Capable");
119 usrp->set_tx_subdev_spec(std::string(
"A:A"), 0);
124 debugMsg(
"Setup one subdevice -- NOT TVRT_LO Capable");
142 std::cerr <<
"Testing for tx power_mode prop." << std::endl;
144 std::cerr <<
"Found for tx power_mode prop." << std::endl;
161 std::cerr <<
"*****Setting power save mode for RX front end.******" << std::endl;
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);
211 uhd::set_thread_priority_safe();
238 bool exitflag =
false;
239 unsigned int cmds_processed = 0;
240 unsigned int loopcount = 0;
245 boost::this_thread::sleep(boost::posix_time::milliseconds(50));
249 if((cmds_processed & 0xff) == 0) {
250 debugMsg(boost::format(
"USRPCtrl processed %d commands") % cmds_processed);
264 gettimeofday(&tv, NULL);
265 ret = (((double) tv.tv_sec) -
first_gettime) + 1.0e-6*((
double) tv.tv_usec);
288 int lock_itercount = 0;
289 uhd::tune_result_t ret = cur;
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;
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);
320 double target_rx_freq;
333 target_rx_freq = freq;
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);
346 uhd::tune_request_t rx_trequest(target_rx_freq);
350 debugMsg(boost::format(
"\t*****target_rx_freq = %lf corrected to %lf\n")
351 % target_rx_freq % rx_trequest.rf_freq);
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;
363 debugMsg(boost::format(
"RX Tune RF_actual %lf DDC = %lf tuned = %lf target = %lf request rf = %lf request ddc = %lf\n")
368 % rx_trequest.rf_freq
369 % rx_trequest.dsp_freq);
382 uhd::tune_request_t tx_request(freq);
385 tx_request.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
392 tx_request.rf_freq_policy = uhd::tune_request_t::POLICY_AUTO;
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);
400 debugMsg(boost::format(
"Tuned TX unit to new frequency %g t.rf %g a.rf %g t.dsp %g a.dsp %g\n")
410 txfreqs[0] =
usrp->get_tx_freq(0);
412 txfreqs[1] =
usrp->get_tx_freq(1);
413 debugMsg(boost::format(
"TX LO = %g TVRT LO = %g\n") % txfreqs[0] % txfreqs[1]);
419 if((sel ==
'r') && set_if_freq) {
421 freq - target_rx_freq));
451 std::cerr <<
"execSetCommand got a non-set command! " << cmd->
toString() << std::endl;
461 debugMsg(boost::format(
"Got RX RETUNE request -- frequency %f diff = %f last actual_rf %f dsp %f\n")
464 if((fdiff < 200e3) && (fdiff > 100e3)) {
483 if(cmd->
dparms[0] == 0.0) {
487 debugMsg(boost::format(
"setting lo check freq to %lf\n") % cmd->
dparms[0]);
506 usrp->get_rx_rate()));
512 usrp->get_tx_rate()));
522 usrp->get_rx_gain()));
532 usrp->get_tx_gain()));
540 usrp->set_rx_gain(0.0);
543 usrp->get_tx_gain()));
550 debugMsg(boost::format(
"Current GPIO = %x ") %
551 dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX));
557 debugMsg(boost::format(
"New GPIO = %x ") %
dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX));
567 usrp->set_tx_gain(0.0);
581 debugMsg(boost::format(
"Got GPIO = %x ") %
582 dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX));
592 if((cmd->
iparms[0] & 1) == 1) {
593 debugMsg(
"Setting reference to external");
594 usrp->set_clock_source(std::string(
"external"));
597 debugMsg(
"Setting reference to internal");
598 usrp->set_clock_source(std::string(
"internal"));
604 debugMsg(boost::format(
"Got RX antenna as [%s]\n") %
usrp->get_rx_antenna());
611 debugMsg(boost::format(
"Got TX antenna as [%s]\n") %
usrp->get_tx_antenna());
653 usrp->get_rx_rate()));
657 usrp->get_tx_rate()));
662 if(
usrp->get_clock_source(0) == std::string(
"external")) {
668 uhd::sensor_value_t ref_locked =
usrp->get_mboard_sensor(
"ref_locked", 0);
669 if(ref_locked.to_bool()) {
680 (boost::format(
"%s\t%6.1f to %6.1f MHz")
710 catch (uhd::lookup_error & v) {
711 std::cerr <<
"No daughterboard interface found..." << std::endl;
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);
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);
728 dboard->set_gpio_ddr(uhd::usrp::dboard_iface::UNIT_TX,
732 dboard->set_pin_ctrl(uhd::usrp::dboard_iface::UNIT_TX,
736 dboard->set_gpio_out(uhd::usrp::dboard_iface::UNIT_TX,
740 std::cerr <<
"GPIO control of TX relay is disabled.\n" 741 <<
"This is normal if this radio is a B2xx.\n";
749 dboard->set_gpio_out(uhd::usrp::dboard_iface::UNIT_TX,
771 double r =
usrp->get_tx_rate();
772 debugMsg(boost::format(
"TX rate = %g\n") % r);
788 debugMsg(boost::format(
"Got %d from call to en/dis TX with val = %d")
791 debugMsg(boost::format(
"Got rx_fe enabled = %d from call to en/dis TX with val = %d")
798 unsigned int enabits = 0;
800 enabits =
dboard->get_gpio_out(uhd::usrp::dboard_iface::UNIT_TX);
809 unsigned int enabits = 0;
811 enabits =
dboard->read_gpio(uhd::usrp::dboard_iface::UNIT_TX);
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();
825 debugMsg(boost::format(
"Setting Transverter LO freq = %10lg power = %g gain = %g\n") % tvrt_lo_freq % power %
tvrt_lo_gain);
827 debugMsg(
"About to report Transverter LO setting.");
839 debugMsg(
"Enabling transverter LO\n");
840 usrp->set_tx_antenna(
"TX2", 1);
845 uhd::tune_result_t tres =
usrp->set_tx_freq(lo_freq_req, 1);
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);
860 usrp->set_tx_gain(0.0, 1);
861 usrp->set_tx_freq(100.0e6, 1);
866 debugMsg(boost::format(
"###### aTFC(%lf...)") % target_freq);
869 treq->dsp_freq_policy = uhd::tune_request_t::POLICY_AUTO;
870 treq->target_freq = target_freq;
872 treq->rf_freq = target_freq;
873 treq->rf_freq_policy = uhd::tune_request_t::POLICY_AUTO;
874 treq->args = uhd::device_addr_t(
"");
877 double steps[] = {12.5e6, 10.0e6, 50.0e6/3.0};
879 if(target_freq < 10.0e6) {
881 debugMsg(
"\t\treturns default request\n");
889 for(i = 0; i < 3; i++) {
890 N = round(target_freq / steps[i]);
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) {
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());
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;
912 rf_freq = N * steps[0];
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());
928 case uhd::msg::error:
929 std::cerr <<
"UHD ERROR: " << msg << std::flush;
931 case uhd::msg::warning:
932 std::cerr <<
"UHD WARNING: " << msg << std::flush;
935 SoDa::USRPCtrl::singleton_ctrl_obj->
debugMsg(msg);
942 uhd::tune_result_t tunres_int, tunres_frac;
948 debugMsg(
"Forced IntN Tuning support ON.");
951 else if(force_frac_N) {
952 debugMsg(
"Forced IntN Tuning support OFF.");
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")
983 debugMsg(boost::format(
"got tf = %g\n") % tf);
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");
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);
995 if(tunres_int.actual_rf_freq != tunres_frac.actual_rf_freq) {
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);
1006 debugMsg(
"Supports INT_N tuning mode.\n");
1009 debugMsg(
"Does not support INT_N tuning mode.\n");
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);
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);
1069 std::vector<std::string> ants;
1071 ants = (sel ==
'r') ?
usrp->get_rx_antennas() :
usrp->get_tx_antennas();
1073 std::string choice = ants[0];
1075 BOOST_FOREACH(std::string a, ants) {
1083 usrp->set_rx_antenna(choice);
1086 usrp->set_tx_antenna(choice);
uhd::usrp::multi_usrp::sptr usrp
to which USRP unit is this connected?
bool rx_fe_has_enable
can we access rx_fe_subtree/enabled ?
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.
Not many choices for TX ant, just TX.
SoDa::PropTree * tx_fe_subtree
property tree from daughtercard module
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...
bool is_B2xx
The B200 and B210 need some special handling, as they don't have frontend lock indications (as of 3...
The Thread baseclass for all SoDa thread objects.
void debugMsg(const std::string &msg, unsigned int threshold=1)
turn transmitter on and off.
Sample rate for RX is typically 600 KHz or better to allow a reasonable span for the waterfall and pe...
T * get(unsigned int subscriber_id)
double tvrt_lo_fe_freq
the frequency of the second transmit channel front-end oscillator
Sample rate for TX needs to be fast enough for reasonable FM We set it to 625000 just because there d...
std::string & getObjName()
get the name of this object
SoDa::TRControl * tr_control
external control widget for TR switching and other things.
uhd::tune_result_t last_tx_tune_result
TX tune result.
Set the TX final amplifier.
bool tx_has_lo_locked_sensor
does the tx frond end have an lo_locked sensor?
Set the RX front end attenuator/amp.
void disableTransverterLO()
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.
Though libuhd is designed to be re-entrant, there are some indications that all control functions (se...
std::string motherboard_name
The model name of the USRP unit.
void setBoolProp(const std::string &propname, const bool val=false)
void execGetCommand(Command *cmd)
Dispatch an incoming GET command.
int iparms[4]
integer parameters
static const double rxmode_offset
tx offset when in RX mode
double tx_samp_rate
sample rate to USRP TX chain.
Set the RX front end (1st LO, the 2nd IF LO), and the 3rd LO in a more-or-less optimal way to positio...
bool getTXRelayOn()
get the state of the TX relay confirm bit
void enableTransverterLO()
uhd::freq_range_t tx_rf_freq_range
property of the device – what is the min/maximum TX frequency?
This class handles command line parameters and built-ins.
The SoDa Exception class.
double rx_rf_gain
rf gain for RX front end amp/attenuator
Report the motherboard name (the model name of the USRP)
std::string getTXAnt() const
which port is the TX channel?
PropTree class encapsulates the USRP property tree functions to allow better trap and error recovery ...
bool supports_IntN_Mode
if true, this unit can tune the front-end LO
CmdTarget target
the thing we're touching
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.
void setStringProp(const std::string &propname, const std::string val=std::string("None"))
Report a string/name pair for modulation mode.
double getTime()
get the number of seconds since the "Epoch"
indicate to GUI that we've sent all the initial configuration information
double getRXRate() const
Sample rates and all that other stuff are fixed.
bool tx_on
if true, we are transmitting.
uhd::tune_result_t last_rx_tune_result
RX tune result – actual LO and DSP freq.
bool getBoolProp(const std::string &propname, const bool defval=false)
void set1stLOFreq(double freq, char sel, bool set_if_freq=false)
Set the front-end (LO + DDS) frequency to 'freq' This includes setting the PLL front end synthesizer ...
static void normal_message_handler(uhd::msg::type_t type, const std::string &msg)
This is the more permanent message handler...
void reportAntennas()
report the antennas that are available, send the report on cmd_stream
double tx_freq
remember current tx freq
On receipt of a STOP command, all threads should exit their run loop.
void setTXEna(bool val)
turn TX on/off
This is a list of all the commands that can "do something" to one or more components in the SoDa radi...
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 ...
Same effect as TX_TUNE_FREQ.
double tx_rf_gain
rf gain for final TX amp
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...
char sparm[64]
a buffer holding the string
bool tx_fe_has_enable
can we access tx_fe_subtree/enabled ?
void setTransverterLOFreqPower(double freq, double power)
set the transverter LO frequency and power This code does not work for libUHD after 3...
uhd::gain_range_t tx_rf_gain_range
property of the device – what is the min/maximum TX gain setting?
void reportAFFilters()
report the audio filters that are implemented, send the report on cmd_stream
std::string getStringProp(const std::string &propname, const std::string defval=std::string("None"))
double getTXRate() const
TX rate will always be 625K.
Set the RX front end 1st LO and the 2nd IF LO.
bool supports_tx_gpio
does this unit support GPIO signals? (B2xx does not as of 3.7.0)
Report TX antenna choice (asciiz string, uint tag)
bool getTXEna()
get the state of the TXEna bit
std::string getRXAnt() const
which port is the RX channel?
RX ant choices are TX/RX, and RX2.
uhd::usrp::dboard_iface::sptr dboard
the daughterboard we're controlling
double first_gettime
timestamps are relative to the first timestamp.
std::string getRadioArgs() const
return args that point to a particular USRP unit
static const unsigned int TX_RELAY_MON
mask for RELAY sense bit
CmdType cmd
the command type (SET, GET, REP)
void initControlGPIO()
Initialize the GPIO control registers to set the direction and enables for the TX/RX relay output and...
double dparms[4]
double float parameters
void testIntNMode(bool force_int_N, bool force_frac_N)
Test for support for integer-N synthesis.
double last_rx_req_freq
remember the last setting – useful for "calibration check"
Thread class that owns the USRP control channel and functions.
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.
void reportModes()
report the modulation modes that are implemented, send the report on cmd_stream
Tune the 3rd LO, if the current FE frequency is such that the desired frequency is between RX_FE_FREQ...
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 ...
bool tvrt_lo_mode
if true, set the transmit frequency, with some knowledge of the tvrt LO.
void setTXFrontEndEnable(bool val)
set TX enable property on front-end module – not present in all daughtercards... ...
Tune the 3rd LO (in SoDa::USRPRX).
double tvrt_lo_freq
the frequency of the second transmit channel oscillator
unsigned int subid
subscriber ID for this thread's connection to the command channel
bool rx_has_lo_locked_sensor
does the rx frond end have an lo_locked sensor?
Set the TX front end (1st LO, the 2nd IF LO), and the 3rd LO in a more-or-less optimal way to positio...
double tvrt_lo_gain
output power for the second transmit channel (used for transverter LO)
uhd::freq_range_t rx_rf_freq_range
property of the device – what is the min/maximum RX frequency?
std::string tx_ant
TX antenna choice (usually has to be TX or TX/RX1?
Report a string/name pair for AF filter bandwidth.
Report RX antenna choice (asciiz string, uint tag)
void run()
start the thread
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.
Manage front end settings for Ettus USRP devices Functions that return a property tree corresponding ...
CmdMBox * cmd_stream
command stream channel
bool hasProperty(const std::string &propname)
does the property tree have this property name as a child?
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.
On receipt of a TVRT_LO_CONFIG command , set the TX2 channel frequency to dparam[0] and the TX2 outpu...
SoDa::PropTree * rx_fe_subtree
property tree from daughtercard module
Same effect as TX_TUNE_FREQ.
USRPCtrl(Params *params, CmdMBox *_cmd_stream)
Constructor Build a USRPCtrl thread.
uhd::gain_range_t rx_rf_gain_range
property of the device – what is the min/maximum RX gain setting?
std::string getClockSource() const
where does the reference come from?
void execRepCommand(Command *cmd)
Dispatch an incoming REPort command.
std::string toString() const
return a string that displays the command
void setAntenna(const std::string &ant, char sel)
Set the antenna choice.
void execSetCommand(Command *cmd)
Dispatch an incoming SET command.
this is a GET/REP command – BaseBandRX takes FFT centered around 0 and reports largest peak within 5...
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...
void execCommand(Command *cmd)
Parse an incoming command and dispatch.
bool is_B210
the B210 has two tx channels – use the second for a Transverter LO – see USRPLO ...