summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp1
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-10-11 12:12:25 -0700
committerJosh Blum <josh@joshknows.com>2011-11-03 20:37:12 -0700
commit5538048873f140f3ac2bbab12dc5b0729f68f1a5 (patch)
treeb59ea73c1f26adde73ff9434a0e37e8581f94517 /host/lib/usrp/usrp1
parentfce49fd66f577b92482af6ad516944befa31b861 (diff)
downloaduhd-5538048873f140f3ac2bbab12dc5b0729f68f1a5.tar.gz
uhd-5538048873f140f3ac2bbab12dc5b0729f68f1a5.tar.bz2
uhd-5538048873f140f3ac2bbab12dc5b0729f68f1a5.zip
usrp1: support variable clock rate through API
Diffstat (limited to 'host/lib/usrp/usrp1')
-rw-r--r--host/lib/usrp/usrp1/dboard_iface.cpp26
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp9
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp36
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.hpp5
4 files changed, 54 insertions, 22 deletions
diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp
index 449ec64fe..34bbe1893 100644
--- a/host/lib/usrp/usrp1/dboard_iface.cpp
+++ b/host/lib/usrp/usrp1/dboard_iface.cpp
@@ -39,7 +39,7 @@ public:
usrp1_dboard_iface(usrp1_iface::sptr iface,
usrp1_codec_ctrl::sptr codec,
usrp1_impl::dboard_slot_t dboard_slot,
- const double master_clock_rate,
+ const double &master_clock_rate,
const dboard_id_t &rx_dboard_id
):
_dboard_slot(dboard_slot),
@@ -49,10 +49,8 @@ public:
_iface = iface;
_codec = codec;
- //init the clock rate shadows
- this->set_clock_rate(UNIT_RX, this->get_clock_rates(UNIT_RX).front());
- this->set_clock_rate(UNIT_TX, this->get_clock_rates(UNIT_TX).front());
-
+ _dbsrx_classic_div = 1;
+
//yes this is evil but it's necessary for TVRX to work on USRP1
if(_rx_dboard_id == tvrx_id) _codec->bypass_adc_buffers(false);
//else _codec->bypass_adc_buffers(false); //don't think this is necessary
@@ -103,9 +101,9 @@ public:
private:
usrp1_iface::sptr _iface;
usrp1_codec_ctrl::sptr _codec;
- uhd::dict<unit_t, double> _clock_rates;
+ unsigned _dbsrx_classic_div;
const usrp1_impl::dboard_slot_t _dboard_slot;
- const double _master_clock_rate;
+ const double &_master_clock_rate;
const dboard_id_t _rx_dboard_id;
};
@@ -115,7 +113,7 @@ private:
dboard_iface::sptr usrp1_impl::make_dboard_iface(usrp1_iface::sptr iface,
usrp1_codec_ctrl::sptr codec,
usrp1_impl::dboard_slot_t dboard_slot,
- const double master_clock_rate,
+ const double &master_clock_rate,
const dboard_id_t &rx_dboard_id
){
return dboard_iface::sptr(new usrp1_dboard_iface(
@@ -137,17 +135,16 @@ static const dboard_id_t dbsrx_classic_id(0x0002);
void usrp1_dboard_iface::set_clock_rate(unit_t unit, double rate)
{
assert_has(this->get_clock_rates(unit), rate, "dboard clock rate");
- _clock_rates[unit] = rate;
if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id){
- size_t divider = size_t(_master_clock_rate/rate);
+ _dbsrx_classic_div = size_t(_master_clock_rate/rate);
switch(_dboard_slot){
case usrp1_impl::DBOARD_SLOT_A:
- _iface->poke32(FR_RX_A_REFCLK, (divider & 0x7f) | 0x80);
+ _iface->poke32(FR_RX_A_REFCLK, (_dbsrx_classic_div & 0x7f) | 0x80);
break;
case usrp1_impl::DBOARD_SLOT_B:
- _iface->poke32(FR_RX_B_REFCLK, (divider & 0x7f) | 0x80);
+ _iface->poke32(FR_RX_B_REFCLK, (_dbsrx_classic_div & 0x7f) | 0x80);
break;
}
}
@@ -168,7 +165,10 @@ std::vector<double> usrp1_dboard_iface::get_clock_rates(unit_t unit)
double usrp1_dboard_iface::get_clock_rate(unit_t unit)
{
- return _clock_rates[unit];
+ if (unit == UNIT_RX && _rx_dboard_id == dbsrx_classic_id){
+ return _master_clock_rate/_dbsrx_classic_div;
+ }
+ return _master_clock_rate;
}
void usrp1_dboard_iface::set_clock_enabled(unit_t, bool)
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index a0fdfc6bf..f46f4741b 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -441,6 +441,14 @@ void usrp1_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){
this->restore_tx(s);
}
+
+void usrp1_impl::update_tick_rate(const double rate){
+ //updating this variable should:
+ //update dboard iface -> it has a reference
+ //update dsp freq bounds -> publisher
+ _master_clock_rate = rate;
+}
+
double usrp1_impl::update_rx_samp_rate(size_t dspno, const double samp_rate){
const size_t div = this->has_rx_halfband()? 2 : 1;
@@ -495,6 +503,7 @@ double usrp1_impl::update_tx_samp_rate(size_t dspno, const double samp_rate){
void usrp1_impl::update_rates(void){
const fs_path mb_path = "/mboards/0";
+ this->update_tick_rate(_master_clock_rate);
BOOST_FOREACH(const std::string &name, _tree->list(mb_path / "rx_dsps")){
_tree->access<double>(mb_path / "rx_dsps" / name / "rate" / "value").update();
}
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index db652b033..5788c536f 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -225,14 +225,25 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){
// create clock control objects
////////////////////////////////////////////////////////////////////
_master_clock_rate = 64e6;
- try{
- if (not mb_eeprom["mcr"].empty())
+ if (device_addr.has_key("mcr")){
+ try{
+ _master_clock_rate = boost::lexical_cast<double>(device_addr["mcr"]);
+ }
+ catch(const std::exception &e){
+ UHD_MSG(error) << "Error parsing FPGA clock rate from device address: " << e.what() << std::endl;
+ }
+ }
+ else if (not mb_eeprom["mcr"].empty()){
+ try{
_master_clock_rate = boost::lexical_cast<double>(mb_eeprom["mcr"]);
- }catch(const std::exception &e){
- UHD_MSG(error) << "Error parsing FPGA clock rate from EEPROM: " << e.what() << std::endl;
+ }
+ catch(const std::exception &e){
+ UHD_MSG(error) << "Error parsing FPGA clock rate from EEPROM: " << e.what() << std::endl;
+ }
}
UHD_MSG(status) << boost::format("Using FPGA clock rate of %fMHz...") % (_master_clock_rate/1e6) << std::endl;
- _tree->create<double>(mb_path / "tick_rate").set(_master_clock_rate);
+ _tree->create<double>(mb_path / "tick_rate")
+ .subscribe(boost::bind(&usrp1_impl::update_tick_rate, this, _1));
////////////////////////////////////////////////////////////////////
// create codec control objects
@@ -278,7 +289,7 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){
_tree->create<double>(rx_dsp_path / "freq/value")
.coerce(boost::bind(&usrp1_impl::update_rx_dsp_freq, this, dspno, _1));
_tree->create<meta_range_t>(rx_dsp_path / "freq/range")
- .set(meta_range_t(-_master_clock_rate/2, +_master_clock_rate/2));
+ .publish(boost::bind(&usrp1_impl::get_rx_dsp_freq_range, this));
_tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd");
if (dspno == 0){
//only subscribe the callback for dspno 0 since it will stream all dsps
@@ -298,8 +309,8 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){
.coerce(boost::bind(&usrp1_impl::update_tx_samp_rate, this, dspno, _1));
_tree->create<double>(tx_dsp_path / "freq/value")
.coerce(boost::bind(&usrp1_impl::update_tx_dsp_freq, this, dspno, _1));
- _tree->create<meta_range_t>(tx_dsp_path / "freq/range") //magic scalar comes from codec control:
- .set(meta_range_t(-_master_clock_rate*0.6875, +_master_clock_rate*0.6875));
+ _tree->create<meta_range_t>(tx_dsp_path / "freq/range")
+ .publish(boost::bind(&usrp1_impl::get_tx_dsp_freq_range, this));
}
////////////////////////////////////////////////////////////////////
@@ -443,3 +454,12 @@ double usrp1_impl::update_rx_codec_gain(const std::string &db, const double gain
_dbc[db].codec->set_rx_pga_gain(gain, 'B');
return _dbc[db].codec->get_rx_pga_gain('A');
}
+
+uhd::meta_range_t usrp1_impl::get_rx_dsp_freq_range(void){
+ return meta_range_t(-_master_clock_rate/2, +_master_clock_rate/2);
+}
+
+uhd::meta_range_t usrp1_impl::get_tx_dsp_freq_range(void){
+ //magic scalar comes from codec control:
+ return meta_range_t(-_master_clock_rate*0.6875, +_master_clock_rate*0.6875);
+}
diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp
index cfdcbbcc1..6f427c31e 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.hpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.hpp
@@ -95,12 +95,15 @@ private:
void update_rates(void);
double update_rx_dsp_freq(const size_t, const double);
double update_tx_dsp_freq(const size_t, const double);
+ void update_tick_rate(const double rate);
+ uhd::meta_range_t get_rx_dsp_freq_range(void);
+ uhd::meta_range_t get_tx_dsp_freq_range(void);
static uhd::usrp::dboard_iface::sptr make_dboard_iface(
usrp1_iface::sptr,
usrp1_codec_ctrl::sptr,
dboard_slot_t,
- const double,
+ const double &,
const uhd::usrp::dboard_id_t &
);