summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/exception.cpp4
-rw-r--r--host/lib/usrp/dboard/db_wbx_common.cpp97
-rw-r--r--host/lib/usrp/dboard/db_wbx_common.hpp6
-rw-r--r--host/lib/usrp/dboard/db_wbx_simple.cpp2
-rw-r--r--host/lib/usrp/gps_ctrl.cpp210
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp24
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp12
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp4
8 files changed, 243 insertions, 116 deletions
diff --git a/host/lib/exception.cpp b/host/lib/exception.cpp
index ecb1fe768..ea056bd3b 100644
--- a/host/lib/exception.cpp
+++ b/host/lib/exception.cpp
@@ -27,7 +27,9 @@ exception::exception(const std::string &what):
#define make_exception_impl(name, class, base) \
class::class(const std::string &what): \
base(str(boost::format("%s: %s") % name % what)){} \
- unsigned class::code(void) const{return boost::hash<std::string>()(#class) & 0xfff;}
+ unsigned class::code(void) const{return boost::hash<std::string>()(#class) & 0xfff;} \
+ class *class::dynamic_clone(void) const{return new class(*this);} \
+ void class::dynamic_throw(void) const{throw *this;}
make_exception_impl("AssertionError", assertion_error, exception)
make_exception_impl("LookupError", lookup_error, exception)
diff --git a/host/lib/usrp/dboard/db_wbx_common.cpp b/host/lib/usrp/dboard/db_wbx_common.cpp
index a1b1437a2..1a016e89c 100644
--- a/host/lib/usrp/dboard/db_wbx_common.cpp
+++ b/host/lib/usrp/dboard/db_wbx_common.cpp
@@ -35,6 +35,14 @@
#define RX_ATTN_SHIFT 8 // lsb of RX Attenuator Control
#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) // valid bits of RX Attenuator Control
+// TX Attenuator Pins (v3 only)
+#define TX_ATTN_16 (1 << 14)
+#define TX_ATTN_8 (1 << 5)
+#define TX_ATTN_4 (1 << 4)
+#define TX_ATTN_2 (1 << 3)
+#define TX_ATTN_1 (1 << 1)
+#define TX_ATTN_MASK (TX_ATTN_16|TX_ATTN_8|TX_ATTN_4|TX_ATTN_2|TX_ATTN_1) // valid bits of TX Attenuator Control
+
// Mixer functions
#define TX_MIXER_ENB (TXMOD_EN|ADF4350_PDBRF)
#define TX_MIXER_DIS 0
@@ -43,7 +51,7 @@
#define RX_MIXER_DIS 0
// Power functions
-#define TX_POWER_UP (TX_PUP_5V|TX_PUP_3V|ADF4350_CE) // high enables power supply
+#define TX_POWER_UP (TX_PUP_5V|TX_PUP_3V) // high enables power supply
#define TX_POWER_DOWN 0
#define RX_POWER_UP (RX_PUP_5V|RX_PUP_3V|ADF4350_CE) // high enables power supply
@@ -75,6 +83,10 @@ static const uhd::dict<std::string, gain_range_t> wbx_tx_gain_ranges = map_list_
("PGA0", gain_range_t(0, 25, 0.05))
;
+static const uhd::dict<std::string, gain_range_t> wbx_v3_tx_gain_ranges = map_list_of
+ ("PGA0", gain_range_t(0, 31, 1.0))
+;
+
static const uhd::dict<std::string, gain_range_t> wbx_rx_gain_ranges = map_list_of
("PGA0", gain_range_t(0, 31.5, 0.5))
;
@@ -88,10 +100,13 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){
this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true);
this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);
+ //v3 has different io bits for attenuator control
+ int v3_iobits = is_v3() ? TX_ATTN_MASK : ADF4350_CE;
+
//set the gpio directions and atr controls
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXMOD_EN|ADF4350_PDBRF);
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB|ADF4350_PDBRF);
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TX_PUP_5V|TX_PUP_3V|ADF4350_CE|TXMOD_EN|ADF4350_PDBRF);
+ this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TX_PUP_5V|TX_PUP_3V|TXMOD_EN|ADF4350_PDBRF|v3_iobits);
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF4350_CE|RXBB_PDB|ADF4350_PDBRF|RX_ATTN_MASK);
//setup ATR for the mixer enables (always enabled to prevent phase slip between bursts)
@@ -106,9 +121,17 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
//set some default values
- BOOST_FOREACH(const std::string &name, wbx_tx_gain_ranges.keys()){
- set_tx_gain(wbx_tx_gain_ranges[name].start(), name);
+ if (is_v3()) {
+ BOOST_FOREACH(const std::string &name, wbx_v3_tx_gain_ranges.keys()){
+ set_tx_gain(wbx_v3_tx_gain_ranges[name].start(), name);
+ }
+ }
+ else {
+ BOOST_FOREACH(const std::string &name, wbx_tx_gain_ranges.keys()){
+ set_tx_gain(wbx_tx_gain_ranges[name].start(), name);
+ }
}
+
BOOST_FOREACH(const std::string &name, wbx_rx_gain_ranges.keys()){
set_rx_gain(wbx_rx_gain_ranges[name].start(), name);
}
@@ -131,7 +154,7 @@ void wbx_base::set_rx_enabled(bool enb){
void wbx_base::set_tx_enabled(bool enb){
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX,
- (enb)? TX_POWER_UP : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN
+ (enb)? TX_POWER_UP | ADF4350_CE : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN | (is_v3() ? 0 : ADF4350_CE)
);
}
@@ -150,7 +173,7 @@ static int rx_pga0_gain_to_iobits(double &gain){
int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK;
UHD_LOGV(often) << boost::format(
- "WBX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x"
+ "WBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x"
) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK << std::endl;
//the actual gain setting
@@ -159,6 +182,35 @@ static int rx_pga0_gain_to_iobits(double &gain){
return iobits;
}
+//v3 TX gains
+static int tx_pga0_gain_to_iobits(double &gain){
+ //clip the input
+ gain = wbx_v3_tx_gain_ranges["PGA0"].clip(gain);
+
+ //convert to attenuation
+ double attn = wbx_v3_tx_gain_ranges["PGA0"].stop() - gain;
+
+ //calculate the attenuation
+ int attn_code = boost::math::iround(attn*2);
+ int iobits = (
+ (attn_code & 16 ? 0 : TX_ATTN_16) |
+ (attn_code & 8 ? 0 : TX_ATTN_8) |
+ (attn_code & 4 ? 0 : TX_ATTN_4) |
+ (attn_code & 2 ? 0 : TX_ATTN_2) |
+ (attn_code & 1 ? 0 : TX_ATTN_1)
+ ) & TX_ATTN_MASK;
+
+ UHD_LOGV(often) << boost::format(
+ "WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x"
+ ) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK << std::endl;
+
+ //the actual gain setting
+ gain = wbx_v3_tx_gain_ranges["PGA0"].stop() - double(attn_code)/2;
+
+ return iobits;
+}
+
+//Pre v3 TX gains
static double tx_pga0_gain_to_dac_volts(double &gain){
//clip the input
gain = wbx_tx_gain_ranges["PGA0"].clip(gain);
@@ -181,15 +233,28 @@ static double tx_pga0_gain_to_dac_volts(double &gain){
}
void wbx_base::set_tx_gain(double gain, const std::string &name){
- assert_has(wbx_tx_gain_ranges.keys(), name, "wbx tx gain name");
- if(name == "PGA0"){
- double dac_volts = tx_pga0_gain_to_dac_volts(gain);
- _tx_gains[name] = gain;
-
- //write the new voltage to the aux dac
- this->get_iface()->write_aux_dac(dboard_iface::UNIT_TX, dboard_iface::AUX_DAC_A, dac_volts);
+ if (is_v3()) {
+ assert_has(wbx_v3_tx_gain_ranges.keys(), name, "wbx tx gain name");
+ if(name == "PGA0"){
+ double dac_volts = tx_pga0_gain_to_iobits(gain);
+ _tx_gains[name] = gain;
+
+ //write the new voltage to the aux dac
+ this->get_iface()->write_aux_dac(dboard_iface::UNIT_TX, dboard_iface::AUX_DAC_A, dac_volts);
+ }
+ else UHD_THROW_INVALID_CODE_PATH();
+ }
+ else {
+ assert_has(wbx_tx_gain_ranges.keys(), name, "wbx tx gain name");
+ if(name == "PGA0"){
+ double dac_volts = tx_pga0_gain_to_dac_volts(gain);
+ _tx_gains[name] = gain;
+
+ //write the new voltage to the aux dac
+ this->get_iface()->write_aux_dac(dboard_iface::UNIT_TX, dboard_iface::AUX_DAC_A, dac_volts);
+ }
+ else UHD_THROW_INVALID_CODE_PATH();
}
- else UHD_THROW_INVALID_CODE_PATH();
}
void wbx_base::set_rx_gain(double gain, const std::string &name){
@@ -381,6 +446,10 @@ bool wbx_base::get_locked(dboard_iface::unit_t unit){
return (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0;
}
+bool wbx_base::is_v3(void){
+ return get_rx_id() == 0x057;
+}
+
/***********************************************************************
* RX Get and Set
**********************************************************************/
diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp
index 07e84a565..5d33ddce9 100644
--- a/host/lib/usrp/dboard/db_wbx_common.hpp
+++ b/host/lib/usrp/dboard/db_wbx_common.hpp
@@ -62,6 +62,12 @@ protected:
*/
virtual bool get_locked(dboard_iface::unit_t unit);
+ /*!
+ * Detect if this a v3 WBX
+ * \return true for locked
+ */
+ virtual bool is_v3(void);
+
private:
uhd::dict<std::string, double> _tx_gains, _rx_gains;
bool _rx_enabled, _tx_enabled;
diff --git a/host/lib/usrp/dboard/db_wbx_simple.cpp b/host/lib/usrp/dboard/db_wbx_simple.cpp
index 82405135e..602ce389d 100644
--- a/host/lib/usrp/dboard/db_wbx_simple.cpp
+++ b/host/lib/usrp/dboard/db_wbx_simple.cpp
@@ -76,6 +76,8 @@ static dboard_base::sptr make_wbx_simple(dboard_base::ctor_args_t args){
UHD_STATIC_BLOCK(reg_wbx_simple_dboards){
dboard_manager::register_dboard(0x0053, 0x0052, &make_wbx_simple, "WBX");
dboard_manager::register_dboard(0x0053, 0x004f, &make_wbx_simple, "WBX + Simple GDB");
+ dboard_manager::register_dboard(0x0057, 0x0056, &make_wbx_simple, "WBX v3");
+ dboard_manager::register_dboard(0x0057, 0x004f, &make_wbx_simple, "WBX v3 + Simple GDB");
}
/***********************************************************************
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index 3bee26340..3cef1ef19 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -17,23 +17,26 @@
#include <uhd/usrp/gps_ctrl.hpp>
#include <uhd/utils/msg.hpp>
+#include <uhd/utils/props.hpp>
#include <uhd/exception.hpp>
+#include <uhd/types/sensors.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/assign/list_of.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
-#include <boost/algorithm/string/trim.hpp>
#include <boost/tokenizer.hpp>
using namespace uhd;
using namespace boost::gregorian;
using namespace boost::posix_time;
using namespace boost::algorithm;
+using namespace boost::this_thread;
/*!
* A GPS control for Jackson Labs devices (and other NMEA compatible GPS's)
*/
-//TODO: multiple baud rate support (requires mboard_impl changes for poking UART registers)
class gps_ctrl_impl : public gps_ctrl{
public:
gps_ctrl_impl(gps_send_fn_t send, gps_recv_fn_t recv){
@@ -42,74 +45,41 @@ public:
std::string reply;
bool i_heard_some_nmea = false, i_heard_something_weird = false;
-
gps_type = GPS_TYPE_NONE;
-
-// set_uart_baud_rate(GPS_UART, 115200);
- //first we look for a Jackson Labs Firefly (since that's what we sell with the USRP2+...)
-
+
+ //first we look for a Jackson Labs Firefly (since that's what we provide...)
_recv(); //get whatever junk is in the rx buffer right now, and throw it away
_send("HAAAY GUYYYYS\n"); //to elicit a response from the Firefly
//then we loop until we either timeout, or until we get a response that indicates we're a JL device
int timeout = GPS_TIMEOUT_TRIES;
while(timeout--) {
- reply = safe_gps_read();
- if(trim_right_copy(reply) == "Command Error") {
+ reply = _recv();
+ if(reply.find("Command Error") != std::string::npos) {
gps_type = GPS_TYPE_JACKSON_LABS;
break;
}
else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response
else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate
- boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ sleep(milliseconds(200));
}
if((i_heard_some_nmea) && (gps_type != GPS_TYPE_JACKSON_LABS)) gps_type = GPS_TYPE_GENERIC_NMEA;
- //otherwise, we can try some other common baud rates looking to see if a GPS is connected (todo, later)
if((gps_type == GPS_TYPE_NONE) && i_heard_something_weird) {
UHD_MSG(error) << "GPS invalid reply \"" << reply << "\", assuming none available" << std::endl;
}
- bool found_gprmc = false;
-
switch(gps_type) {
case GPS_TYPE_JACKSON_LABS:
UHD_MSG(status) << "Found a Jackson Labs GPS" << std::endl;
- //issue some setup stuff so it spits out the appropriate data
- //none of these should issue replies so we don't bother looking for them
- //we have to sleep between commands because the JL device, despite not acking, takes considerable time to process each command.
- boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS));
- _send("SYST:COMM:SER:ECHO OFF\n");
- boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS));
- _send("SYST:COMM:SER:PRO OFF\n");
- boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS));
- _send("GPS:GPGGA 0\n");
- boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS));
- _send("GPS:GGAST 0\n");
- boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS));
- _send("GPS:GPRMC 1\n");
- boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS));
-
-// break;
+ init_firefly();
case GPS_TYPE_GENERIC_NMEA:
if(gps_type == GPS_TYPE_GENERIC_NMEA) UHD_MSG(status) << "Found a generic NMEA GPS device" << std::endl;
- found_gprmc = false;
- //here we loop around looking for a GPRMC packet. if we don't get one, we don't have a usable GPS.
- timeout = GPS_TIMEOUT_TRIES;
- while(timeout--) {
- reply = safe_gps_read();
- if(reply.substr(0, 6) == "$GPRMC") {
- found_gprmc = true;
- break;
- }
- boost::this_thread::sleep(boost::posix_time::milliseconds(200));
- }
- if(!found_gprmc) {
- if(gps_type == GPS_TYPE_JACKSON_LABS) UHD_MSG(error) << "Firefly GPS not locked or warming up." << std::endl;
- else UHD_MSG(error) << "GPS does not output GPRMC packets. Cannot retrieve time." << std::endl;
- gps_type = GPS_TYPE_NONE;
+ if(get_time() == ptime()) {
+ UHD_MSG(status) << "No valid GPRMC packet found. Ignoring discovered GPS.";
+ gps_type = GPS_TYPE_NONE;
}
break;
@@ -118,71 +88,134 @@ public:
break;
}
-
-
}
~gps_ctrl_impl(void){
+ /* NOP */
+ }
+ //return a list of supported sensors
+ std::vector<std::string> get_sensors(void) {
+ std::vector<std::string> ret = boost::assign::list_of
+ ("gps_gpgga")
+ ("gps_gprmc")
+ ("gps_gpgsa")
+ ("gps_time")
+ ("gps_locked");
+ return ret;
}
- std::string safe_gps_read() {
- return _recv();
+ uhd::sensor_value_t get_sensor(std::string key) {
+ if(key == "gps_gpgga"
+ or key == "gps_gprmc"
+ or key == "gps_gpgsa") {
+ return sensor_value_t(
+ boost::to_upper_copy(key),
+ get_nmea(boost::to_upper_copy(key.substr(4,8))),
+ "");
+ }
+ else if(key == "gps_time") {
+ return sensor_value_t("GPS epoch time", int(get_epoch_time()), "seconds");
+ }
+ else if(key == "gps_locked") {
+ return sensor_value_t("GPS lock status", locked(), "locked", "unlocked");
+ }
+ else {
+ UHD_THROW_PROP_GET_ERROR();
+ }
}
- ptime get_time(void) {
+private:
+ void init_firefly(void) {
+ //issue some setup stuff so it spits out the appropriate data
+ //none of these should issue replies so we don't bother looking for them
+ //we have to sleep between commands because the JL device, despite not acking, takes considerable time to process each command.
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("SYST:COMM:SER:ECHO OFF\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("SYST:COMM:SER:PRO OFF\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("GPS:GPGGA 1\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("GPS:GGAST 0\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("GPS:GPRMC 1\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("GPS:GPGSA 1\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ }
+
+ //retrieve a raw NMEA sentence
+ std::string get_nmea(std::string msgtype) {
+ msgtype.insert(0, "$");
std::string reply;
- ptime now;
- boost::tokenizer<boost::escaped_list_separator<char> > tok(reply);
- std::vector<std::string> toked;
+ if(not gps_detected()) {
+ UHD_MSG(error) << "get_nmea(): unsupported GPS or no GPS detected";
+ return std::string();
+ }
int timeout = GPS_TIMEOUT_TRIES;
- bool found_gprmc = false;
- switch(gps_type) {
- case GPS_TYPE_JACKSON_LABS: //deprecated in favor of a single NMEA parser
- case GPS_TYPE_GENERIC_NMEA:
+ while(timeout--) {
+ reply = _recv();
+ if(reply.substr(0, 6) == msgtype)
+ return reply;
+ boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
+ }
+ UHD_MSG(error) << "get_nmea(): no " << msgtype << " message found";
+ return std::string();
+ }
- while(timeout--) {
- reply = safe_gps_read();
- if(reply.substr(0, 6) == "$GPRMC") {
- found_gprmc = true;
- break;
- }
- boost::this_thread::sleep(boost::posix_time::milliseconds(200));
- }
- UHD_ASSERT_THROW(found_gprmc);
-
- tok.assign(reply);
- toked.assign(tok.begin(), tok.end());
-
- UHD_ASSERT_THROW(toked.size() == 12); //if it's not we got something weird in there
-
- now = ptime( date(
- greg_year(boost::lexical_cast<int>(toked[9].substr(4, 2)) + 2000), //just trust me on this one
- greg_month(boost::lexical_cast<int>(toked[9].substr(2, 2))),
- greg_day(boost::lexical_cast<int>(toked[9].substr(0, 2)))
- ),
- hours( boost::lexical_cast<int>(toked[1].substr(0, 2)))
- + minutes(boost::lexical_cast<int>(toked[1].substr(2, 2)))
- + seconds(boost::lexical_cast<int>(toked[1].substr(4, 2)))
- );
- break;
- case GPS_TYPE_NONE:
- default:
- throw uhd::runtime_error("get_time(): Unsupported GPS or no GPS detected\n");
- break;
+ //helper function to retrieve a field from an NMEA sentence
+ std::string get_token(std::string sentence, size_t offset) {
+ boost::tokenizer<boost::escaped_list_separator<char> > tok(sentence);
+ std::vector<std::string> toked;
+
+ tok.assign(sentence);
+ toked.assign(tok.begin(), tok.end());
+
+ if(toked.size() <= offset) {
+ UHD_MSG(error) << "get_token: too few tokens in reply " << sentence;
+ return std::string();
}
- return now;
+ return toked[offset];
+ }
+
+ ptime get_time(void) {
+ std::string reply = get_nmea("GPRMC");
+
+ std::string datestr = get_token(reply, 9);
+ std::string timestr = get_token(reply, 1);
+
+ if(datestr.size() == 0 or timestr.size() == 0) {
+ return ptime();
+ }
+
+ //just trust me on this one
+ return ptime( date(
+ greg_year(boost::lexical_cast<int>(datestr.substr(4, 2)) + 2000),
+ greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))),
+ greg_day(boost::lexical_cast<int>(datestr.substr(0, 2)))
+ ),
+ hours( boost::lexical_cast<int>(timestr.substr(0, 2)))
+ + minutes(boost::lexical_cast<int>(timestr.substr(2, 2)))
+ + seconds(boost::lexical_cast<int>(timestr.substr(4, 2)))
+ );
}
time_t get_epoch_time(void) {
- return (get_time() - boost::posix_time::from_time_t(0)).total_seconds();
+ return (get_time() - from_time_t(0)).total_seconds();
}
bool gps_detected(void) {
return (gps_type != GPS_TYPE_NONE);
}
-private:
+ bool locked(void) {
+ std::string reply = get_nmea("GPGGA");
+ if(reply.size() <= 1) return false;
+
+ return (get_token(reply, 6) != "0");
+ }
+
gps_send_fn_t _send;
gps_recv_fn_t _recv;
@@ -195,7 +228,6 @@ private:
static const int GPS_TIMEOUT_TRIES = 10;
static const int GPS_TIMEOUT_DELAY_MS = 200;
static const int FIREFLY_STUPID_DELAY_MS = 200;
-
};
/***********************************************************************
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 197296cf0..5583a4335 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -149,7 +149,13 @@ usrp2_mboard_impl::usrp2_mboard_impl(
(_mimo_clocking_mode_is_master?"master":"slave") << std::endl;
//init the clock config
- _clock_config = clock_config_t::internal();
+ if(_iface->mb_eeprom["gpsdo"] == "internal" or
+ _iface->mb_eeprom["gpsdo"] == "external") {
+ _clock_config = clock_config_t::external();
+ }
+ else {
+ _clock_config = clock_config_t::internal();
+ }
update_clock_config();
//init the codec before the dboard
@@ -174,6 +180,13 @@ usrp2_mboard_impl::usrp2_mboard_impl(
_iface->poke32(U2_REG_RX_CTRL_CLEAR(i), 1); //resets sequence
}
//------------------------------------------------------------------
+
+ //initialize VITA time to GPS time
+ if( _gps_ctrl.get()
+ and _gps_ctrl->gps_detected()) {
+ UHD_MSG(status) << "Setting device time to GPS time...\n";
+ set_time_spec(time_spec_t(double(_gps_ctrl->get_sensor("gps_time").to_int()+1)), false);
+ }
}
usrp2_mboard_impl::~usrp2_mboard_impl(void){UHD_SAFE_CALL(
@@ -375,7 +388,10 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
case SUBDEV_PROP_SENSOR_NAMES:{
prop_names_t names = boost::assign::list_of("mimo_locked")("ref_locked");
- if (_gps_ctrl.get()) names.push_back("gps_time");
+ if (_gps_ctrl.get()) {
+ std::vector<std::string> gs = _gps_ctrl->get_sensors();
+ names.insert(names.end(), gs.begin(), gs.end());
+ }
val = names;
}
return;
@@ -389,8 +405,8 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
val = sensor_value_t("Ref", this->get_ref_locked(), "locked", "unlocked");
return;
}
- else if(key.name == "gps_time" and _gps_ctrl.get()) {
- val = sensor_value_t("GPS time", int(_gps_ctrl->get_epoch_time()), "seconds");
+ else if(uhd::has(_gps_ctrl->get_sensors(), key.name) and _gps_ctrl.get()) {
+ val = _gps_ctrl->get_sensor(key.name);
}
else {
UHD_THROW_PROP_GET_ERROR();
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index ec1a2e94c..6ba364b28 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -179,7 +179,7 @@ public:
template <class T, usrp2_reg_action_t action>
T get_reg(boost::uint32_t addr, T data = 0){
//setup the out data
- usrp2_ctrl_data_t out_data;
+ usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
out_data.id = htonl(USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO);
out_data.data.reg_args.addr = htonl(addr);
out_data.data.reg_args.data = htonl(boost::uint32_t(data));
@@ -207,7 +207,7 @@ public:
;
//setup the out data
- usrp2_ctrl_data_t out_data;
+ usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO);
out_data.data.spi_args.dev = htonl(which_slave);
out_data.data.spi_args.miso_edge = spi_edge_to_otw[config.miso_edge];
@@ -228,7 +228,7 @@ public:
**********************************************************************/
void write_i2c(boost::uint8_t addr, const byte_vector_t &buf){
//setup the out data
- usrp2_ctrl_data_t out_data;
+ usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO);
out_data.data.i2c_args.addr = addr;
out_data.data.i2c_args.bytes = buf.size();
@@ -246,7 +246,7 @@ public:
byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){
//setup the out data
- usrp2_ctrl_data_t out_data;
+ usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO);
out_data.data.i2c_args.addr = addr;
out_data.data.i2c_args.bytes = num_bytes;
@@ -276,7 +276,7 @@ public:
BOOST_FOREACH(std::string item, queue) {
//setup the out data
- usrp2_ctrl_data_t out_data;
+ usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
out_data.id = htonl(USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO);
out_data.data.uart_args.dev = dev;
out_data.data.uart_args.bytes = item.size();
@@ -298,7 +298,7 @@ public:
std::string result;
while(readlen == 20) { //while we keep receiving full packets
//setup the out data
- usrp2_ctrl_data_t out_data;
+ usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
out_data.id = htonl(USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO);
out_data.data.uart_args.dev = dev;
out_data.data.uart_args.bytes = 20;
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 9947e71e7..aa584ac8b 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -93,7 +93,7 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){
);
//send a hello control packet
- usrp2_ctrl_data_t ctrl_data_out;
+ usrp2_ctrl_data_t ctrl_data_out = usrp2_ctrl_data_t();
ctrl_data_out.proto_ver = uhd::htonx<boost::uint32_t>(USRP2_FW_COMPAT_NUM);
ctrl_data_out.id = uhd::htonx<boost::uint32_t>(USRP2_CTRL_ID_WAZZUP_BRO);
udp_transport->send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out)));
@@ -249,7 +249,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
//extract the user's requested MTU size or default
mtu_result_t user_mtu;
user_mtu.recv_mtu = size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu));
- user_mtu.send_mtu = size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu));
+ user_mtu.send_mtu = size_t(device_addr.cast<double>("send_frame_size", udp_simple::mtu));
try{
//calculate the minimum send and recv mtu of all devices