aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/cores
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-11-07 18:47:29 -0800
committerJosh Blum <josh@joshknows.com>2011-11-07 18:47:29 -0800
commite219ad10a6e86cd4edc748f2218e01a9890e108c (patch)
tree372f2e426781de9885889bec6aa98697006268ec /host/lib/usrp/cores
parent8ff8f206d317e8d9c026fef9228a80edc241f9d4 (diff)
parent11f1390bbde65c60f45962acb128cac1ce21e474 (diff)
downloaduhd-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.cpp12
-rw-r--r--host/lib/usrp/cores/gpio_core_200.hpp2
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_200.cpp44
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_200.hpp3
-rw-r--r--host/lib/usrp/cores/rx_frontend_core_200.cpp26
-rw-r--r--host/lib/usrp/cores/rx_frontend_core_200.hpp6
-rw-r--r--host/lib/usrp/cores/tx_dsp_core_200.cpp23
-rw-r--r--host/lib/usrp/cores/tx_dsp_core_200.hpp2
-rw-r--r--host/lib/usrp/cores/tx_frontend_core_200.cpp14
-rw-r--r--host/lib/usrp/cores/tx_frontend_core_200.hpp4
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;
};