diff options
| author | Josh Blum <josh@joshknows.com> | 2011-11-07 18:47:29 -0800 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2011-11-07 18:47:29 -0800 | 
| commit | e219ad10a6e86cd4edc748f2218e01a9890e108c (patch) | |
| tree | 372f2e426781de9885889bec6aa98697006268ec /host/lib/usrp/cores | |
| parent | 8ff8f206d317e8d9c026fef9228a80edc241f9d4 (diff) | |
| parent | 11f1390bbde65c60f45962acb128cac1ce21e474 (diff) | |
| download | uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.tar.gz uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.tar.bz2 uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.zip | |
Merge branch 'uhd_next'
Diffstat (limited to 'host/lib/usrp/cores')
| -rw-r--r-- | host/lib/usrp/cores/gpio_core_200.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/cores/gpio_core_200.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/cores/rx_dsp_core_200.cpp | 44 | ||||
| -rw-r--r-- | host/lib/usrp/cores/rx_dsp_core_200.hpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/cores/rx_frontend_core_200.cpp | 26 | ||||
| -rw-r--r-- | host/lib/usrp/cores/rx_frontend_core_200.hpp | 6 | ||||
| -rw-r--r-- | host/lib/usrp/cores/tx_dsp_core_200.cpp | 23 | ||||
| -rw-r--r-- | host/lib/usrp/cores/tx_dsp_core_200.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/cores/tx_frontend_core_200.cpp | 14 | ||||
| -rw-r--r-- | host/lib/usrp/cores/tx_frontend_core_200.hpp | 4 | 
10 files changed, 103 insertions, 33 deletions
| diff --git a/host/lib/usrp/cores/gpio_core_200.cpp b/host/lib/usrp/cores/gpio_core_200.cpp index 8639b1851..d756097ff 100644 --- a/host/lib/usrp/cores/gpio_core_200.cpp +++ b/host/lib/usrp/cores/gpio_core_200.cpp @@ -23,15 +23,14 @@  #define REG_GPIO_TX_ONLY       _base + 8  #define REG_GPIO_BOTH          _base + 12  #define REG_GPIO_DDR           _base + 16 -#define REG_GPIO_READ          _base + 0 //any address will readback  using namespace uhd;  using namespace usrp;  class gpio_core_200_impl : public gpio_core_200{  public: -    gpio_core_200_impl(wb_iface::sptr iface, const size_t base): -        _iface(iface), _base(base) { /* NOP */ } +    gpio_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t rb_addr): +        _iface(iface), _base(base), _rb_addr(rb_addr) { /* NOP */ }      void set_pin_ctrl(const unit_t unit, const boost::uint16_t value){          _pin_ctrl[unit] = value; //shadow @@ -57,12 +56,13 @@ public:      }      boost::uint16_t read_gpio(const unit_t unit){ -        return boost::uint16_t(_iface->peek32(REG_GPIO_READ) >> unit2shit(unit)); +        return boost::uint16_t(_iface->peek32(_rb_addr) >> unit2shit(unit));      }  private:      wb_iface::sptr _iface;      const size_t _base; +    const size_t _rb_addr;      uhd::dict<unit_t, boost::uint16_t> _pin_ctrl, _gpio_out, _gpio_ddr;      uhd::dict<unit_t, uhd::dict<atr_reg_t, boost::uint16_t> > _atr_regs; @@ -95,6 +95,6 @@ private:  }; -gpio_core_200::sptr gpio_core_200::make(wb_iface::sptr iface, const size_t base){ -    return sptr(new gpio_core_200_impl(iface, base)); +gpio_core_200::sptr gpio_core_200::make(wb_iface::sptr iface, const size_t base, const size_t rb_addr){ +    return sptr(new gpio_core_200_impl(iface, base, rb_addr));  } diff --git a/host/lib/usrp/cores/gpio_core_200.hpp b/host/lib/usrp/cores/gpio_core_200.hpp index 7ff2af649..278575874 100644 --- a/host/lib/usrp/cores/gpio_core_200.hpp +++ b/host/lib/usrp/cores/gpio_core_200.hpp @@ -33,7 +33,7 @@ public:      typedef uhd::usrp::dboard_iface::atr_reg_t atr_reg_t;      //! makes a new GPIO core from iface and slave base -    static sptr make(wb_iface::sptr iface, const size_t base); +    static sptr make(wb_iface::sptr iface, const size_t base, const size_t rb_addr);      //! 1 = ATR      virtual void set_pin_ctrl(const unit_t unit, const boost::uint16_t value) = 0; diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index d562c64db..b97f9c58e 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -42,6 +42,7 @@  #define REG_RX_CTRL_VRT_TLR        _ctrl_base + 24  #define REG_RX_CTRL_NSAMPS_PP      _ctrl_base + 28  #define REG_RX_CTRL_NCHANNELS      _ctrl_base + 32 +#define REG_RX_CTRL_FORMAT         _ctrl_base + 36  template <class T> T ceil_log2(T num){      return std::ceil(std::log(num)/std::log(T(2))); @@ -129,15 +130,26 @@ public:      }      void set_link_rate(const double rate){ -        _link_rate = rate/sizeof(boost::uint32_t); //in samps/s +        //_link_rate = rate/sizeof(boost::uint32_t); //in samps/s +        _link_rate = rate/sizeof(boost::uint16_t); //in samps/s (allows for 8sc) +    } + +    uhd::meta_range_t get_host_rates(void){ +        meta_range_t range; +        for (int rate = 512; rate > 256; rate -= 4){ +            range.push_back(range_t(_tick_rate/rate)); +        } +        for (int rate = 256; rate > 128; rate -= 2){ +            range.push_back(range_t(_tick_rate/rate)); +        } +        for (int rate = 128; rate >= int(std::ceil(_tick_rate/_link_rate)); rate -= 1){ +            range.push_back(range_t(_tick_rate/rate)); +        } +        return range;      }      double set_host_rate(const double rate){ -        size_t decim_rate = uhd::clip<size_t>( -            boost::math::iround(_tick_rate/rate), size_t(std::ceil(_tick_rate/_link_rate)), 512 -        ); -        if (decim_rate > 128) decim_rate &= ~0x1; //CIC up to 128, have to use 1 HB -        if (decim_rate > 256) decim_rate &= ~0x3; //CIC up to 128, have to use 2 HB +        const size_t decim_rate = boost::math::iround(_tick_rate/this->get_host_rates().clip(rate, true));          size_t decim = decim_rate;          //determine which half-band filters are activated @@ -162,7 +174,7 @@ public:      }      double get_scaling_adjustment(void){ -        return _scaling_adjustment; +        return _scaling_adjustment/_fxpt_scale_adj;      }      double set_freq(const double freq_){ @@ -192,12 +204,28 @@ public:          if (_continuous_streaming) issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);      } +    void set_format(const std::string &format, const unsigned scale){ +        unsigned format_word = 0; +        if (format == "sc16"){ +            format_word = 0; +            _fxpt_scale_adj = 32767.; +        } +        else if (format == "sc8"){ +            format_word = (1 << 18); +            _fxpt_scale_adj = 32767./scale; +        } +        else throw uhd::value_error("USRP RX cannot handle requested wire format: " + format); + +        const unsigned scale_word = scale & 0x3ffff; //18 bits; +        _iface->poke32(REG_RX_CTRL_FORMAT, format_word | scale_word); +    } +  private:      wb_iface::sptr _iface;      const size_t _dsp_base, _ctrl_base;      double _tick_rate, _link_rate;      bool _continuous_streaming; -    double _scaling_adjustment; +    double _scaling_adjustment, _fxpt_scale_adj;  };  rx_dsp_core_200::sptr rx_dsp_core_200::make(wb_iface::sptr iface, const size_t dsp_base, const size_t ctrl_base, const boost::uint32_t sid, const bool lingering_packet){ diff --git a/host/lib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/usrp/cores/rx_dsp_core_200.hpp index 391cc8441..89b8c1f51 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.hpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.hpp @@ -48,6 +48,8 @@ public:      virtual double set_host_rate(const double rate) = 0; +    virtual uhd::meta_range_t get_host_rates(void) = 0; +      virtual double get_scaling_adjustment(void) = 0;      virtual uhd::meta_range_t get_freq_range(void) = 0; @@ -56,6 +58,7 @@ public:      virtual void handle_overflow(void) = 0; +    virtual void set_format(const std::string &format, const unsigned scale) = 0;  };  #endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/rx_frontend_core_200.cpp b/host/lib/usrp/cores/rx_frontend_core_200.cpp index 0e8220b49..d42022947 100644 --- a/host/lib/usrp/cores/rx_frontend_core_200.cpp +++ b/host/lib/usrp/cores/rx_frontend_core_200.cpp @@ -24,6 +24,9 @@  #define REG_RX_FE_OFFSET_I            _base + 12 //18 bits  #define REG_RX_FE_OFFSET_Q            _base + 16 //18 bits +#define OFFSET_FIXED (1ul << 31) +#define OFFSET_SET   (1ul << 30) +  static boost::uint32_t fs_to_bits(const double num, const size_t bits){      return boost::int32_t(boost::math::round(num * (1 << (bits-1))));  } @@ -41,17 +44,32 @@ public:          _iface->poke32(REG_RX_FE_SWAP_IQ, swap? 1 : 0);      } -    void set_offset(const std::complex<double> &off){ -        _iface->poke32(REG_RX_FE_OFFSET_I, fs_to_bits(off.real(), 24)); -        _iface->poke32(REG_RX_FE_OFFSET_Q, fs_to_bits(off.imag(), 24)); +    void set_dc_offset_auto(const bool enb){ +        this->set_dc_offset(enb? 0 : OFFSET_FIXED); +    } + +    std::complex<double> set_dc_offset(const std::complex<double> &off){ +        static const double scaler = double(1ul << 29); +        _i_dc_off = boost::math::iround(off.real()*scaler); +        _q_dc_off = boost::math::iround(off.imag()*scaler); + +        this->set_dc_offset(OFFSET_SET | OFFSET_FIXED); + +        return std::complex<double>(_i_dc_off/scaler, _q_dc_off/scaler); +    } + +    void set_dc_offset(const boost::uint32_t flags){ +        _iface->poke32(REG_RX_FE_OFFSET_I, flags | _i_dc_off); +        _iface->poke32(REG_RX_FE_OFFSET_Q, flags | _q_dc_off);      } -    void set_correction(const std::complex<double> &cor){ +    void set_iq_balance(const std::complex<double> &cor){          _iface->poke32(REG_RX_FE_MAG_CORRECTION, fs_to_bits(std::abs(cor), 18));          _iface->poke32(REG_RX_FE_PHASE_CORRECTION, fs_to_bits(std::atan2(cor.real(), cor.imag()), 18));      }  private: +    boost::int32_t _i_dc_off, _q_dc_off;      wb_iface::sptr _iface;      const size_t _base;  }; diff --git a/host/lib/usrp/cores/rx_frontend_core_200.hpp b/host/lib/usrp/cores/rx_frontend_core_200.hpp index a950e2bb7..5755424c8 100644 --- a/host/lib/usrp/cores/rx_frontend_core_200.hpp +++ b/host/lib/usrp/cores/rx_frontend_core_200.hpp @@ -33,9 +33,11 @@ public:      virtual void set_mux(const bool swap) = 0; -    virtual void set_offset(const std::complex<double> &off) = 0; +    virtual void set_dc_offset_auto(const bool enb) = 0; -    virtual void set_correction(const std::complex<double> &cor) = 0; +    virtual std::complex<double> set_dc_offset(const std::complex<double> &off) = 0; + +    virtual void set_iq_balance(const std::complex<double> &cor) = 0;  }; diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 04e9f5da4..9d90d30cc 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -70,15 +70,26 @@ public:      }      void set_link_rate(const double rate){ -        _link_rate = rate/sizeof(boost::uint32_t); //in samps/s +        //_link_rate = rate/sizeof(boost::uint32_t); //in samps/s +        _link_rate = rate/sizeof(boost::uint16_t); //in samps/s (allows for 8sc) +    } + +    uhd::meta_range_t get_host_rates(void){ +        meta_range_t range; +        for (int rate = 512; rate > 256; rate -= 4){ +            range.push_back(range_t(_tick_rate/rate)); +        } +        for (int rate = 256; rate > 128; rate -= 2){ +            range.push_back(range_t(_tick_rate/rate)); +        } +        for (int rate = 128; rate >= int(std::ceil(_tick_rate/_link_rate)); rate -= 1){ +            range.push_back(range_t(_tick_rate/rate)); +        } +        return range;      }      double set_host_rate(const double rate){ -        size_t interp_rate = uhd::clip<size_t>( -            boost::math::iround(_tick_rate/rate), size_t(std::ceil(_tick_rate/_link_rate)), 512 -        ); -        if (interp_rate > 128) interp_rate &= ~0x1; //CIC up to 128, have to use 1 HB -        if (interp_rate > 256) interp_rate &= ~0x3; //CIC up to 128, have to use 2 HB +        const size_t interp_rate = boost::math::iround(_tick_rate/this->get_host_rates().clip(rate, true));          size_t interp = interp_rate;          //determine which half-band filters are activated diff --git a/host/lib/usrp/cores/tx_dsp_core_200.hpp b/host/lib/usrp/cores/tx_dsp_core_200.hpp index 65f822558..e6be63557 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.hpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.hpp @@ -40,6 +40,8 @@ public:      virtual double set_host_rate(const double rate) = 0; +    virtual uhd::meta_range_t get_host_rates(void) = 0; +      virtual uhd::meta_range_t get_freq_range(void) = 0;      virtual double set_freq(const double freq) = 0; diff --git a/host/lib/usrp/cores/tx_frontend_core_200.cpp b/host/lib/usrp/cores/tx_frontend_core_200.cpp index a7568a81e..327e8d344 100644 --- a/host/lib/usrp/cores/tx_frontend_core_200.cpp +++ b/host/lib/usrp/cores/tx_frontend_core_200.cpp @@ -50,12 +50,18 @@ public:          _iface->poke32(REG_TX_FE_MUX, mode_to_mux[mode]);      } -    void set_dc_offset(const std::complex<double> &off){ -        _iface->poke32(REG_TX_FE_DC_OFFSET_I, fs_to_bits(off.real(), 24)); -        _iface->poke32(REG_TX_FE_DC_OFFSET_Q, fs_to_bits(off.imag(), 24)); +    std::complex<double> set_dc_offset(const std::complex<double> &off){ +        static const double scaler = double(1ul << 23); +        const boost::int32_t i_dc_off = boost::math::iround(off.real()*scaler); +        const boost::int32_t q_dc_off = boost::math::iround(off.imag()*scaler); + +        _iface->poke32(REG_TX_FE_DC_OFFSET_I, i_dc_off); +        _iface->poke32(REG_TX_FE_DC_OFFSET_Q, q_dc_off); + +        return std::complex<double>(i_dc_off/scaler, q_dc_off/scaler);      } -    void set_correction(const std::complex<double> &cor){ +    void set_iq_balance(const std::complex<double> &cor){          _iface->poke32(REG_TX_FE_MAG_CORRECTION, fs_to_bits(std::abs(cor), 18));          _iface->poke32(REG_TX_FE_PHASE_CORRECTION, fs_to_bits(std::atan2(cor.real(), cor.imag()), 18));      } diff --git a/host/lib/usrp/cores/tx_frontend_core_200.hpp b/host/lib/usrp/cores/tx_frontend_core_200.hpp index 9e4a7bc79..8ee0f3e6d 100644 --- a/host/lib/usrp/cores/tx_frontend_core_200.hpp +++ b/host/lib/usrp/cores/tx_frontend_core_200.hpp @@ -33,9 +33,9 @@ public:      virtual void set_mux(const std::string &mode) = 0; -    virtual void set_dc_offset(const std::complex<double> &off) = 0; +    virtual std::complex<double> set_dc_offset(const std::complex<double> &off) = 0; -    virtual void set_correction(const std::complex<double> &cor) = 0; +    virtual void set_iq_balance(const std::complex<double> &cor) = 0;  }; | 
