diff options
author | Ashish Chaudhari <ashish@ettus.com> | 2015-03-30 16:56:01 -0700 |
---|---|---|
committer | Ashish Chaudhari <ashish@ettus.com> | 2015-03-30 16:56:01 -0700 |
commit | 700bf99bdc483fdcc9deb54abc29bd7f81e16089 (patch) | |
tree | 42d4f30e7a4abc9e47dcd01300a2f44ab1b91510 /host | |
parent | 6a34824ad10eaa2d2b642b959f278f6c4e326d6d (diff) | |
parent | 61599b3eaadcc46ac8d24974176d7fd89778d06e (diff) | |
download | uhd-700bf99bdc483fdcc9deb54abc29bd7f81e16089.tar.gz uhd-700bf99bdc483fdcc9deb54abc29bd7f81e16089.tar.bz2 uhd-700bf99bdc483fdcc9deb54abc29bd7f81e16089.zip |
Merge branch 'master' into ashish/vivado
Diffstat (limited to 'host')
62 files changed, 1032 insertions, 258 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 0c168e09b..2666aa1d3 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -120,7 +120,7 @@ INCLUDE(CheckCXXCompilerFlag) MACRO(UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG flag have) CHECK_CXX_COMPILER_FLAG(${flag} ${have}) IF(${have}) - ADD_DEFINITIONS(${flag}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") ENDIF(${have}) ENDMACRO(UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG) diff --git a/host/docs/Doxyfile.in b/host/docs/Doxyfile.in index 6d38a9a79..b0490c5c0 100644 --- a/host/docs/Doxyfile.in +++ b/host/docs/Doxyfile.in @@ -686,7 +686,8 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = @CMAKE_SOURCE_DIR@/include/uhd/transport/nirio \ + @CMAKE_SOURCE_DIR@/include/uhd/transport/nirio_zero_copy.hpp # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/host/docs/e3x0_imu_demo.png b/host/docs/res/e3x0_imu_demo.png Binary files differindex cbf156224..cbf156224 100644 --- a/host/docs/e3x0_imu_demo.png +++ b/host/docs/res/e3x0_imu_demo.png diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp index 7ff8b9939..cc3ef04a4 100644 --- a/host/examples/benchmark_rate.cpp +++ b/host/examples/benchmark_rate.cpp @@ -142,7 +142,7 @@ void benchmark_tx_rate( md.has_time_spec = (buffs.size() != 1); if (random_nsamps) { - std::srand( time(NULL) ); + std::srand( (unsigned int)time(NULL) ); while(not boost::this_thread::interruption_requested()){ size_t total_num_samps = rand() % max_samps_per_packet; size_t num_acc_samps = 0; diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp index f71c4ed47..934dce586 100644 --- a/host/examples/rx_samples_to_file.cpp +++ b/host/examples/rx_samples_to_file.cpp @@ -64,7 +64,7 @@ template<typename samp_type> void recv_to_file( uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS: uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE ); - stream_cmd.num_samps = num_requested_samples; + stream_cmd.num_samps = size_t(num_requested_samples); stream_cmd.stream_now = true; stream_cmd.time_spec = uhd::time_spec_t(); rx_stream->issue_stream_cmd(stream_cmd); diff --git a/host/examples/test_clock_synch.cpp b/host/examples/test_clock_synch.cpp index 50a1444f8..9d1883665 100644 --- a/host/examples/test_clock_synch.cpp +++ b/host/examples/test_clock_synch.cpp @@ -37,7 +37,7 @@ using namespace uhd::usrp; void wait_for_pps(multi_usrp::sptr usrp, size_t chan, double timeout){ time_t last_pps_time = usrp->get_time_last_pps(chan).get_full_secs(); time_t system_time = uhd::time_spec_t::get_system_time().get_full_secs(); - time_t exit_time = system_time + timeout; + time_t exit_time = system_time + time_t(timeout); bool detected_pps = false; //Otherwise, this would hang if the USRP doesn't detect any PPS @@ -54,7 +54,7 @@ void wait_for_pps(multi_usrp::sptr usrp, size_t chan, double timeout){ } -void get_usrp_time(multi_usrp::sptr usrp, size_t chan, std::vector<boost::uint32_t> *times){ +void get_usrp_time(multi_usrp::sptr usrp, size_t chan, std::vector<time_t> *times){ wait_for_pps(usrp, chan, 2); (*times)[chan] = usrp->get_time_now(chan).get_full_secs(); } @@ -130,7 +130,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //Wait for next PPS to start polling wait_for_pps(usrp, 0, 2); - srand(time(NULL)); + srand((unsigned int)time(NULL)); std::cout << boost::format("\nRunning %d comparisons at random intervals.") % num_tests << std::endl << std::endl; boost::uint32_t num_matches = 0; @@ -140,7 +140,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ boost::this_thread::sleep(boost::posix_time::milliseconds(wait_time)); //Get all times before output - std::vector<boost::uint32_t> usrp_times(usrp->get_num_mboards()); + std::vector<time_t> usrp_times(usrp->get_num_mboards()); boost::thread_group thread_group; clock_time = clock->get_time(); for(size_t j = 0; j < usrp->get_num_mboards(); j++){ diff --git a/host/examples/tx_samples_from_file.cpp b/host/examples/tx_samples_from_file.cpp index e9d0e8721..cc7e963d5 100644 --- a/host/examples/tx_samples_from_file.cpp +++ b/host/examples/tx_samples_from_file.cpp @@ -55,7 +55,7 @@ template<typename samp_type> void send_from_file( while(not md.end_of_burst and not stop_signal_called){ infile.read((char*)&buff.front(), buff.size()*sizeof(samp_type)); - size_t num_tx_samps = infile.gcount()/sizeof(samp_type); + size_t num_tx_samps = size_t(infile.gcount()/sizeof(samp_type)); md.end_of_burst = infile.eof(); @@ -104,7 +104,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ return ~0; } - bool repeat = vm.count("repeat"); + bool repeat = vm.count("repeat") > 0; //create a usrp device std::cout << std::endl; diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp index 23eb9cdb2..8939cd773 100644 --- a/host/include/uhd/config.hpp +++ b/host/include/uhd/config.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011,2014 Ettus Research LLC +// Copyright 2010-2011,2014-2015 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 @@ -62,7 +62,7 @@ typedef ptrdiff_t ssize_t; #define UHD_INLINE inline #define UHD_DEPRECATED __declspec(deprecated) #define UHD_ALIGNED(x) __declspec(align(x)) - #define UHD_UNUSED(x) x + #define UHD_UNUSED(x) x __attribute__((unused)) #elif defined(__GNUG__) && __GNUG__ >= 4 #define UHD_EXPORT __attribute__((visibility("default"))) #define UHD_IMPORT __attribute__((visibility("default"))) diff --git a/host/include/uhd/transport/nirio/nirio_driver_iface.h b/host/include/uhd/transport/nirio/nirio_driver_iface.h index 3e0e56a7f..c562f0ca5 100644 --- a/host/include/uhd/transport/nirio/nirio_driver_iface.h +++ b/host/include/uhd/transport/nirio/nirio_driver_iface.h @@ -1,5 +1,5 @@ // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 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 @@ -25,9 +25,13 @@ #include <uhd/config.hpp> #if defined(UHD_PLATFORM_WIN32) #include <windows.h> - #pragma warning(disable:4201) // nonstandard extension used : nameless struct/union + #ifdef _MSC_VER + #pragma warning(disable:4201) // nonstandard extension used : nameless struct/union + #endif #include <winioctl.h> - #pragma warning(default:4201) + #ifdef _MSC_VER + #pragma warning(default:4201) + #endif #elif !defined(UHD_PLATFORM_LINUX) #include <IOKit/IOKitLib.h> #endif diff --git a/host/include/uhd/transport/nirio/nirio_fifo.ipp b/host/include/uhd/transport/nirio/nirio_fifo.ipp index 49ce43888..72a337ac2 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.ipp +++ b/host/include/uhd/transport/nirio/nirio_fifo.ipp @@ -1,5 +1,5 @@ // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 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 @@ -42,7 +42,8 @@ nirio_fifo<data_t>::nirio_fifo( { nirio_status status = 0; nirio_status_chain(_riok_proxy_ptr->set_attribute(RIO_ADDRESS_SPACE, BUS_INTERFACE), status); - uint32_t base_addr, addr_space_word; + uint32_t base_addr = 0; + uint32_t addr_space_word = 0; nirio_status_chain(_riok_proxy_ptr->peek(0x1C, base_addr), status); nirio_status_chain(_riok_proxy_ptr->peek(0xC, addr_space_word), status); _dma_base_addr = base_addr + (_fifo_channel * (1<<((addr_space_word>>16)&0xF))); diff --git a/host/include/uhd/transport/nirio/nirio_resource_manager.h b/host/include/uhd/transport/nirio/nirio_resource_manager.h index c71f1c8aa..301b588c7 100644 --- a/host/include/uhd/transport/nirio/nirio_resource_manager.h +++ b/host/include/uhd/transport/nirio/nirio_resource_manager.h @@ -1,5 +1,5 @@ // -// Copyright 2013 Ettus Research LLC +// Copyright 2013,2015 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 @@ -78,7 +78,7 @@ public: } if (fifo->get_channel() != fifo_info_ptr->channel) return NiRio_Status_InvalidParameter; - if (fifo->get_scalar_type() != fifo_info_ptr->scalar_type) return NiRio_Status_InvalidParameter; + if (nirio_scalar_type_t(fifo->get_scalar_type()) != fifo_info_ptr->scalar_type) return NiRio_Status_InvalidParameter; return NiRio_Status_Success; } @@ -94,7 +94,7 @@ public: } if (fifo->get_channel() != fifo_info_ptr->channel) return NiRio_Status_InvalidParameter; - if (fifo->get_scalar_type() != fifo_info_ptr->scalar_type) return NiRio_Status_InvalidParameter; + if (nirio_scalar_type_t(fifo->get_scalar_type()) != fifo_info_ptr->scalar_type) return NiRio_Status_InvalidParameter; return NiRio_Status_Success; } diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index b82c2b7f2..2a25df35f 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -17,6 +17,7 @@ UHD_INSTALL(FILES + byte_vector.hpp clock_config.hpp device_addr.hpp dict.ipp diff --git a/host/include/uhd/types/byte_vector.hpp b/host/include/uhd/types/byte_vector.hpp new file mode 100644 index 000000000..b7637fb5d --- /dev/null +++ b/host/include/uhd/types/byte_vector.hpp @@ -0,0 +1,48 @@ +// +// Copyright 2015 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/>. +// + +#ifndef INCLUDED_UHD_TYPES_BYTE_VECTOR_HPP +#define INCLUDED_UHD_TYPES_BYTE_VECTOR_HPP + +#include <algorithm> +#include <string> +#include <vector> + +#include <boost/assign.hpp> +#include <boost/cstdint.hpp> + +#include <uhd/config.hpp> + +namespace uhd{ + + //! Byte vector used for I2C data passing and EEPROM parsing. + typedef std::vector<boost::uint8_t> byte_vector_t; + + template<typename RangeSrc, typename RangeDst> UHD_INLINE + void byte_copy(const RangeSrc &src, RangeDst &dst){ + std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); + } + + //! Create a string from a byte vector, terminate when invalid ASCII encountered + UHD_API std::string bytes_to_string(const byte_vector_t &bytes); + + //! Create a byte vector from a string, end at null terminator or max length + UHD_API byte_vector_t string_to_bytes(const std::string &str, size_t max_length); + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_BYTE_VECTOR_HPP */ diff --git a/host/include/uhd/types/filters.hpp b/host/include/uhd/types/filters.hpp index 0cb23b294..976ae233d 100644 --- a/host/include/uhd/types/filters.hpp +++ b/host/include/uhd/types/filters.hpp @@ -224,7 +224,7 @@ namespace uhd{ "\ttaps: "<<std::endl; os<<"\t\t"; - for(int i = 0; i < _taps.size(); i++) + for(size_t i = 0; i < _taps.size(); i++) { os<<"(tap "<<i<<": "<<_taps[i]<<")"; if( ((i%10) == 0) && (i != 0)) diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index 1c408d56e..f0bb6d8d3 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -22,6 +22,7 @@ #define UHD_USRP_MULTI_USRP_REF_SOURCES_API #define UHD_USRP_MULTI_USRP_GET_RATES_API #define UHD_USRP_MULTI_USRP_FRONTEND_CAL_API +#define UHD_USRP_MULTI_USRP_FRONTEND_IQ_AUTO_API #define UHD_USRP_MULTI_USRP_COMMAND_TIME_API #define UHD_USRP_MULTI_USRP_BW_RANGE_API #define UHD_USRP_MULTI_USRP_USER_REGS_API diff --git a/host/include/uhd/usrp_clock/multi_usrp_clock.hpp b/host/include/uhd/usrp_clock/multi_usrp_clock.hpp index 0b50b32ae..48d433d71 100644 --- a/host/include/uhd/usrp_clock/multi_usrp_clock.hpp +++ b/host/include/uhd/usrp_clock/multi_usrp_clock.hpp @@ -57,6 +57,8 @@ class UHD_API multi_usrp_clock : boost::noncopyable { public: typedef boost::shared_ptr<multi_usrp_clock> sptr; + virtual ~multi_usrp_clock(void) = 0; + /*! * Make a new Multi-USRP-Clock from the given device address. * \param dev_addr the device address diff --git a/host/lib/transport/chdr.cpp b/host/lib/transport/chdr.cpp index 47ac961b9..632887e56 100644 --- a/host/lib/transport/chdr.cpp +++ b/host/lib/transport/chdr.cpp @@ -115,12 +115,12 @@ UHD_INLINE void _hdr_unpack_chdr( if_packet_info.sob = false; // Set configurable members - if_packet_info.has_tsf = bool(chdr & HDR_FLAG_TSF); + if_packet_info.has_tsf = (chdr & HDR_FLAG_TSF) > 0; if_packet_info.packet_type = if_packet_info_t::packet_type_t((chdr >> 30) & 0x3); if_packet_info.eob = (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_DATA) - && bool(chdr & HDR_FLAG_EOB); + && ((chdr & HDR_FLAG_EOB) > 0); if_packet_info.error = (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_RESP) - && bool(chdr & HDR_FLAG_ERROR); + && ((chdr & HDR_FLAG_ERROR) > 0); if_packet_info.packet_count = (chdr >> 16) & 0xFFF; // Set packet length variables diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp index 18acb1fdc..b1045ffa5 100644 --- a/host/lib/transport/libusb1_base.cpp +++ b/host/lib/transport/libusb1_base.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2014 Ettus Research LLC +// Copyright 2010-2015 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 @@ -326,7 +326,8 @@ public: } bool firmware_loaded() { - return (get_manufacturer() == "Ettus Research LLC"); + return (get_manufacturer() == "Ettus Research LLC") or + (get_manufacturer() == "Free Software Folks"); } private: diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 4ea2032e3..1ac02d16f 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -192,7 +192,7 @@ public: result.usb_transfer_complete.timed_wait(lock, timeout_time, lut_result_completed(result)); } } - return result.completed; + return (result.completed > 0); } private: diff --git a/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp b/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp index d265efa63..ba0febe20 100644 --- a/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp +++ b/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp @@ -1,5 +1,5 @@ // -// Copyright 2013 Ettus Research LLC +// Copyright 2013,2015 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 @@ -19,43 +19,43 @@ namespace nirio_driver_iface { nirio_status rio_open( - const std::string& /* device_path */, - rio_dev_handle_t& /* device_handle */) + UHD_UNUSED(const std::string& device_path), + UHD_UNUSED(rio_dev_handle_t& device_handle)) { return NiRio_Status_FeatureNotSupported; } -void rio_close(rio_dev_handle_t& /* device_handle */) +void rio_close(UHD_UNUSED(rio_dev_handle_t& device_handle)) { } -bool rio_isopen(rio_dev_handle_t /* device_handle */) +bool rio_isopen(UHD_UNUSED(rio_dev_handle_t device_handle)) { return false; } nirio_status rio_ioctl( - rio_dev_handle_t /* device_handle */, - uint32_t /* ioctl_code */, - const void* /* write_buf */, - size_t /* write_buf_len */, - void* /* read_buf */, - size_t /* read_buf_len */) + UHD_UNUSED(rio_dev_handle_t device_handle), + UHD_UNUSED(uint32_t ioctl_code), + UHD_UNUSED(const void *write_buf), + UHD_UNUSED(size_t write_buf_len), + UHD_UNUSED(void *read_buf), + UHD_UNUSED(size_t read_buf_len)) { return NiRio_Status_FeatureNotSupported; } nirio_status rio_mmap( - rio_dev_handle_t /* device_handle */, - uint16_t /* memory_type */, - size_t /* size */, - bool /* writable */, - rio_mmap_t& /* map */) + UHD_UNUSED(rio_dev_handle_t device_handle), + UHD_UNUSED(uint16_t memory_type), + UHD_UNUSED(size_t size), + UHD_UNUSED(bool writable), + UHD_UNUSED(rio_mmap_t &map)) { return NiRio_Status_FeatureNotSupported; } -nirio_status rio_munmap(rio_mmap_t& /* map */) +nirio_status rio_munmap(UHD_UNUSED(rio_mmap_t &map)) { return NiRio_Status_FeatureNotSupported; } diff --git a/host/lib/transport/nirio_zero_copy.cpp b/host/lib/transport/nirio_zero_copy.cpp index 9d64d0792..1eb431a19 100644 --- a/host/lib/transport/nirio_zero_copy.cpp +++ b/host/lib/transport/nirio_zero_copy.cpp @@ -1,5 +1,5 @@ // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 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 @@ -51,7 +51,8 @@ public: UHD_INLINE sptr get_new(const double timeout, size_t &index) { nirio_status status = 0; - size_t elems_acquired, elems_remaining; + size_t elems_acquired = 0; + size_t elems_remaining = 0; nirio_status_chain(_fifo.acquire( _typed_buffer, _frame_size / sizeof(fifo_data_t), static_cast<uint32_t>(timeout*1000), @@ -91,7 +92,8 @@ public: UHD_INLINE sptr get_new(const double timeout, size_t &index) { nirio_status status = 0; - size_t elems_acquired, elems_remaining; + size_t elems_acquired = 0; + size_t elems_remaining = 0; nirio_status_chain(_fifo.acquire( _typed_buffer, _frame_size / sizeof(fifo_data_t), static_cast<uint32_t>(timeout*1000), @@ -299,10 +301,10 @@ private: nirio_status_chain(_proxy()->peek( PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); - tx_busy = (reg_data & DMA_STATUS_BUSY); + tx_busy = (reg_data & DMA_STATUS_BUSY) > 0; nirio_status_chain(_proxy()->peek( PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); - rx_busy = (reg_data & DMA_STATUS_BUSY); + rx_busy = (reg_data & DMA_STATUS_BUSY) > 0; if (nirio_status_not_fatal(status) && (tx_busy || rx_busy)) { start_time = boost::posix_time::microsec_clock::local_time(); @@ -311,10 +313,10 @@ private: elapsed = boost::posix_time::microsec_clock::local_time() - start_time; nirio_status_chain(_proxy()->peek( PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); - tx_busy = (reg_data & DMA_STATUS_BUSY); + tx_busy = (reg_data & DMA_STATUS_BUSY) > 0; nirio_status_chain(_proxy()->peek( PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); - rx_busy = (reg_data & DMA_STATUS_BUSY); + rx_busy = (reg_data & DMA_STATUS_BUSY) > 0; } while ( nirio_status_not_fatal(status) && (tx_busy || rx_busy) && diff --git a/host/lib/types/CMakeLists.txt b/host/lib/types/CMakeLists.txt index 821754386..5e97628f0 100644 --- a/host/lib/types/CMakeLists.txt +++ b/host/lib/types/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2011-2013 Ettus Research LLC +# Copyright 2011-2013,2015 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 @@ -92,4 +92,5 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/types.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wb_iface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/filters.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/byte_vector.cpp ) diff --git a/host/lib/types/byte_vector.cpp b/host/lib/types/byte_vector.cpp new file mode 100644 index 000000000..36b311faf --- /dev/null +++ b/host/lib/types/byte_vector.cpp @@ -0,0 +1,55 @@ +// +// Copyright 2015 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 <boost/foreach.hpp> +#include <boost/lexical_cast.hpp> + +#include <uhd/types/byte_vector.hpp> + +namespace uhd{ + +std::string bytes_to_string(const byte_vector_t &bytes){ + std::string out; + BOOST_FOREACH(boost::uint8_t byte, bytes){ + if (byte < 32 or byte > 127) return out; + out += byte; + } + return out; +} + +std::string uint16_bytes_to_string(const byte_vector_t &bytes){ + const boost::uint16_t num = (boost::uint16_t(bytes.at(0)) << 0) | (boost::uint16_t(bytes.at(1)) << 8); + return (num == 0 or num == 0xffff)? "" : boost::lexical_cast<std::string>(num); +} + +byte_vector_t string_to_bytes(const std::string &str, size_t max_length){ + byte_vector_t bytes; + for (size_t i = 0; i < std::min(str.size(), max_length); i++){ + bytes.push_back(str[i]); + } + if (bytes.size() < max_length - 1) bytes.push_back('\0'); + return bytes; +} + +byte_vector_t string_to_uint16_bytes(const std::string &num_str){ + const boost::uint16_t num = boost::lexical_cast<boost::uint16_t>(num_str); + const byte_vector_t lsb_msb = boost::assign::list_of + (boost::uint8_t(num >> 0))(boost::uint8_t(num >> 8)); + return lsb_msb; +} + +} /* namespace uhd */ diff --git a/host/lib/usrp/b100/clock_ctrl.cpp b/host/lib/usrp/b100/clock_ctrl.cpp index febc8ba4b..53a35df2b 100644 --- a/host/lib/usrp/b100/clock_ctrl.cpp +++ b/host/lib/usrp/b100/clock_ctrl.cpp @@ -114,8 +114,8 @@ static clock_settings_type get_clock_settings(double rate){ const size_t gcd = size_t(boost::math::gcd(ref_rate, out_rate)); for (size_t i = 1; i <= 100; i++){ - const size_t X = i*ref_rate/gcd; - const size_t Y = i*out_rate/gcd; + const size_t X = size_t(i*ref_rate/gcd); + const size_t Y = size_t(i*out_rate/gcd); //determine A and B (P is fixed) cs.b_counter = Y/cs.prescaler; diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp index 820090959..270d3bb4b 100644 --- a/host/lib/usrp/b200/b200_iface.cpp +++ b/host/lib/usrp/b200/b200_iface.cpp @@ -89,7 +89,7 @@ typedef boost::uint32_t hash_type; * Create a file hash * The hash will be used to identify the loaded firmware and fpga image * \param filename file used to generate hash value - * \return hash value in a size_t type + * \return hash value in a uint32_t type */ static hash_type generate_hash(const char *filename) { @@ -101,13 +101,15 @@ static hash_type generate_hash(const char *filename) throw uhd::io_error(std::string("cannot open input file ") + filename); } - size_t hash = 0; + hash_type hash = 0; char ch; long long count = 0; while (file.get(ch)) { count++; - boost::hash_combine(hash, ch); + //hash algorithm derived from boost hash_combine + //http://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html + hash ^= ch + 0x9e3779b9 + (hash<<6) + (hash>>2); } if (count == 0){ @@ -547,7 +549,7 @@ public: size_t file_size = 0; { std::ifstream file(filename, std::ios::in | std::ios::binary | std::ios::ate); - file_size = file.tellg(); + file_size = size_t(file.tellg()); } std::ifstream file; diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index 647c64695..e1b106208 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -738,6 +738,15 @@ void b200_impl::setup_radio(const size_t dspno) .subscribe(boost::bind(&ad9361_ctrl::set_iq_balance_auto, _codec_ctrl, key, _1)).set(true); } + //add all frontend filters + std::vector<std::string> filter_names = _codec_ctrl->get_filter_names(key); + for(size_t i = 0;i < filter_names.size(); i++) + { + _tree->create<filter_info_base::sptr>(rf_fe_path / "filters" / filter_names[i] / "value" ) + .publish(boost::bind(&ad9361_ctrl::get_filter, _codec_ctrl, key, filter_names[i])) + .subscribe(boost::bind(&ad9361_ctrl::set_filter, _codec_ctrl, key, filter_names[i], _1)); + } + //setup antenna stuff if (key[0] == 'R') { @@ -777,7 +786,7 @@ void b200_impl::register_loopback_self_test(wb_iface::sptr iface) { bool test_fail = false; UHD_MSG(status) << "Performing register loopback test... " << std::flush; - size_t hash = time(NULL); + size_t hash = size_t(time(NULL)); for (size_t i = 0; i < 100; i++) { boost::hash_combine(hash, i); @@ -1025,7 +1034,7 @@ void b200_impl::update_gpio_state(void) | (_gpio_state.ref_sel << 0) ; - _local_ctrl->poke32(TOREG(RB32_CORE_MISC), misc_word); + _local_ctrl->poke32(TOREG(SR_CORE_MISC), misc_word); } void b200_impl::reset_codec_dcm(void) @@ -1122,6 +1131,6 @@ sensor_value_t b200_impl::get_ref_locked(void) sensor_value_t b200_impl::get_fe_pll_locked(const bool is_tx) { const boost::uint32_t st = _local_ctrl->peek32(RB32_CORE_PLL); - const bool locked = is_tx ? bool(st & 0x1) : bool(st & 0x2); + const bool locked = is_tx ? ((st & 0x1) > 0) : ((st & 0x2) > 0); return sensor_value_t("LO", locked, "locked", "unlocked"); } diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp index a0a5fa663..9c17a582d 100644 --- a/host/lib/usrp/common/ad9361_ctrl.cpp +++ b/host/lib/usrp/common/ad9361_ctrl.cpp @@ -214,6 +214,40 @@ public: _device.set_iq_balance_auto(direction,on); } + double set_bw_filter(const std::string &which, const double bw) + { + boost::lock_guard<boost::mutex> lock(_mutex); + + ad9361_device_t::direction_t direction = _get_direction_from_antenna(which); + return _device.set_bw_filter(direction, bw); + } + + std::vector<std::string> get_filter_names(const std::string &which) + { + boost::lock_guard<boost::mutex> lock(_mutex); + + ad9361_device_t::direction_t direction = _get_direction_from_antenna(which); + return _device.get_filter_names(direction); + } + + filter_info_base::sptr get_filter(const std::string &which, const std::string &filter_name) + { + boost::lock_guard<boost::mutex> lock(_mutex); + + ad9361_device_t::direction_t direction = _get_direction_from_antenna(which); + ad9361_device_t::chain_t chain =_get_chain_from_antenna(which); + return _device.get_filter(direction, chain, filter_name); + } + + void set_filter(const std::string &which, const std::string &filter_name, const filter_info_base::sptr filter) + { + boost::lock_guard<boost::mutex> lock(_mutex); + + ad9361_device_t::direction_t direction = _get_direction_from_antenna(which); + ad9361_device_t::chain_t chain = _get_chain_from_antenna(which); + _device.set_filter(direction, chain, filter_name, filter); + } + private: static ad9361_device_t::direction_t _get_direction_from_antenna(const std::string& antenna) { diff --git a/host/lib/usrp/common/ad9361_ctrl.hpp b/host/lib/usrp/common/ad9361_ctrl.hpp index 0dd1b08d9..a6d65ad11 100644 --- a/host/lib/usrp/common/ad9361_ctrl.hpp +++ b/host/lib/usrp/common/ad9361_ctrl.hpp @@ -27,6 +27,8 @@ #include <ad9361_device.h> #include <string> #include <complex> +#include <uhd/types/filters.hpp> +#include <vector> namespace uhd { namespace usrp { @@ -79,11 +81,8 @@ public: return uhd::meta_range_t(5e6, ad9361_device_t::AD9361_MAX_CLOCK_RATE); //5 MHz DCM low end } - //! set the filter bandwidth for the frontend - double set_bw_filter(const std::string &/*which*/, const double /*bw*/) - { - return 56e6; //TODO - } + //! set the filter bandwidth for the frontend's analog low pass + virtual double set_bw_filter(const std::string &/*which*/, const double /*bw*/) = 0; //! set the gain for a particular gain element virtual double set_gain(const std::string &which, const double value) = 0; @@ -131,6 +130,15 @@ public: //! read the internal temp sensor virtual sensor_value_t get_temperature() = 0; + + //! List all available filters by name + virtual std::vector<std::string> get_filter_names(const std::string &which) = 0; + + //! Return a list of all filters + virtual filter_info_base::sptr get_filter(const std::string &which, const std::string &filter_name) = 0; + + //! Write back a filter + virtual void set_filter(const std::string &which, const std::string &filter_name, const filter_info_base::sptr) = 0; }; }} diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp index 92ad0ee3f..c3eb5fb9d 100644 --- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp +++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp @@ -88,7 +88,7 @@ const double ad9361_device_t::AD9361_CAL_VALID_WINDOW = 100e6; * how many taps are in the filter, and given a vector of the taps * themselves. */ -void ad9361_device_t::_program_fir_filter(direction_t direction, int num_taps, boost::uint16_t *coeffs) +void ad9361_device_t::_program_fir_filter(direction_t direction, chain_t chain, int num_taps, boost::uint16_t *coeffs) { boost::uint16_t base; @@ -103,8 +103,20 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, int num_taps, b /* Encode number of filter taps for programming register */ boost::uint8_t reg_numtaps = (((num_taps / 16) - 1) & 0x07) << 5; + boost::uint8_t reg_chain = 0; + switch (chain) { + case CHAIN_1: + reg_chain = 0x01 << 3; + break; + case CHAIN_2: + reg_chain = 0x02 << 3; + break; + default: + reg_chain = 0x03 << 3; + } + /* Turn on the filter clock. */ - _io_iface->poke8(base + 5, reg_numtaps | 0x1a); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain | 0x02); boost::this_thread::sleep(boost::posix_time::milliseconds(1)); /* Zero the unused taps just in case they have stale data */ @@ -113,7 +125,7 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, int num_taps, b _io_iface->poke8(base + 0, addr); _io_iface->poke8(base + 1, 0x0); _io_iface->poke8(base + 2, 0x0); - _io_iface->poke8(base + 5, reg_numtaps | 0x1e); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain | (1 << 1) | (1 << 2)); _io_iface->poke8(base + 4, 0x00); _io_iface->poke8(base + 4, 0x00); } @@ -123,7 +135,7 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, int num_taps, b _io_iface->poke8(base + 0, addr); _io_iface->poke8(base + 1, (coeffs[addr]) & 0xff); _io_iface->poke8(base + 2, (coeffs[addr] >> 8) & 0xff); - _io_iface->poke8(base + 5, reg_numtaps | 0x1e); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain | (1 << 1) | (1 << 2)); _io_iface->poke8(base + 4, 0x00); _io_iface->poke8(base + 4, 0x00); } @@ -134,9 +146,9 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, int num_taps, b before the clock stops. Wait 4 sample clock periods after setting D2 high while that data writes into the table" */ - _io_iface->poke8(base + 5, reg_numtaps | 0x1A); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain | (1 << 1)); if (direction == RX) { - _io_iface->poke8(base + 5, reg_numtaps | 0x18); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain ); /* Rx Gain, set to prevent digital overflow/saturation in filters 0:+6dB, 1:0dB, 2:-6dB, 3:-12dB page 35 of UG-671 */ @@ -145,7 +157,7 @@ void ad9361_device_t::_program_fir_filter(direction_t direction, int num_taps, b /* Tx Gain. bit[0]. set to prevent digital overflow/saturation in filters 0: 0dB, 1:-6dB page 25 of UG-671 */ - _io_iface->poke8(base + 5, reg_numtaps | 0x18); + _io_iface->poke8(base + 5, reg_numtaps | reg_chain ); } } @@ -176,7 +188,7 @@ void ad9361_device_t::_setup_rx_fir(size_t num_taps, boost::int32_t decimation) } } - _program_fir_filter(RX, num_taps, coeffs.get()); + _program_fir_filter(RX, CHAIN_BOTH, num_taps, coeffs.get()); } /* Program the TX FIR Filter. */ @@ -208,7 +220,7 @@ void ad9361_device_t::_setup_tx_fir(size_t num_taps, boost::int32_t interpolatio } } - _program_fir_filter(TX, num_taps, coeffs.get()); + _program_fir_filter(TX, CHAIN_BOTH, num_taps, coeffs.get()); } /*********************************************************************** @@ -283,16 +295,24 @@ void ad9361_device_t::_calibrate_synth_charge_pumps() * * Note that the filter calibration depends heavily on the baseband * bandwidth, so this must be re-done after any change to the RX sample - * rate. */ -double ad9361_device_t::_calibrate_baseband_rx_analog_filter() + * rate. + * UG570 Page 33 states that this filter should be calibrated to 1.4 * bbbw*/ +double ad9361_device_t::_calibrate_baseband_rx_analog_filter(double req_rfbw) { - /* For filter tuning, baseband BW is half the complex BW, and must be - * between 28e6 and 0.2e6. */ - double bbbw = _baseband_bw / 2.0; + double bbbw = req_rfbw / 2.0; + if(bbbw > _baseband_bw / 2.0) + { + UHD_LOG << "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + bbbw = _baseband_bw / 2.0; + } + + /* Baseband BW must be between 28e6 and 0.143e6. + * Max filter BW is 39.2 MHz. 39.2 / 1.4 = 28 + * Min filter BW is 200kHz. 200 / 1.4 = 143 */ if (bbbw > 28e6) { bbbw = 28e6; - } else if (bbbw < 0.20e6) { - bbbw = 0.20e6; + } else if (bbbw < 0.143e6) { + bbbw = 0.143e6; } double rxtune_clk = ((1.4 * bbbw * 2 * M_PI) / M_LN2); @@ -341,16 +361,25 @@ double ad9361_device_t::_calibrate_baseband_rx_analog_filter() * * Note that the filter calibration depends heavily on the baseband * bandwidth, so this must be re-done after any change to the TX sample - * rate. */ -double ad9361_device_t::_calibrate_baseband_tx_analog_filter() + * rate. + * UG570 Page 32 states that this filter should be calibrated to 1.6 * bbbw*/ +double ad9361_device_t::_calibrate_baseband_tx_analog_filter(double req_rfbw) { - /* For filter tuning, baseband BW is half the complex BW, and must be - * between 28e6 and 0.2e6. */ - double bbbw = _baseband_bw / 2.0; + double bbbw = req_rfbw / 2.0; + + if(bbbw > _baseband_bw / 2.0) + { + UHD_LOG << "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + bbbw = _baseband_bw / 2.0; + } + + /* Baseband BW must be between 20e6 and 0.391e6. + * Max filter BW is 32 MHz. 32 / 1.6 = 20 + * Min filter BW is 625 kHz. 625 / 1.6 = 391 */ if (bbbw > 20e6) { bbbw = 20e6; - } else if (bbbw < 0.625e6) { - bbbw = 0.625e6; + } else if (bbbw < 0.391e6) { + bbbw = 0.391e6; } double txtune_clk = ((1.6 * bbbw * 2 * M_PI) / M_LN2); @@ -387,16 +416,25 @@ double ad9361_device_t::_calibrate_baseband_tx_analog_filter() /* Calibrate the secondary TX filter. * * This filter also depends on the TX sample rate, so if a rate change is - * made, the previous calibration will no longer be valid. */ -void ad9361_device_t::_calibrate_secondary_tx_filter() + * made, the previous calibration will no longer be valid. + * UG570 Page 32 states that this filter should be calibrated to 5 * bbbw*/ +double ad9361_device_t::_calibrate_secondary_tx_filter(double req_rfbw) { - /* For filter tuning, baseband BW is half the complex BW, and must be - * between 20e6 and 0.53e6. */ - double bbbw = _baseband_bw / 2.0; + double bbbw = req_rfbw / 2.0; + + if(bbbw > _baseband_bw / 2.0) + { + UHD_LOG << "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + bbbw = _baseband_bw / 2.0; + } + + /* Baseband BW must be between 20e6 and 0.54e6. + * Max filter BW is 100 MHz. 100 / 5 = 20 + * Min filter BW is 2.7 MHz. 2.7 / 5 = 0.54 */ if (bbbw > 20e6) { bbbw = 20e6; - } else if (bbbw < 0.53e6) { - bbbw = 0.53e6; + } else if (bbbw < 0.54e6) { + bbbw = 0.54e6; } double bbbw_mhz = bbbw / 1e6; @@ -457,13 +495,17 @@ void ad9361_device_t::_calibrate_secondary_tx_filter() _io_iface->poke8(0x0d2, reg0d2); _io_iface->poke8(0x0d1, reg0d1); _io_iface->poke8(0x0d0, reg0d0); + + return bbbw; } /* Calibrate the RX TIAs. * * Note that the values in the TIA register, after calibration, vary with - * the RX gain settings. */ -void ad9361_device_t::_calibrate_rx_TIAs() + * the RX gain settings. + * We do not really program the BW here. Most settings are taken form the BB LPF registers + * UG570 page 33 states that this filter should be calibrated to 2.5 * bbbw */ +double ad9361_device_t::_calibrate_rx_TIAs(double req_rfbw) { boost::uint8_t reg1eb = _io_iface->peek8(0x1eb) & 0x3F; boost::uint8_t reg1ec = _io_iface->peek8(0x1ec) & 0x7F; @@ -474,13 +516,21 @@ void ad9361_device_t::_calibrate_rx_TIAs() boost::uint8_t reg1de = 0x00; boost::uint8_t reg1df = 0x00; - /* For calibration, baseband BW is half the complex BW, and must be - * between 28e6 and 0.2e6. */ - double bbbw = _baseband_bw / 2.0; - if (bbbw > 20e6) { - bbbw = 20e6; - } else if (bbbw < 0.20e6) { - bbbw = 0.20e6; + double bbbw = req_rfbw / 2.0; + + if(bbbw > _baseband_bw / 2.0) + { + UHD_LOG << "baseband bandwidth too large for current sample rate. Setting bandwidth to: "<<_baseband_bw; + bbbw = _baseband_bw / 2.0; + } + + /* Baseband BW must be between 28e6 and 0.4e6. + * Max filter BW is 70 MHz. 70 / 2.5 = 28 + * Min filter BW is 1 MHz. 1 / 2.5 = 0.4*/ + if (bbbw > 28e6) { + bbbw = 28e6; + } else if (bbbw < 0.40e6) { + bbbw = 0.40e6; } double ceil_bbbw_mhz = std::ceil(bbbw / 1e6); @@ -521,6 +571,8 @@ void ad9361_device_t::_calibrate_rx_TIAs() _io_iface->poke8(0x1df, reg1df); _io_iface->poke8(0x1dc, reg1dc); _io_iface->poke8(0x1de, reg1de); + + return bbbw; } /* Setup the AD9361 ADC. @@ -1457,6 +1509,12 @@ void ad9361_device_t::initialize() _rx1_agc_enable = false; _rx2_agc_enable = false; _last_calibration_freq = -AD9361_CAL_VALID_WINDOW; + _rx_analog_bw = 0; + _tx_analog_bw = 0; + _rx_tia_lp_bw = 0; + _tx_sec_lp_bw = 0; + _rx_bb_lp_bw = 0; + _tx_bb_lp_bw = 0; /* Reset the device. */ _io_iface->poke8(0x000, 0x01); @@ -1602,10 +1660,8 @@ void ad9361_device_t::initialize() _program_gain_table(); _setup_gain_control(false); - _calibrate_baseband_rx_analog_filter(); - _calibrate_baseband_tx_analog_filter(); - _calibrate_rx_TIAs(); - _calibrate_secondary_tx_filter(); + set_bw_filter(RX, _baseband_bw); + set_bw_filter(TX, _baseband_bw); _setup_adc(); @@ -1729,10 +1785,8 @@ double ad9361_device_t::set_clock_rate(const double req_rate) _setup_gain_control(false); _reprogram_gains(); - _calibrate_baseband_rx_analog_filter(); - _calibrate_baseband_tx_analog_filter(); - _calibrate_rx_TIAs(); - _calibrate_secondary_tx_filter(); + set_bw_filter(RX, _baseband_bw); + set_bw_filter(TX, _baseband_bw); _setup_adc(); @@ -2198,4 +2252,485 @@ void ad9361_device_t::set_agc_mode(chain_t chain, gain_mode_t gain_mode) } } +std::vector<std::string> ad9361_device_t::get_filter_names(direction_t direction) +{ + std::vector<std::string> ret; + if(direction == RX) { + for(std::map<std::string, filter_query_helper>::iterator it = _rx_filters.begin(); it != _rx_filters.end(); ++it) { + ret.push_back(it->first); + } + } else if (direction == TX) + { + for(std::map<std::string, filter_query_helper>::iterator it = _tx_filters.begin(); it != _tx_filters.end(); ++it) { + ret.push_back(it->first); + } + } + return ret; +} + +filter_info_base::sptr ad9361_device_t::get_filter(direction_t direction, chain_t chain, const std::string &name) +{ + if(direction == RX) { + if (not _rx_filters[name].get) + { + throw uhd::runtime_error("ad9361_device_t::get_filter this filter can not be read."); + } + return _rx_filters[name].get(direction, chain); + } else if (direction == TX) { + if (not _tx_filters[name].get) + { + throw uhd::runtime_error("ad9361_device_t::get_filter this filter can not be read."); + } + return _tx_filters[name].get(direction, chain); + } + + throw uhd::runtime_error("ad9361_device_t::get_filter wrong direction parameter."); +} + +void ad9361_device_t::set_filter(direction_t direction, chain_t chain, const std::string &name, filter_info_base::sptr filter) +{ + + if(direction == RX) { + if(not _rx_filters[name].set) + { + throw uhd::runtime_error("ad9361_device_t::set_filter this filter can not be written."); + } + _rx_filters[name].set(direction, chain, filter); + } else if (direction == TX) { + if(not _tx_filters[name].set) + { + throw uhd::runtime_error("ad9361_device_t::set_filter this filter can not be written."); + } + _tx_filters[name].set(direction, chain, filter); + } + +} + +double ad9361_device_t::set_bw_filter(direction_t direction, const double rf_bw) +{ + //both low pass filters are programmed to the same bw. However, their cutoffs will differ. + //Together they should create the requested bb bw. + double set_analog_bb_bw = 0; + if(direction == RX) + { + _rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(rf_bw); //returns bb bw + _rx_tia_lp_bw = _calibrate_rx_TIAs(rf_bw); + _rx_analog_bw = _rx_bb_lp_bw; + set_analog_bb_bw = _rx_analog_bw; + } else { + _tx_bb_lp_bw = _calibrate_baseband_tx_analog_filter(rf_bw); //returns bb bw + _tx_sec_lp_bw = _calibrate_secondary_tx_filter(rf_bw); + _tx_analog_bw = _tx_bb_lp_bw; + set_analog_bb_bw = _tx_analog_bw; + } + return (2.0 * set_analog_bb_bw); +} + +void ad9361_device_t::_set_fir_taps(direction_t direction, chain_t chain, const std::vector<boost::int16_t>& taps) +{ + size_t num_taps = taps.size(); + size_t num_taps_avail = _get_num_fir_taps(direction); + if(num_taps == num_taps_avail) + { + boost::scoped_array<boost::uint16_t> coeffs(new boost::uint16_t[num_taps_avail]); + for (size_t i = 0; i < num_taps_avail; i++) + { + coeffs[i] = boost::uint16_t(taps[i]); + } + _program_fir_filter(direction, chain, num_taps_avail, coeffs.get()); + } else if(num_taps < num_taps_avail){ + throw uhd::runtime_error("ad9361_device_t::_set_fir_taps not enough coefficients."); + } else { + throw uhd::runtime_error("ad9361_device_t::_set_fir_taps too many coefficients."); + } +} + +size_t ad9361_device_t::_get_num_fir_taps(direction_t direction) +{ + boost::uint8_t num = 0; + if(direction == RX) + num = _io_iface->peek8(0x0F5); + else + num = _io_iface->peek8(0x065); + num = ((num >> 5) & 0x07); + return ((num + 1) * 16); +} + +size_t ad9361_device_t::_get_fir_dec_int(direction_t direction) +{ + boost::uint8_t dec_int = 0; + if(direction == RX) + dec_int = _io_iface->peek8(0x003); + else + dec_int = _io_iface->peek8(0x002); + /* + * 0 = dec/int by 1 and bypass filter + * 1 = dec/int by 1 + * 2 = dec/int by 2 + * 3 = dec/int by 4 */ + dec_int = (dec_int & 0x03); + if(dec_int == 3) + { + return 4; + } + return dec_int; +} + +std::vector<boost::int16_t> ad9361_device_t::_get_fir_taps(direction_t direction, chain_t chain) +{ + int base; + size_t num_taps = _get_num_fir_taps(direction); + boost::uint8_t config; + boost::uint8_t reg_numtaps = (((num_taps / 16) - 1) & 0x07) << 5; + config = reg_numtaps | 0x02; //start the programming clock + + if(chain == CHAIN_1) + { + config = config | (1 << 3); + } else if (chain == CHAIN_2){ + config = config | (1 << 4); + } else { + throw uhd::runtime_error("[ad9361_device_t] Can not read both chains synchronously"); + } + + if(direction == RX) + { + base = 0xF0; + } else { + base = 0x60; + } + + _io_iface->poke8(base+5,config); + + std::vector<boost::int16_t> taps; + boost::uint8_t lower_val; + boost::uint8_t higher_val; + boost::uint16_t coeff; + for(size_t i = 0;i < num_taps;i++) + { + _io_iface->poke8(base,0x00+i); + lower_val = _io_iface->peek8(base+3); + higher_val = _io_iface->peek8(base+4); + coeff = ((higher_val << 8) | lower_val); + taps.push_back(boost::int16_t(coeff)); + } + + config = (config & (~(1 << 1))); //disable filter clock + _io_iface->poke8(base+5,config); + return taps; +} + +/* + * Returns either RX TIA LPF or TX Secondary LPF + * depending on the direction. + * See UG570 for details on used scaling factors. */ +filter_info_base::sptr ad9361_device_t::_get_filter_lp_tia_sec(direction_t direction) +{ + double cutoff = 0; + + if(direction == RX) + { + cutoff = 2.5 * _rx_tia_lp_bw; + } else { + cutoff = 5 * _tx_sec_lp_bw; + } + + filter_info_base::sptr lp(new analog_filter_lp(filter_info_base::ANALOG_LOW_PASS, false, 0, "single-pole", cutoff, 20)); + return lp; +} + +/* + * Returns RX/TX BB LPF. + * See UG570 for details on used scaling factors. */ +filter_info_base::sptr ad9361_device_t::_get_filter_lp_bb(direction_t direction) +{ + double cutoff = 0; + if(direction == RX) + { + cutoff = 1.4 * _rx_bb_lp_bw; + } else { + cutoff = 1.6 * _tx_bb_lp_bw; + } + + filter_info_base::sptr bb_lp(new analog_filter_lp(filter_info_base::ANALOG_LOW_PASS, false, 1, "third-order Butterworth", cutoff, 60)); + return bb_lp; +} + +/* + * For RX direction the DEC3 is returned. + * For TX direction the INT3 is returned. */ +filter_info_base::sptr ad9361_device_t::_get_filter_dec_int_3(direction_t direction) +{ + boost::uint8_t enable = 0; + double rate = _adcclock_freq; + double full_scale; + size_t dec = 0; + size_t interpol = 0; + filter_info_base::filter_type type = filter_info_base::DIGITAL_I16; + std::string name; + boost::int16_t taps_array_rx[] = {55, 83, 0, -393, -580, 0, 1914, 4041, 5120, 4041, 1914, 0, -580, -393, 0, 83, 55}; + boost::int16_t taps_array_tx[] = {36, -19, 0, -156, -12, 0, 479, 233, 0, -1215, -993, 0, 3569, 6277, 8192, 6277, 3569, 0, -993, -1215, 0, 223, 479, 0, -12, -156, 0, -19, 36}; + std::vector<boost::int16_t> taps; + + filter_info_base::sptr ret; + + if(direction == RX) + { + full_scale = 16384; + dec = 3; + interpol = 1; + + enable = _io_iface->peek8(0x003); + enable = ((enable >> 4) & 0x03); + taps.assign(taps_array_rx, taps_array_rx + sizeof(taps_array_rx) / sizeof(boost::int16_t) ); + + } else { + full_scale = 8192; + dec = 1; + interpol = 3; + + boost::uint8_t use_dac_clk_div = _io_iface->peek8(0x00A); + use_dac_clk_div = ((use_dac_clk_div >> 3) & 0x01); + if(use_dac_clk_div == 1) + { + rate = rate / 2; + } + + enable = _io_iface->peek8(0x002); + enable = ((enable >> 4) & 0x03); + if(enable == 2) //0 => int. by 1, 1 => int. by 2 (HB3), 2 => int. by 3 + { + rate /= 3; + } + + taps.assign(taps_array_tx, taps_array_tx + sizeof(taps_array_tx) / sizeof(boost::int16_t) ); + } + + ret = filter_info_base::sptr(new digital_filter_base<boost::int16_t>(type, (enable != 2) ? true : false, 2, rate, interpol, dec, full_scale, taps.size(), taps)); + return ret; +} + +filter_info_base::sptr ad9361_device_t::_get_filter_hb_3(direction_t direction) +{ + boost::uint8_t enable = 0; + double rate = _adcclock_freq; + double full_scale = 0; + size_t dec = 1; + size_t interpol = 1; + filter_info_base::filter_type type = filter_info_base::DIGITAL_I16; + boost::int16_t taps_array_rx[] = {1, 4, 6, 4, 1}; + boost::int16_t taps_array_tx[] = {1, 2, 1}; + std::vector<boost::int16_t> taps; + + if(direction == RX) + { + full_scale = 16; + dec = 2; + + enable = _io_iface->peek8(0x003); + enable = ((enable >> 4) & 0x03); + taps.assign(taps_array_rx, taps_array_rx + sizeof(taps_array_rx) / sizeof(boost::int16_t) ); + } else { + full_scale = 2; + interpol = 2; + + boost::uint8_t use_dac_clk_div = _io_iface->peek8(0x00A); + use_dac_clk_div = ((use_dac_clk_div >> 3) & 0x01); + if(use_dac_clk_div == 1) + { + rate = rate / 2; + } + + enable = _io_iface->peek8(0x002); + enable = ((enable >> 4) & 0x03); + if(enable == 1) + { + rate /= 2; + } + taps.assign(taps_array_tx, taps_array_tx + sizeof(taps_array_tx) / sizeof(boost::int16_t) ); + } + + filter_info_base::sptr hb = filter_info_base::sptr(new digital_filter_base<boost::int16_t>(type, (enable != 1) ? true : false, 2, rate, interpol, dec, full_scale, taps.size(), taps)); + return hb; +} + +filter_info_base::sptr ad9361_device_t::_get_filter_hb_2(direction_t direction) +{ + boost::uint8_t enable = 0; + double rate = _adcclock_freq; + double full_scale = 0; + size_t dec = 1; + size_t interpol = 1; + filter_info_base::filter_type type = filter_info_base::DIGITAL_I16; + boost::int16_t taps_array[] = {-9, 0, 73, 128, 73, 0, -9}; + std::vector<boost::int16_t> taps(taps_array, taps_array + sizeof(taps_array) / sizeof(boost::int16_t) ); + + digital_filter_base<boost::int16_t>::sptr hb_3 = boost::dynamic_pointer_cast<digital_filter_base<boost::int16_t> >(_get_filter_hb_3(direction)); + digital_filter_base<boost::int16_t>::sptr dec_int_3 = boost::dynamic_pointer_cast<digital_filter_base<boost::int16_t> >(_get_filter_dec_int_3(direction)); + + if(direction == RX) + { + full_scale = 256; + dec = 2; + enable = _io_iface->peek8(0x003); + } else { + full_scale = 128; + interpol = 2; + enable = _io_iface->peek8(0x002); + } + + enable = ((enable >> 3) & 0x01); + + if(!(hb_3->is_bypassed())) + { + if(direction == RX) + { + rate = hb_3->get_output_rate(); + }else if (direction == TX) { + rate = hb_3->get_input_rate(); + if(enable) + { + rate /= 2; + } + } + } else { //else dec3/int3 or none of them is used. + if(direction == RX) + { + rate = dec_int_3->get_output_rate(); + }else if (direction == TX) { + rate = dec_int_3->get_input_rate(); + if(enable) + { + rate /= 2; + } + } + } + + filter_info_base::sptr hb(new digital_filter_base<boost::int16_t>(type, (enable == 0) ? true : false, 3, rate, interpol, dec, full_scale, taps.size(), taps)); + return hb; +} + +filter_info_base::sptr ad9361_device_t::_get_filter_hb_1(direction_t direction) +{ + boost::uint8_t enable = 0; + double rate = 0; + double full_scale = 0; + size_t dec = 1; + size_t interpol = 1; + filter_info_base::filter_type type = filter_info_base::DIGITAL_I16; + + std::vector<boost::int16_t> taps; + boost::int16_t taps_rx_array[] = {-8, 0, 42, 0, -147, 0, 619, 1013, 619, 0, -147, 0, 42, 0, -8}; + boost::int16_t taps_tx_array[] = {-53, 0, 313, 0, -1155, 0, 4989, 8192, 4989, 0, -1155, 0, 313, 0, -53}; + + digital_filter_base<boost::int16_t>::sptr hb_2 = boost::dynamic_pointer_cast<digital_filter_base<boost::int16_t> >(_get_filter_hb_2(direction)); + + if(direction == RX) + { + full_scale = 2048; + dec = 2; + enable = _io_iface->peek8(0x003); + enable = ((enable >> 2) & 0x01); + rate = hb_2->get_output_rate(); + taps.assign(taps_rx_array, taps_rx_array + sizeof(taps_rx_array) / sizeof(boost::int16_t) ); + } else if (direction == TX) { + full_scale = 8192; + interpol = 2; + enable = _io_iface->peek8(0x002); + enable = ((enable >> 2) & 0x01); + rate = hb_2->get_input_rate(); + if(enable) + { + rate /= 2; + } + taps.assign(taps_tx_array, taps_tx_array + sizeof(taps_tx_array) / sizeof(boost::int16_t) ); + } + + filter_info_base::sptr hb(new digital_filter_base<boost::int16_t>(type, (enable == 0) ? true : false, 4, rate, interpol, dec, full_scale, taps.size(), taps)); + return hb; +} + +filter_info_base::sptr ad9361_device_t::_get_filter_fir(direction_t direction, chain_t chain) +{ + double rate = 0; + size_t dec = 1; + size_t interpol = 1; + size_t max_num_taps = 128; + boost::uint8_t enable = 1; + + digital_filter_base<boost::int16_t>::sptr hb_1 = boost::dynamic_pointer_cast<digital_filter_base<boost::int16_t> >(_get_filter_hb_1(direction)); + + if(direction == RX) + { + dec = _get_fir_dec_int(direction); + if(dec == 0) + { + enable = 0; + dec = 1; + } + interpol = 1; + rate = hb_1->get_output_rate(); + }else if (direction == TX) { + interpol = _get_fir_dec_int(direction); + if(interpol == 0) + { + enable = 0; + interpol = 1; + } + dec = 1; + rate = hb_1->get_input_rate(); + if(enable) + { + rate /= interpol; + } + } + max_num_taps = _get_num_fir_taps(direction); + + filter_info_base::sptr fir(new digital_filter_fir<boost::int16_t>(filter_info_base::DIGITAL_FIR_I16, (enable == 0) ? true : false, 5, rate, interpol, dec, 32767, max_num_taps, _get_fir_taps(direction, chain))); + + return fir; +} + +void ad9361_device_t::_set_filter_fir(direction_t direction, chain_t channel, filter_info_base::sptr filter) +{ + digital_filter_fir<boost::int16_t>::sptr fir = boost::dynamic_pointer_cast<digital_filter_fir<boost::int16_t> >(filter); + //only write taps. Ignore everything else for now + _set_fir_taps(direction, channel, fir->get_taps()); +} + +/* + * If BW of one of the analog filters gets overwritten manually, + * _tx_analog_bw and _rx_analog_bw are not valid any more! + * For useful data in those variables set_bw_filter method should be used + */ +void ad9361_device_t::_set_filter_lp_bb(direction_t direction, filter_info_base::sptr filter) +{ + analog_filter_lp::sptr lpf = boost::dynamic_pointer_cast<analog_filter_lp>(filter); + double bw = lpf->get_cutoff(); + if(direction == RX) + { + //remember: this function takes rf bw as its input and calibrated to 1.4 x the given value + _rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(2 * bw / 1.4); //returns bb bw + + } else { + //remember: this function takes rf bw as its input and calibrates to 1.6 x the given value + _tx_bb_lp_bw = _calibrate_baseband_tx_analog_filter(2 * bw / 1.6); + } +} + +void ad9361_device_t::_set_filter_lp_tia_sec(direction_t direction, filter_info_base::sptr filter) +{ + analog_filter_lp::sptr lpf = boost::dynamic_pointer_cast<analog_filter_lp>(filter); + double bw = lpf->get_cutoff(); + if(direction == RX) + { + //remember: this function takes rf bw as its input and calibrated to 2.5 x the given value + _rx_tia_lp_bw = _calibrate_rx_TIAs(2 * bw / 2.5); //returns bb bw + + } else { + //remember: this function takes rf bw as its input and calibrates to 5 x the given value + _tx_sec_lp_bw = _calibrate_secondary_tx_filter(2 * bw / 5); + } +} + }} diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.h b/host/lib/usrp/common/ad9361_driver/ad9361_device.h index 7c53ff0c4..a242f35e9 100644 --- a/host/lib/usrp/common/ad9361_driver/ad9361_device.h +++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.h @@ -8,6 +8,14 @@ #include <ad9361_client.h> #include <boost/noncopyable.hpp> #include <boost/thread/recursive_mutex.hpp> +#include <uhd/types/filters.hpp> +#include <uhd/types/sensors.hpp> +#include <complex> +#include <vector> +#include <map> +#include "boost/assign.hpp" +#include "boost/bind.hpp" +#include "boost/function.hpp" namespace uhd { namespace usrp { @@ -15,11 +23,34 @@ class ad9361_device_t : public boost::noncopyable { public: enum direction_t { RX, TX }; - enum chain_t { CHAIN_1, CHAIN_2 }; enum gain_mode_t {GAIN_MODE_MANUAL, GAIN_MODE_SLOW_AGC, GAIN_MODE_FAST_AGC}; + enum chain_t { CHAIN_1, CHAIN_2, CHAIN_BOTH }; ad9361_device_t(ad9361_params::sptr client, ad9361_io::sptr io_iface) : - _client_params(client), _io_iface(io_iface) {} + _client_params(client), _io_iface(io_iface) { + + _rx_filters = boost::assign::map_list_of("LPF_TIA", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_lp_tia_sec, this, _1), + boost::bind(&ad9361_device_t::_set_filter_lp_tia_sec, this, _1, _3))) + ("LPF_BB", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_lp_bb, this, _1), + boost::bind(&ad9361_device_t::_set_filter_lp_bb, this, _1, _3))) + ("HB_3", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_hb_3, this, _1), 0)) + ("DEC_3", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_dec_int_3, this, _1), 0)) + ("HB_2", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_hb_2, this, _1), 0)) + ("HB_1", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_hb_1, this, _1), 0)) + ("FIR_1", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_fir, this, _1, _2), + boost::bind(&ad9361_device_t::_set_filter_fir, this, _1, _2, _3))); + + _tx_filters = boost::assign::map_list_of("LPF_SECONDARY", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_lp_tia_sec, this, _1), + boost::bind(&ad9361_device_t::_set_filter_lp_tia_sec, this, _1, _3))) + ("LPF_BB", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_lp_bb, this, _1), + boost::bind(&ad9361_device_t::_set_filter_lp_bb, this, _1, _3))) + ("HB_3", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_hb_3, this, _1), 0)) + ("INT_3", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_dec_int_3, this, _1), 0)) + ("HB_2", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_hb_2, this, _1), 0)) + ("HB_1", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_hb_1, this, _1), 0)) + ("FIR_1", filter_query_helper(boost::bind(&ad9361_device_t::_get_filter_fir, this, _1, _2), + boost::bind(&ad9361_device_t::_set_filter_fir, this, _1, _2, _3))); + } /* Initialize the AD9361 codec. */ void initialize(); @@ -85,6 +116,19 @@ public: /* Enable AD9361's AGC gain mode. */ void set_agc(chain_t chain, bool enable); + /* Set bandwidth of AD9361's analog LP filters. + * Bandwidth should be RF bandwidth */ + double set_bw_filter(direction_t direction, const double rf_bw); + + /* + * Filter API implementation + * */ + filter_info_base::sptr get_filter(direction_t direction, chain_t chain, const std::string &name); + + void set_filter(direction_t direction, chain_t chain, const std::string &name, filter_info_base::sptr filter); + + std::vector<std::string> get_filter_names(direction_t direction); + //Constants static const double AD9361_MAX_GAIN; static const double AD9361_MAX_CLOCK_RATE; @@ -95,12 +139,15 @@ private: //Methods void _program_fir_filter(direction_t direction, int num_taps, boost::uint16_t *coeffs); void _setup_tx_fir(size_t num_taps, boost::int32_t interpolation); void _setup_rx_fir(size_t num_taps, boost::int32_t decimation); + void _program_fir_filter(direction_t direction, chain_t chain, int num_taps, boost::uint16_t *coeffs); + void _setup_tx_fir(size_t num_taps); + void _setup_rx_fir(size_t num_taps); void _calibrate_lock_bbpll(); void _calibrate_synth_charge_pumps(); - double _calibrate_baseband_rx_analog_filter(); - double _calibrate_baseband_tx_analog_filter(); - void _calibrate_secondary_tx_filter(); - void _calibrate_rx_TIAs(); + double _calibrate_baseband_rx_analog_filter(double rfbw); + double _calibrate_baseband_tx_analog_filter(double rfbw); + double _calibrate_secondary_tx_filter(double rfbw); + double _calibrate_rx_TIAs(double rfbw); void _setup_adc(); void _calibrate_baseband_dc_offset(); void _calibrate_rf_dc_offset(); @@ -118,6 +165,20 @@ private: //Methods double _get_temperature(const double cal_offset, const double timeout = 0.1); void _configure_bb_rf_dc_tracking(const bool on); void _setup_agc(chain_t chain, gain_mode_t gain_mode); + void _set_fir_taps(direction_t direction, chain_t chain, const std::vector<boost::int16_t>& taps); + std::vector<boost::int16_t> _get_fir_taps(direction_t direction, chain_t chain); + size_t _get_num_fir_taps(direction_t direction); + size_t _get_fir_dec_int(direction_t direction); + filter_info_base::sptr _get_filter_lp_tia_sec(direction_t direction); + filter_info_base::sptr _get_filter_lp_bb(direction_t direction); + filter_info_base::sptr _get_filter_dec_int_3(direction_t direction); + filter_info_base::sptr _get_filter_hb_3(direction_t direction); + filter_info_base::sptr _get_filter_hb_2(direction_t direction); + filter_info_base::sptr _get_filter_hb_1(direction_t direction); + filter_info_base::sptr _get_filter_fir(direction_t direction, chain_t chain); + void _set_filter_fir(direction_t direction, chain_t channel, filter_info_base::sptr filter); + void _set_filter_lp_bb(direction_t direction, filter_info_base::sptr filter); + void _set_filter_lp_tia_sec(direction_t direction, filter_info_base::sptr filter); private: //Members typedef struct { @@ -130,6 +191,22 @@ private: //Members boost::uint8_t bbftune_mode; } chip_regs_t; + struct filter_query_helper + { + filter_query_helper( + boost::function<filter_info_base::sptr (direction_t, chain_t)> p_get, + boost::function<void (direction_t, chain_t, filter_info_base::sptr)> p_set + ) : get(p_get), set(p_set) { } + + filter_query_helper(){ } + + boost::function<filter_info_base::sptr (direction_t, chain_t)> get; + boost::function<void (direction_t, chain_t, filter_info_base::sptr)> set; + }; + + std::map<std::string, filter_query_helper> _rx_filters; + std::map<std::string, filter_query_helper> _tx_filters; + //Interfaces ad9361_params::sptr _client_params; ad9361_io::sptr _io_iface; @@ -137,6 +214,8 @@ private: //Members double _rx_freq, _tx_freq, _req_rx_freq, _req_tx_freq; double _last_calibration_freq; double _baseband_bw, _bbpll_freq, _adcclock_freq; + double _rx_analog_bw, _tx_analog_bw, _rx_bb_lp_bw, _tx_bb_lp_bw; + double _rx_tia_lp_bw, _tx_sec_lp_bw; double _req_clock_rate, _req_coreclk; boost::uint16_t _rx_bbf_tunediv; boost::uint8_t _curr_gain_table; diff --git a/host/lib/usrp/common/adf435x_common.cpp b/host/lib/usrp/common/adf435x_common.cpp index 9b362a4d9..474a1c932 100644 --- a/host/lib/usrp/common/adf435x_common.cpp +++ b/host/lib/usrp/common/adf435x_common.cpp @@ -129,11 +129,11 @@ adf435x_tuning_settings tune_adf435x_synth( settings.frac_12_bit = FRAC; settings.int_16_bit = N; settings.mod_12_bit = MOD; - settings.clock_divider_12_bit = std::max<boost::uint16_t>(1, std::ceil(PHASE_RESYNC_TIME*pfd_freq/MOD)); + settings.clock_divider_12_bit = std::max<boost::uint16_t>(1, boost::uint16_t(std::ceil(PHASE_RESYNC_TIME*pfd_freq/MOD))); settings.r_counter_10_bit = R; settings.r_divide_by_2_en = T; settings.r_doubler_en = D; - settings.band_select_clock_div = BS; + settings.band_select_clock_div = boost::uint8_t(BS); settings.rf_divider = RFdiv; std::string tuning_str = (constraints.force_frac0) ? "Integer-N" : "Fractional"; diff --git a/host/lib/usrp/common/fifo_ctrl_excelsior.cpp b/host/lib/usrp/common/fifo_ctrl_excelsior.cpp index c0e2c5ea0..2ea5b66da 100644 --- a/host/lib/usrp/common/fifo_ctrl_excelsior.cpp +++ b/host/lib/usrp/common/fifo_ctrl_excelsior.cpp @@ -119,7 +119,7 @@ public: /******************************************************************* * Peek and poke 32 bit implementation ******************************************************************/ - void poke32(wb_addr_type addr, boost::uint32_t data){ + void poke32(const wb_addr_type addr, const boost::uint32_t data){ boost::mutex::scoped_lock lock(_mutex); this->send_pkt(addr, data, POKE32_CMD); @@ -127,7 +127,7 @@ public: this->wait_for_ack(_seq_out-MAX_SEQS_OUT); } - boost::uint32_t peek32(wb_addr_type addr){ + boost::uint32_t peek32(const wb_addr_type addr){ boost::mutex::scoped_lock lock(_mutex); this->send_pkt(addr, 0, PEEK32_CMD); @@ -138,11 +138,11 @@ public: /******************************************************************* * Peek and poke 16 bit not implemented ******************************************************************/ - void poke16(wb_addr_type, boost::uint16_t){ + void poke16(const wb_addr_type, const boost::uint16_t){ throw uhd::not_implemented_error("poke16 not implemented in fifo ctrl module"); } - boost::uint16_t peek16(wb_addr_type){ + boost::uint16_t peek16(const wb_addr_type){ throw uhd::not_implemented_error("peek16 not implemented in fifo ctrl module"); } diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index 6552f1b2d..7ae97e4d0 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -421,7 +421,7 @@ public: boost::uint16_t offset, size_t num_bytes ){ - this->write_i2c(addr, byte_vector_t(1, offset)); + this->write_i2c(addr, byte_vector_t(1, boost::uint8_t(offset))); return this->read_i2c(addr, num_bytes); } diff --git a/host/lib/usrp/cores/i2c_core_100_wb32.cpp b/host/lib/usrp/cores/i2c_core_100_wb32.cpp index a85cdea42..530267f6c 100644 --- a/host/lib/usrp/cores/i2c_core_100_wb32.cpp +++ b/host/lib/usrp/cores/i2c_core_100_wb32.cpp @@ -70,7 +70,7 @@ public: void set_clock_rate(const double rate) { static const boost::uint32_t i2c_datarate = 400000; - boost::uint16_t prescaler = rate / (i2c_datarate*5) - 1; + boost::uint16_t prescaler = boost::uint16_t(rate / (i2c_datarate*5) - 1); _iface->poke32(REG_I2C_PRESCALER_LO, prescaler & 0xFF); _iface->poke32(REG_I2C_PRESCALER_HI, (prescaler >> 8) & 0xFF); } @@ -127,7 +127,7 @@ public: //the default implementation calls read i2c once per byte byte_vector_t read_eeprom(boost::uint16_t addr, boost::uint16_t offset, size_t num_bytes) { - this->write_i2c(addr, byte_vector_t(1, offset)); + this->write_i2c(addr, byte_vector_t(1, boost::uint8_t(offset))); return this->read_i2c(addr, num_bytes); } diff --git a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp index 6357102fb..1c9b5c4fa 100644 --- a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp +++ b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp @@ -190,7 +190,7 @@ private: try { UHD_ASSERT_THROW(bool(buff)); - UHD_ASSERT_THROW(bool(buff->size())); + UHD_ASSERT_THROW(buff->size() > 0); } catch(const std::exception &ex) { diff --git a/host/lib/usrp/dboard/db_tvrx2.cpp b/host/lib/usrp/dboard/db_tvrx2.cpp index c74c64471..9300483d1 100644 --- a/host/lib/usrp/dboard/db_tvrx2.cpp +++ b/host/lib/usrp/dboard/db_tvrx2.cpp @@ -1103,7 +1103,7 @@ tvrx2::~tvrx2(void){ * TDA18272 Register IO Functions **********************************************************************/ void tvrx2::set_scaled_rf_freq(double rf_freq){ - _tda18272hnm_regs.set_rf_freq(_freq_scalar*rf_freq/1e3); + _tda18272hnm_regs.set_rf_freq(boost::uint32_t(_freq_scalar*rf_freq/1e3)); } double tvrx2::get_scaled_rf_freq(void){ @@ -1320,9 +1320,9 @@ void tvrx2::tvrx2_tda18272_tune_rf_filter(boost::uint32_t uRF) read_reg(0x26, 0x2B); subband_freqs = get_tda18272_rfcal_result_freq_range(1); - uRFCal0 = subband_freqs.start(); + uRFCal0 = boost::uint32_t(subband_freqs.start()); subband_freqs = get_tda18272_rfcal_result_freq_range(4); - uRFCal1 = subband_freqs.start(); + uRFCal1 = boost::uint32_t(subband_freqs.start()); if(uRF < uRFCal0) subband = 0; @@ -1335,9 +1335,9 @@ void tvrx2::tvrx2_tda18272_tune_rf_filter(boost::uint32_t uRF) else { subband_freqs = get_tda18272_rfcal_result_freq_range(7); - uRFCal0 = subband_freqs.start(); + uRFCal0 = boost::uint32_t(subband_freqs.start()); subband_freqs = get_tda18272_rfcal_result_freq_range(10); - uRFCal1 = subband_freqs.start(); + uRFCal1 = boost::uint32_t(subband_freqs.start()); if(uRF < uRFCal0) subband = 4; @@ -1351,7 +1351,7 @@ void tvrx2::tvrx2_tda18272_tune_rf_filter(boost::uint32_t uRF) cal_result = _rfcal_coeffs[subband].cal_number; subband_freqs = get_tda18272_rfcal_result_freq_range(cal_result); - uRFCal0 = subband_freqs.start(); + uRFCal0 = boost::uint32_t(subband_freqs.start()); RF_A1 = _rfcal_coeffs[subband].RF_A1; RF_B1 = _rfcal_coeffs[subband].RF_B1; @@ -1721,7 +1721,7 @@ void tvrx2::wait_irq(void){ send_reg(0xA, 0xA); read_reg(0xA, 0xB); - irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]); + irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]) > 0; UHD_LOGV(often) << boost::format( "\nTVRX2 (%s): Cleared IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq << std::endl; diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp index 5184d2ecb..06bfad7d3 100644 --- a/host/lib/usrp/dboard/db_ubx.cpp +++ b/host/lib/usrp/dboard/db_ubx.cpp @@ -191,7 +191,7 @@ protected: } //keep pfd freq low enough to achieve 50kHz BS clock - BS = std::ceil(pfd_freq / 50e3); + BS = int(std::ceil(pfd_freq / 50e3)); if(BS <= 1023) break; } UHD_ASSERT_THROW(R <= 1023); diff --git a/host/lib/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp index f2bee47a9..3b56ae19a 100644 --- a/host/lib/usrp/dboard_eeprom.cpp +++ b/host/lib/usrp/dboard_eeprom.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2011,2015 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 @@ -15,6 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // +#include <uhd/types/byte_vector.hpp> #include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/exception.hpp> #include <uhd/utils/log.hpp> @@ -27,30 +28,6 @@ using namespace uhd; using namespace uhd::usrp; -/*********************************************************************** - * Utility functions - **********************************************************************/ - -//! create a string from a byte vector, return empty if invalid ascii -static const std::string bytes_to_string(const byte_vector_t &bytes){ - std::string out; - BOOST_FOREACH(boost::uint8_t byte, bytes){ - if (byte < 32 or byte > 127) return out; - out += byte; - } - return out; -} - -//! create a byte vector from a string, null terminate unless max length -static const byte_vector_t string_to_bytes(const std::string &string, size_t max_length){ - byte_vector_t bytes; - for (size_t i = 0; i < std::min(string.size(), max_length); i++){ - bytes.push_back(string[i]); - } - if (bytes.size() < max_length - 1) bytes.push_back('\0'); - return bytes; -} - //////////////////////////////////////////////////////////////////////// // format of daughterboard EEPROM // 00: 0xDB code for ``I'm a daughterboard'' diff --git a/host/lib/usrp/e300/e300_common.cpp b/host/lib/usrp/e300/e300_common.cpp index 97e906be7..db5b37055 100644 --- a/host/lib/usrp/e300/e300_common.cpp +++ b/host/lib/usrp/e300/e300_common.cpp @@ -45,7 +45,7 @@ void load_fpga_image(const std::string &path) char buff[16384]; // devcfg driver can't handle huge writes do { fpga_file.read(buff, sizeof(buff)); - std::fwrite(buff, 1, fpga_file.gcount(), wfile); + std::fwrite(buff, 1, size_t(fpga_file.gcount()), wfile); } while (fpga_file); fpga_file.close(); diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp index 8be3e47c9..3d92bc5c8 100644 --- a/host/lib/usrp/e300/e300_impl.cpp +++ b/host/lib/usrp/e300/e300_impl.cpp @@ -361,7 +361,7 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr) e300_fifo_config_t fifo_cfg; try { fifo_cfg = e300_read_sysfs(); - } catch (uhd::lookup_error &e) { + } catch (...) { throw uhd::runtime_error("Failed to get driver parameters from sysfs."); } _fifo_iface = e300_fifo_interface::make(fifo_cfg); @@ -610,7 +610,7 @@ uhd::sensor_value_t e300_impl::_get_fe_pll_lock(const bool is_tx) { const boost::uint32_t st = _global_regs->peek32(global_regs::RB32_CORE_PLL); - const bool locked = is_tx ? st & 0x1 : st & 0x2; + const bool locked = is_tx ? ((st & 0x1) > 0) : ((st & 0x2) > 0); return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -665,7 +665,7 @@ void e300_impl::_register_loopback_self_test(wb_iface::sptr iface) { bool test_fail = false; UHD_MSG(status) << "Performing register loopback test... " << std::flush; - size_t hash = time(NULL); + size_t hash = size_t(time(NULL)); for (size_t i = 0; i < 100; i++) { boost::hash_combine(hash, i); @@ -705,7 +705,7 @@ void e300_impl::_codec_loopback_self_test(wb_iface::sptr iface) bool test_fail = false; UHD_ASSERT_THROW(bool(iface)); UHD_MSG(status) << "Performing CODEC loopback test... " << std::flush; - size_t hash = time(NULL); + size_t hash = size_t(time(NULL)); for (size_t i = 0; i < 100; i++) { boost::hash_combine(hash, i); @@ -1056,6 +1056,18 @@ void e300_impl::_setup_radio(const size_t dspno) _tree->create<meta_range_t>(rf_fe_path / "freq" / "range") .publish(boost::bind(&ad9361_ctrl::get_rf_freq_range)); + //only in local mode + if(_xport_path == AXI) { + //add all frontend filters + std::vector<std::string> filter_names = _codec_ctrl->get_filter_names(key); + for(size_t i = 0;i < filter_names.size(); i++) + { + _tree->create<filter_info_base::sptr>(rf_fe_path / "filters" / filter_names[i] / "value" ) + .publish(boost::bind(&ad9361_ctrl::get_filter, _codec_ctrl, key, filter_names[i])) + .subscribe(boost::bind(&ad9361_ctrl::set_filter, _codec_ctrl, key, filter_names[i], _1)); + } + } + //setup RX related stuff if (key[0] == 'R') { static const std::vector<std::string> ants = boost::assign::list_of("TX/RX")("RX2"); diff --git a/host/lib/usrp/e300/e300_network.cpp b/host/lib/usrp/e300/e300_network.cpp index cb06a5740..2a63abc25 100644 --- a/host/lib/usrp/e300/e300_network.cpp +++ b/host/lib/usrp/e300/e300_network.cpp @@ -245,6 +245,9 @@ static void e300_codec_ctrl_tunnel( _codec_ctrl->set_agc_mode(which_str, "fast"); } break; + case codec_xact_t::ACTION_SET_BW: + out->bw = _codec_ctrl->set_bw_filter(which_str, in->bw); + break; default: UHD_MSG(status) << "Got unknown request?!" << std::endl; //Zero out actions to fail this request on client diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp index 871885a7b..c78946a6c 100644 --- a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp +++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp @@ -194,6 +194,40 @@ public: _transact(); } + //! set the filter bandwidth for the frontend's analog low pass + double set_bw_filter(const std::string &which, const double bw) + { + _clear(); + _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_SET_BW); + if (which == "TX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1); + else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2); + else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1); + else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2); + else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string."); + _args.bw = bw; + + _transact(); + return _retval.bw; + } + + //! List all available filters by name + std::vector<std::string> get_filter_names(const std::string &) + { + UHD_THROW_INVALID_CODE_PATH(); + } + + //! Return a list of all filters + filter_info_base::sptr get_filter(const std::string &, const std::string &) + { + UHD_THROW_INVALID_CODE_PATH(); + } + + //! Write back a filter + void set_filter(const std::string &, const std::string &, const filter_info_base::sptr) + { + UHD_THROW_INVALID_CODE_PATH(); + } + private: void _transact() { { diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp index 459d0ec55..065c5e7a0 100644 --- a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp +++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp @@ -35,6 +35,7 @@ public: double freq; double rssi; double temp; + double bw; boost::uint32_t use_dc_correction; boost::uint32_t use_iq_correction; boost::uint32_t use_agc; @@ -54,6 +55,8 @@ public: static const boost::uint32_t ACTION_SET_IQ_BALANCE_AUTO = 18; static const boost::uint32_t ACTION_SET_AGC = 19; static const boost::uint32_t ACTION_SET_AGC_MODE = 20; + static const boost::uint32_t ACTION_SET_BW = 21; + //Values for "which" static const boost::uint32_t CHAIN_NONE = 0; diff --git a/host/lib/usrp/e300/e300_sensor_manager.cpp b/host/lib/usrp/e300/e300_sensor_manager.cpp index 95f31742b..527cfb91a 100644 --- a/host/lib/usrp/e300/e300_sensor_manager.cpp +++ b/host/lib/usrp/e300/e300_sensor_manager.cpp @@ -159,7 +159,7 @@ public: } UHD_ASSERT_THROW(uhd::ntohx<boost::uint32_t>(transaction.which) == GPS_FOUND); // TODO: Use proper serialization here ... - return static_cast<bool>(uhd::ntohx(transaction.value)); + return (uhd::ntohx(transaction.value) > 0); } uhd::sensor_value_t get_gps_lock(void) @@ -193,7 +193,7 @@ public: } UHD_ASSERT_THROW(uhd::ntohx<boost::uint32_t>(transaction.which) == GPS_LOCK); // TODO: Use proper serialization here ... - return sensor_value_t("GPS lock status", static_cast<bool>(uhd::ntohx(transaction.value)), "locked", "unlocked"); + return sensor_value_t("GPS lock status", (uhd::ntohx(transaction.value) > 0), "locked", "unlocked"); } uhd::sensor_value_t get_ref_lock(void) @@ -227,7 +227,7 @@ public: } UHD_ASSERT_THROW(uhd::ntohx<boost::uint32_t>(transaction.which) == REF_LOCK); // TODO: Use proper serialization here ... - return sensor_value_t("Ref", static_cast<bool>(uhd::ntohx(transaction.value)), "locked", "unlocked"); + return sensor_value_t("Ref", (uhd::ntohx(transaction.value) > 0), "locked", "unlocked"); } private: diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 68c084589..9c92fe252 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2013 Ettus Research LLC +// Copyright 2010-2013,2015 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 @@ -16,6 +16,7 @@ // #include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/types/byte_vector.hpp> #include <uhd/types/mac_addr.hpp> #include <uhd/utils/byteswap.hpp> #include <boost/asio/ip/address_v4.hpp> @@ -39,32 +40,6 @@ static const size_t NAME_MAX_LEN = 32 - SERIAL_LEN; * Utility functions **********************************************************************/ -//! A wrapper around std::copy that takes ranges instead of iterators. -template<typename RangeSrc, typename RangeDst> inline -void byte_copy(const RangeSrc &src, RangeDst &dst){ - std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); -} - -//! create a string from a byte vector, return empty if invalid ascii -static const std::string bytes_to_string(const byte_vector_t &bytes){ - std::string out; - BOOST_FOREACH(boost::uint8_t byte, bytes){ - if (byte < 32 or byte > 127) return out; - out += byte; - } - return out; -} - -//! create a byte vector from a string, null terminate unless max length -static const byte_vector_t string_to_bytes(const std::string &string, size_t max_length){ - byte_vector_t bytes; - for (size_t i = 0; i < std::min(string.size(), max_length); i++){ - bytes.push_back(string[i]); - } - if (bytes.size() < max_length - 1) bytes.push_back('\0'); - return bytes; -} - //! convert a string to a byte vector to write to eeprom static byte_vector_t string_to_uint16_bytes(const std::string &num_str){ const boost::uint16_t num = boost::lexical_cast<boost::uint16_t>(num_str); diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp index 6eff9d3ad..48fdfcf12 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.cpp +++ b/host/lib/usrp/usrp1/usrp1_iface.cpp @@ -45,7 +45,7 @@ public: /******************************************************************* * Peek and Poke ******************************************************************/ - void poke32(boost::uint32_t addr, boost::uint32_t value) + void poke32(const boost::uint32_t addr, const boost::uint32_t value) { boost::uint32_t swapped = uhd::htonx(value); @@ -68,7 +68,7 @@ public: if (ret < 0) throw uhd::io_error("USRP1: failed control write"); } - boost::uint32_t peek32(boost::uint32_t addr) + boost::uint32_t peek32(const boost::uint32_t addr) { UHD_LOGV(always) << "peek32(" @@ -92,11 +92,11 @@ public: return uhd::ntohx(value_out); } - void poke16(boost::uint32_t, boost::uint16_t) { + void poke16(const boost::uint32_t, const boost::uint16_t) { throw uhd::not_implemented_error("Unhandled command poke16()"); } - boost::uint16_t peek16(boost::uint32_t) { + boost::uint16_t peek16(const boost::uint32_t) { throw uhd::not_implemented_error("Unhandled command peek16()"); return 0; } diff --git a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp index efb88eb82..9e8687b94 100644 --- a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp +++ b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp @@ -67,7 +67,7 @@ public: /******************************************************************* * Peek and poke 32 bit implementation ******************************************************************/ - void poke32(wb_addr_type addr, boost::uint32_t data){ + void poke32(const wb_addr_type addr, const boost::uint32_t data){ boost::mutex::scoped_lock lock(_mutex); this->send_pkt((addr - SETTING_REGS_BASE)/4, data, POKE32_CMD); @@ -75,7 +75,7 @@ public: this->wait_for_ack(_seq_out-MAX_SEQS_OUT); } - boost::uint32_t peek32(wb_addr_type addr){ + boost::uint32_t peek32(const wb_addr_type addr){ boost::mutex::scoped_lock lock(_mutex); this->send_pkt((addr - READBACK_BASE)/4, 0, PEEK32_CMD); @@ -86,11 +86,11 @@ public: /******************************************************************* * Peek and poke 16 bit not implemented ******************************************************************/ - void poke16(wb_addr_type, boost::uint16_t){ + void poke16(const wb_addr_type, const boost::uint16_t){ throw uhd::not_implemented_error("poke16 not implemented in fifo ctrl module"); } - boost::uint16_t peek16(wb_addr_type){ + boost::uint16_t peek16(const wb_addr_type){ throw uhd::not_implemented_error("peek16 not implemented in fifo ctrl module"); } diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 2f2c345be..3ffbf9aac 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -139,19 +139,19 @@ public: /*********************************************************************** * Peek and Poke **********************************************************************/ - void poke32(wb_addr_type addr, boost::uint32_t data){ + void poke32(const wb_addr_type addr, const boost::uint32_t data){ this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FPGA_POKE32>(addr, data); } - boost::uint32_t peek32(wb_addr_type addr){ + boost::uint32_t peek32(const wb_addr_type addr){ return this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FPGA_PEEK32>(addr); } - void poke16(wb_addr_type addr, boost::uint16_t data){ + void poke16(const wb_addr_type addr, const boost::uint16_t data){ this->get_reg<boost::uint16_t, USRP2_REG_ACTION_FPGA_POKE16>(addr, data); } - boost::uint16_t peek16(wb_addr_type addr){ + boost::uint16_t peek16(const wb_addr_type addr){ return this->get_reg<boost::uint16_t, USRP2_REG_ACTION_FPGA_PEEK16>(addr); } @@ -219,7 +219,7 @@ public: //setup the out data usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO); - out_data.data.i2c_args.addr = addr; + out_data.data.i2c_args.addr = uint8_t(addr); out_data.data.i2c_args.bytes = buf.size(); //limitation of i2c transaction size @@ -237,7 +237,7 @@ public: //setup the out data usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t(); out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); - out_data.data.i2c_args.addr = addr; + out_data.data.i2c_args.addr = uint8_t(addr); out_data.data.i2c_args.bytes = num_bytes; //limitation of i2c transaction size diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index d9b27b6b4..641adc048 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -1306,7 +1306,7 @@ void x300_impl::register_loopback_self_test(wb_iface::sptr iface) { bool test_fail = false; UHD_MSG(status) << "Performing register loopback test... " << std::flush; - size_t hash = time(NULL); + size_t hash = size_t(time(NULL)); for (size_t i = 0; i < 100; i++) { boost::hash_combine(hash, i); @@ -1561,7 +1561,7 @@ void x300_impl::claimer_loop(wb_iface::sptr iface) { { //Critical section boost::mutex::scoped_lock(claimer_mutex); - iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_TIME), time(NULL)); + iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_TIME), uint32_t(time(NULL))); iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_SRC), get_process_hash()); } boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); //1 second diff --git a/host/lib/usrp_clock/multi_usrp_clock.cpp b/host/lib/usrp_clock/multi_usrp_clock.cpp index 77489e13b..4d3e526d6 100644 --- a/host/lib/usrp_clock/multi_usrp_clock.cpp +++ b/host/lib/usrp_clock/multi_usrp_clock.cpp @@ -84,6 +84,10 @@ private: property_tree::sptr _tree; }; +multi_usrp_clock::~multi_usrp_clock(void){ + /* NOP */ +} + /*********************************************************************** * Multi USRP Clock factory function **********************************************************************/ diff --git a/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp b/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp index 6d54cac70..49d1a0442 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp @@ -1,5 +1,5 @@ // -// Copyright 2014 Ettus Research LLC +// Copyright 2014-2015 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 @@ -19,6 +19,7 @@ #include <uhd/usrp_clock/octoclock_eeprom.hpp> #include <uhd/transport/udp_simple.hpp> #include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/types/byte_vector.hpp> #include <uhd/types/mac_addr.hpp> #include <uhd/utils/byteswap.hpp> #include <boost/assign/list_of.hpp> @@ -37,30 +38,10 @@ using namespace uhd::usrp_clock; using namespace uhd::transport; /*********************************************************************** - * Utility functions - **********************************************************************/ - -//! A wrapper around std::copy that takes ranges instead of iterators. -template<typename RangeSrc, typename RangeDst> inline -void byte_copy(const RangeSrc &src, RangeDst &dst){ - std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); -} - -//! create a string from a byte vector, return empty if invalid ascii -static const std::string bytes_to_string(const byte_vector_t &bytes){ - std::string out; - BOOST_FOREACH(boost::uint8_t byte, bytes){ - if (byte < 32 or byte > 127) return out; - out += byte; - } - return out; -} - -/*********************************************************************** * Implementation **********************************************************************/ void octoclock_eeprom_t::_load(){ - boost::uint32_t octoclock_data[udp_simple::mtu]; + boost::uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t *pkt_in = reinterpret_cast<const octoclock_packet_t*>(octoclock_data); const octoclock_fw_eeprom_t *eeprom_in = reinterpret_cast<const octoclock_fw_eeprom_t*>(pkt_in->data); @@ -109,7 +90,7 @@ void octoclock_eeprom_t::_load(){ } void octoclock_eeprom_t::_store() const { - boost::uint32_t octoclock_data[udp_simple::mtu]; + boost::uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t *pkt_in = reinterpret_cast<const octoclock_packet_t *>(octoclock_data); octoclock_packet_t pkt_out; diff --git a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp index eb3f40d9c..e879c4b70 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp @@ -111,6 +111,7 @@ namespace uhd{ void octoclock_uart_iface::_update_cache(){ octoclock_packet_t pkt_out; pkt_out.len = 0; + pkt_out.sequence = 0; size_t len = 0; boost::uint8_t octoclock_data[udp_simple::mtu]; diff --git a/host/lib/utils/thread_priority.cpp b/host/lib/utils/thread_priority.cpp index 7c3faa37a..af25d088a 100644 --- a/host/lib/utils/thread_priority.cpp +++ b/host/lib/utils/thread_priority.cpp @@ -74,7 +74,7 @@ static void check_priority_range(float priority){ #ifdef HAVE_WIN_SETTHREADPRIORITY #include <windows.h> - void uhd::set_thread_priority(float priority, bool realtime){ + void uhd::set_thread_priority(float priority, UHD_UNUSED(bool realtime)){ check_priority_range(priority); /* diff --git a/host/tests/chdr_test.cpp b/host/tests/chdr_test.cpp index ed6c690f9..f48073a09 100644 --- a/host/tests/chdr_test.cpp +++ b/host/tests/chdr_test.cpp @@ -47,7 +47,10 @@ static void pack_and_unpack( ); std::cout << std::endl; boost::uint32_t header_bits = (uhd::ntohx(packet_buff[0]) >> 28); - std::cout << boost::format("header bits = 0b%d%d%d%d") % bool(header_bits & 8) % bool(header_bits & 4) % bool(header_bits & 2) % bool(header_bits & 1) << std::endl; + std::cout << boost::format("header bits = 0b%d%d%d%d") % ((header_bits & 8) > 0) + % ((header_bits & 4) > 0) + % ((header_bits & 2) > 0) + % ((header_bits & 1) > 0) << std::endl; for (size_t i = 0; i < 5; i++) { std::cout << boost::format("packet_buff[%u] = 0x%08x") % i % uhd::ntohx(packet_buff[i]) << std::endl; diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp index e8c51b847..5ade52a9c 100644 --- a/host/tests/sph_recv_test.cpp +++ b/host/tests/sph_recv_test.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2012,2015 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 @@ -675,7 +675,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(metadata.has_time_spec); BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, (size_t)10); + BOOST_CHECK_EQUAL(num_samps_ret, 10UL); num_accum_samps += num_samps_ret; if (not metadata.more_fragments) continue; @@ -685,7 +685,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ ); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); - BOOST_CHECK_EQUAL(metadata.fragment_offset, (size_t)10); + BOOST_CHECK_EQUAL(metadata.fragment_offset, 10UL); BOOST_CHECK(metadata.has_time_spec); BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, i%10); diff --git a/host/tests/sph_send_test.cpp b/host/tests/sph_send_test.cpp index 58d47c76d..9cd195c7e 100644 --- a/host/tests/sph_send_test.cpp +++ b/host/tests/sph_send_test.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011-2012 Ettus Research LLC +// Copyright 2011-2012,2015 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 @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode){ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ std::cout << "data check " << i << std::endl; dummy_send_xport.pop_front_packet(ifpi); - BOOST_CHECK_EQUAL(ifpi.num_payload_words32, (size_t)20); + BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 20UL); BOOST_CHECK(ifpi.has_tsf); BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE); BOOST_CHECK_EQUAL(ifpi.sob, i == 0); diff --git a/host/utils/nirio_programmer.cpp b/host/utils/nirio_programmer.cpp index 43ec1ff43..c8c5e72d3 100644 --- a/host/utils/nirio_programmer.cpp +++ b/host/utils/nirio_programmer.cpp @@ -173,7 +173,7 @@ int main(int argc, char *argv[]) ss >> peek_addr; niriok_scoped_addr_space(dev_proxy, peek_tokens[0]=="c"?BUS_INTERFACE:FPGA, status); - uint32_t reg_val; + uint32_t reg_val = 0; if (peek_tokens[0]=="z") { nirio_status_chain(dev_proxy->poke((uint32_t)0x60000 + peek_addr, (uint32_t)0), status); do { @@ -190,7 +190,7 @@ int main(int argc, char *argv[]) //Display attributes if (vm.count("stats")){ printf("[Interface %u]\n", interface_num); - uint32_t attr_val; + uint32_t attr_val = 0; nirio_status_chain(dev_proxy->get_attribute(RIO_IS_FPGA_PROGRAMMED, attr_val), status); printf("* Is FPGA Programmed? = %s\n", (attr_val==1)?"YES":"NO"); @@ -208,7 +208,7 @@ int main(int argc, char *argv[]) } printf("* FPGA Bitstream Checksum = %s\n", checksum.c_str()); - uint32_t reg_val; + uint32_t reg_val = 0; nirio_status_chain(dev_proxy->set_attribute(RIO_ADDRESS_SPACE, BUS_INTERFACE), status); nirio_status_chain(dev_proxy->peek(0, reg_val), status); printf("* Chinch Signature = %x\n", reg_val); diff --git a/host/utils/octoclock_firmware_burner.cpp b/host/utils/octoclock_firmware_burner.cpp index 0a48caabd..d624095e6 100644 --- a/host/utils/octoclock_firmware_burner.cpp +++ b/host/utils/octoclock_firmware_burner.cpp @@ -123,7 +123,7 @@ device_addrs_t bootloader_find(const std::string &ip_addr){ void read_firmware(){ std::ifstream firmware_file(firmware_path.c_str(), std::ios::binary); firmware_file.seekg(0, std::ios::end); - firmware_size = firmware_file.tellg(); + firmware_size = size_t(firmware_file.tellg()); if(firmware_size > MAX_FIRMWARE_SIZE){ firmware_file.close(); throw uhd::runtime_error(str(boost::format("Firmware file too large: %d > %d") diff --git a/host/utils/uhd_images_downloader.py.in b/host/utils/uhd_images_downloader.py.in index 5b16c7bb5..3903edc8c 100644 --- a/host/utils/uhd_images_downloader.py.in +++ b/host/utils/uhd_images_downloader.py.in @@ -308,11 +308,12 @@ def main(): if options.verbose: print "Downloaded %d of %d bytes" % (downloaded_size, reported_size) else: - temp_images_dest = os.path.join(options.base_url, options.filename) - print "Copying images from: {0}".format(temp_images_dest) - if not os.path.isfile(temp_images_dest): + local_images_pkg = os.path.join(options.base_url, options.filename) + print "Copying images from: {0}".format(local_images_pkg) + if not os.path.isfile(local_images_pkg): print "[ERROR] No such file." return 1 + shutil.copyfile(local_images_pkg, temp_images_dest) (checksum_match, calculated_checksum) = downloader.validate_checksum( checksum_fn, temp_images_dest, diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index ea346b4c9..a03646cc0 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2011,2015 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 @@ -35,10 +35,6 @@ namespace po = boost::program_options; using namespace uhd; -static std::string indent(size_t level){ - return (level)? (indent(level-1) + " ") : ""; -} - static std::string make_border(const std::string &text){ std::stringstream ss; ss << boost::format(" _____________________________________________________") << std::endl; diff --git a/host/utils/usrp_n2xx_simple_net_burner.cpp b/host/utils/usrp_n2xx_simple_net_burner.cpp index b06e67bb2..642e9a407 100644 --- a/host/utils/usrp_n2xx_simple_net_burner.cpp +++ b/host/utils/usrp_n2xx_simple_net_burner.cpp @@ -262,7 +262,7 @@ int read_fpga_image(std::string& fpga_path){ //Check size of given image std::ifstream fpga_file(fpga_path.c_str(), std::ios::binary); fpga_file.seekg(0, std::ios::end); - int fpga_image_size = fpga_file.tellg(); + size_t fpga_image_size = size_t(fpga_file.tellg()); if(fpga_image_size > FPGA_IMAGE_SIZE_BYTES){ throw std::runtime_error(str(boost::format("FPGA image is too large. %d > %d") % fpga_image_size % FPGA_IMAGE_SIZE_BYTES)); @@ -297,7 +297,7 @@ int read_fw_image(std::string& fw_path){ //Check size of given image std::ifstream fw_file(fw_path.c_str(), std::ios::binary); fw_file.seekg(0, std::ios::end); - int fw_image_size = fw_file.tellg(); + size_t fw_image_size = size_t(fw_file.tellg()); if(fw_image_size > FW_IMAGE_SIZE_BYTES){ throw std::runtime_error(str(boost::format("Firmware image is too large. %d > %d") % fw_image_size % FW_IMAGE_SIZE_BYTES)); diff --git a/host/utils/usrp_x3xx_fpga_burner.cpp b/host/utils/usrp_x3xx_fpga_burner.cpp index abd5815e8..e32e4d636 100644 --- a/host/utils/usrp_x3xx_fpga_burner.cpp +++ b/host/utils/usrp_x3xx_fpga_burner.cpp @@ -487,7 +487,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ if(vm.count("addr")){ udp_simple::sptr udp_transport = udp_simple::make_connected(ip_addr, BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT)); - ethernet_burn(udp_transport, fpga_path, vm.count("verify")); + ethernet_burn(udp_transport, fpga_path, (vm.count("verify") > 0)); if(vm.count("configure")){ if(configure_fpga(udp_transport, ip_addr)) std::cout << "Successfully configured FPGA!" << std::endl; |