diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 97 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.hpp | 6 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.hpp | 2 | 
6 files changed, 82 insertions, 36 deletions
| diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index ae098dba6..7705037dd 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -80,6 +80,9 @@ usrp2_mboard_impl::usrp2_mboard_impl(          ) % int(USRP2_FPGA_COMPAT_NUM) % fpga_compat_num));      } +    //lock the device/motherboard to this process +    _iface->lock_device(true); +      //construct transports for dsp and async errors      std::cout << "Making transport for DSP0..." << std::endl;      device.dsp_xports.push_back(udp_zero_copy::make( diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 87a878b10..4bcc61444 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -26,7 +26,10 @@  #include <boost/assign/list_of.hpp>  #include <boost/format.hpp>  #include <boost/tokenizer.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/barrier.hpp>  #include <algorithm> +#include <iostream>  using namespace uhd;  using namespace uhd::usrp; @@ -41,6 +44,9 @@ static const boost::uint32_t MIN_PROTO_COMPAT_I2C = 7;  static const boost::uint32_t MIN_PROTO_COMPAT_REG = USRP2_FW_COMPAT_NUM;  static const boost::uint32_t MIN_PROTO_COMPAT_UART = 7; +// Map for virtual firmware regs (not very big so we can keep it here for now) +#define U2_FW_REG_LOCK_TIME 0 +  class usrp2_iface_impl : public usrp2_iface{  public:  /*********************************************************************** @@ -62,21 +68,50 @@ public:          _protocol_compat = ntohl(ctrl_data.proto_ver);          mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_N100); -        switch(this->get_rev()){ -        case USRP2_REV3: -        case USRP2_REV4: -            regs = usrp2_get_regs(false); -            break; - -        case USRP_N200: -        case USRP_N210: -            regs = usrp2_get_regs(true); -            break; - -        case USRP_NXXX: //fallthough case is old register map (USRP2) -            regs = usrp2_get_regs(false); -            break; +        regs = usrp2_get_regs(); //reg map identical across all boards +    } + +    ~usrp2_iface_impl(void){ +        this->lock_device(false); +    } + +/*********************************************************************** + * Device locking + **********************************************************************/ + +    void lock_device(bool lock){ +        if (lock){ +            boost::barrier spawn_barrier(2); +            _lock_thread_group.create_thread(boost::bind(&usrp2_iface_impl::lock_loop, this, boost::ref(spawn_barrier))); +            spawn_barrier.wait();          } +        else{ +            _lock_thread_group.interrupt_all(); +            _lock_thread_group.join_all(); +        } +    } + +    bool is_device_locked(void){ +        boost::uint32_t lock_secs = this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_LOCK_TIME); +        boost::uint32_t curr_secs = this->peek32(this->regs.time64_secs_rb_imm); +        return (curr_secs - lock_secs < 3); //if the difference is larger, assume not locked anymore +    } + +    void lock_loop(boost::barrier &spawn_barrier){ +        spawn_barrier.wait(); + +        try{ +            while(true){ +                //re-lock in loop +                boost::uint32_t curr_secs = this->peek32(this->regs.time64_secs_rb_imm); +                this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_POKE32>(U2_FW_REG_LOCK_TIME, curr_secs); +                //sleep for a bit +                boost::this_thread::sleep(boost::posix_time::milliseconds(1500)); +            } +        } catch(const boost::thread_interrupted &){} + +        //unlock on exit +        this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_POKE32>(U2_FW_REG_LOCK_TIME, 0);      }  /*********************************************************************** @@ -98,6 +133,21 @@ public:          return this->get_reg<boost::uint16_t, USRP2_REG_ACTION_FPGA_PEEK16>(addr);      } +    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; +        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)); +        out_data.data.reg_args.action = action; + +        //send and recv +        usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_REG); +        UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE); +        return T(ntohl(in_data.data.reg_args.data)); +    } +  /***********************************************************************   * SPI   **********************************************************************/ @@ -302,23 +352,8 @@ private:      boost::uint32_t _ctrl_seq_num;      boost::uint32_t _protocol_compat; -/*********************************************************************** - * Private Templated Peek and Poke - **********************************************************************/ -    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; -        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)); -        out_data.data.reg_args.action = action; - -        //send and recv -        usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_REG); -        UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE); -        return T(ntohl(in_data.data.reg_args.data)); -    } +    //lock thread stuff +    boost::thread_group _lock_thread_group;  };  /*********************************************************************** diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index 08f3955f1..e4d1a166b 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -66,6 +66,12 @@ public:      //! Get the canonical name for this device      virtual const std::string get_cname(void) = 0; +    //! Lock the device to this iface +    virtual void lock_device(bool lock) = 0; + +    //! Is this device locked? +    virtual bool is_device_locked(void) = 0; +      /*!       * Register map selected from USRP2/USRP2+.       */ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 48443bba4..2d1f901d7 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -115,9 +115,11 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){              //Attempt to read the name from the EEPROM and perform filtering.              //This operation can throw due to compatibility mismatch.              try{ -                mboard_eeprom_t mb_eeprom = usrp2_iface::make(udp_simple::make_connected( -                    new_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT) -                ))->mb_eeprom; +                usrp2_iface::sptr iface = usrp2_iface::make(udp_simple::make_connected( +                    new_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) +                )); +                if (iface->is_device_locked()) continue; //ignore locked devices +                mboard_eeprom_t mb_eeprom = iface->mb_eeprom;                  new_addr["name"] = mb_eeprom["name"];                  new_addr["serial"] = mb_eeprom["serial"];              } diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp index 57ae36857..240bc3bab 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.cpp +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -56,7 +56,7 @@ int sr_addr(int sr) {      return SETTING_REGS_BASE + (4 * sr);  } -usrp2_regs_t usrp2_get_regs(bool) { +usrp2_regs_t usrp2_get_regs(void) {    usrp2_regs_t x;    x.misc_ctrl_clock = sr_addr(0);    x.misc_ctrl_serdes = sr_addr(1); diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index b50f8b506..8390f065d 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -88,7 +88,7 @@ typedef struct {  extern const usrp2_regs_t usrp2_regs; //the register definitions, set in usrp2_regs.cpp and usrp2p_regs.cpp -usrp2_regs_t usrp2_get_regs(bool); +usrp2_regs_t usrp2_get_regs(void);  ////////////////////////////////////////////////////  // Settings Bus, Slave #7, Not Byte Addressable! | 
