summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/convert/CMakeLists.txt9
-rw-r--r--host/lib/ic_reg_maps/CMakeLists.txt5
-rw-r--r--host/lib/ic_reg_maps/gen_max2870_regs.py133
-rw-r--r--host/lib/transport/CMakeLists.txt4
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp27
-rw-r--r--host/lib/transport/usb_zero_copy_wrapper.cpp8
-rw-r--r--host/lib/usrp/b100/b100_impl.cpp1
-rw-r--r--host/lib/usrp/b100/io_impl.cpp4
-rw-r--r--host/lib/usrp/common/recv_packet_demuxer.cpp30
-rw-r--r--host/lib/usrp/dboard/CMakeLists.txt1
-rw-r--r--host/lib/usrp/dboard/db_cbx.cpp212
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.cpp23
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.hpp25
-rw-r--r--host/lib/usrp/gps_ctrl.cpp144
-rw-r--r--host/lib/usrp/multi_usrp.cpp8
-rw-r--r--host/lib/utils/CMakeLists.txt8
-rw-r--r--host/lib/utils/images.cpp2
-rw-r--r--host/lib/utils/paths.cpp8
18 files changed, 595 insertions, 57 deletions
diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt
index 0d9d0983f..28defa8bc 100644
--- a/host/lib/convert/CMakeLists.txt
+++ b/host/lib/convert/CMakeLists.txt
@@ -24,12 +24,11 @@ MESSAGE(STATUS "")
########################################################################
# Look for Orc support
########################################################################
-FIND_PACKAGE(PkgConfig)
-IF(PKG_CONFIG_FOUND)
-PKG_CHECK_MODULES(ORC "orc-0.4 > 0.4.11")
-ENDIF(PKG_CONFIG_FOUND)
+FIND_PACKAGE(ORC)
-FIND_PROGRAM(ORCC_EXECUTABLE orcc)
+IF(NOT ORCC_EXECUTABLE)
+ FIND_PROGRAM(ORCC_EXECUTABLE orcc)
+ENDIF()
LIBUHD_REGISTER_COMPONENT("ORC" ENABLE_ORC ON "ENABLE_LIBUHD;ORC_FOUND;ORCC_EXECUTABLE" OFF)
diff --git a/host/lib/ic_reg_maps/CMakeLists.txt b/host/lib/ic_reg_maps/CMakeLists.txt
index dc2ab7847..b6e121db3 100644
--- a/host/lib/ic_reg_maps/CMakeLists.txt
+++ b/host/lib/ic_reg_maps/CMakeLists.txt
@@ -33,6 +33,11 @@ LIBUHD_PYTHON_GEN_SOURCE(
)
LIBUHD_PYTHON_GEN_SOURCE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gen_max2870_regs.py
+ ${CMAKE_CURRENT_BINARY_DIR}/max2870_regs.hpp
+)
+
+LIBUHD_PYTHON_GEN_SOURCE(
${CMAKE_CURRENT_SOURCE_DIR}/gen_adf4360_regs.py
${CMAKE_CURRENT_BINARY_DIR}/adf4360_regs.hpp
)
diff --git a/host/lib/ic_reg_maps/gen_max2870_regs.py b/host/lib/ic_reg_maps/gen_max2870_regs.py
new file mode 100644
index 000000000..f26c27281
--- /dev/null
+++ b/host/lib/ic_reg_maps/gen_max2870_regs.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 Ettus Research LLC
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+########################################################################
+# Template for raw text data describing registers
+# name addr[bit range inclusive] default optional enums
+########################################################################
+
+REGS_TMPL="""\
+########################################################################
+## Address 0x00
+## Divider control
+## Write-only, default = 0x007D0000
+########################################################################
+int_n_mode 0x00[31] 0 frac_n, int_n
+int_16_bit 0x00[15:30] 0x007D ##Integer divider: 16-65535 in int-N mode, 19-4091 in frac-N mode.
+frac_12_bit 0x00[3:14] 0 ##Frac divider: 0-4095
+########################################################################
+## Address 0x01
+## Charge pump control
+## Write-only, default = 0x2000FFF9
+########################################################################
+cpoc 0x01[31] 0 disabled, enabled
+cpl 0x01[29:30] 1 disabled, enabled, res1, res2
+cpt 0x01[27:28] 0 normal, reserved, force_source, force_sink
+phase_12_bit 0x01[15:26] 1 ##sets phase shift
+mod_12_bit 0x01[3:14] 0xFFF ##VCO frac modulus
+########################################################################
+## Address 0x02
+## Misc. control
+## Write-only, default = 0x00004042
+########################################################################
+lds 0x02[31] 0 slow, fast
+low_noise_and_spur 0x02[29:30] 3 low_noise, reserved, low_spur_1, low_spur_2
+muxout 0x02[26:28] 1 tri_state, high, low, rdiv, ndiv, ald, dld, res7
+reference_doubler 0x02[25] 0 disabled, enabled
+reference_divide_by_2 0x02[24] 0 disabled, enabled
+r_counter_10_bit 0x02[14:23] 1 ##R divider value, 1-1023
+double_buffer 0x02[13] 0 disabled, enabled
+#set $current_setting_enums = ', '.join(map(lambda x: '_'.join(("%0.2fma"%(1.631/5.1 * (1.+x))).split('.')), range(0,16)))
+charge_pump_current 0x02[9:12] 7 $current_setting_enums
+ldf 0x02[8] 0 frac_n, int_n
+ldp 0x02[7] 0 10ns, 6ns
+pd_polarity 0x02[6] 1 negative, positive
+power_down 0x02[5] 0 normal, shutdown
+cp_three_state 0x02[4] 0 disabled, enabled
+counter_reset 0x02[3] 0 normal, reset
+########################################################################
+## Address 0x03
+## VCO control
+## Write-only, default = 0x0000000B
+########################################################################
+vco 0x03[26:31] 0 ##VCO subband selection, used when VAS disabledd
+vas 0x03[25] 0 enabled, disabled ##VCO autoselect
+retune 0x03[24] 1 disabled, enabled
+clock_div_mode 0x03[15:16] 0 clock_divider_off, fast_lock, phase, reserved
+clock_divider_12_bit 0x03[3:14] 1 ##clock divider, 1-4095
+########################################################################
+## Address 0x04
+## RF output control
+## Write-only, default = 0x6180B23C
+########################################################################
+res4 0x04[26:31] 0x18
+bs_msb 0x04[24:25] 0 ##Band select MSBs
+feedback_select 0x04[23] 1 divided, fundamental
+rf_divider_select 0x04[20:22] 0 div1, div2, div4, div8, div16, div32, div64, div128
+band_select_clock_div 0x04[12:19] 0
+aux_output_select 0x04[9] 1 divided, fundamental
+aux_output_enable 0x04[8] 0 disabled, enabled
+aux_output_power 0x04[6:7] 0 m4dBm, m1dBm, 2dBm, 5dBm
+rf_output_enable 0x04[5] 1 disabled, enabled
+output_power 0x04[3:4] 3 m4dBm, m1dBm, 2dBm, 5dBm
+########################################################################
+## Address 0x05
+## Misc
+## Write only, default = 0x00400005
+########################################################################
+f01 0x05[24] 1 frac_n, auto
+ld_pin_mode 0x05[22:23] 1 low, dld, ald, high
+mux_sdo 0x05[18] 0 normal, sdo
+"""
+
+########################################################################
+# Template for methods in the body of the struct
+########################################################################
+BODY_TMPL="""\
+enum addr_t{
+ ADDR_R0 = 0,
+ ADDR_R1 = 1,
+ ADDR_R2 = 2,
+ ADDR_R3 = 3,
+ ADDR_R4 = 4,
+ ADDR_R5 = 5
+};
+
+boost::uint32_t get_reg(boost::uint8_t addr){
+ boost::uint32_t reg = addr & 0x7;
+ switch(addr){
+ #for $addr in range(5+1)
+ case $addr:
+ #for $reg in filter(lambda r: r.get_addr() == addr, $regs)
+ reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();
+ #end for
+ break;
+ #end for
+ }
+ return reg;
+}
+"""
+
+if __name__ == '__main__':
+ import common; common.generate(
+ name='max2870_regs',
+ regs_tmpl=REGS_TMPL,
+ body_tmpl=BODY_TMPL,
+ file=__file__,
+ )
+
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index 6524a8412..4eb7c8c92 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -37,6 +37,10 @@ IF(ENABLE_USB)
${CMAKE_CURRENT_SOURCE_DIR}/libusb1_base.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libusb1_base.hpp
)
+ SET_SOURCE_FILES_PROPERTIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/libusb1_zero_copy.cpp
+ PROPERTIES COMPILE_DEFINITIONS "${LIBUSB_DEFINITIONS}"
+ )
ELSE(ENABLE_USB)
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/usb_dummy_impl.cpp
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 28bff9709..3532dc4aa 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2012 Ettus Research LLC
+// Copyright 2010-2013 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -36,6 +36,12 @@ static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
#define LIBUSB_CALL
#endif /*LIBUSB_CALL*/
+//! libusb_handle_events_timeout_completed is only in newer API
+#ifndef HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED
+ #define libusb_handle_events_timeout_completed(ctx, tx, completed)\
+ libusb_handle_events_timeout(ctx, tx)
+#endif
+
/*!
* All libusb callback functions should be marked with the LIBUSB_CALL macro
* to ensure that they are compiled with the same calling convention as libusb.
@@ -43,7 +49,8 @@ static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
//! helper function: handles all async callbacks
static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut){
- *(static_cast<bool *>(lut->user_data)) = true;
+ int *completed = (int *)lut->user_data;
+ *completed = 1;
}
/*!
@@ -61,7 +68,7 @@ static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut){
* \param completed a reference to the completed flag
* \return true for completion, false for timeout
*/
-UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, bool &completed){
+UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, int &completed){
//already completed by a previous call?
if (completed) return true;
@@ -69,7 +76,7 @@ UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, b
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
- libusb_handle_events_timeout(ctx, &tv);
+ libusb_handle_events_timeout_completed(ctx, &tv, &completed);
if (completed) return true;
//finish the rest with a timeout loop
@@ -78,7 +85,7 @@ UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, b
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 10000; /*10ms*/
- libusb_handle_events_timeout(ctx, &tv);
+ libusb_handle_events_timeout_completed(ctx, &tv, &completed);
}
return completed;
@@ -96,7 +103,7 @@ public:
_lut(lut), _frame_size(frame_size) { /* NOP */ }
void release(void){
- completed = false;
+ completed = 0;
_lut->length = _frame_size; //always reset length
UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);
}
@@ -109,7 +116,7 @@ public:
return managed_recv_buffer::sptr();
}
- bool completed;
+ int completed;
private:
libusb_context *_ctx;
@@ -129,7 +136,7 @@ public:
_lut(lut), _frame_size(frame_size) { completed = true; }
void release(void){
- completed = false;
+ completed = 0;
_lut->length = size();
UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);
}
@@ -142,7 +149,7 @@ public:
return managed_send_buffer::sptr();
}
- bool completed;
+ int completed;
private:
libusb_context *_ctx;
@@ -249,7 +256,7 @@ public:
}
//process all transfers until timeout occurs
- bool completed = false;
+ int completed = 0;
wait_for_completion(ctx, 0.01, completed);
//free all transfers
diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp
index d04244ca9..ec5667020 100644
--- a/host/lib/transport/usb_zero_copy_wrapper.cpp
+++ b/host/lib/transport/usb_zero_copy_wrapper.cpp
@@ -176,6 +176,14 @@ public:
}
managed_recv_buffer::sptr get_recv_buff(double timeout){
+ //lazy flush mechanism - negative timeout
+ if (timeout < 0.0)
+ {
+ _last_recv_buff.reset();
+ while (_internal_zc->get_recv_buff()){}
+ return managed_recv_buffer::sptr();
+ }
+
//attempt to get a managed recv buffer
if (not _last_recv_buff){
_last_recv_buff = _internal_zc->get_recv_buff(timeout);
diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp
index c4d050242..b3237d547 100644
--- a/host/lib/usrp/b100/b100_impl.cpp
+++ b/host/lib/usrp/b100/b100_impl.cpp
@@ -516,6 +516,7 @@ void b100_impl::check_fw_compat(void){
"%s"
) % B100_FW_COMPAT_NUM % fw_compat_num % print_images_error()));
}
+ _tree->create<std::string>("/mboards/0/fw_version").set(str(boost::format("%u.0") % fw_compat_num));
}
void b100_impl::check_fpga_compat(void){
diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp
index 723756dcc..bcf712cd9 100644
--- a/host/lib/usrp/b100/io_impl.cpp
+++ b/host/lib/usrp/b100/io_impl.cpp
@@ -153,6 +153,10 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){
id.num_outputs = 1;
my_streamer->set_converter(id);
+ //flush stuff
+ _data_transport->get_recv_buff(-1.0); //negative flushes!!
+ _recv_demuxer = recv_packet_demuxer::make(_data_transport, _rx_dsps.size(), B100_RX_SID_BASE);
+
//bind callbacks for the handler
for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){
const size_t dsp = args.channels[chan_i];
diff --git a/host/lib/usrp/common/recv_packet_demuxer.cpp b/host/lib/usrp/common/recv_packet_demuxer.cpp
index f2cfe3bb0..fe606213c 100644
--- a/host/lib/usrp/common/recv_packet_demuxer.cpp
+++ b/host/lib/usrp/common/recv_packet_demuxer.cpp
@@ -19,6 +19,8 @@
#include <uhd/utils/msg.hpp>
#include <uhd/utils/byteswap.hpp>
#include <boost/thread/mutex.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include <uhd/types/metadata.hpp>
#include <queue>
#include <deque>
#include <vector>
@@ -27,6 +29,19 @@ using namespace uhd;
using namespace uhd::usrp;
using namespace uhd::transport;
+struct recv_pkt_demux_mrb : public managed_recv_buffer
+{
+public:
+ recv_pkt_demux_mrb(void){/*NOP*/}
+
+ void release(void)
+ {
+ delete this;
+ }
+
+ boost::uint32_t buff[10];
+};
+
static UHD_INLINE boost::uint32_t extract_sid(managed_recv_buffer::sptr &buff){
//ASSUME that the data is in little endian format
return uhd::wtohx(buff->cast<const boost::uint32_t *>()[1]);
@@ -66,7 +81,20 @@ public:
//otherwise queue and try again
if (rx_index < _queues.size()) _queues[rx_index].wrapper.push(buff);
- else UHD_MSG(error) << "Got a data packet with unknown SID " << extract_sid(buff) << std::endl;
+ else
+ {
+ UHD_MSG(error) << "Got a data packet with unknown SID " << extract_sid(buff) << std::endl;
+ recv_pkt_demux_mrb *mrb = new recv_pkt_demux_mrb();
+ vrt::if_packet_info_t info;
+ info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ info.num_payload_words32 = 1;
+ info.num_payload_bytes = info.num_payload_words32*sizeof(boost::uint32_t);
+ info.has_sid = true;
+ info.sid = _sid_base + index;
+ vrt::if_hdr_pack_le(mrb->buff, info);
+ mrb->buff[info.num_header_words32] = rx_metadata_t::ERROR_CODE_OVERFLOW;
+ return mrb->make(mrb, mrb->buff, info.num_packet_words32*sizeof(boost::uint32_t));
+ }
}
}
diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt
index b000c7f33..9e8653608 100644
--- a/host/lib/usrp/dboard/CMakeLists.txt
+++ b/host/lib/usrp/dboard/CMakeLists.txt
@@ -26,6 +26,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/db_sbx_common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_sbx_version3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_sbx_version4.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/db_cbx.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_version2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_version3.cpp
diff --git a/host/lib/usrp/dboard/db_cbx.cpp b/host/lib/usrp/dboard/db_cbx.cpp
new file mode 100644
index 000000000..04399e64e
--- /dev/null
+++ b/host/lib/usrp/dboard/db_cbx.cpp
@@ -0,0 +1,212 @@
+//
+// Copyright 2011-2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+
+#include "max2870_regs.hpp"
+#include "db_sbx_common.hpp"
+
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace boost::assign;
+
+/***********************************************************************
+ * Structors
+ **********************************************************************/
+sbx_xcvr::cbx::cbx(sbx_xcvr *_self_sbx_xcvr) {
+ //register the handle to our base CBX class
+ self_base = _self_sbx_xcvr;
+}
+
+
+sbx_xcvr::cbx::~cbx(void){
+ /* NOP */
+}
+
+
+/***********************************************************************
+ * Tuning
+ **********************************************************************/
+double sbx_xcvr::cbx::set_lo_freq(dboard_iface::unit_t unit, double target_freq) {
+ UHD_LOGV(often) << boost::format(
+ "CBX tune: target frequency %f Mhz"
+ ) % (target_freq/1e6) << std::endl;
+
+ //clip the input
+ target_freq = cbx_freq_range.clip(target_freq);
+
+ //map mode setting to valid integer divider (N) values
+ static const uhd::range_t int_n_mode_div_range(16,4095,1);
+ static const uhd::range_t frac_n_mode_div_range(19,4091,1);
+
+ //map rf divider select output dividers to enums
+ static const uhd::dict<int, max2870_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
+ (1, max2870_regs_t::RF_DIVIDER_SELECT_DIV1)
+ (2, max2870_regs_t::RF_DIVIDER_SELECT_DIV2)
+ (4, max2870_regs_t::RF_DIVIDER_SELECT_DIV4)
+ (8, max2870_regs_t::RF_DIVIDER_SELECT_DIV8)
+ (16, max2870_regs_t::RF_DIVIDER_SELECT_DIV16)
+ (32, max2870_regs_t::RF_DIVIDER_SELECT_DIV32)
+ (64, max2870_regs_t::RF_DIVIDER_SELECT_DIV64)
+ (128, max2870_regs_t::RF_DIVIDER_SELECT_DIV128)
+ ;
+
+ double actual_freq, pfd_freq;
+ double ref_freq = self_base->get_iface()->get_clock_rate(unit);
+ max2870_regs_t::int_n_mode_t int_n_mode;
+ int R=0, BS=0, N=0, FRAC=0, MOD=4095;
+ int RFdiv = 1;
+ max2870_regs_t::reference_divide_by_2_t T = max2870_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
+ max2870_regs_t::reference_doubler_t D = max2870_regs_t::REFERENCE_DOUBLER_DISABLED;
+
+ //Reference doubler for 50% duty cycle
+ // if ref_freq < 12.5MHz enable regs.reference_divide_by_2
+ //NOTE: MAX2870 goes down to 10MHz ref vs. 12.5MHz on ADF4351
+ if(ref_freq <= 10.0e6) D = max2870_regs_t::REFERENCE_DOUBLER_ENABLED;
+
+ //increase RF divider until acceptable VCO frequency
+ double vco_freq = target_freq;
+ //NOTE: MIN freq for MAX2870 VCO is 3GHz vs. 2.2GHz on ADF4351
+ while (vco_freq < 3e9) {
+ vco_freq *= 2;
+ RFdiv *= 2;
+ }
+
+ /*
+ * The goal here is to loop though possible R dividers,
+ * band select clock dividers, N (int) dividers, and FRAC
+ * (frac) dividers.
+ *
+ * Calculate the N and F dividers for each set of values.
+ * The loop exits when it meets all of the constraints.
+ * The resulting loop values are loaded into the registers.
+ *
+ * from pg.21
+ *
+ * f_pfd = f_ref*(1+D)/(R*(1+T))
+ * f_vco = (N + (FRAC/MOD))*f_pfd
+ * N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD
+ * f_rf = f_vco/RFdiv
+ */
+ for(R = 1; R <= 1023; R+=1){
+ //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T)
+ pfd_freq = ref_freq*(1+D)/(R*(1+T));
+
+ //keep the PFD frequency at or below 25MHz
+ if (pfd_freq > 25e6) continue;
+
+ //ignore fractional part of tuning
+ N = int(vco_freq/pfd_freq);
+
+ //Fractional-N calculation
+ FRAC = int((vco_freq/pfd_freq - N)*MOD);
+
+ //are we in int-N or frac-N mode?
+ int_n_mode = (FRAC == 0) ? max2870_regs_t::INT_N_MODE_INT_N : max2870_regs_t::INT_N_MODE_FRAC_N;
+
+ //keep N within int divider requirements
+ if(int_n_mode == max2870_regs_t::INT_N_MODE_INT_N) {
+ if(N < int_n_mode_div_range.start()) continue;
+ if(N > int_n_mode_div_range.stop()) continue;
+ } else {
+ if(N < frac_n_mode_div_range.start()) continue;
+ if(N > frac_n_mode_div_range.stop()) continue;
+ }
+
+ //keep pfd freq low enough to achieve 50kHz BS clock
+ BS = std::ceil(pfd_freq / 50e3);
+ if(BS <= 1023) break;
+ }
+
+ UHD_ASSERT_THROW(R <= 1023);
+
+ //Reference divide-by-2 for 50% duty cycle
+ // if R even, move one divide by 2 to to regs.reference_divide_by_2
+ if(R % 2 == 0){
+ T = max2870_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED;
+ R /= 2;
+ }
+
+ //actual frequency calculation
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv);
+
+ UHD_LOGV(often)
+ << boost::format("CBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
+ << boost::format("CBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
+ << boost::format("CBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
+ ) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
+
+ //load the register values
+ max2870_regs_t regs;
+
+ if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq)))
+ regs.output_power = max2870_regs_t::OUTPUT_POWER_2DBM;
+ else
+ regs.output_power = max2870_regs_t::OUTPUT_POWER_5DBM;
+
+ //set frac/int CPL mode
+ max2870_regs_t::cpl_t cpl;
+ max2870_regs_t::ldf_t ldf;
+ max2870_regs_t::cpoc_t cpoc;
+ if(int_n_mode == max2870_regs_t::INT_N_MODE_INT_N) {
+ cpl = max2870_regs_t::CPL_DISABLED;
+ cpoc = max2870_regs_t::CPOC_ENABLED;
+ ldf = max2870_regs_t::LDF_INT_N;
+ } else {
+ cpl = max2870_regs_t::CPL_ENABLED;
+ ldf = max2870_regs_t::LDF_FRAC_N;
+ cpoc = max2870_regs_t::CPOC_DISABLED;
+ }
+
+ regs.frac_12_bit = FRAC;
+ regs.int_16_bit = N;
+ regs.mod_12_bit = MOD;
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = (target_freq >= 3.0e9) ? max2870_regs_t::FEEDBACK_SELECT_DIVIDED : max2870_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
+ regs.r_counter_10_bit = R;
+ regs.reference_divide_by_2 = T;
+ regs.reference_doubler = D;
+ regs.band_select_clock_div = BS;
+ UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv));
+ regs.rf_divider_select = rfdivsel_to_enum[RFdiv];
+ regs.int_n_mode = int_n_mode;
+ regs.cpl = cpl;
+ regs.ldf = ldf;
+ regs.cpoc = cpoc;
+
+ //write the registers
+ //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
+ int addr;
+
+ for(addr=5; addr>=0; addr--){
+ UHD_LOGV(often) << boost::format(
+ "CBX SPI Reg (0x%02x): 0x%08x"
+ ) % addr % regs.get_reg(addr) << std::endl;
+ self_base->get_iface()->write_spi(
+ unit, spi_config_t::EDGE_RISE,
+ regs.get_reg(addr), 32
+ );
+ }
+
+ //return the actual frequency
+ UHD_LOGV(often) << boost::format(
+ "CBX tune: actual frequency %f Mhz"
+ ) % (actual_freq/1e6) << std::endl;
+ return actual_freq;
+}
+
diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp
index 728cb17e9..9db29e65a 100644
--- a/host/lib/usrp/dboard/db_sbx_common.cpp
+++ b/host/lib/usrp/dboard/db_sbx_common.cpp
@@ -32,6 +32,7 @@ static dboard_base::sptr make_sbx(dboard_base::ctor_args_t args){
UHD_STATIC_BLOCK(reg_sbx_dboards){
dboard_manager::register_dboard(0x0054, 0x0055, &make_sbx, "SBX");
dboard_manager::register_dboard(0x0065, 0x0064, &make_sbx, "SBX v4");
+ dboard_manager::register_dboard(0x0067, 0x0066, &make_sbx, "CBX");
}
@@ -114,9 +115,15 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
switch(get_rx_id().to_uint16()) {
case 0x054:
db_actual = sbx_versionx_sptr(new sbx_version3(this));
+ freq_range = sbx_freq_range;
break;
case 0x065:
db_actual = sbx_versionx_sptr(new sbx_version4(this));
+ freq_range = sbx_freq_range;
+ break;
+ case 0x067:
+ db_actual = sbx_versionx_sptr(new cbx(this));
+ freq_range = cbx_freq_range;
break;
default:
/* We didn't recognize the version of the board... */
@@ -128,7 +135,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
////////////////////////////////////////////////////////////////////
if(get_rx_id() == 0x054) this->get_rx_subtree()->create<std::string>("name").set("SBXv3 RX");
else if(get_rx_id() == 0x065) this->get_rx_subtree()->create<std::string>("name").set("SBXv4 RX");
- else this->get_rx_subtree()->create<std::string>("name").set("SBX RX");
+ else if(get_rx_id() == 0x067) this->get_rx_subtree()->create<std::string>("name").set("CBX RX");
+ else this->get_rx_subtree()->create<std::string>("name").set("SBX/CBX RX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_RX));
@@ -141,8 +149,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
}
this->get_rx_subtree()->create<double>("freq/value")
.coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
- .set((sbx_freq_range.start() + sbx_freq_range.stop())/2.0);
- this->get_rx_subtree()->create<meta_range_t>("freq/range").set(sbx_freq_range);
+ .set((freq_range.start() + freq_range.stop())/2.0);
+ this->get_rx_subtree()->create<meta_range_t>("freq/range").set(freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
.subscribe(boost::bind(&sbx_xcvr::set_rx_ant, this, _1))
.set("RX2");
@@ -159,8 +167,9 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
// Register TX properties
////////////////////////////////////////////////////////////////////
if(get_tx_id() == 0x055) this->get_tx_subtree()->create<std::string>("name").set("SBXv3 TX");
- else if(get_tx_id() == 0x067) this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX");
- else this->get_tx_subtree()->create<std::string>("name").set("SBX TX");
+ else if(get_tx_id() == 0x064) this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX");
+ else if(get_tx_id() == 0x066) this->get_tx_subtree()->create<std::string>("name").set("CBX TX");
+ else this->get_tx_subtree()->create<std::string>("name").set("SBX/CBX TX");
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_TX));
@@ -173,8 +182,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
}
this->get_tx_subtree()->create<double>("freq/value")
.coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
- .set((sbx_freq_range.start() + sbx_freq_range.stop())/2.0);
- this->get_tx_subtree()->create<meta_range_t>("freq/range").set(sbx_freq_range);
+ .set((freq_range.start() + freq_range.stop())/2.0);
+ this->get_tx_subtree()->create<meta_range_t>("freq/range").set(freq_range);
this->get_tx_subtree()->create<std::string>("antenna/value")
.subscribe(boost::bind(&sbx_xcvr::set_tx_ant, this, _1))
.set(sbx_tx_antennas.at(0));
diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp
index 2a0e83115..4f3a2eeaa 100644
--- a/host/lib/usrp/dboard/db_sbx_common.hpp
+++ b/host/lib/usrp/dboard/db_sbx_common.hpp
@@ -100,6 +100,7 @@ using namespace boost::assign;
* The SBX dboard constants
**********************************************************************/
static const freq_range_t sbx_freq_range(400e6, 4.4e9);
+static const freq_range_t cbx_freq_range(1200e6, 6.0e9);
static const freq_range_t sbx_tx_lo_2dbm = list_of
(range_t(0.35e9, 0.37e9))
@@ -213,6 +214,30 @@ protected:
};
/*!
+ * CBX daughterboard
+ *
+ * The only driver difference between SBX and CBX is the MAX2870 vs. ADF435x.
+ * There is also no LO filter switching required, but the GPIO is left blank
+ * so we don't worry about it.
+ */
+ class cbx : public sbx_versionx {
+ public:
+ cbx(sbx_xcvr *_self_sbx_xcvr);
+ ~cbx(void);
+
+ double set_lo_freq(dboard_iface::unit_t unit, double target_freq);
+
+ /*! This is the registered instance of the wrapper class, sbx_base. */
+ sbx_xcvr *self_base;
+ };
+
+ /*!
+ * Frequency range of the daughterboard; this is set in the constructor
+ * to correspond either to SBX or CBX.
+ */
+ freq_range_t freq_range;
+
+ /*!
* Handle to the version-specific implementation of the SBX.
*
* Since many of this class's functions are dependent on the version of the
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index f3bdded60..c3af75faa 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -26,6 +26,10 @@
#include <boost/thread/thread.hpp>
#include <boost/tokenizer.hpp>
#include <boost/format.hpp>
+#include <boost/regex.hpp>
+
+#include "boost/tuple/tuple.hpp"
+#include "boost/foreach.hpp"
using namespace uhd;
using namespace boost::gregorian;
@@ -38,14 +42,69 @@ using namespace boost::this_thread;
*/
class gps_ctrl_impl : public gps_ctrl{
+private:
+ std::map<std::string, boost::tuple<std::string, boost::system_time, bool> > sensors;
+
+ std::string get_cached_sensor(const std::string sensor, const int freshness, const bool once, const bool touch=true) {
+ boost::system_time time = boost::get_system_time();
+ try {
+ // this is nasty ...
+ //std::cout << boost::format("Requested %s - seen? ") % sensor << sensors[sensor].get<2>() << " once? " << once << std::endl;
+ if(time - sensors[sensor].get<1>() < milliseconds(freshness) && (!once or !sensors[sensor].get<2>())) {
+ sensors[sensor] = boost::make_tuple(sensors[sensor].get<0>(), sensors[sensor].get<1>(), touch);
+ return sensors[sensor].get<0>();
+ } else {
+ return update_cached_sensors(sensor);
+ }
+ } catch(std::exception &e) {
+ UHD_MSG(warning) << "get_cached_sensor: " << e.what();
+ }
+ return std::string();
+ }
+
+ std::string update_cached_sensors(const std::string sensor) {
+ if(not gps_detected() || (gps_type != GPS_TYPE_JACKSON_LABS)) {
+ UHD_MSG(error) << "get_stat(): unsupported GPS or no GPS detected";
+ return std::string();
+ }
+
+ std::string msg = _recv();
+ static const boost::regex status_regex("\\d\\d-\\d\\d-\\d\\d");
+ boost::system_time time = boost::get_system_time();
+ if(msg.size() < 6)
+ return std::string();
+
+ std::string nmea = msg.substr(1,5);
+ const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC");
+ BOOST_FOREACH(std::string key, list) {
+ // beginning matches one of the NMEA keys
+ if(!nmea.compare(key)) {
+ sensors[key] = boost::make_tuple(msg, time, !sensor.compare(key));
+ // if this was what we're looking for return it
+ return (!sensor.compare(key))? msg : std::string();
+ }
+ }
+
+ //We're still here so it's not one of the NMEA strings from above
+ if(boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous)) {
+ trim(msg);
+ sensors["SERVO"] = boost::make_tuple(msg, time, false);
+ if(!sensor.compare("SERVO"))
+ return msg;
+ else
+ return std::string();
+ }
+ return std::string();
+ }
public:
gps_ctrl_impl(uart_iface::sptr uart){
_uart = uart;
+
std::string reply;
bool i_heard_some_nmea = false, i_heard_something_weird = false;
gps_type = GPS_TYPE_NONE;
-
+
//first we look for a Jackson Labs Firefly (since that's what we provide...)
_flush(); //get whatever junk is in the rx buffer right now, and throw it away
_send("HAAAY GUYYYYS\n"); //to elicit a response from the Firefly
@@ -60,7 +119,7 @@ public:
if(reply.find("Command Error") != std::string::npos) {
gps_type = GPS_TYPE_JACKSON_LABS;
break;
- }
+ }
else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response
else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate
sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
@@ -99,7 +158,8 @@ public:
("gps_gpgga")
("gps_gprmc")
("gps_time")
- ("gps_locked");
+ ("gps_locked")
+ ("gps_servo");
return ret;
}
@@ -108,7 +168,7 @@ public:
or key == "gps_gprmc") {
return sensor_value_t(
boost::to_upper_copy(key),
- get_nmea(boost::to_upper_copy(key.substr(4,8))),
+ get_cached_sensor(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, false, false),
"");
}
else if(key == "gps_time") {
@@ -117,6 +177,9 @@ public:
else if(key == "gps_locked") {
return sensor_value_t("GPS lock status", locked(), "locked", "unlocked");
}
+ else if(key == "gps_servo") {
+ return sensor_value_t("GPS servo status", get_servo(), "");
+ }
else {
throw uhd::value_error("gps ctrl get_sensor unknown key: " + key);
}
@@ -138,24 +201,25 @@ private:
sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
_send("GPS:GPRMC 1\n");
sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("SERV:TRAC 0\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
}
-
+
//retrieve a raw NMEA sentence
std::string get_nmea(std::string msgtype) {
- msgtype.insert(0, "$");
std::string reply;
- if(not gps_detected()) {
- UHD_MSG(error) << "get_nmea(): unsupported GPS or no GPS detected";
- return std::string();
- }
-
- _flush(); //flush all input before waiting for a message
const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
while(boost::get_system_time() < comm_timeout) {
- reply = _recv();
- if(reply.substr(0, 6) == msgtype)
- return reply;
+ if(!msgtype.compare("GPRMC")) {
+ reply = get_cached_sensor(msgtype, GPS_NMEA_FRESHNESS, true);
+ }
+ else {
+ reply = get_cached_sensor(msgtype, GPS_NMEA_LOW_FRESHNESS, false);
+ }
+ if(reply.size()) {
+ if(reply.substr(1, 5) == msgtype) return reply;
+ }
boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
}
throw uhd::value_error(str(boost::format("get_nmea(): no %s message found") % msgtype));
@@ -176,9 +240,10 @@ private:
}
ptime get_time(void) {
+ _flush();
int error_cnt = 0;
ptime gps_time;
- while(error_cnt < 3) {
+ while(error_cnt < 2) {
try {
std::string reply = get_nmea("GPRMC");
@@ -188,29 +253,30 @@ private:
if(datestr.size() == 0 or timestr.size() == 0) {
throw uhd::value_error(str(boost::format("Invalid response \"%s\"") % reply));
}
-
+
//just trust me on this one
- gps_time = ptime( date(
+ gps_time = ptime( date(
greg_year(boost::lexical_cast<int>(datestr.substr(4, 2)) + 2000),
- greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))),
- greg_day(boost::lexical_cast<int>(datestr.substr(0, 2)))
+ greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))),
+ greg_day(boost::lexical_cast<int>(datestr.substr(0, 2)))
),
hours( boost::lexical_cast<int>(timestr.substr(0, 2)))
+ minutes(boost::lexical_cast<int>(timestr.substr(2, 2)))
+ seconds(boost::lexical_cast<int>(timestr.substr(4, 2)))
);
return gps_time;
-
+
} catch(std::exception &e) {
UHD_MSG(warning) << "get_time: " << e.what();
+ _flush();
error_cnt++;
}
}
throw uhd::value_error("Timeout after no valid message found");
-
+
return gps_time; //keep gcc from complaining
}
-
+
time_t get_epoch_time(void) {
return (get_time() - from_time_t(0)).total_seconds();
}
@@ -223,7 +289,7 @@ private:
int error_cnt = 0;
while(error_cnt < 3) {
try {
- std::string reply = get_nmea("GPGGA");
+ std::string reply = get_cached_sensor("GPGGA", GPS_LOCK_FRESHNESS, false, false);
if(reply.size() <= 1) return false;
return (get_token(reply, 6) != "0");
@@ -236,6 +302,29 @@ private:
return false;
}
+ std::string get_servo(void) {
+
+ //enable servo reporting
+ _send("SERV:TRAC 1\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+
+ std::string reply;
+
+ const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
+ while(boost::get_system_time() < comm_timeout) {
+ reply = get_cached_sensor("SERVO", GPS_NMEA_LOW_FRESHNESS, false);
+ if(reply.size())
+ {
+ //disable it before leaving function
+ _send("SERV:TRAC 0\n");
+ return reply;
+ }
+ boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
+ }
+ throw uhd::value_error("get_stat(): no servo message found");
+ return std::string();
+ }
+
uart_iface::sptr _uart;
void _flush(void){
@@ -258,7 +347,12 @@ private:
GPS_TYPE_NONE
} gps_type;
- static const int GPS_COMM_TIMEOUT_MS = 1500;
+ static const int GPS_COMM_TIMEOUT_MS = 1300;
+ static const int GPS_NMEA_FRESHNESS = 10;
+ static const int GPS_NMEA_LOW_FRESHNESS = 2500;
+ static const int GPS_NMEA_NORMAL_FRESHNESS = 1000;
+ static const int GPS_SERVO_FRESHNESS = 2500;
+ static const int GPS_LOCK_FRESHNESS = 2500;
static const int GPS_TIMEOUT_DELAY_MS = 200;
static const int FIREFLY_STUPID_DELAY_MS = 200;
};
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 0331cf93a..46dd8b670 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -140,6 +140,14 @@ static tune_result_t tune_xx_subdev_and_dsp(
}
//------------------------------------------------------------------
+ //-- poke the tune request args into the dboard
+ //------------------------------------------------------------------
+ if (rf_fe_subtree->exists("tune_args"))
+ {
+ rf_fe_subtree->access<device_addr_t>("tune_args").set(tune_request.args);
+ }
+
+ //------------------------------------------------------------------
//-- set the RF frequency depending upon the policy
//------------------------------------------------------------------
double target_rf_freq = 0.0;
diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt
index 95105f917..a28e1f9ef 100644
--- a/host/lib/utils/CMakeLists.txt
+++ b/host/lib/utils/CMakeLists.txt
@@ -115,14 +115,14 @@ SET_SOURCE_FILES_PROPERTIES(
########################################################################
# Define UHD_PKG_DATA_PATH for paths.cpp
########################################################################
-FILE(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${PKG_DATA_DIR} UHD_PKG_DATA_PATH)
-STRING(REPLACE "\\" "\\\\" UHD_PKG_DATA_PATH ${UHD_PKG_DATA_PATH})
-MESSAGE(STATUS "Full package data directory: ${UHD_PKG_DATA_PATH}")
+FILE(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX} UHD_PKG_PATH)
+STRING(REPLACE "\\" "\\\\" UHD_PKG_PATH ${UHD_PKG_PATH})
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/images.cpp
PROPERTIES COMPILE_DEFINITIONS
- "UHD_PKG_DATA_PATH=\"${UHD_PKG_DATA_PATH}\""
+ "UHD_PKG_PATH=\"${UHD_PKG_PATH}\";UHD_LIB_DIR=\"lib${LIB_SUFFIX}\""
)
########################################################################
diff --git a/host/lib/utils/images.cpp b/host/lib/utils/images.cpp
index 251cadeaa..1ba2f81e6 100644
--- a/host/lib/utils/images.cpp
+++ b/host/lib/utils/images.cpp
@@ -42,7 +42,7 @@ std::string uhd::find_image_path(const std::string &image_name){
}
std::string uhd::find_images_downloader(void){
- return fs::path((fs::path(get_pkg_data_path()) / "utils" / "uhd_images_downloader.py")).string();
+ return fs::path(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "uhd_images_downloader.py").string();
}
std::string uhd::print_images_error(void){
diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp
index 26fa6d1c7..53055314b 100644
--- a/host/lib/utils/paths.cpp
+++ b/host/lib/utils/paths.cpp
@@ -71,20 +71,20 @@ static std::vector<fs::path> get_env_paths(const std::string &var_name){
/***********************************************************************
* Get a list of special purpose paths
**********************************************************************/
-std::string uhd::get_pkg_data_path(void)
+std::string uhd::get_pkg_path(void)
{
- return get_env_var("UHD_PKG_DATA_PATH", UHD_PKG_DATA_PATH);
+ return get_env_var("UHD_PKG_PATH", UHD_PKG_PATH);
}
std::vector<fs::path> get_image_paths(void){
std::vector<fs::path> paths = get_env_paths("UHD_IMAGE_PATH");
- paths.push_back(fs::path(uhd::get_pkg_data_path()) / "images");
+ paths.push_back(fs::path(uhd::get_pkg_path()) / "share" / "uhd" / "images");
return paths;
}
std::vector<fs::path> get_module_paths(void){
std::vector<fs::path> paths = get_env_paths("UHD_MODULE_PATH");
- paths.push_back(fs::path(uhd::get_pkg_data_path()) / "modules");
+ paths.push_back(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "modules");
return paths;
}