From 0021abf18aaf3831d8aaa40574f1876c4f346a92 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 12 Apr 2010 12:22:29 -0700 Subject: Created zero copy interface/framework, made use of it in usrp2 udp transport stuff. --- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host/lib/usrp/usrp2/usrp2_impl.hpp') diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index baa6530b8..be09c4ee1 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -136,7 +136,7 @@ private: (_mtu - _hdrs)/sizeof(boost::uint32_t) - uhd::transport::vrt::max_header_words32 ; - uhd::transport::smart_buffer::sptr _rx_smart_buff; + uhd::transport::managed_recv_buffer::sptr _rx_smart_buff; boost::asio::const_buffer _rx_copy_buff; size_t _fragment_offset_in_samps; void io_init(void); -- cgit v1.2.3 From e611e610f64b473cdd9d0aa5e40690d7550c3cc0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 12 Apr 2010 13:39:09 -0700 Subject: Added data type conversion routines to transport api. --- host/include/uhd/transport/CMakeLists.txt | 1 + host/include/uhd/transport/convert_types.hpp | 59 +++++++++++ host/include/uhd/transport/vrt.hpp | 2 +- host/lib/CMakeLists.txt | 1 + host/lib/transport/convert_types.cpp | 144 +++++++++++++++++++++++++++ host/lib/transport/udp_zero_copy_asio.cpp | 11 +- host/lib/usrp/usrp2/io_impl.cpp | 128 ++++-------------------- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 + 8 files changed, 236 insertions(+), 112 deletions(-) create mode 100644 host/include/uhd/transport/convert_types.hpp create mode 100644 host/lib/transport/convert_types.cpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.hpp') diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 9a94ead1b..4cefffa24 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -17,6 +17,7 @@ INSTALL(FILES + convert_types.hpp if_addrs.hpp udp_simple.hpp udp_zero_copy.hpp diff --git a/host/include/uhd/transport/convert_types.hpp b/host/include/uhd/transport/convert_types.hpp new file mode 100644 index 000000000..a4d999240 --- /dev/null +++ b/host/include/uhd/transport/convert_types.hpp @@ -0,0 +1,59 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP +#define INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP + +#include +#include +#include + +namespace uhd{ namespace transport{ + +/*! + * Convert IO samples to OWT samples. + * + * \param io_buff memory containing samples + * \param io_type the type of these samples + * \param otw_buff memory to write converted samples + * \param otw_type the type of these samples + * \param num_samps the number of samples in io_buff + */ +UHD_API void convert_io_type_to_otw_type( + const void *io_buff, const io_type_t &io_type, + void *otw_buff, const otw_type_t &otw_type, + size_t num_samps +); + +/*! + * Convert OTW samples to IO samples. + * + * \param otw_buff memory containing samples + * \param otw_type the type of these samples + * \param io_buff memory to write converted samples + * \param io_type the type of these samples + * \param num_samps the number of samples in io_buff + */ +UHD_API void convert_otw_type_to_io_type( + const void *otw_buff, const otw_type_t &otw_type, + void *io_buff, const io_type_t &io_type, + size_t num_samps +); + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP */ diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp index 04945b347..c30a73489 100644 --- a/host/include/uhd/transport/vrt.hpp +++ b/host/include/uhd/transport/vrt.hpp @@ -26,7 +26,7 @@ namespace uhd{ namespace transport{ namespace vrt{ - static const size_t max_header_words32 = 7; + static const size_t max_header_words32 = 5; //hdr+sid+tsi+tsf (no class id supported) /*! * Pack a vrt header from metadata. diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index a5345cae4..fac1bd19f 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -24,6 +24,7 @@ SET(libuhd_sources load_modules.cpp types.cpp wax.cpp + transport/convert_types.cpp transport/if_addrs.cpp transport/udp_simple.cpp transport/vrt.cpp diff --git a/host/lib/transport/convert_types.cpp b/host/lib/transport/convert_types.cpp new file mode 100644 index 000000000..2a6854f50 --- /dev/null +++ b/host/lib/transport/convert_types.cpp @@ -0,0 +1,144 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include //endianness conversion +#include + +using namespace uhd; + +/*********************************************************************** + * Constants + **********************************************************************/ +typedef std::complex fc32_t; + +static const float shorts_per_float = float(1 << 15); +static const float floats_per_short = float(1.0/shorts_per_float); + +#define unrolled_loop(__inst, __len){ \ + size_t __i = 0; \ + for(; __i < (__len & ~0x3); __i+= 4){ \ + __inst(__i+0); __inst(__i+1); \ + __inst(__i+2); __inst(__i+3); \ + } \ + for(; __i < __len; __i++){ \ + __inst(__i); \ + } \ +} + +// set a boolean flag that indicates the endianess +#ifdef HAVE_BIG_ENDIAN +static const bool is_big_endian = true; +#else +static const bool is_big_endian = false; +#endif + +static inline void host_floats_to_usrp2_items( + boost::uint32_t *usrp2_items, + const fc32_t *host_floats, + size_t num_samps +){ + #define host_floats_to_usrp2_items_i(i){ \ + boost::uint16_t real = boost::int16_t(host_floats[i].real()*shorts_per_float); \ + boost::uint16_t imag = boost::int16_t(host_floats[i].imag()*shorts_per_float); \ + usrp2_items[i] = htonl((real << 16) | (imag << 0)); \ + } + unrolled_loop(host_floats_to_usrp2_items_i, num_samps); +} + +static inline void usrp2_items_to_host_floats( + fc32_t *host_floats, + const boost::uint32_t *usrp2_items, + size_t num_samps +){ + #define usrp2_items_to_host_floats_i(i){ \ + boost::uint32_t item = ntohl(usrp2_items[i]); \ + boost::int16_t real = boost::uint16_t(item >> 16); \ + boost::int16_t imag = boost::uint16_t(item >> 0); \ + host_floats[i] = fc32_t(float(real*floats_per_short), float(imag*floats_per_short)); \ + } + unrolled_loop(usrp2_items_to_host_floats_i, num_samps); +} + +static inline void host_items_to_usrp2_items( + boost::uint32_t *usrp2_items, + const boost::uint32_t *host_items, + size_t num_samps +){ + #define host_items_to_usrp2_items_i(i) usrp2_items[i] = htonl(host_items[i]) + if (is_big_endian){ + std::memcpy(usrp2_items, host_items, num_samps*sizeof(boost::uint32_t)); + } + else{ + unrolled_loop(host_items_to_usrp2_items_i, num_samps); + } +} + +static inline void usrp2_items_to_host_items( + boost::uint32_t *host_items, + const boost::uint32_t *usrp2_items, + size_t num_samps +){ + #define usrp2_items_to_host_items_i(i) host_items[i] = ntohl(usrp2_items[i]) + if (is_big_endian){ + std::memcpy(host_items, usrp2_items, num_samps*sizeof(boost::uint32_t)); + } + else{ + unrolled_loop(usrp2_items_to_host_items_i, num_samps); + } +} + +void transport::convert_io_type_to_otw_type( + const void *io_buff, const io_type_t &io_type, + void *otw_buff, const otw_type_t &otw_type, + size_t num_samps +){ + //all we handle for now: + ASSERT_THROW(otw_type.width == 16 and otw_type.byteorder == otw_type_t::BO_BIG_ENDIAN); + + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: + host_floats_to_usrp2_items((boost::uint32_t *)otw_buff, (const fc32_t*)io_buff, num_samps); + break; + case io_type_t::COMPLEX_INT16: + host_items_to_usrp2_items((boost::uint32_t *)otw_buff, (const boost::uint32_t*)io_buff, num_samps); + break; + default: + throw std::runtime_error(str(boost::format("convert_types: cannot handle type \"%c\"") % io_type.tid)); + } +} + +void transport::convert_otw_type_to_io_type( + const void *otw_buff, const otw_type_t &otw_type, + void *io_buff, const io_type_t &io_type, + size_t num_samps +){ + //all we handle for now: + ASSERT_THROW(otw_type.width == 16 and otw_type.byteorder == otw_type_t::BO_BIG_ENDIAN); + + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: + usrp2_items_to_host_floats((fc32_t*)io_buff, (const boost::uint32_t *)otw_buff, num_samps); + break; + case io_type_t::COMPLEX_INT16: + usrp2_items_to_host_items((boost::uint32_t*)io_buff, (const boost::uint32_t *)otw_buff, num_samps); + break; + default: + throw std::runtime_error(str(boost::format("convert_types: cannot handle type \"%c\"") % io_type.tid)); + } +} diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 13fd50f65..3e0e80bd8 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -110,6 +110,9 @@ private: size_t get_recv_buff_size(void); void set_recv_buff_size(size_t); + + static const size_t _mtu = 1500; //FIXME we have no idea + static const size_t _hdrs = (2 + 14 + 20 + 8); //size of headers (pad, eth, ip, udp) }; udp_zero_copy_impl::udp_zero_copy_impl(const std::string &addr, const std::string &port){ @@ -143,7 +146,7 @@ udp_zero_copy_impl::~udp_zero_copy_impl(void){ } managed_recv_buffer::sptr udp_zero_copy_impl::get_recv_buff(void){ - boost::uint32_t *buff_mem = new boost::uint32_t[1500/sizeof(boost::uint32_t)]; + boost::uint32_t *buff_mem = new boost::uint32_t[_mtu/sizeof(boost::uint32_t)]; //implement timeout through polling and sleeping size_t available = 0; @@ -155,7 +158,7 @@ managed_recv_buffer::sptr udp_zero_copy_impl::get_recv_buff(void){ //receive only if data is available if (available){ - available = _socket->receive(boost::asio::buffer(buff_mem, available)); + available = _socket->receive(boost::asio::buffer(buff_mem, _mtu)); } //create a new managed buffer to house the data @@ -165,9 +168,9 @@ managed_recv_buffer::sptr udp_zero_copy_impl::get_recv_buff(void){ } managed_send_buffer::sptr udp_zero_copy_impl::get_send_buff(void){ - boost::uint32_t *buff_mem = new boost::uint32_t[1500/sizeof(boost::uint32_t)]; + boost::uint32_t *buff_mem = new boost::uint32_t[_mtu/sizeof(boost::uint32_t)]; return managed_send_buffer::sptr( - new managed_send_buffer_impl(boost::asio::buffer(buff_mem, 1500), _socket) + new managed_send_buffer_impl(boost::asio::buffer(buff_mem, _mtu-_hdrs), _socket) ); } diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a54c0a409..19a1ecf0f 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -15,28 +15,25 @@ // along with this program. If not, see . // -#include -#include #include "usrp2_impl.hpp" +#include +#include +#include using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -/*********************************************************************** - * Constants - **********************************************************************/ -typedef std::complex fc32_t; -typedef std::complex sc16_t; - -static const float shorts_per_float = float(1 << 15); -static const float floats_per_short = float(1.0/shorts_per_float); - /*********************************************************************** * Helper Functions **********************************************************************/ void usrp2_impl::io_init(void){ + //setup otw type + _otw_type.width = 16; + _otw_type.shift = 0; + _otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; + //initially empty copy buffer _rx_copy_buff = asio::buffer("", 0); @@ -51,79 +48,6 @@ void usrp2_impl::io_init(void){ send_buff->done(sizeof(data)); } -#define unrolled_loop(__inst, __len){ \ - size_t __i = 0; \ - for(; __i < (__len & ~0x3); __i+= 4){ \ - __inst(__i+0); __inst(__i+1); \ - __inst(__i+2); __inst(__i+3); \ - } \ - for(; __i < __len; __i++){ \ - __inst(__i); \ - } \ -} - -// set a boolean flag that indicates the endianess -#ifdef HAVE_BIG_ENDIAN -static const bool is_big_endian = true; -#else -static const bool is_big_endian = false; -#endif - -static inline void host_floats_to_usrp2_items( - boost::uint32_t *usrp2_items, - const fc32_t *host_floats, - size_t num_samps -){ - #define host_floats_to_usrp2_items_i(i){ \ - boost::uint16_t real = boost::int16_t(host_floats[i].real()*shorts_per_float); \ - boost::uint16_t imag = boost::int16_t(host_floats[i].imag()*shorts_per_float); \ - usrp2_items[i] = htonl((real << 16) | (imag << 0)); \ - } - unrolled_loop(host_floats_to_usrp2_items_i, num_samps); -} - -static inline void usrp2_items_to_host_floats( - fc32_t *host_floats, - const boost::uint32_t *usrp2_items, - size_t num_samps -){ - #define usrp2_items_to_host_floats_i(i){ \ - boost::uint32_t item = ntohl(usrp2_items[i]); \ - boost::int16_t real = boost::uint16_t(item >> 16); \ - boost::int16_t imag = boost::uint16_t(item >> 0); \ - host_floats[i] = fc32_t(float(real*floats_per_short), float(imag*floats_per_short)); \ - } - unrolled_loop(usrp2_items_to_host_floats_i, num_samps); -} - -static inline void host_items_to_usrp2_items( - boost::uint32_t *usrp2_items, - const boost::uint32_t *host_items, - size_t num_samps -){ - #define host_items_to_usrp2_items_i(i) usrp2_items[i] = htonl(host_items[i]) - if (is_big_endian){ - std::memcpy(usrp2_items, host_items, num_samps*sizeof(boost::uint32_t)); - } - else{ - unrolled_loop(host_items_to_usrp2_items_i, num_samps); - } -} - -static inline void usrp2_items_to_host_items( - boost::uint32_t *host_items, - const boost::uint32_t *usrp2_items, - size_t num_samps -){ - #define usrp2_items_to_host_items_i(i) host_items[i] = ntohl(usrp2_items[i]) - if (is_big_endian){ - std::memcpy(host_items, usrp2_items, num_samps*sizeof(boost::uint32_t)); - } - else{ - unrolled_loop(usrp2_items_to_host_items_i, num_samps); - } -} - /*********************************************************************** * Receive Raw Data **********************************************************************/ @@ -182,7 +106,7 @@ size_t usrp2_impl::send( boost::uint32_t *tx_mem = send_buff->cast(); size_t num_samps = std::min( asio::buffer_size(buff), - send_buff->size() + send_buff->size()-vrt::max_header_words32*sizeof(boost::uint32_t) )/io_type.size; //kill the end of burst flag if this is a fragment @@ -204,17 +128,12 @@ size_t usrp2_impl::send( boost::uint32_t *items = tx_mem + num_header_words32; //offset for data - //copy the samples into the send buffer - switch(io_type.tid){ - case io_type_t::COMPLEX_FLOAT32: - host_floats_to_usrp2_items(items, asio::buffer_cast(buff), num_samps); - break; - case io_type_t::COMPLEX_INT16: - host_items_to_usrp2_items(items, asio::buffer_cast(buff), num_samps); - break; - default: - throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%c\"") % io_type.tid)); - } + //copy-convert the samples into the send buffer + convert_io_type_to_otw_type( + asio::buffer_cast(buff), io_type, + (void*)items, _otw_type, + num_samps + ); //send and return number of samples send_buff->done(num_packet_words32*sizeof(boost::uint32_t)); @@ -254,17 +173,12 @@ size_t usrp2_impl::recv( metadata.fragment_offset = _fragment_offset_in_samps; _fragment_offset_in_samps += num_samps; //set for next time - //copy the samples from the recv buffer - switch(io_type.tid){ - case io_type_t::COMPLEX_FLOAT32: - usrp2_items_to_host_floats(asio::buffer_cast(buff), items, num_samps); - break; - case io_type_t::COMPLEX_INT16: - usrp2_items_to_host_items(asio::buffer_cast(buff), items, num_samps); - break; - default: - throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%c\"") % io_type.tid)); - } + //copy-convert the samples from the recv buffer + convert_otw_type_to_io_type( + (const void*)items, _otw_type, + asio::buffer_cast(buff), io_type, + num_samps + ); //update the rx copy buffer to reflect the bytes copied _rx_copy_buff = asio::buffer( diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index be09c4ee1..4e7154afa 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -139,6 +140,7 @@ private: uhd::transport::managed_recv_buffer::sptr _rx_smart_buff; boost::asio::const_buffer _rx_copy_buff; size_t _fragment_offset_in_samps; + uhd::otw_type_t _otw_type; void io_init(void); //udp transports for control and data -- cgit v1.2.3 From 40c231937e1ab4fb70ffb241a5ddb2455db0e907 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 12 Apr 2010 16:10:29 -0700 Subject: moved spi transact to usrp2 impl, and removed spi read --- host/include/uhd/usrp/dboard_interface.hpp | 68 ++++++++++++------------------ host/lib/usrp/dboard/db_rfx.cpp | 2 +- host/lib/usrp/usrp2/dboard_interface.cpp | 60 ++++++-------------------- host/lib/usrp/usrp2/usrp2_impl.cpp | 32 +++++++++++++- host/lib/usrp/usrp2/usrp2_impl.hpp | 9 ++++ 5 files changed, 80 insertions(+), 91 deletions(-) (limited to 'host/lib/usrp/usrp2/usrp2_impl.hpp') diff --git a/host/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp index dab5a2281..43fd1f143 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -25,6 +25,33 @@ namespace uhd{ namespace usrp{ +//spi configuration struct +struct UHD_API spi_config_t{ + /*! + * The edge type specifies when data is valid + * relative to the edge of the serial clock. + */ + enum edge_t{ + EDGE_RISE = 'r', + EDGE_FALL = 'f' + }; + + //! on what edge is the mosi data valid? + edge_t mosi_edge; + + //! on what edge is the miso data valid? + edge_t miso_edge; + + /*! + * Create a new spi config. + * \param edge the default edge for mosi and miso + */ + spi_config_t(edge_t edge = EDGE_RISE){ + mosi_edge = edge; + miso_edge = edge; + } +}; + /*! * The daughter board dboard_interface to be subclassed. * A dboard instance dboard_interfaces with the mboard though this api. @@ -42,33 +69,6 @@ public: UNIT_TYPE_TX = 't' }; - //spi configuration struct - struct UHD_API spi_config_t{ - /*! - * The edge type specifies when data is valid - * relative to the edge of the serial clock. - */ - enum edge_t{ - EDGE_RISE = 'r', - EDGE_FALL = 'f' - }; - - //! on what edge is the mosi data valid? - edge_t mosi_edge; - - //! on what edge is the miso data valid? - edge_t miso_edge; - - /*! - * Create a new spi config. - * \param edge the default edge for mosi and miso - */ - spi_config_t(edge_t edge = EDGE_RISE){ - mosi_edge = edge; - miso_edge = edge; - } - }; - //tell the host which gpio bank enum gpio_bank_t{ GPIO_BANK_RX = 'r', @@ -154,20 +154,6 @@ public: size_t num_bits ) = 0; - /*! - * \brief Read data to SPI bus peripheral. - * - * \param unit which unit, rx or tx - * \param config configuration settings - * \param num_bits the number of bits - * \return the data that was read - */ - virtual boost::uint32_t read_spi( - unit_type_t unit, - const spi_config_t &config, - size_t num_bits - ) = 0; - /*! * \brief Read and write data to SPI bus peripheral. * The data read back will be the same length as the input buffer. diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 68fa51144..4bf931660 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -138,7 +138,7 @@ void rfx_xcvr::reload_adf4360_regs(void){ BOOST_FOREACH(adf4360_regs_t::addr_t addr, addrs){ this->get_interface()->write_spi( dboard_interface::UNIT_TYPE_TX, - dboard_interface::spi_config_t::EDGE_RISE, + spi_config_t::EDGE_RISE, _adf4360_regs.get_reg(addr), 24 ); } diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index eee7c087a..d10cfa37e 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -47,32 +47,16 @@ public: const spi_config_t &config, boost::uint32_t data, size_t num_bits - ){ - transact_spi(unit, config, data, num_bits, false /*no rb*/); - } - - boost::uint32_t read_spi( - unit_type_t unit, - const spi_config_t &config, - size_t num_bits - ){ - return transact_spi(unit, config, 0, num_bits, true /*rb*/); - } + ); boost::uint32_t read_write_spi( unit_type_t unit, const spi_config_t &config, boost::uint32_t data, size_t num_bits - ){ - return transact_spi(unit, config, data, num_bits, true /*rb*/); - } - -private: - boost::uint32_t transact_spi( - unit_type_t, const spi_config_t &, boost::uint32_t, size_t, bool ); +private: usrp2_impl *_impl; boost::uint32_t _ddr_shadow; }; @@ -175,42 +159,22 @@ static boost::uint8_t unit_to_otw_dev(dboard_interface::unit_type_t unit){ throw std::invalid_argument("unknown unit type type"); } -/*! - * Static function to convert a spi edge enum - * to an over-the-wire value for the usrp2 control. - * \param edge the dboard interface spi edge enum - * \return an over the wire representation - */ -static boost::uint8_t spi_edge_to_otw(dboard_interface::spi_config_t::edge_t edge){ - switch(edge){ - case dboard_interface::spi_config_t::EDGE_RISE: return USRP2_CLK_EDGE_RISE; - case dboard_interface::spi_config_t::EDGE_FALL: return USRP2_CLK_EDGE_FALL; - } - throw std::invalid_argument("unknown spi edge type"); +void usrp2_dboard_interface::write_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits +){ + _impl->transact_spi(unit_to_otw_dev(unit), config, data, num_bits, false /*no rb*/); } -boost::uint32_t usrp2_dboard_interface::transact_spi( +boost::uint32_t usrp2_dboard_interface::read_write_spi( unit_type_t unit, const spi_config_t &config, boost::uint32_t data, - size_t num_bits, - bool readback + size_t num_bits ){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO); - out_data.data.spi_args.dev = unit_to_otw_dev(unit); - out_data.data.spi_args.miso_edge = spi_edge_to_otw(config.miso_edge); - out_data.data.spi_args.mosi_edge = spi_edge_to_otw(config.mosi_edge); - out_data.data.spi_args.readback = (readback)? 1 : 0; - out_data.data.spi_args.num_bits = num_bits; - out_data.data.spi_args.data = htonl(data); - - //send and recv - usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); - - return ntohl(out_data.data.spi_args.data); + return _impl->transact_spi(unit_to_otw_dev(unit), config, data, num_bits, true /*rb*/); } /*********************************************************************** diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index a7be2da8c..6d8c1a86c 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -15,15 +15,16 @@ // along with this program. If not, see . // +#include "usrp2_impl.hpp" #include #include #include #include +#include #include #include #include #include -#include "usrp2_impl.hpp" using namespace uhd; using namespace uhd::usrp; @@ -217,6 +218,35 @@ boost::uint16_t usrp2_impl::peek16(boost::uint32_t addr){ return impl_peek(this, addr); } +boost::uint32_t usrp2_impl::transact_spi( + int which_slave, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback +){ + static const uhd::dict spi_edge_to_otw = boost::assign::map_list_of + (spi_config_t::EDGE_RISE, USRP2_CLK_EDGE_RISE) + (spi_config_t::EDGE_FALL, USRP2_CLK_EDGE_FALL) + ; + + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO); + out_data.data.spi_args.dev = which_slave; + out_data.data.spi_args.miso_edge = spi_edge_to_otw[config.miso_edge]; + out_data.data.spi_args.mosi_edge = spi_edge_to_otw[config.mosi_edge]; + out_data.data.spi_args.readback = (readback)? 1 : 0; + out_data.data.spi_args.num_bits = num_bits; + out_data.data.spi_args.data = htonl(data); + + //send and recv + usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); + + return ntohl(out_data.data.spi_args.data); +} + /*********************************************************************** * Control Send/Recv **********************************************************************/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 4e7154afa..5a02b33dc 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -110,6 +110,15 @@ public: void poke16(boost::uint32_t addr, boost::uint16_t data); boost::uint16_t peek16(boost::uint32_t addr); + //spi read and write + boost::uint32_t transact_spi( + int which_slave, + const uhd::usrp::spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback + ); + //misc access methods double get_master_clock_freq(void); -- cgit v1.2.3 From ad0d641b38dd79cc29b4ca7a3a02c02e35eb8f71 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 13 Apr 2010 12:42:23 -0700 Subject: Moved clock control into abstraction clock control class. --- host/include/uhd/usrp/dboard_interface.hpp | 8 --- host/lib/CMakeLists.txt | 19 ++++--- host/lib/usrp/usrp2/clock_control.cpp | 84 ++++++++++++++++++++++++++++++ host/lib/usrp/usrp2/clock_control.hpp | 55 +++++++++++++++++++ host/lib/usrp/usrp2/dboard_interface.cpp | 27 ++-------- host/lib/usrp/usrp2/mboard_impl.cpp | 6 +++ host/lib/usrp/usrp2/usrp2_impl.hpp | 5 ++ 7 files changed, 167 insertions(+), 37 deletions(-) create mode 100644 host/lib/usrp/usrp2/clock_control.cpp create mode 100644 host/lib/usrp/usrp2/clock_control.hpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.hpp') diff --git a/host/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp index 2fa05c09d..c4e822751 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -183,14 +183,6 @@ public: * \param enb true for enabled */ virtual void set_clock_enabled(unit_t unit, bool enb) = 0; - - /*! - * Get the enabled status of a dboard block. - * - * \param unit which unit rx or tx - * \return true for enabled - */ - virtual bool get_clock_enabled(unit_t unit) = 0; }; }} //namespace diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 0483cd11c..b25ba38e2 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -60,12 +60,6 @@ SET(libuhd_sources usrp/simple_usrp.cpp usrp/dboard_manager.cpp usrp/tune_helper.cpp - usrp/usrp2/dboard_impl.cpp - usrp/usrp2/dboard_interface.cpp - usrp/usrp2/dsp_impl.cpp - usrp/usrp2/io_impl.cpp - usrp/usrp2/mboard_impl.cpp - usrp/usrp2/usrp2_impl.cpp ) ######################################################################## @@ -97,6 +91,19 @@ UHD_PYTHON_GEN_SOURCE_FILE( ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/ad9510_regs.hpp ) +######################################################################## +# Add usrp2 sources +######################################################################## +LIST(APPEND libuhd_sources + usrp/usrp2/clock_control.cpp + usrp/usrp2/dboard_impl.cpp + usrp/usrp2/dboard_interface.cpp + usrp/usrp2/dsp_impl.cpp + usrp/usrp2/io_impl.cpp + usrp/usrp2/mboard_impl.cpp + usrp/usrp2/usrp2_impl.cpp +) + ######################################################################## # Conditionally add the udp sources ######################################################################## diff --git a/host/lib/usrp/usrp2/clock_control.cpp b/host/lib/usrp/usrp2/clock_control.cpp new file mode 100644 index 000000000..74db5958a --- /dev/null +++ b/host/lib/usrp/usrp2/clock_control.cpp @@ -0,0 +1,84 @@ +// +// Copyright 2010 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 . +// + +#include "usrp2_impl.hpp" +#include "clock_control.hpp" +#include "ad9510_regs.hpp" +#include "usrp2_regs.hpp" //spi slave constants +#include + +using namespace uhd::usrp; + +/*! + * A usrp2 clock control specific to the ad9510 ic. + */ +class clock_control_ad9510 : public clock_control{ +public: + clock_control_ad9510(usrp2_impl *impl){ + _impl = impl; + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); + } + + ~clock_control_ad9510(void){ + /* NOP */ + } + + void enable_rx_dboard_clock(bool enb){ + _ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1; + _ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS; + _ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; + this->write_reg(0x43); + this->update_regs(); + } + + void enable_tx_dboard_clock(bool enb){ + _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; + _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; + _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; + this->write_reg(0x42); + this->update_regs(); + } + +private: + /*! + * Write a single register to the spi regs. + * \param addr the address to write + */ + void write_reg(boost::uint8_t addr){ + boost::uint32_t data = _ad9510_regs.get_write_reg(addr); + _impl->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24, false /*no rb*/); + } + + /*! + * Tells the ad9510 to latch the settings into the operational registers. + */ + void update_regs(void){ + _ad9510_regs.update_registers = 1; + this->write_reg(0x5a); + } + + usrp2_impl *_impl; + ad9510_regs_t _ad9510_regs; +}; + +/*********************************************************************** + * Public make function for the ad9510 clock control + **********************************************************************/ +clock_control::sptr clock_control::make_ad9510(usrp2_impl *impl){ + return clock_control::sptr(new clock_control_ad9510(impl)); +} diff --git a/host/lib/usrp/usrp2/clock_control.hpp b/host/lib/usrp/usrp2/clock_control.hpp new file mode 100644 index 000000000..366e09c28 --- /dev/null +++ b/host/lib/usrp/usrp2/clock_control.hpp @@ -0,0 +1,55 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_CLOCK_CONTROL_HPP +#define INCLUDED_CLOCK_CONTROL_HPP + +class usrp2_impl; //dummy class + +#include +#include + +class clock_control : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a clock config for the ad9510 ic. + * \param impl a pointer to the usrp2 implementation object + * \return a new clock control object + */ + static sptr make_ad9510(usrp2_impl *impl); + + /*! + * Enable/disable the rx dboard clock. + * \param enb true to enable + */ + virtual void enable_rx_dboard_clock(bool enb) = 0; + + /*! + * Enable/disable the tx dboard clock. + * \param enb true to enable + */ + virtual void enable_tx_dboard_clock(bool enb) = 0; + + /*! + * TODO other clock control api here.... + */ + +}; + +#endif /* INCLUDED_CLOCK_CONTROL_HPP */ diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index 8a3df08cb..c74bdaf44 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -17,7 +17,6 @@ #include "usrp2_impl.hpp" #include "usrp2_regs.hpp" -#include "ad9510_regs.hpp" #include #include #include @@ -61,8 +60,6 @@ public: private: usrp2_impl *_impl; boost::uint32_t _ddr_shadow; - ad9510_regs_t _ad9510_regs; - uhd::dict _clock_enb_shadow; }; /*********************************************************************** @@ -100,30 +97,14 @@ double usrp2_dboard_interface::get_clock_rate(unit_t){ } void usrp2_dboard_interface::set_clock_enabled(unit_t unit, bool enb){ - uint16_t data = 0; switch(unit){ case UNIT_RX: - _ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS; - _ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; - data = _ad9510_regs.get_write_reg(0x43); - break; + _impl->get_clock_control()->enable_rx_dboard_clock(enb); + return; case UNIT_TX: - _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; - _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; - data = _ad9510_regs.get_write_reg(0x42); - break; + _impl->get_clock_control()->enable_tx_dboard_clock(enb); + return; } - _impl->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24, false /*no rb*/); - - _ad9510_regs.update_registers = 1; - _impl->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, _ad9510_regs.get_write_reg(0x5a), 24, false /*no rb*/); - _clock_enb_shadow[unit] = unit; -} - -bool usrp2_dboard_interface::get_clock_enabled(unit_t unit){ - return _clock_enb_shadow[unit]; } /*********************************************************************** diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 2fa2e5211..faa34d0b3 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -33,6 +33,12 @@ void usrp2_impl::mboard_init(void){ boost::bind(&usrp2_impl::mboard_get, this, _1, _2), boost::bind(&usrp2_impl::mboard_set, this, _1, _2) ); + + _clock_control = clock_control::make_ad9510(this); +} + +clock_control::sptr usrp2_impl::get_clock_control(void){ + return _clock_control; } void usrp2_impl::init_clock_config(void){ diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 5a02b33dc..f2e823391 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -18,6 +18,7 @@ #ifndef INCLUDED_USRP2_IMPL_HPP #define INCLUDED_USRP2_IMPL_HPP +#include "clock_control.hpp" #include #include #include @@ -110,6 +111,9 @@ public: void poke16(boost::uint32_t addr, boost::uint16_t data); boost::uint16_t peek16(boost::uint32_t addr); + //clock control + clock_control::sptr get_clock_control(void); + //spi read and write boost::uint32_t transact_spi( int which_slave, @@ -130,6 +134,7 @@ private: //device properties interface void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); + clock_control::sptr _clock_control; //the raw io interface (samples are in the usrp2 native format) void recv_raw(uhd::rx_metadata_t &); -- cgit v1.2.3 From 51a9c2d42d12caa607ae33feb12a6f16ab8a3fe5 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 13 Apr 2010 17:48:48 -0700 Subject: Created a usrp2 interface class with the control, spi, peek/poke functionality. Its used in all the implementation level code --- host/lib/CMakeLists.txt | 3 +- host/lib/usrp/usrp2/clock_control.cpp | 16 +- host/lib/usrp/usrp2/clock_control.hpp | 7 +- host/lib/usrp/usrp2/dboard_iface.cpp | 278 +++++++++++++++++++++++++++++++ host/lib/usrp/usrp2/dboard_impl.cpp | 10 +- host/lib/usrp/usrp2/dboard_interface.cpp | 271 ------------------------------ host/lib/usrp/usrp2/dsp_impl.cpp | 13 +- host/lib/usrp/usrp2/io_impl.cpp | 1 + host/lib/usrp/usrp2/mboard_impl.cpp | 37 ++-- host/lib/usrp/usrp2/usrp2_iface.cpp | 168 +++++++++++++++++++ host/lib/usrp/usrp2/usrp2_iface.hpp | 103 ++++++++++++ host/lib/usrp/usrp2/usrp2_impl.cpp | 110 +----------- host/lib/usrp/usrp2/usrp2_impl.hpp | 55 ++---- 13 files changed, 614 insertions(+), 458 deletions(-) create mode 100644 host/lib/usrp/usrp2/dboard_iface.cpp delete mode 100644 host/lib/usrp/usrp2/dboard_interface.cpp create mode 100644 host/lib/usrp/usrp2/usrp2_iface.cpp create mode 100644 host/lib/usrp/usrp2/usrp2_iface.hpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.hpp') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 4f38c94c5..b9e525bad 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -103,10 +103,11 @@ UHD_PYTHON_GEN_SOURCE_FILE( LIST(APPEND libuhd_sources usrp/usrp2/clock_control.cpp usrp/usrp2/dboard_impl.cpp - usrp/usrp2/dboard_interface.cpp + usrp/usrp2/dboard_iface.cpp usrp/usrp2/dsp_impl.cpp usrp/usrp2/io_impl.cpp usrp/usrp2/mboard_impl.cpp + usrp/usrp2/usrp2_iface.cpp usrp/usrp2/usrp2_impl.cpp ) diff --git a/host/lib/usrp/usrp2/clock_control.cpp b/host/lib/usrp/usrp2/clock_control.cpp index 2d27361a8..dcd7ce9da 100644 --- a/host/lib/usrp/usrp2/clock_control.cpp +++ b/host/lib/usrp/usrp2/clock_control.cpp @@ -28,8 +28,8 @@ using namespace uhd::usrp; */ class clock_control_ad9510 : public clock_control{ public: - clock_control_ad9510(usrp2_impl *impl){ - _impl = impl; + clock_control_ad9510(usrp2_iface::sptr iface){ + _iface = iface; _ad9510_regs.cp_current_setting = ad9510_regs_t::CP_CURRENT_SETTING_3_0MA; this->write_reg(0x09); @@ -71,8 +71,8 @@ public: ~clock_control_ad9510(void){ /* private clock enables, must be set here */ - //this->enable_dac_clock(false); - //this->enable_adc_clock(false); //FIXME cant do yet + this->enable_dac_clock(false); + this->enable_adc_clock(false); } //uses output clock 7 (cmos) @@ -114,7 +114,7 @@ private: */ void write_reg(boost::uint8_t addr){ boost::uint32_t data = _ad9510_regs.get_write_reg(addr); - _impl->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24, false /*no rb*/); + _iface->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24, false /*no rb*/); } /*! @@ -144,13 +144,13 @@ private: this->update_regs(); } - usrp2_impl *_impl; + usrp2_iface::sptr _iface; ad9510_regs_t _ad9510_regs; }; /*********************************************************************** * Public make function for the ad9510 clock control **********************************************************************/ -clock_control::sptr clock_control::make_ad9510(usrp2_impl *impl){ - return clock_control::sptr(new clock_control_ad9510(impl)); +clock_control::sptr clock_control::make_ad9510(usrp2_iface::sptr iface){ + return clock_control::sptr(new clock_control_ad9510(iface)); } diff --git a/host/lib/usrp/usrp2/clock_control.hpp b/host/lib/usrp/usrp2/clock_control.hpp index 4302941f0..b64a53196 100644 --- a/host/lib/usrp/usrp2/clock_control.hpp +++ b/host/lib/usrp/usrp2/clock_control.hpp @@ -18,8 +18,7 @@ #ifndef INCLUDED_CLOCK_CONTROL_HPP #define INCLUDED_CLOCK_CONTROL_HPP -class usrp2_impl; //dummy class - +#include "usrp2_iface.hpp" #include #include @@ -29,10 +28,10 @@ public: /*! * Make a clock config for the ad9510 ic. - * \param impl a pointer to the usrp2 implementation object + * \param _iface a pointer to the usrp2 interface object * \return a new clock control object */ - static sptr make_ad9510(usrp2_impl *impl); + static sptr make_ad9510(usrp2_iface::sptr iface); /*! * Enable/disable the rx dboard clock. diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp new file mode 100644 index 000000000..d0c4bf6c1 --- /dev/null +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -0,0 +1,278 @@ +// +// Copyright 2010 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 . +// + +#include "usrp2_iface.hpp" +#include "clock_control.hpp" +#include "usrp2_regs.hpp" +#include +#include +#include +#include //htonl and ntohl +#include + +using namespace uhd::usrp; + +class usrp2_dboard_iface : public dboard_interface{ +public: + usrp2_dboard_iface(usrp2_iface::sptr iface, clock_control::sptr clk_ctrl); + ~usrp2_dboard_iface(void); + + void write_aux_dac(unit_t, int, int); + int read_aux_adc(unit_t, int); + + void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); + void set_gpio_ddr(unit_t, boost::uint16_t); + boost::uint16_t read_gpio(unit_t); + + void write_i2c(int, const byte_vector_t &); + byte_vector_t read_i2c(int, size_t); + + double get_clock_rate(unit_t); + void set_clock_enabled(unit_t, bool); + bool get_clock_enabled(unit_t); + + void write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ); + + boost::uint32_t read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ); + +private: + usrp2_iface::sptr _iface; + clock_control::sptr _clk_ctrl; + boost::uint32_t _ddr_shadow; +}; + +/*********************************************************************** + * Make Function + **********************************************************************/ +dboard_interface::sptr make_usrp2_dboard_iface( + usrp2_iface::sptr iface, + clock_control::sptr clk_ctrl +){ + return dboard_interface::sptr(new usrp2_dboard_iface(iface, clk_ctrl)); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp2_dboard_iface::usrp2_dboard_iface(usrp2_iface::sptr iface, clock_control::sptr clk_ctrl){ + _iface = iface; + _clk_ctrl = clk_ctrl; + _ddr_shadow = 0; + + //set the selection mux to use atr + boost::uint32_t new_sels = 0x0; + for(size_t i = 0; i < 16; i++){ + new_sels |= FRF_GPIO_SEL_ATR << (i*2); + } + _iface->poke32(FR_GPIO_TX_SEL, new_sels); + _iface->poke32(FR_GPIO_RX_SEL, new_sels); +} + +usrp2_dboard_iface::~usrp2_dboard_iface(void){ + /* NOP */ +} + +/*********************************************************************** + * Clocks + **********************************************************************/ +double usrp2_dboard_iface::get_clock_rate(unit_t){ + return _iface->get_master_clock_freq(); +} + +void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ + switch(unit){ + case UNIT_RX: + _clk_ctrl->enable_rx_dboard_clock(enb); + return; + case UNIT_TX: + _clk_ctrl->enable_tx_dboard_clock(enb); + return; + } +} + +/*********************************************************************** + * GPIO + **********************************************************************/ +static int unit_to_shift(dboard_interface::unit_t unit){ + switch(unit){ + case dboard_interface::UNIT_RX: return 0; + case dboard_interface::UNIT_TX: return 16; + } + throw std::runtime_error("unknown unit type"); +} + +void usrp2_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ + _ddr_shadow = \ + (_ddr_shadow & ~(0xffff << unit_to_shift(unit))) | + (boost::uint32_t(value) << unit_to_shift(unit)); + _iface->poke32(FR_GPIO_DDR, _ddr_shadow); +} + +boost::uint16_t usrp2_dboard_iface::read_gpio(unit_t unit){ + return boost::uint16_t(_iface->peek32(FR_GPIO_IO) >> unit_to_shift(unit)); +} + +void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ + //define mapping of unit to atr regs to register address + static const uhd::dict< + unit_t, uhd::dict + > unit_to_atr_to_addr = boost::assign::map_list_of + (UNIT_RX, boost::assign::map_list_of + (ATR_REG_IDLE, FR_ATR_IDLE_RXSIDE) + (ATR_REG_TX_ONLY, FR_ATR_INTX_RXSIDE) + (ATR_REG_RX_ONLY, FR_ATR_INRX_RXSIDE) + (ATR_REG_FULL_DUPLEX, FR_ATR_FULL_RXSIDE) + ) + (UNIT_TX, boost::assign::map_list_of + (ATR_REG_IDLE, FR_ATR_IDLE_TXSIDE) + (ATR_REG_TX_ONLY, FR_ATR_INTX_TXSIDE) + (ATR_REG_RX_ONLY, FR_ATR_INRX_TXSIDE) + (ATR_REG_FULL_DUPLEX, FR_ATR_FULL_TXSIDE) + ) + ; + _iface->poke16(unit_to_atr_to_addr[unit][atr], value); +} + +/*********************************************************************** + * SPI + **********************************************************************/ +/*! + * Static function to convert a unit type enum + * to an over-the-wire value for the spi device. + * \param unit the dboard interface unit type enum + * \return an over the wire representation + */ +static boost::uint8_t unit_to_otw_spi_dev(dboard_interface::unit_t unit){ + switch(unit){ + case dboard_interface::UNIT_TX: return SPI_SS_TX_DB; + case dboard_interface::UNIT_RX: return SPI_SS_RX_DB; + } + throw std::invalid_argument("unknown unit type"); +} + +void usrp2_dboard_iface::write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits +){ + _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); +} + +boost::uint32_t usrp2_dboard_iface::read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits +){ + return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); +} + +/*********************************************************************** + * I2C + **********************************************************************/ +void usrp2_dboard_iface::write_i2c(int i2c_addr, const byte_vector_t &buf){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO); + out_data.data.i2c_args.addr = i2c_addr; + out_data.data.i2c_args.bytes = buf.size(); + + //limitation of i2c transaction size + ASSERT_THROW(buf.size() <= sizeof(out_data.data.i2c_args.data)); + + //copy in the data + std::copy(buf.begin(), buf.end(), out_data.data.i2c_args.data); + + //send and recv + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); +} + +dboard_interface::byte_vector_t usrp2_dboard_iface::read_i2c(int i2c_addr, size_t num_bytes){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); + out_data.data.i2c_args.addr = i2c_addr; + out_data.data.i2c_args.bytes = num_bytes; + + //limitation of i2c transaction size + ASSERT_THROW(num_bytes <= sizeof(out_data.data.i2c_args.data)); + + //send and recv + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); + ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes); + + //copy out the data + byte_vector_t result(num_bytes); + std::copy(in_data.data.i2c_args.data, in_data.data.i2c_args.data + num_bytes, result.begin()); + return result; +} + +/*********************************************************************** + * Aux DAX/ADC + **********************************************************************/ +/*! + * Static function to convert a unit type enum + * to an over-the-wire value for the usrp2 control. + * \param unit the dboard interface unit type enum + * \return an over the wire representation + */ +static boost::uint8_t unit_to_otw(dboard_interface::unit_t unit){ + switch(unit){ + case dboard_interface::UNIT_TX: return USRP2_DIR_TX; + case dboard_interface::UNIT_RX: return USRP2_DIR_RX; + } + throw std::invalid_argument("unknown unit type"); +} + +void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, int value){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_WRITE_THIS_TO_THE_AUX_DAC_BRO); + out_data.data.aux_args.dir = unit_to_otw(unit); + out_data.data.aux_args.which = which; + out_data.data.aux_args.value = htonl(value); + + //send and recv + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_DAC_DUDE); +} + +int usrp2_dboard_iface::read_aux_adc(unit_t unit, int which){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_READ_FROM_THIS_AUX_ADC_BRO); + out_data.data.aux_args.dir = unit_to_otw(unit); + out_data.data.aux_args.which = which; + + //send and recv + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_ADC_DUDE); + return ntohl(in_data.data.aux_args.value); +} diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 3ac805421..4b300de68 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include //htonl and ntohl #include using namespace uhd; @@ -34,7 +36,7 @@ void usrp2_impl::dboard_init(void){ //grab the dboard ids over the control line usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_GIVE_ME_YOUR_DBOARD_IDS_BRO); - usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THESE_ARE_MY_DBOARD_IDS_DUDE); //extract the dboard ids an convert them @@ -43,7 +45,7 @@ void usrp2_impl::dboard_init(void){ //create a new dboard interface and manager dboard_interface::sptr _dboard_interface( - make_usrp2_dboard_interface(this) + make_usrp2_dboard_iface(_iface, _clk_ctrl) ); _dboard_manager = dboard_manager::make( rx_dboard_id, tx_dboard_id, _dboard_interface @@ -82,7 +84,7 @@ void usrp2_impl::update_rx_mux_config(void){ rx_mux = (((rx_mux >> 0) & 0x3) << 2) | (((rx_mux >> 2) & 0x3) << 0); } - this->poke32(FR_DSP_RX_MUX, rx_mux); + _iface->poke32(FR_DSP_RX_MUX, rx_mux); } void usrp2_impl::update_tx_mux_config(void){ @@ -95,7 +97,7 @@ void usrp2_impl::update_tx_mux_config(void){ tx_mux = (((tx_mux >> 0) & 0x1) << 1) | (((tx_mux >> 1) & 0x1) << 0); } - this->poke32(FR_DSP_TX_MUX, tx_mux); + _iface->poke32(FR_DSP_TX_MUX, tx_mux); } /*********************************************************************** diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp deleted file mode 100644 index c74bdaf44..000000000 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ /dev/null @@ -1,271 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp2_impl.hpp" -#include "usrp2_regs.hpp" -#include -#include -#include -#include - -using namespace uhd::usrp; - -class usrp2_dboard_interface : public dboard_interface{ -public: - usrp2_dboard_interface(usrp2_impl *impl); - ~usrp2_dboard_interface(void); - - void write_aux_dac(unit_t, int, int); - int read_aux_adc(unit_t, int); - - void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); - void set_gpio_ddr(unit_t, boost::uint16_t); - boost::uint16_t read_gpio(unit_t); - - void write_i2c(int, const byte_vector_t &); - byte_vector_t read_i2c(int, size_t); - - double get_clock_rate(unit_t); - void set_clock_enabled(unit_t, bool); - bool get_clock_enabled(unit_t); - - void write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits - ); - - boost::uint32_t read_write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits - ); - -private: - usrp2_impl *_impl; - boost::uint32_t _ddr_shadow; -}; - -/*********************************************************************** - * Make Function - **********************************************************************/ -dboard_interface::sptr make_usrp2_dboard_interface(usrp2_impl *impl){ - return dboard_interface::sptr(new usrp2_dboard_interface(impl)); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp2_dboard_interface::usrp2_dboard_interface(usrp2_impl *impl){ - _impl = impl; - _ddr_shadow = 0; - - //set the selection mux to use atr - boost::uint32_t new_sels = 0x0; - for(size_t i = 0; i < 16; i++){ - new_sels |= FRF_GPIO_SEL_ATR << (i*2); - } - _impl->poke32(FR_GPIO_TX_SEL, new_sels); - _impl->poke32(FR_GPIO_RX_SEL, new_sels); -} - -usrp2_dboard_interface::~usrp2_dboard_interface(void){ - /* NOP */ -} - -/*********************************************************************** - * Clocks - **********************************************************************/ -double usrp2_dboard_interface::get_clock_rate(unit_t){ - return _impl->get_master_clock_freq(); -} - -void usrp2_dboard_interface::set_clock_enabled(unit_t unit, bool enb){ - switch(unit){ - case UNIT_RX: - _impl->get_clock_control()->enable_rx_dboard_clock(enb); - return; - case UNIT_TX: - _impl->get_clock_control()->enable_tx_dboard_clock(enb); - return; - } -} - -/*********************************************************************** - * GPIO - **********************************************************************/ -static int unit_to_shift(dboard_interface::unit_t unit){ - switch(unit){ - case dboard_interface::UNIT_RX: return 0; - case dboard_interface::UNIT_TX: return 16; - } - throw std::runtime_error("unknown unit type"); -} - -void usrp2_dboard_interface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ - _ddr_shadow = \ - (_ddr_shadow & ~(0xffff << unit_to_shift(unit))) | - (boost::uint32_t(value) << unit_to_shift(unit)); - _impl->poke32(FR_GPIO_DDR, _ddr_shadow); -} - -boost::uint16_t usrp2_dboard_interface::read_gpio(unit_t unit){ - return boost::uint16_t(_impl->peek32(FR_GPIO_IO) >> unit_to_shift(unit)); -} - -void usrp2_dboard_interface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ - //define mapping of unit to atr regs to register address - static const uhd::dict< - unit_t, uhd::dict - > unit_to_atr_to_addr = boost::assign::map_list_of - (UNIT_RX, boost::assign::map_list_of - (ATR_REG_IDLE, FR_ATR_IDLE_RXSIDE) - (ATR_REG_TX_ONLY, FR_ATR_INTX_RXSIDE) - (ATR_REG_RX_ONLY, FR_ATR_INRX_RXSIDE) - (ATR_REG_FULL_DUPLEX, FR_ATR_FULL_RXSIDE) - ) - (UNIT_TX, boost::assign::map_list_of - (ATR_REG_IDLE, FR_ATR_IDLE_TXSIDE) - (ATR_REG_TX_ONLY, FR_ATR_INTX_TXSIDE) - (ATR_REG_RX_ONLY, FR_ATR_INRX_TXSIDE) - (ATR_REG_FULL_DUPLEX, FR_ATR_FULL_TXSIDE) - ) - ; - _impl->poke16(unit_to_atr_to_addr[unit][atr], value); -} - -/*********************************************************************** - * SPI - **********************************************************************/ -/*! - * Static function to convert a unit type enum - * to an over-the-wire value for the spi device. - * \param unit the dboard interface unit type enum - * \return an over the wire representation - */ -static boost::uint8_t unit_to_otw_spi_dev(dboard_interface::unit_t unit){ - switch(unit){ - case dboard_interface::UNIT_TX: return SPI_SS_TX_DB; - case dboard_interface::UNIT_RX: return SPI_SS_RX_DB; - } - throw std::invalid_argument("unknown unit type"); -} - -void usrp2_dboard_interface::write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits -){ - _impl->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); -} - -boost::uint32_t usrp2_dboard_interface::read_write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits -){ - return _impl->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); -} - -/*********************************************************************** - * I2C - **********************************************************************/ -void usrp2_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO); - out_data.data.i2c_args.addr = i2c_addr; - out_data.data.i2c_args.bytes = buf.size(); - - //limitation of i2c transaction size - ASSERT_THROW(buf.size() <= sizeof(out_data.data.i2c_args.data)); - - //copy in the data - std::copy(buf.begin(), buf.end(), out_data.data.i2c_args.data); - - //send and recv - usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); -} - -dboard_interface::byte_vector_t usrp2_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); - out_data.data.i2c_args.addr = i2c_addr; - out_data.data.i2c_args.bytes = num_bytes; - - //limitation of i2c transaction size - ASSERT_THROW(num_bytes <= sizeof(out_data.data.i2c_args.data)); - - //send and recv - usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); - ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes); - - //copy out the data - byte_vector_t result(num_bytes); - std::copy(in_data.data.i2c_args.data, in_data.data.i2c_args.data + num_bytes, result.begin()); - return result; -} - -/*********************************************************************** - * Aux DAX/ADC - **********************************************************************/ -/*! - * Static function to convert a unit type enum - * to an over-the-wire value for the usrp2 control. - * \param unit the dboard interface unit type enum - * \return an over the wire representation - */ -static boost::uint8_t unit_to_otw(dboard_interface::unit_t unit){ - switch(unit){ - case dboard_interface::UNIT_TX: return USRP2_DIR_TX; - case dboard_interface::UNIT_RX: return USRP2_DIR_RX; - } - throw std::invalid_argument("unknown unit type"); -} - -void usrp2_dboard_interface::write_aux_dac(unit_t unit, int which, int value){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_WRITE_THIS_TO_THE_AUX_DAC_BRO); - out_data.data.aux_args.dir = unit_to_otw(unit); - out_data.data.aux_args.which = which; - out_data.data.aux_args.value = htonl(value); - - //send and recv - usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_DAC_DUDE); -} - -int usrp2_dboard_interface::read_aux_adc(unit_t unit, int which){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_READ_FROM_THIS_AUX_ADC_BRO); - out_data.data.aux_args.dir = unit_to_otw(unit); - out_data.data.aux_args.which = which; - - //send and recv - usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_ADC_DUDE); - return ntohl(in_data.data.aux_args.value); -} diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 92b55d029..664d69948 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -82,11 +83,11 @@ void usrp2_impl::init_ddc_config(void){ void usrp2_impl::update_ddc_config(void){ //set the decimation - this->poke32(FR_DSP_RX_DECIM_RATE, _ddc_decim); + _iface->poke32(FR_DSP_RX_DECIM_RATE, _ddc_decim); //set the scaling static const boost::int16_t default_rx_scale_iq = 1024; - this->poke32(FR_DSP_RX_SCALE_IQ, + _iface->poke32(FR_DSP_RX_SCALE_IQ, calculate_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) ); } @@ -126,7 +127,7 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){ ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _ddc_freq = new_freq; //shadow - this->poke32(FR_DSP_RX_FREQ, + _iface->poke32(FR_DSP_RX_FREQ, calculate_freq_word_and_update_actual_freq(_ddc_freq, get_master_clock_freq()) ); } @@ -170,10 +171,10 @@ void usrp2_impl::update_duc_config(void){ boost::int16_t scale = rint((4096*std::pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed)); //set the interpolation - this->poke32(FR_DSP_TX_INTERP_RATE, _ddc_decim); + _iface->poke32(FR_DSP_TX_INTERP_RATE, _ddc_decim); //set the scaling - this->poke32(FR_DSP_TX_SCALE_IQ, calculate_iq_scale_word(scale, scale)); + _iface->poke32(FR_DSP_TX_SCALE_IQ, calculate_iq_scale_word(scale, scale)); } /*********************************************************************** @@ -211,7 +212,7 @@ void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){ ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _duc_freq = new_freq; //shadow - this->poke32(FR_DSP_TX_FREQ, + _iface->poke32(FR_DSP_TX_FREQ, calculate_freq_word_and_update_actual_freq(_duc_freq, get_master_clock_freq()) ); } diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 87fc88ceb..367a1d9fb 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -18,6 +18,7 @@ #include "usrp2_impl.hpp" #include #include +#include //htonl and ntohl #include using namespace uhd; diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index ea268651a..1521de1fe 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -22,6 +22,9 @@ #include #include #include +#include +#include //htonl and ntohl +#include using namespace uhd; using namespace uhd::usrp; @@ -35,7 +38,7 @@ void usrp2_impl::mboard_init(void){ boost::bind(&usrp2_impl::mboard_set, this, _1, _2) ); - _clock_control = clock_control::make_ad9510(this); + _clk_ctrl = clock_control::make_ad9510(_iface); //setup the ad9777 dac ad9777_regs_t ad9777_regs; @@ -58,14 +61,10 @@ void usrp2_impl::mboard_init(void){ //write all regs for(boost::uint8_t addr = 0; addr <= 0xC; addr++){ boost::uint16_t data = ad9777_regs.get_write_reg(addr); - this->transact_spi(SPI_SS_AD9777, spi_config_t::EDGE_RISE, data, 16, false /*no rb*/); + _iface->transact_spi(SPI_SS_AD9777, spi_config_t::EDGE_RISE, data, 16, false /*no rb*/); } } -clock_control::sptr usrp2_impl::get_clock_control(void){ - return _clock_control; -} - void usrp2_impl::init_clock_config(void){ //setup the clock configuration settings _clock_config.ref_source = clock_config_t::REF_INT; @@ -94,28 +93,28 @@ void usrp2_impl::update_clock_config(void){ } //set the pps flags - this->poke32(FR_TIME64_FLAGS, pps_flags); + _iface->poke32(FR_TIME64_FLAGS, pps_flags); //clock source ref 10mhz switch(_clock_config.ref_source){ - case clock_config_t::REF_INT : this->poke32(FR_CLOCK_CONTROL, 0x10); break; - case clock_config_t::REF_SMA : this->poke32(FR_CLOCK_CONTROL, 0x1C); break; - case clock_config_t::REF_MIMO: this->poke32(FR_CLOCK_CONTROL, 0x15); break; + case clock_config_t::REF_INT : _iface->poke32(FR_CLOCK_CONTROL, 0x10); break; + case clock_config_t::REF_SMA : _iface->poke32(FR_CLOCK_CONTROL, 0x1C); break; + case clock_config_t::REF_MIMO: _iface->poke32(FR_CLOCK_CONTROL, 0x15); break; } //clock source ref 10mhz bool use_external = _clock_config.ref_source != clock_config_t::REF_INT; - this->get_clock_control()->enable_external_ref(use_external); + _clk_ctrl->enable_external_ref(use_external); } void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){ //set ticks and seconds - this->poke32(FR_TIME64_SECS, time_spec.secs); - this->poke32(FR_TIME64_TICKS, time_spec.get_ticks(get_master_clock_freq())); + _iface->poke32(FR_TIME64_SECS, time_spec.secs); + _iface->poke32(FR_TIME64_TICKS, time_spec.get_ticks(get_master_clock_freq())); //set the register to latch it all in boost::uint32_t imm_flags = (now)? FRF_TIME64_LATCH_NOW : FRF_TIME64_LATCH_NEXT_PPS; - this->poke32(FR_TIME64_IMM, imm_flags); + _iface->poke32(FR_TIME64_IMM, imm_flags); } void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ @@ -151,7 +150,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ } //send and recv - usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE); } @@ -170,7 +169,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ out_data.id = htonl(USRP2_CTRL_ID_GIVE_ME_YOUR_MAC_ADDR_BRO); //send and recv - usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE); //extract the address @@ -184,7 +183,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ out_data.id = htonl(USRP2_CTRL_ID_GIVE_ME_YOUR_IP_ADDR_BRO); //send and recv - usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THIS_IS_MY_IP_ADDR_DUDE); //extract the address @@ -272,7 +271,7 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ std::copy(mac_addr.to_bytes(), mac_addr.to_bytes()+mac_addr_t::hlen, out_data.data.mac_addr); //send and recv - usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE); return; } @@ -284,7 +283,7 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ out_data.data.ip_addr = htonl(boost::asio::ip::address_v4::from_string(val.as()).to_ulong()); //send and recv - usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THIS_IS_MY_IP_ADDR_DUDE); return; } diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp new file mode 100644 index 000000000..5c84fd8d3 --- /dev/null +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -0,0 +1,168 @@ +// +// Copyright 2010 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 . +// + +#include "usrp2_iface.hpp" +#include +#include +#include +#include //used for htonl and ntohl +#include +#include + +using namespace uhd; +using namespace uhd::usrp; + +class usrp2_iface_impl : public usrp2_iface{ +public: +/*********************************************************************** + * Structors + **********************************************************************/ + usrp2_iface_impl(transport::udp_simple::sptr ctrl_transport){ + _ctrl_transport = ctrl_transport; + } + + ~usrp2_iface_impl(void){ + /* NOP */ + } + +/*********************************************************************** + * Peek and Poke + **********************************************************************/ + void poke32(boost::uint32_t addr, boost::uint32_t data){ + return this->poke(addr, data); + } + + boost::uint32_t peek32(boost::uint32_t addr){ + return this->peek(addr); + } + + void poke16(boost::uint32_t addr, boost::uint16_t data){ + return this->poke(addr, data); + } + + boost::uint16_t peek16(boost::uint32_t addr){ + return this->peek(addr); + } + +/*********************************************************************** + * SPI + **********************************************************************/ + boost::uint32_t transact_spi( + int which_slave, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback + ){ + static const uhd::dict spi_edge_to_otw = boost::assign::map_list_of + (spi_config_t::EDGE_RISE, USRP2_CLK_EDGE_RISE) + (spi_config_t::EDGE_FALL, USRP2_CLK_EDGE_FALL) + ; + + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO); + out_data.data.spi_args.dev = which_slave; + out_data.data.spi_args.miso_edge = spi_edge_to_otw[config.miso_edge]; + out_data.data.spi_args.mosi_edge = spi_edge_to_otw[config.mosi_edge]; + out_data.data.spi_args.readback = (readback)? 1 : 0; + out_data.data.spi_args.num_bits = num_bits; + out_data.data.spi_args.data = htonl(data); + + //send and recv + usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); + + return ntohl(out_data.data.spi_args.data); + } + +/*********************************************************************** + * Send/Recv over control + **********************************************************************/ + usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &out_data){ + boost::mutex::scoped_lock lock(_ctrl_mutex); + + //fill in the seq number and send + usrp2_ctrl_data_t out_copy = out_data; + out_copy.seq = htonl(++_ctrl_seq_num); + _ctrl_transport->send(boost::asio::buffer(&out_copy, sizeof(usrp2_ctrl_data_t))); + + //loop until we get the packet or timeout + while(true){ + usrp2_ctrl_data_t in_data; + size_t len = _ctrl_transport->recv(boost::asio::buffer(&in_data, sizeof(in_data))); + if (len >= sizeof(usrp2_ctrl_data_t) and ntohl(in_data.seq) == _ctrl_seq_num){ + return in_data; + } + if (len == 0) break; //timeout + //didnt get seq or bad packet, continue looking... + } + throw std::runtime_error("usrp2 no control response"); + } + +/*********************************************************************** + * Master Clock! Ahhhhh + **********************************************************************/ + double get_master_clock_freq(void){ + return 100e6; + } + +private: + //this lovely lady makes it all possible + transport::udp_simple::sptr _ctrl_transport; + + //used in send/recv + boost::mutex _ctrl_mutex; + boost::uint32_t _ctrl_seq_num; + +/*********************************************************************** + * Private Templated Peek and Poke + **********************************************************************/ + template void poke(boost::uint32_t addr, T data){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_POKE_THIS_REGISTER_FOR_ME_BRO); + out_data.data.poke_args.addr = htonl(addr); + out_data.data.poke_args.data = htonl(boost::uint32_t(data)); + out_data.data.poke_args.num_bytes = sizeof(T); + + //send and recv + usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_POKED_REGISTER_SO_BAD_DUDE); + } + + template T peek(boost::uint32_t addr){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_PEEK_AT_THIS_REGISTER_FOR_ME_BRO); + out_data.data.poke_args.addr = htonl(addr); + out_data.data.poke_args.num_bytes = sizeof(T); + + //send and recv + usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE); + return T(ntohl(out_data.data.poke_args.data)); + } + +}; + +/*********************************************************************** + * Public make function for usrp2 interface + **********************************************************************/ +usrp2_iface::sptr usrp2_iface::make(transport::udp_simple::sptr ctrl_transport){ + return usrp2_iface::sptr(new usrp2_iface_impl(ctrl_transport)); +} diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp new file mode 100644 index 000000000..7b4321c0b --- /dev/null +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -0,0 +1,103 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP2_IFACE_HPP +#define INCLUDED_USRP2_IFACE_HPP + +#include +#include //spi config +#include +#include +#include +#include "fw_common.h" + +/*! + * The usrp2 interface class: + * Provides a set of functions to implementation layer. + * Including spi, peek, poke, control... + */ +class usrp2_iface : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new usrp2 interface with the control transport. + * \param ctrl_transport the udp transport object + * \return a new usrp2 interface object + */ + static sptr make(uhd::transport::udp_simple::sptr ctrl_transport); + + /*! + * Perform a control transaction. + * \param data a control data struct + * \return the result control data + */ + virtual usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &data) = 0; + + /*! + * Write a register (32 bits) + * \param addr the address + * \param data the 32bit data + */ + virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; + + /*! + * Read a register (32 bits) + * \param addr the address + * \return the 32bit data + */ + virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; + + /*! + * Write a register (16 bits) + * \param addr the address + * \param data the 16bit data + */ + virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; + + /*! + * Read a register (16 bits) + * \param addr the address + * \return the 16bit data + */ + virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; + + /*! + * Perform an spi transaction. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write + * \param num_bits how many bits in data + * \param readback true to readback a value + * \return spi data if readback set + */ + virtual boost::uint32_t transact_spi( + int which_slave, + const uhd::usrp::spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback + ) = 0; + + /*! + * Get the master clock frequency. + * \return the frequency in Hz + */ + virtual double get_master_clock_freq(void) = 0; +}; + +#endif /* INCLUDED_USRP2_IFACE_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 6d8c1a86c..3bdc5bd02 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -17,6 +17,7 @@ #include "usrp2_impl.hpp" #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include //htonl and ntohl #include using namespace uhd; @@ -61,7 +63,6 @@ uhd::device_addrs_t usrp2::find(const device_addr_t &hint){ } //create a udp transport to communicate - //TODO if an addr is not provided, search all interfaces? std::string ctrl_port = boost::lexical_cast(USRP2_UDP_CTRL_PORT); udp_simple::sptr udp_transport = udp_simple::make_broadcast( hint["addr"], ctrl_port @@ -128,9 +129,11 @@ usrp2_impl::usrp2_impl( udp_simple::sptr ctrl_transport, udp_zero_copy::sptr data_transport ){ - _ctrl_transport = ctrl_transport; _data_transport = data_transport; + //make a new interface for usrp2 stuff + _iface = usrp2_iface::make(ctrl_transport); + //load the allowed decim/interp rates //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4) _allowed_decim_and_interp_rates.clear(); @@ -168,109 +171,6 @@ usrp2_impl::~usrp2_impl(void){ /* NOP */ } -/*********************************************************************** - * Misc Access Methods - **********************************************************************/ -double usrp2_impl::get_master_clock_freq(void){ - return 100e6; -} - -template void impl_poke(usrp2_impl *impl, boost::uint32_t addr, T data){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_POKE_THIS_REGISTER_FOR_ME_BRO); - out_data.data.poke_args.addr = htonl(addr); - out_data.data.poke_args.data = htonl(boost::uint32_t(data)); - out_data.data.poke_args.num_bytes = sizeof(T); - - //send and recv - usrp2_ctrl_data_t in_data = impl->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_POKED_REGISTER_SO_BAD_DUDE); -} - -template T impl_peek(usrp2_impl *impl, boost::uint32_t addr){ - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_PEEK_AT_THIS_REGISTER_FOR_ME_BRO); - out_data.data.poke_args.addr = htonl(addr); - out_data.data.poke_args.num_bytes = sizeof(T); - - //send and recv - usrp2_ctrl_data_t in_data = impl->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE); - return T(ntohl(out_data.data.poke_args.data)); -} - - -void usrp2_impl::poke32(boost::uint32_t addr, boost::uint32_t data){ - return impl_poke(this, addr, data); -} - -boost::uint32_t usrp2_impl::peek32(boost::uint32_t addr){ - return impl_peek(this, addr); -} - -void usrp2_impl::poke16(boost::uint32_t addr, boost::uint16_t data){ - return impl_poke(this, addr, data); -} - -boost::uint16_t usrp2_impl::peek16(boost::uint32_t addr){ - return impl_peek(this, addr); -} - -boost::uint32_t usrp2_impl::transact_spi( - int which_slave, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits, - bool readback -){ - static const uhd::dict spi_edge_to_otw = boost::assign::map_list_of - (spi_config_t::EDGE_RISE, USRP2_CLK_EDGE_RISE) - (spi_config_t::EDGE_FALL, USRP2_CLK_EDGE_FALL) - ; - - //setup the out data - usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO); - out_data.data.spi_args.dev = which_slave; - out_data.data.spi_args.miso_edge = spi_edge_to_otw[config.miso_edge]; - out_data.data.spi_args.mosi_edge = spi_edge_to_otw[config.mosi_edge]; - out_data.data.spi_args.readback = (readback)? 1 : 0; - out_data.data.spi_args.num_bits = num_bits; - out_data.data.spi_args.data = htonl(data); - - //send and recv - usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); - - return ntohl(out_data.data.spi_args.data); -} - -/*********************************************************************** - * Control Send/Recv - **********************************************************************/ -usrp2_ctrl_data_t usrp2_impl::ctrl_send_and_recv(const usrp2_ctrl_data_t &out_data){ - boost::mutex::scoped_lock lock(_ctrl_mutex); - - //fill in the seq number and send - usrp2_ctrl_data_t out_copy = out_data; - out_copy.seq = htonl(++_ctrl_seq_num); - _ctrl_transport->send(boost::asio::buffer(&out_copy, sizeof(usrp2_ctrl_data_t))); - - //loop until we get the packet or timeout - while(true){ - usrp2_ctrl_data_t in_data; - size_t len = _ctrl_transport->recv(asio::buffer(&in_data, sizeof(in_data))); - if (len >= sizeof(usrp2_ctrl_data_t) and ntohl(in_data.seq) == _ctrl_seq_num){ - return in_data; - } - if (len == 0) break; //timeout - //didnt get seq or bad packet, continue looking... - } - throw std::runtime_error("usrp2 no control response"); -} - /*********************************************************************** * Device Properties **********************************************************************/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index f2e823391..7eea1e250 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -18,31 +18,29 @@ #ifndef INCLUDED_USRP2_IMPL_HPP #define INCLUDED_USRP2_IMPL_HPP +#include "usrp2_iface.hpp" #include "clock_control.hpp" #include #include #include #include #include -#include -#include #include #include -#include #include -#include #include #include -#include "fw_common.h" - -class usrp2_impl; //dummy class declaration /*! * Make a usrp2 dboard interface. - * \param impl a pointer to the usrp2 impl object + * \param iface the usrp2 interface object + * \param clk_ctrl the clock control object * \return a sptr to a new dboard interface */ -uhd::usrp::dboard_interface::sptr make_usrp2_dboard_interface(usrp2_impl *impl); +uhd::usrp::dboard_interface::sptr make_usrp2_dboard_iface( + usrp2_iface::sptr iface, + clock_control::sptr clk_ctrl +); /*! * Simple wax obj proxy class: @@ -101,40 +99,22 @@ public: ~usrp2_impl(void); - //performs a control transaction - usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &); - - //peek and poke registers - void poke32(boost::uint32_t addr, boost::uint32_t data); - boost::uint32_t peek32(boost::uint32_t addr); - - void poke16(boost::uint32_t addr, boost::uint16_t data); - boost::uint16_t peek16(boost::uint32_t addr); - - //clock control - clock_control::sptr get_clock_control(void); - - //spi read and write - boost::uint32_t transact_spi( - int which_slave, - const uhd::usrp::spi_config_t &config, - boost::uint32_t data, - size_t num_bits, - bool readback - ); - - //misc access methods - double get_master_clock_freq(void); - //the io interface size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); private: + double get_master_clock_freq(void){ + return _iface->get_master_clock_freq(); + } + //device properties interface void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); - clock_control::sptr _clock_control; + + //interfaces + clock_control::sptr _clk_ctrl; + usrp2_iface::sptr _iface; //the raw io interface (samples are in the usrp2 native format) void recv_raw(uhd::rx_metadata_t &); @@ -158,13 +138,8 @@ private: void io_init(void); //udp transports for control and data - uhd::transport::udp_simple::sptr _ctrl_transport; uhd::transport::udp_zero_copy::sptr _data_transport; - //private vars for dealing with send/recv control - boost::uint32_t _ctrl_seq_num; - boost::mutex _ctrl_mutex; - //methods and shadows for clock configuration uhd::clock_config_t _clock_config; void init_clock_config(void); -- cgit v1.2.3 From e2a9419385bee4d08862553ddd0a637964557272 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 14 Apr 2010 08:41:13 -0700 Subject: renamed dboard interface to dboard iface, the lengthy name was getting to be a burden --- host/include/uhd/usrp/dboard_base.hpp | 10 +- host/include/uhd/usrp/dboard_iface.hpp | 190 +++++++++++++++++++++++++++++ host/include/uhd/usrp/dboard_interface.hpp | 190 ----------------------------- host/include/uhd/usrp/dboard_manager.hpp | 6 +- host/lib/usrp/dboard/db_rfx.cpp | 28 ++--- host/lib/usrp/dboard_base.cpp | 6 +- host/lib/usrp/dboard_manager.cpp | 34 +++--- host/lib/usrp/usrp2/dboard_iface.cpp | 26 ++-- host/lib/usrp/usrp2/dboard_impl.cpp | 4 +- host/lib/usrp/usrp2/usrp2_iface.hpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 +- 11 files changed, 249 insertions(+), 249 deletions(-) create mode 100644 host/include/uhd/usrp/dboard_iface.hpp delete mode 100644 host/include/uhd/usrp/dboard_interface.hpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.hpp') diff --git a/host/include/uhd/usrp/dboard_base.hpp b/host/include/uhd/usrp/dboard_base.hpp index 907a7814a..2025760ee 100644 --- a/host/include/uhd/usrp/dboard_base.hpp +++ b/host/include/uhd/usrp/dboard_base.hpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace uhd{ namespace usrp{ @@ -35,10 +35,10 @@ namespace uhd{ namespace usrp{ class UHD_API dboard_base : boost::noncopyable{ public: typedef boost::shared_ptr sptr; - //the constructor args consist of a subdev name and an interface + //the constructor args consist of a subdev name, interface, and ids //derived classes should pass the args into the dboard_base class ctor //but should not have to deal with the internals of the args - typedef boost::tuple ctor_args_t; + typedef boost::tuple ctor_args_t; //structors dboard_base(ctor_args_t const&); @@ -52,13 +52,13 @@ public: protected: std::string get_subdev_name(void); - dboard_interface::sptr get_interface(void); + dboard_iface::sptr get_iface(void); dboard_id_t get_rx_id(void); dboard_id_t get_tx_id(void); private: std::string _subdev_name; - dboard_interface::sptr _dboard_interface; + dboard_iface::sptr _dboard_iface; dboard_id_t _rx_id, _tx_id; }; diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp new file mode 100644 index 000000000..ca40bf778 --- /dev/null +++ b/host/include/uhd/usrp/dboard_iface.hpp @@ -0,0 +1,190 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_IFACE_HPP +#define INCLUDED_UHD_USRP_DBOARD_IFACE_HPP + +#include +#include +#include +#include + +namespace uhd{ namespace usrp{ + +//spi configuration struct +struct UHD_API spi_config_t{ + /*! + * The edge type specifies when data is valid + * relative to the edge of the serial clock. + */ + enum edge_t{ + EDGE_RISE = 'r', + EDGE_FALL = 'f' + }; + + //! on what edge is the mosi data valid? + edge_t mosi_edge; + + //! on what edge is the miso data valid? + edge_t miso_edge; + + /*! + * Create a new spi config. + * \param edge the default edge for mosi and miso + */ + spi_config_t(edge_t edge = EDGE_RISE){ + mosi_edge = edge; + miso_edge = edge; + } +}; + +/*! + * The daughter board dboard interface to be subclassed. + * A dboard instance interfaces with the mboard though this api. + * This interface provides i2c, spi, gpio, atr, aux dac/adc access. + * Each mboard should have a specially tailored iface for its dboard. + */ +class UHD_API dboard_iface{ +public: + typedef boost::shared_ptr sptr; + typedef std::vector byte_vector_t; + + //tells the host which unit to use + enum unit_t{ + UNIT_RX = 'r', + UNIT_TX = 't' + }; + + //possible atr registers + enum atr_reg_t{ + ATR_REG_IDLE = 'i', + ATR_REG_TX_ONLY = 't', + ATR_REG_RX_ONLY = 'r', + ATR_REG_FULL_DUPLEX = 'f' + }; + + /*! + * Write to an aux dac. + * + * \param unit which unit rx or tx + * \param which_dac the dac index 0, 1, 2, 3... + * \param value the value to write + */ + virtual void write_aux_dac(unit_t unit, int which_dac, int value) = 0; + + /*! + * Read from an aux adc. + * + * \param unit which unit rx or tx + * \param which_adc the adc index 0, 1, 2, 3... + * \return the value that was read + */ + virtual int read_aux_adc(unit_t unit, int which_adc) = 0; + + /*! + * Set a daughterboard ATR register. + * + * \param unit which unit rx or tx + * \param reg which ATR register to set + * \param value 16-bits, 0=FPGA output low, 1=FPGA output high + */ + virtual void set_atr_reg(unit_t unit, atr_reg_t reg, boost::uint16_t value) = 0; + + /*! + * Set daughterboard GPIO data direction register. + * + * \param unit which unit rx or tx + * \param value 16-bits, 0=FPGA input, 1=FPGA output + */ + virtual void set_gpio_ddr(unit_t unit, boost::uint16_t value) = 0; + + /*! + * Read daughterboard GPIO pin values. + * + * \param unit which unit rx or tx + * \return the value of the gpio unit + */ + virtual boost::uint16_t read_gpio(unit_t unit) = 0; + + /*! + * Write to an I2C peripheral. + * + * \param i2c_addr I2C bus address (7-bits) + * \param buf the data to write + */ + virtual void write_i2c(int i2c_addr, const byte_vector_t &buf) = 0; + + /*! + * Read from an I2C peripheral. + * + * \param i2c_addr I2C bus address (7-bits) + * \param num_bytes number of bytes to read + * \return the data read if successful, else a zero length string. + */ + virtual byte_vector_t read_i2c(int i2c_addr, size_t num_bytes) = 0; + + /*! + * Write data to SPI bus peripheral. + * + * \param unit which unit, rx or tx + * \param config configuration settings + * \param data the bits to write LSB first + * \param num_bits the number of bits in data + */ + virtual void write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; + + /*! + * Read and write data to SPI bus peripheral. + * + * \param unit which unit, rx or tx + * \param config configuration settings + * \param data the bits to write LSB first + * \param num_bits the number of bits in data + * \return the data that was read + */ + virtual boost::uint32_t read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; + + /*! + * Get the rate of a dboard clock. + * + * \param unit which unit rx or tx + * \return the clock rate in Hz + */ + virtual double get_clock_rate(unit_t unit) = 0; + + /*! + * Enable or disable a dboard clock. + * + * \param unit which unit rx or tx + * \param enb true for enabled + */ + virtual void set_clock_enabled(unit_t unit, bool enb) = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_IFACE_HPP */ diff --git a/host/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp deleted file mode 100644 index c4e822751..000000000 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ /dev/null @@ -1,190 +0,0 @@ -// -// Copyright 2010 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 . -// - -#ifndef INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP -#define INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP - -#include -#include -#include -#include - -namespace uhd{ namespace usrp{ - -//spi configuration struct -struct UHD_API spi_config_t{ - /*! - * The edge type specifies when data is valid - * relative to the edge of the serial clock. - */ - enum edge_t{ - EDGE_RISE = 'r', - EDGE_FALL = 'f' - }; - - //! on what edge is the mosi data valid? - edge_t mosi_edge; - - //! on what edge is the miso data valid? - edge_t miso_edge; - - /*! - * Create a new spi config. - * \param edge the default edge for mosi and miso - */ - spi_config_t(edge_t edge = EDGE_RISE){ - mosi_edge = edge; - miso_edge = edge; - } -}; - -/*! - * The daughter board dboard_interface to be subclassed. - * A dboard instance dboard_interfaces with the mboard though this api. - * This dboard_interface provides i2c, spi, gpio, atr, aux dac/adc access. - * Each mboard should have a specially tailored interface for its dboard. - */ -class UHD_API dboard_interface{ -public: - typedef boost::shared_ptr sptr; - typedef std::vector byte_vector_t; - - //tells the host which unit to use - enum unit_t{ - UNIT_RX = 'r', - UNIT_TX = 't' - }; - - //possible atr registers - enum atr_reg_t{ - ATR_REG_IDLE = 'i', - ATR_REG_TX_ONLY = 't', - ATR_REG_RX_ONLY = 'r', - ATR_REG_FULL_DUPLEX = 'f' - }; - - /*! - * Write to an aux dac. - * - * \param unit which unit rx or tx - * \param which_dac the dac index 0, 1, 2, 3... - * \param value the value to write - */ - virtual void write_aux_dac(unit_t unit, int which_dac, int value) = 0; - - /*! - * Read from an aux adc. - * - * \param unit which unit rx or tx - * \param which_adc the adc index 0, 1, 2, 3... - * \return the value that was read - */ - virtual int read_aux_adc(unit_t unit, int which_adc) = 0; - - /*! - * Set a daughterboard ATR register. - * - * \param unit which unit rx or tx - * \param reg which ATR register to set - * \param value 16-bits, 0=FPGA output low, 1=FPGA output high - */ - virtual void set_atr_reg(unit_t unit, atr_reg_t reg, boost::uint16_t value) = 0; - - /*! - * Set daughterboard GPIO data direction register. - * - * \param unit which unit rx or tx - * \param value 16-bits, 0=FPGA input, 1=FPGA output - */ - virtual void set_gpio_ddr(unit_t unit, boost::uint16_t value) = 0; - - /*! - * Read daughterboard GPIO pin values. - * - * \param unit which unit rx or tx - * \return the value of the gpio unit - */ - virtual boost::uint16_t read_gpio(unit_t unit) = 0; - - /*! - * Write to an I2C peripheral. - * - * \param i2c_addr I2C bus address (7-bits) - * \param buf the data to write - */ - virtual void write_i2c(int i2c_addr, const byte_vector_t &buf) = 0; - - /*! - * Read from an I2C peripheral. - * - * \param i2c_addr I2C bus address (7-bits) - * \param num_bytes number of bytes to read - * \return the data read if successful, else a zero length string. - */ - virtual byte_vector_t read_i2c(int i2c_addr, size_t num_bytes) = 0; - - /*! - * Write data to SPI bus peripheral. - * - * \param unit which unit, rx or tx - * \param config configuration settings - * \param data the bits to write LSB first - * \param num_bits the number of bits in data - */ - virtual void write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits - ) = 0; - - /*! - * Read and write data to SPI bus peripheral. - * - * \param unit which unit, rx or tx - * \param config configuration settings - * \param data the bits to write LSB first - * \param num_bits the number of bits in data - * \return the data that was read - */ - virtual boost::uint32_t read_write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits - ) = 0; - - /*! - * Get the rate of a dboard clock. - * - * \param unit which unit rx or tx - * \return the clock rate in Hz - */ - virtual double get_clock_rate(unit_t unit) = 0; - - /*! - * Enable or disable a dboard clock. - * - * \param unit which unit rx or tx - * \param enb true for enabled - */ - virtual void set_clock_enabled(unit_t unit, bool enb) = 0; -}; - -}} //namespace - -#endif /* INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP */ diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp index ed8ee73ef..6de64b02d 100644 --- a/host/include/uhd/usrp/dboard_manager.hpp +++ b/host/include/uhd/usrp/dboard_manager.hpp @@ -59,16 +59,16 @@ public: * Make a new dboard manager. * \param rx_dboard_id the id of the rx dboard * \param tx_dboard_id the id of the tx dboard - * \param interface the custom dboard interface + * \param iface the custom dboard interface * \return an sptr to the new dboard manager */ static sptr make( dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, - dboard_interface::sptr interface + dboard_iface::sptr iface ); - //dboard_interface + //dboard manager interface virtual prop_names_t get_rx_subdev_names(void) = 0; virtual prop_names_t get_tx_subdev_names(void) = 0; virtual wax::obj get_rx_subdev(const std::string &subdev_name) = 0; diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 1cb39f83c..e5dc16808 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -112,19 +112,19 @@ rfx_xcvr::rfx_xcvr( _freq_range = freq_range; //enable the clocks that we need - this->get_interface()->set_clock_enabled(dboard_interface::UNIT_TX, true); - this->get_interface()->set_clock_enabled(dboard_interface::UNIT_RX, true); + this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); + this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); //set the gpio directions boost::uint16_t output_enables = POWER_UP | ANT_SW | MIX_EN; - this->get_interface()->set_gpio_ddr(dboard_interface::UNIT_TX, output_enables); - this->get_interface()->set_gpio_ddr(dboard_interface::UNIT_RX, output_enables); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, output_enables); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, output_enables); //setup the tx atr (this does not change with antenna) - this->get_interface()->set_atr_reg(dboard_interface::UNIT_TX, dboard_interface::ATR_REG_IDLE, POWER_UP | ANT_SW); - this->get_interface()->set_atr_reg(dboard_interface::UNIT_TX, dboard_interface::ATR_REG_RX_ONLY, POWER_UP | ANT_SW); - this->get_interface()->set_atr_reg(dboard_interface::UNIT_TX, dboard_interface::ATR_REG_TX_ONLY, POWER_UP | MIX_EN); - this->get_interface()->set_atr_reg(dboard_interface::UNIT_TX, dboard_interface::ATR_REG_FULL_DUPLEX, POWER_UP | MIX_EN); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, POWER_UP | ANT_SW); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, POWER_UP | ANT_SW); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, POWER_UP | MIX_EN); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, POWER_UP | MIX_EN); //set some default values set_lo_freq((_freq_range.min + _freq_range.max)/2.0); @@ -148,10 +148,10 @@ void rfx_xcvr::set_rx_ant(const std::string &ant){ boost::uint16_t ant_val = (ant == "tx/rx")? 0 : ANT_SW; //set the rx atr regs - this->get_interface()->set_atr_reg(dboard_interface::UNIT_RX, dboard_interface::ATR_REG_IDLE, POWER_UP | ant_val); - this->get_interface()->set_atr_reg(dboard_interface::UNIT_RX, dboard_interface::ATR_REG_RX_ONLY, POWER_UP | ant_val | MIX_EN); - this->get_interface()->set_atr_reg(dboard_interface::UNIT_RX, dboard_interface::ATR_REG_TX_ONLY, POWER_UP | ant_val); - this->get_interface()->set_atr_reg(dboard_interface::UNIT_RX, dboard_interface::ATR_REG_FULL_DUPLEX, POWER_UP | ant_val | MIX_EN); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, POWER_UP | ant_val); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, POWER_UP | ant_val | MIX_EN); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, POWER_UP | ant_val); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, POWER_UP | ant_val | MIX_EN); } void rfx_xcvr::set_rx_pga0_gain(float gain){ @@ -165,8 +165,8 @@ void rfx_xcvr::reload_adf4360_regs(void){ (adf4360_regs_t::ADDR_RCOUNTER) ; BOOST_FOREACH(adf4360_regs_t::addr_t addr, addrs){ - this->get_interface()->write_spi( - dboard_interface::UNIT_TX, + this->get_iface()->write_spi( + dboard_iface::UNIT_TX, spi_config_t::EDGE_RISE, _adf4360_regs.get_reg(addr), 24 ); diff --git a/host/lib/usrp/dboard_base.cpp b/host/lib/usrp/dboard_base.cpp index 09d3bbfd4..68e4743d1 100644 --- a/host/lib/usrp/dboard_base.cpp +++ b/host/lib/usrp/dboard_base.cpp @@ -25,7 +25,7 @@ using namespace uhd::usrp; * dboard_base dboard dboard_base class **********************************************************************/ dboard_base::dboard_base(ctor_args_t const& args){ - boost::tie(_subdev_name, _dboard_interface, _rx_id, _tx_id) = args; + boost::tie(_subdev_name, _dboard_iface, _rx_id, _tx_id) = args; } dboard_base::~dboard_base(void){ @@ -36,8 +36,8 @@ std::string dboard_base::get_subdev_name(void){ return _subdev_name; } -dboard_interface::sptr dboard_base::get_interface(void){ - return _dboard_interface; +dboard_iface::sptr dboard_base::get_iface(void){ + return _dboard_iface; } dboard_id_t dboard_base::get_rx_id(void){ diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 5e62b5564..06f8c55b6 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -125,11 +125,11 @@ public: dboard_manager_impl( dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, - dboard_interface::sptr interface + dboard_iface::sptr iface ); ~dboard_manager_impl(void); - //dboard_interface + //dboard_iface prop_names_t get_rx_subdev_names(void); prop_names_t get_tx_subdev_names(void); wax::obj get_rx_subdev(const std::string &subdev_name); @@ -141,7 +141,7 @@ private: //the subdevice proxy is internal to the cpp file uhd::dict _rx_dboards; uhd::dict _tx_dboards; - dboard_interface::sptr _interface; + dboard_iface::sptr _iface; void set_nice_dboard_if(void); }; @@ -151,10 +151,10 @@ private: dboard_manager::sptr dboard_manager::make( dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, - dboard_interface::sptr interface + dboard_iface::sptr iface ){ return dboard_manager::sptr( - new dboard_manager_impl(rx_dboard_id, tx_dboard_id, interface) + new dboard_manager_impl(rx_dboard_id, tx_dboard_id, iface) ); } @@ -190,9 +190,9 @@ static args_t get_dboard_args( dboard_manager_impl::dboard_manager_impl( dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, - dboard_interface::sptr interface + dboard_iface::sptr iface ){ - _interface = interface; + _iface = iface; dboard_ctor_t rx_dboard_ctor; std::string rx_name; prop_names_t rx_subdevs; boost::tie(rx_dboard_ctor, rx_name, rx_subdevs) = get_dboard_args(rx_dboard_id, "rx"); @@ -208,7 +208,7 @@ dboard_manager_impl::dboard_manager_impl( ASSERT_THROW(rx_subdevs == tx_subdevs); BOOST_FOREACH(const std::string &subdev, rx_subdevs){ dboard_base::sptr xcvr_dboard = rx_dboard_ctor( - dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, tx_dboard_id) + dboard_base::ctor_args_t(subdev, iface, rx_dboard_id, tx_dboard_id) ); //create a rx proxy for this xcvr board _rx_dboards[subdev] = subdev_proxy::sptr( @@ -226,7 +226,7 @@ dboard_manager_impl::dboard_manager_impl( //make the rx subdevs BOOST_FOREACH(const std::string &subdev, rx_subdevs){ dboard_base::sptr rx_dboard = rx_dboard_ctor( - dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, dboard_id::NONE) + dboard_base::ctor_args_t(subdev, iface, rx_dboard_id, dboard_id::NONE) ); //create a rx proxy for this rx board _rx_dboards[subdev] = subdev_proxy::sptr( @@ -236,7 +236,7 @@ dboard_manager_impl::dboard_manager_impl( //make the tx subdevs BOOST_FOREACH(const std::string &subdev, tx_subdevs){ dboard_base::sptr tx_dboard = tx_dboard_ctor( - dboard_base::ctor_args_t(subdev, interface, dboard_id::NONE, tx_dboard_id) + dboard_base::ctor_args_t(subdev, iface, dboard_id::NONE, tx_dboard_id) ); //create a tx proxy for this tx board _tx_dboards[subdev] = subdev_proxy::sptr( @@ -276,15 +276,15 @@ wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){ void dboard_manager_impl::set_nice_dboard_if(void){ //make a list of possible unit types - std::vector units = boost::assign::list_of - (dboard_interface::UNIT_RX) - (dboard_interface::UNIT_TX) + std::vector units = boost::assign::list_of + (dboard_iface::UNIT_RX) + (dboard_iface::UNIT_TX) ; //set nice settings on each unit - BOOST_FOREACH(dboard_interface::unit_t unit, units){ - _interface->set_gpio_ddr(unit, 0x0000); //all inputs - _interface->set_atr_reg(unit, dboard_interface::ATR_REG_IDLE, 0x0000); //all low - _interface->set_clock_enabled(unit, false); //clock off + BOOST_FOREACH(dboard_iface::unit_t unit, units){ + _iface->set_gpio_ddr(unit, 0x0000); //all inputs + _iface->set_atr_reg(unit, dboard_iface::ATR_REG_IDLE, 0x0000); //all low + _iface->set_clock_enabled(unit, false); //clock off } } diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index d0c4bf6c1..f77dfc495 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -26,7 +26,7 @@ using namespace uhd::usrp; -class usrp2_dboard_iface : public dboard_interface{ +class usrp2_dboard_iface : public dboard_iface{ public: usrp2_dboard_iface(usrp2_iface::sptr iface, clock_control::sptr clk_ctrl); ~usrp2_dboard_iface(void); @@ -68,11 +68,11 @@ private: /*********************************************************************** * Make Function **********************************************************************/ -dboard_interface::sptr make_usrp2_dboard_iface( +dboard_iface::sptr make_usrp2_dboard_iface( usrp2_iface::sptr iface, clock_control::sptr clk_ctrl ){ - return dboard_interface::sptr(new usrp2_dboard_iface(iface, clk_ctrl)); + return dboard_iface::sptr(new usrp2_dboard_iface(iface, clk_ctrl)); } /*********************************************************************** @@ -117,10 +117,10 @@ void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ /*********************************************************************** * GPIO **********************************************************************/ -static int unit_to_shift(dboard_interface::unit_t unit){ +static int unit_to_shift(dboard_iface::unit_t unit){ switch(unit){ - case dboard_interface::UNIT_RX: return 0; - case dboard_interface::UNIT_TX: return 16; + case dboard_iface::UNIT_RX: return 0; + case dboard_iface::UNIT_TX: return 16; } throw std::runtime_error("unknown unit type"); } @@ -166,10 +166,10 @@ void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t * \param unit the dboard interface unit type enum * \return an over the wire representation */ -static boost::uint8_t unit_to_otw_spi_dev(dboard_interface::unit_t unit){ +static boost::uint8_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ switch(unit){ - case dboard_interface::UNIT_TX: return SPI_SS_TX_DB; - case dboard_interface::UNIT_RX: return SPI_SS_RX_DB; + case dboard_iface::UNIT_TX: return SPI_SS_TX_DB; + case dboard_iface::UNIT_RX: return SPI_SS_RX_DB; } throw std::invalid_argument("unknown unit type"); } @@ -213,7 +213,7 @@ void usrp2_dboard_iface::write_i2c(int i2c_addr, const byte_vector_t &buf){ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); } -dboard_interface::byte_vector_t usrp2_dboard_iface::read_i2c(int i2c_addr, size_t num_bytes){ +dboard_iface::byte_vector_t usrp2_dboard_iface::read_i2c(int i2c_addr, size_t num_bytes){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); @@ -243,10 +243,10 @@ dboard_interface::byte_vector_t usrp2_dboard_iface::read_i2c(int i2c_addr, size_ * \param unit the dboard interface unit type enum * \return an over the wire representation */ -static boost::uint8_t unit_to_otw(dboard_interface::unit_t unit){ +static boost::uint8_t unit_to_otw(dboard_iface::unit_t unit){ switch(unit){ - case dboard_interface::UNIT_TX: return USRP2_DIR_TX; - case dboard_interface::UNIT_RX: return USRP2_DIR_RX; + case dboard_iface::UNIT_TX: return USRP2_DIR_TX; + case dboard_iface::UNIT_RX: return USRP2_DIR_RX; } throw std::invalid_argument("unknown unit type"); } diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 4b300de68..fe74219d6 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -44,11 +44,11 @@ void usrp2_impl::dboard_init(void){ dboard_id_t tx_dboard_id = ntohs(in_data.data.dboard_ids.tx_id); //create a new dboard interface and manager - dboard_interface::sptr _dboard_interface( + dboard_iface::sptr _dboard_iface( make_usrp2_dboard_iface(_iface, _clk_ctrl) ); _dboard_manager = dboard_manager::make( - rx_dboard_id, tx_dboard_id, _dboard_interface + rx_dboard_id, tx_dboard_id, _dboard_iface ); //load dboards diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index 7b4321c0b..1298d87f1 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -19,7 +19,7 @@ #define INCLUDED_USRP2_IFACE_HPP #include -#include //spi config +#include //spi config #include #include #include diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 7eea1e250..dbcee367b 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -37,7 +37,7 @@ * \param clk_ctrl the clock control object * \return a sptr to a new dboard interface */ -uhd::usrp::dboard_interface::sptr make_usrp2_dboard_iface( +uhd::usrp::dboard_iface::sptr make_usrp2_dboard_iface( usrp2_iface::sptr iface, clock_control::sptr clk_ctrl ); -- cgit v1.2.3