aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2016-10-07 16:44:49 -0700
committerMartin Braun <martin.braun@ettus.com>2016-10-07 16:44:49 -0700
commit1b70b3e70df40aae4d1e53037212d77af2fdc4e4 (patch)
treedcde2a418b7cfb4672e5ef5e57bbf85ae3c2d4b1 /host
parent811444b126ed40aed115af4464422122afd0c607 (diff)
parent006c321c552781501bcb0cff9e156c991c24ce45 (diff)
downloaduhd-1b70b3e70df40aae4d1e53037212d77af2fdc4e4.tar.gz
uhd-1b70b3e70df40aae4d1e53037212d77af2fdc4e4.tar.bz2
uhd-1b70b3e70df40aae4d1e53037212d77af2fdc4e4.zip
Merge branch 'maint'
Diffstat (limited to 'host')
-rw-r--r--host/docs/usrp_e3x0.dox14
-rw-r--r--host/examples/benchmark_rate.cpp7
-rw-r--r--host/examples/test_messages.cpp15
-rw-r--r--host/include/uhd/usrp/multi_usrp.hpp21
-rwxr-xr-xhost/lib/ic_reg_maps/gen_max2871_regs.py5
-rw-r--r--host/lib/rfnoc/sink_block_ctrl_base.cpp8
-rw-r--r--host/lib/usrp/common/max287x.hpp7
-rw-r--r--host/lib/usrp/dboard/db_ubx.cpp10
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp2
-rw-r--r--host/lib/usrp/multi_usrp.cpp2
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.cpp39
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.hpp14
12 files changed, 90 insertions, 54 deletions
diff --git a/host/docs/usrp_e3x0.dox b/host/docs/usrp_e3x0.dox
index fdaea80e2..fda5c7e1d 100644
--- a/host/docs/usrp_e3x0.dox
+++ b/host/docs/usrp_e3x0.dox
@@ -628,13 +628,13 @@ TRX-B | 1200 – 1800 | 10 | 01 | 001 | 1
TRX-B | 1800 – 2350 | 10 | 01 | 011 | 11 | XX
TRX-B | 2350 – 2600 | 10 | 01 | 101 | 01 | XX
TRX-B | 2600 – 6000 | 10 | 10 | XXX | XX | XX
-RX2-B | 70 – 450 | TT | 10 | 100 | XX | 10
-RX2-B | 450 – 700 | TT | 10 | 010 | XX | 11
-RX2-B | 700 – 1200 | TT | 10 | 000 | XX | 01
-RX2-B | 1200 – 1800 | TT | 10 | 001 | 10 | XX
-RX2-B | 1800 – 2350 | TT | 10 | 011 | 11 | XX
-RX2-B | 2350 – 2600 | TT | 10 | 101 | 01 | XX
-RX2-B | >= 2600 | TT | 01 | XXX | XX | XX
+RX2-B | 70 – 450 | TT | 01 | 100 | XX | 10
+RX2-B | 450 – 700 | TT | 01 | 010 | XX | 11
+RX2-B | 700 – 1200 | TT | 01 | 000 | XX | 01
+RX2-B | 1200 – 1800 | TT | 01 | 001 | 10 | XX
+RX2-B | 1800 – 2350 | TT | 01 | 011 | 11 | XX
+RX2-B | 2350 – 2600 | TT | 01 | 101 | 01 | XX
+RX2-B | >= 2600 | TT | 10 | XXX | XX | XX
__Transmit__
TX Port | TX Filter (MHz) | VCTXRX1_V1,V2 | TX_ENABLE1A,1B | TX1_BANDSEL[2:0]
diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp
index 1ea754ef2..6854fa43d 100644
--- a/host/examples/benchmark_rate.cpp
+++ b/host/examples/benchmark_rate.cpp
@@ -433,7 +433,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
}
std::cout << boost::format("Setting device timestamp to 0...") << std::endl;
- bool sync_channels = (pps == "mimo" or ref == "mimo" or (rx_channel_nums.size() <= 1 and tx_channel_nums.size() <= 1));
+ const bool sync_channels =
+ pps == "mimo" or
+ ref == "mimo" or
+ rx_channel_nums.size() > 1 or
+ tx_channel_nums.size() > 1
+ ;
if (!sync_channels) {
usrp->set_time_now(0.0);
} else {
diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp
index 4240e830b..4c07d34b1 100644
--- a/host/examples/test_messages.cpp
+++ b/host/examples/test_messages.cpp
@@ -143,10 +143,7 @@ bool test_burst_ack_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr,
//3 times max-sps guarantees a SOB, no burst, and EOB packet
std::vector<std::complex<float> > buff(tx_stream->get_max_num_samps()*3);
-
- tx_stream->send(
- &buff.front(), buff.size(), md
- );
+ tx_stream->send(&buff.front(), buff.size(), md);
uhd::async_metadata_t async_md;
if (not tx_stream->recv_async_msg(async_md)){
@@ -187,7 +184,8 @@ bool test_underflow_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr,
md.end_of_burst = false;
md.has_time_spec = false;
- tx_stream->send("", 0, md);
+ std::vector< std::complex<float> > buff(tx_stream->get_max_num_samps());
+ tx_stream->send(&buff.front(), buff.size(), md);
uhd::async_metadata_t async_md;
if (not tx_stream->recv_async_msg(async_md, 1)){
@@ -231,7 +229,8 @@ bool test_time_error_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer:
usrp->set_time_now(uhd::time_spec_t(200.0)); //time at 200s
- tx_stream->send("", 0, md);
+ std::vector< std::complex<float> > buff(tx_stream->get_max_num_samps());
+ tx_stream->send(&buff.front(), buff.size(), md);
uhd::async_metadata_t async_md;
if (not tx_stream->recv_async_msg(async_md)){
@@ -341,15 +340,17 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
}
//print the result summary
+ bool any_failure = false;
std::cout << std::endl << "Summary:" << std::endl << std::endl;
BOOST_FOREACH(const std::string &key, tests.keys()){
std::cout << boost::format(
"%s -> %3u successes, %3u failures"
) % key % successes[key] % failures[key] << std::endl;
+ any_failure = any_failure or bool(failures[key]);
}
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return EXIT_SUCCESS;
+ return any_failure ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp
index 8c50178eb..f0029c1af 100644
--- a/host/include/uhd/usrp/multi_usrp.hpp
+++ b/host/include/uhd/usrp/multi_usrp.hpp
@@ -160,15 +160,22 @@ public:
/*!
* Set the master clock rate.
- * This controls the rate of the clock that feeds the FPGA DSP.
- * On some devices, this re-tunes the clock to the specified rate.
- * If the specified rate is not available, this method will throw.
- * On other devices, this method notifies the software of the rate,
- * but requires the the user has made the necessary hardware change.
+ *
+ * What exactly this changes is device-dependent, but it will always
+ * affect the rate at which the ADC/DAC is running.
+ *
+ * Like tuning receive or transmit frequencies, this call will do a best
+ * effort to change the master clock rate. The device will coerce to the
+ * closest clock rate available, and on many devices won't actually change
+ * anything at all. Call get_master_clock_rate() to see which rate was
+ * actually applied.
+ *
+ * Note that changing this value during streaming is not recommended and
+ * can have random side effects.
*
* If the device has an 'auto clock rate' setting (e.g. B200, see also
- * \ref b200_auto_mcr), this will get disabled and the clock rate will be
- * fixed to \p rate.
+ * \ref b200_auto_mcr), calling this function will disable the automatic
+ * clock rate selection, and the clock rate will be fixed to \p rate.
*
* \param rate the new master clock rate in Hz
* \param mboard the motherboard index 0 to M-1
diff --git a/host/lib/ic_reg_maps/gen_max2871_regs.py b/host/lib/ic_reg_maps/gen_max2871_regs.py
index f591c1636..f500d8aa8 100755
--- a/host/lib/ic_reg_maps/gen_max2871_regs.py
+++ b/host/lib/ic_reg_maps/gen_max2871_regs.py
@@ -74,6 +74,7 @@ counter_reset 0x02[3] 0 normal, reset
vco 0x03[26:31] 0
## VCO autoselect
shutdown_vas 0x03[25] 0 enabled, disabled
+## should actually be called vas_temp ...
retune 0x03[24] 1 disabled, enabled
res3 0x3[19:23] 0
csm 0x3[18] 0 disabled, enabled
@@ -107,7 +108,9 @@ output_power 0x04[3:4] 3 m4dBm, m1dBm, 2dBm, 5dBm
## Misc
## Write only, default = 0x18400005
########################################################################
-res5_26_31 0x05[26:31] 0x18
+res5_31 0x05[31] 0
+vas_dly 0x05[29:30] 3 disabled, res0, res1, enabled
+res5_26_28 0x05[26:28] 0
shutdown_pll 0x05[25] 0 enabled, disabled
f01 0x05[24] 1 frac_n, auto
ld_pin_mode 0x05[22:23] 1 low, dld, ald, high
diff --git a/host/lib/rfnoc/sink_block_ctrl_base.cpp b/host/lib/rfnoc/sink_block_ctrl_base.cpp
index 56755a269..e4107c0b8 100644
--- a/host/lib/rfnoc/sink_block_ctrl_base.cpp
+++ b/host/lib/rfnoc/sink_block_ctrl_base.cpp
@@ -85,11 +85,15 @@ void sink_block_ctrl_base::set_error_policy(
) {
if (policy == "next_packet")
{
- sr_write(SR_ERROR_POLICY, (1 << 1) | 1);
+ sr_write(SR_ERROR_POLICY, (1 << 2) | 1);
}
else if (policy == "next_burst")
{
- sr_write(SR_ERROR_POLICY, (1 << 2) | 1);
+ sr_write(SR_ERROR_POLICY, (1 << 3) | 1);
+ }
+ else if (policy == "continue")
+ {
+ sr_write(SR_ERROR_POLICY, (1 << 1) | 1);
}
else if (policy == "wait")
{
diff --git a/host/lib/usrp/common/max287x.hpp b/host/lib/usrp/common/max287x.hpp
index 596d992e0..540f5207f 100644
--- a/host/lib/usrp/common/max287x.hpp
+++ b/host/lib/usrp/common/max287x.hpp
@@ -824,6 +824,13 @@ void max287x<max287x_regs_t>::set_auto_retune(bool enabled)
_regs.retune = enabled ? max287x_regs_t::RETUNE_ENABLED : max287x_regs_t::RETUNE_DISABLED;
}
+template <>
+inline void max287x<max2871_regs_t>::set_auto_retune(bool enabled)
+{
+ _regs.retune = enabled ? max2871_regs_t::RETUNE_ENABLED : max2871_regs_t::RETUNE_DISABLED;
+ _regs.vas_dly = enabled ? max2871_regs_t::VAS_DLY_ENABLED : max2871_regs_t::VAS_DLY_DISABLED;
+}
+
template <typename max287x_regs_t>
void max287x<max287x_regs_t>::set_clock_divider_mode(clock_divider_mode_t mode)
{
diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp
index 7416de735..05a02c321 100644
--- a/host/lib/usrp/dboard/db_ubx.cpp
+++ b/host/lib/usrp/dboard/db_ubx.cpp
@@ -1146,17 +1146,17 @@ private:
set_cpld_field(RXLNA1_FORCEON, 1);
set_cpld_field(RXLNA2_FORCEON, 1);
- /*
// Placeholders in case some components need to be forced on to
// reduce settling time. Note that some FORCEON lines are still gated
// by other bits in the CPLD register are are asserted during
// frequency tuning.
- set_cpld_field(RXAMP_FORCEON, 0);
- set_cpld_field(RXDEMOD_FORCEON, 0);
+ set_cpld_field(RXAMP_FORCEON, 1);
+ set_cpld_field(RXDEMOD_FORCEON, 1);
set_cpld_field(RXDRV_FORCEON, 0);
set_cpld_field(RXMIXER_FORCEON, 0);
- set_cpld_field(RXLO1_FORCEON, 0);
- set_cpld_field(RXLO2_FORCEON, 0);
+ set_cpld_field(RXLO1_FORCEON, 1);
+ set_cpld_field(RXLO2_FORCEON, 1);
+ /*
//set_cpld_field(TXDRV_FORCEON, 1); // controlled by RX antenna selection
set_cpld_field(TXMOD_FORCEON, 0);
set_cpld_field(TXMIXER_FORCEON, 0);
diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp
index 4a3f69f69..aa0bae8b8 100644
--- a/host/lib/usrp/dboard/db_xcvr2450.cpp
+++ b/host/lib/usrp/dboard/db_xcvr2450.cpp
@@ -371,7 +371,7 @@ double xcvr2450::set_lo_freq_core(double target_freq){
//variables used in the calculation below
double scaler = xcvr2450::is_highband(target_freq)? (4.0/5.0) : (4.0/3.0);
- double ref_freq = this->get_iface()->get_codec_rate(dboard_iface::UNIT_TX);
+ double ref_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_TX);
int R, intdiv, fracdiv;
//loop through values until we get a match
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 7905a6d32..52dfa5773 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -1877,6 +1877,7 @@ private:
//! \param is_tx True for tx
// Assumption is that all mboards use the same link
+ // and that the rate sum is evenly distributed among the mboards
bool _check_link_rate(const stream_args_t &args, bool is_tx) {
bool link_rate_is_ok = true;
size_t bytes_per_sample = convert::get_bytes_per_item(args.otw_format.empty() ? "sc16" : args.otw_format);
@@ -1892,6 +1893,7 @@ private:
}
sum_rate += is_tx ? get_tx_rate(chan) : get_rx_rate(chan);
}
+ sum_rate /= get_num_mboards();
if (max_link_rate > 0 and (max_link_rate / bytes_per_sample) < sum_rate) {
UHD_MSG(warning) << boost::format(
"The total sum of rates (%f MSps on %u channels) exceeds the maximum capacity of the connection.\n"
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
index e11548703..f14ea3fd9 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
@@ -76,8 +76,6 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)
_spi = spi_core_3000::make(ctrl,
radio_ctrl_impl::regs::sr_addr(radio_ctrl_impl::regs::SPI),
radio_ctrl_impl::regs::RB_SPI);
- _leds = gpio_atr::gpio_atr_3000::make_write_only(ctrl, regs::sr_addr(regs::LEDS));
- _leds->set_atr_mode(usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL);
_adc = x300_adc_ctrl::make(_spi, DB_ADC_SEN);
_dac = x300_dac_ctrl::make(_spi, DB_DAC_SEN, _radio_clk_rate);
@@ -109,6 +107,9 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)
// create front-end objects
////////////////////////////////////////////////////////////////
for (size_t i = 0; i < _get_num_radios(); i++) {
+ _leds[i] = gpio_atr::gpio_atr_3000::make_write_only(_get_ctrl(i), regs::sr_addr(regs::LEDS));
+ _leds[i]->set_atr_mode(usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL);
+
_rx_fe_map[i].core = rx_frontend_core_3000::make(_get_ctrl(i), regs::sr_addr(x300_regs::RX_FE_BASE));
_rx_fe_map[i].core->set_adc_rate(_radio_clk_rate);
_rx_fe_map[i].core->set_dc_offset(rx_frontend_core_3000::DEFAULT_DC_OFFSET_VALUE);
@@ -385,12 +386,16 @@ void x300_radio_ctrl_impl::setup_radio(
_db_manager->initialize_dboards();
//now that dboard is created -- register into rx antenna event
- if (not _rx_fe_map.empty()
- and _tree->exists(db_path / "rx_frontends" / _rx_fe_map[0].db_fe_name / "antenna" / "value")) {
- _tree->access<std::string>(db_path / "rx_frontends" / _rx_fe_map[0].db_fe_name / "antenna" / "value")
- .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::_update_atr_leds, this, _1));
+ if (not _rx_fe_map.empty()) {
+ for (size_t i = 0; i < _get_num_radios(); i++) {
+ if (_tree->exists(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value")) {
+ // We need a desired subscriber for antenna/value because the experts don't coerce that property.
+ _tree->access<std::string>(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value")
+ .add_desired_subscriber(boost::bind(&x300_radio_ctrl_impl::_update_atr_leds, this, _1, i));
+ }
+ _update_atr_leds("", i); //init anyway, even if never called
+ }
}
- _update_atr_leds(""); //init anyway, even if never called
//bind frontend corrections to the dboard freq props
const fs_path db_tx_fe_path = db_path / "tx_frontends";
@@ -734,16 +739,18 @@ double x300_radio_ctrl_impl::self_cal_adc_xfer_delay(
/****************************************************************************
* Helpers
***************************************************************************/
-void x300_radio_ctrl_impl::_update_atr_leds(const std::string &rx_ant)
+void x300_radio_ctrl_impl::_update_atr_leds(const std::string &rx_ant, const size_t chan)
{
- const bool is_txrx = (rx_ant == "TX/RX");
- const int rx_led = (1 << 2);
- const int tx_led = (1 << 1);
- const int txrx_led = (1 << 0);
- _leds->set_atr_reg(gpio_atr::ATR_REG_IDLE, 0);
- _leds->set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, is_txrx? txrx_led : rx_led);
- _leds->set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, tx_led);
- _leds->set_atr_reg(gpio_atr::ATR_REG_FULL_DUPLEX, rx_led | tx_led);
+ // The "RX1" port is used by TwinRX and the "TX/RX" port is used by all
+ // other full-duplex dboards. We need to handle both here.
+ const bool is_txrx = (rx_ant == "TX/RX" or rx_ant == "RX1");
+ const int TXRX_RX = (1 << 0);
+ const int TXRX_TX = (1 << 1);
+ const int RX2_RX = (1 << 2);
+ _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_IDLE, 0);
+ _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, is_txrx ? TXRX_RX : RX2_RX);
+ _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, TXRX_TX);
+ _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_FULL_DUPLEX, RX2_RX | TXRX_TX);
}
void x300_radio_ctrl_impl::_self_cal_adc_capture_delay(bool print_status)
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
index 46540a0c7..65d4443eb 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
@@ -150,7 +150,7 @@ private:
static const uint32_t RX_FE_BASE = 232;
};
- void _update_atr_leds(const std::string &rx_ant);
+ void _update_atr_leds(const std::string &rx_ant, const size_t chan);
void _self_cal_adc_capture_delay(bool print_status);
@@ -170,12 +170,12 @@ private: // members
// Not necessarily this block's sampling rate (tick rate).
double _radio_clk_rate;
- radio_regmap_t::sptr _regs;
- usrp::gpio_atr::gpio_atr_3000::sptr _leds;
- spi_core_3000::sptr _spi;
- x300_adc_ctrl::sptr _adc;
- x300_dac_ctrl::sptr _dac;
- usrp::gpio_atr::gpio_atr_3000::sptr _fp_gpio;
+ radio_regmap_t::sptr _regs;
+ std::map<size_t, usrp::gpio_atr::gpio_atr_3000::sptr> _leds;
+ spi_core_3000::sptr _spi;
+ x300_adc_ctrl::sptr _adc;
+ x300_dac_ctrl::sptr _dac;
+ usrp::gpio_atr::gpio_atr_3000::sptr _fp_gpio;
std::map<size_t, usrp::dboard_eeprom_t> _db_eeproms;
usrp::dboard_manager::sptr _db_manager;