diff options
| author | Josh Blum <josh@joshknows.com> | 2011-06-25 20:22:12 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2011-06-25 20:22:12 -0700 | 
| commit | b8d0dc0918c90c03b5e69593c8f79b5457aa5d7a (patch) | |
| tree | a5003aa4e1e44b619b41e0b819700b09fc65cee5 /host/lib | |
| parent | 58679377fba07be56548874ed117a76eae79e846 (diff) | |
| parent | 25d6e39c6af61acde0616cf50178d40741c4eace (diff) | |
| download | uhd-b8d0dc0918c90c03b5e69593c8f79b5457aa5d7a.tar.gz uhd-b8d0dc0918c90c03b5e69593c8f79b5457aa5d7a.tar.bz2 uhd-b8d0dc0918c90c03b5e69593c8f79b5457aa5d7a.zip | |
Merge branch 'master' into next
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/exception.cpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_common.cpp | 97 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_common.hpp | 6 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_simple.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/gps_ctrl.cpp | 210 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 24 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 4 | 
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 | 
