From 275b29e07f97cdf638ecb22c602d26b7d340547a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 2 Apr 2010 17:54:06 -0700 Subject: some work on rfx board code --- host/include/uhd/usrp/subdev_props.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host/include') diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp index 92d18340b..b7d22b777 100644 --- a/host/include/uhd/usrp/subdev_props.hpp +++ b/host/include/uhd/usrp/subdev_props.hpp @@ -35,7 +35,7 @@ namespace uhd{ namespace usrp{ SUBDEV_PROP_FREQ_RANGE = 'F', //ro, freq_range_t SUBDEV_PROP_ANTENNA = 'a', //rw, std::string SUBDEV_PROP_ANTENNA_NAMES = 'A', //ro, prop_names_t - SUBDEV_PROP_ENABLED = 'e', //rw, bool + //SUBDEV_PROP_ENABLED = 'e', //rw, bool //---> dont need, we have atr SUBDEV_PROP_QUADRATURE = 'q', //ro, bool SUBDEV_PROP_IQ_SWAPPED = 'i', //ro, bool SUBDEV_PROP_SPECTRUM_INVERTED = 's', //ro, bool -- cgit v1.2.3 From b66a74ff1f629af714e26040b410d472c08be522 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Apr 2010 00:46:42 -0700 Subject: Reworked the spi part of the dboard interface. It turns out to be more complicated. The integer type is better for holding the bits. The edges can be different, so the spi config hold 2 edge setting for mosi and miso. --- firmware/microblaze/apps/txrx.c | 25 ++------ host/include/uhd/usrp/dboard_interface.hpp | 100 ++++++++++++++++------------- host/lib/CMakeLists.txt | 1 - host/lib/usrp/dboard/db_rfx.cpp | 16 ++--- host/lib/usrp/dboard_interface.cpp | 53 --------------- host/lib/usrp/usrp2/dboard_interface.cpp | 95 ++++++++++++++++----------- host/lib/usrp/usrp2/fw_common.h | 7 +- 7 files changed, 128 insertions(+), 169 deletions(-) delete mode 100644 host/lib/usrp/dboard_interface.cpp (limited to 'host/include') diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c index 69a04d771..561f3148f 100644 --- a/firmware/microblaze/apps/txrx.c +++ b/firmware/microblaze/apps/txrx.c @@ -253,29 +253,18 @@ void handle_udp_ctrl_packet( * SPI ******************************************************************/ case USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO:{ - uint8_t num_bytes = ctrl_data_in->data.spi_args.bytes; - - //load the data from the array of bytes - uint32_t data = 0x0; - for (size_t i = 0; i < num_bytes; i++){ - data = (data << 8) | ctrl_data_in->data.spi_args.data[i]; - } - //transact uint32_t result = spi_transact( (ctrl_data_in->data.spi_args.readback == 0)? SPI_TXONLY : SPI_TXRX, - ctrl_data_in->data.spi_args.dev, - data, num_bytes*8, //length in bits - (ctrl_data_in->data.spi_args.edge == USRP2_CLK_EDGE_RISE)? SPIF_PUSH_RISE : SPIF_PUSH_FALL | - (ctrl_data_in->data.spi_args.edge == USRP2_CLK_EDGE_RISE)? SPIF_LATCH_RISE : SPIF_LATCH_FALL + ctrl_data_in->data.spi_args.dev, //which device + ctrl_data_in->data.spi_args.data, //32 bit data + ctrl_data_in->data.spi_args.num_bits, //length in bits + (ctrl_data_in->data.spi_args.mosi_edge == USRP2_CLK_EDGE_RISE)? SPIF_PUSH_FALL : SPIF_PUSH_RISE | + (ctrl_data_in->data.spi_args.miso_edge == USRP2_CLK_EDGE_RISE)? SPIF_LATCH_RISE : SPIF_LATCH_FALL ); - //load the result into the array of bytes - for (size_t i = 0; i < num_bytes; i++){ - uint8_t byte_shift = num_bytes - i - 1; - ctrl_data_out.data.spi_args.data[i] = (result >> (byte_shift*8)) & 0xff; - } - ctrl_data_out.data.spi_args.bytes = num_bytes; + //load output + ctrl_data_out.data.spi_args.data = result; ctrl_data_out.id = USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE; } break; diff --git a/host/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp index b3bab131d..dab5a2281 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -42,16 +42,31 @@ public: UNIT_TYPE_TX = 't' }; - //tells the host which device to use - enum spi_dev_t{ - SPI_DEV_RX = 'r', - SPI_DEV_TX = 't' - }; - - //args for spi format - enum spi_edge_t{ - SPI_EDGE_RISE = 'r', - SPI_EDGE_FALL = 'f' + //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 @@ -68,10 +83,6 @@ public: ATR_REG_FULL_DUPLEX = 'f' }; - //structors - dboard_interface(void); - virtual ~dboard_interface(void); - /*! * Write to an aux dac. * \param unit which unit rx or tx @@ -131,61 +142,60 @@ public: /*! * \brief Write data to SPI bus peripheral. * - * \param dev which spi device - * \param edge args for format - * \param buf the data to write + * \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 */ - void write_spi(spi_dev_t dev, spi_edge_t edge, const byte_vector_t &buf); + virtual void write_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; /*! * \brief Read data to SPI bus peripheral. * - * \param dev which spi device - * \param edge args for format - * \param num_bytes number of bytes to read + * \param unit which unit, rx or tx + * \param config configuration settings + * \param num_bits the number of bits * \return the data that was read */ - byte_vector_t read_spi(spi_dev_t dev, spi_edge_t edge, size_t num_bytes); + 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. * - * \param dev which spi device - * \param edge args for format - * \param buf the data to write + * \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 */ - byte_vector_t read_write_spi(spi_dev_t dev, spi_edge_t edge, const byte_vector_t &buf); + virtual boost::uint32_t read_write_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; /*! * \brief Get the rate of the rx dboard clock. - * \return the clock rate + * \return the clock rate in Hz */ virtual double get_rx_clock_rate(void) = 0; /*! * \brief Get the rate of the tx dboard clock. - * \return the clock rate + * \return the clock rate in Hz */ virtual double get_tx_clock_rate(void) = 0; - -private: - /*! - * \brief Read and write data to SPI bus peripheral. - * - * \param dev which spi device - * \param edge args for format - * \param buf the data to write - * \param readback false for write only - * \return the data that was read - */ - virtual byte_vector_t transact_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf, - bool readback - ) = 0; }; }} //namespace diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index a4bf46f1a..f21a4a491 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -30,7 +30,6 @@ SET(libuhd_sources usrp/dboard/db_basic_and_lf.cpp usrp/dboard/db_rfx.cpp usrp/dboard_base.cpp - usrp/dboard_interface.cpp usrp/simple_usrp.cpp usrp/dboard_manager.cpp usrp/tune_helper.cpp diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 57ea03da5..68fa51144 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -136,17 +136,11 @@ void rfx_xcvr::reload_adf4360_regs(void){ (adf4360_regs_t::ADDR_RCOUNTER) ; BOOST_FOREACH(adf4360_regs_t::addr_t addr, addrs){ - boost::uint32_t reg = _adf4360_regs.get_reg(addr); - dboard_interface::byte_vector_t spi_bytes = list_of - ((reg >> 16) & 0xff) - ((reg >> 8) & 0xff) - ((reg >> 0) & 0xff) - ; - //this->get_interface.write_spi( - // dboard_interface::SPI_DEV_TX, - // dboard_interface::SPI_EDGE_FALL, - // spi_bytes - //); + this->get_interface()->write_spi( + dboard_interface::UNIT_TYPE_TX, + dboard_interface::spi_config_t::EDGE_RISE, + _adf4360_regs.get_reg(addr), 24 + ); } } diff --git a/host/lib/usrp/dboard_interface.cpp b/host/lib/usrp/dboard_interface.cpp deleted file mode 100644 index c40c9b398..000000000 --- a/host/lib/usrp/dboard_interface.cpp +++ /dev/null @@ -1,53 +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 - -using namespace uhd::usrp; - -dboard_interface::dboard_interface(void){ - /* NOP */ -} - -dboard_interface::~dboard_interface(void){ - /* NOP */ -} - -void dboard_interface::write_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf -){ - transact_spi(dev, edge, buf, false); //dont readback -} - -dboard_interface::byte_vector_t dboard_interface::read_spi( - spi_dev_t dev, - spi_edge_t edge, - size_t num_bytes -){ - byte_vector_t buf(num_bytes, 0x00); //dummy data - return transact_spi(dev, edge, buf, true); //readback -} - -dboard_interface::byte_vector_t dboard_interface::read_write_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf -){ - return transact_spi(dev, edge, buf, true); //readback -} diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index 6dd756420..eee7c087a 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -42,9 +42,35 @@ public: double get_rx_clock_rate(void); double get_tx_clock_rate(void); + void write_spi( + unit_type_t unit, + 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: - byte_vector_t transact_spi( - spi_dev_t, spi_edge_t, const byte_vector_t &, bool + boost::uint32_t transact_spi( + unit_type_t, const spi_config_t &, boost::uint32_t, size_t, bool ); usrp2_impl *_impl; @@ -136,17 +162,17 @@ void usrp2_dboard_interface::set_atr_reg(gpio_bank_t bank, atr_reg_t atr, boost: * SPI **********************************************************************/ /*! - * Static function to convert a spi dev enum - * to an over-the-wire value for the usrp2 control. - * \param dev the dboard interface spi dev enum + * 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 spi_dev_to_otw(dboard_interface::spi_dev_t dev){ - switch(dev){ - case uhd::usrp::dboard_interface::SPI_DEV_TX: return SPI_SS_TX_DB; - case uhd::usrp::dboard_interface::SPI_DEV_RX: return SPI_SS_RX_DB; +static boost::uint8_t unit_to_otw_dev(dboard_interface::unit_type_t unit){ + switch(unit){ + case dboard_interface::UNIT_TYPE_TX: return SPI_SS_TX_DB; + case dboard_interface::UNIT_TYPE_RX: return SPI_SS_RX_DB; } - throw std::invalid_argument("unknown spi device type"); + throw std::invalid_argument("unknown unit type type"); } /*! @@ -155,43 +181,36 @@ static boost::uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){ * \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_edge_t edge){ +static boost::uint8_t spi_edge_to_otw(dboard_interface::spi_config_t::edge_t edge){ switch(edge){ - case uhd::usrp::dboard_interface::SPI_EDGE_RISE: return USRP2_CLK_EDGE_RISE; - case uhd::usrp::dboard_interface::SPI_EDGE_FALL: return USRP2_CLK_EDGE_FALL; + 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"); } -dboard_interface::byte_vector_t usrp2_dboard_interface::transact_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf, +boost::uint32_t usrp2_dboard_interface::transact_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits, bool readback ){ //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 = spi_dev_to_otw(dev); - out_data.data.spi_args.edge = spi_edge_to_otw(edge); + 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.bytes = buf.size(); - - //limitation of spi transaction size - ASSERT_THROW(buf.size() <= sizeof(out_data.data.spi_args.data)); - - //copy in the data - std::copy(buf.begin(), buf.end(), out_data.data.spi_args.data); + 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); - ASSERT_THROW(in_data.data.spi_args.bytes == buf.size()); - //copy out the data - byte_vector_t result(buf.size()); - std::copy(in_data.data.spi_args.data, in_data.data.spi_args.data + buf.size(), result.begin()); - return result; + return ntohl(out_data.data.spi_args.data); } /*********************************************************************** @@ -245,19 +264,19 @@ dboard_interface::byte_vector_t usrp2_dboard_interface::read_i2c(int i2c_addr, s * \param unit the dboard interface unit type enum * \return an over the wire representation */ -static boost::uint8_t spi_dev_to_otw(dboard_interface::unit_type_t unit){ +static boost::uint8_t unit_to_otw(dboard_interface::unit_type_t unit){ switch(unit){ - case uhd::usrp::dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX; - case uhd::usrp::dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX; + case dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX; + case dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX; } throw std::invalid_argument("unknown unit type type"); } -void usrp2_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ +void usrp2_dboard_interface::write_aux_dac(unit_type_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 = spi_dev_to_otw(unit); + 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); @@ -266,11 +285,11 @@ void usrp2_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, i ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_DAC_DUDE); } -int usrp2_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ +int usrp2_dboard_interface::read_aux_adc(unit_type_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 = spi_dev_to_otw(unit); + out_data.data.aux_args.dir = unit_to_otw(unit); out_data.data.aux_args.which = which; //send and recv diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 019f3b931..b600a2a70 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -110,10 +110,11 @@ typedef struct{ } dboard_ids; struct { _SINS_ uint8_t dev; - _SINS_ uint8_t edge; + _SINS_ uint8_t miso_edge; + _SINS_ uint8_t mosi_edge; _SINS_ uint8_t readback; - _SINS_ uint8_t bytes; - _SINS_ uint8_t data[sizeof(_SINS_ uint32_t)]; + _SINS_ uint32_t data; + _SINS_ uint8_t num_bits; } spi_args; struct { _SINS_ uint8_t addr; -- cgit v1.2.3 From d743784919b362d93e6408f05bdef6e543e3fc7e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 8 Apr 2010 10:57:16 -0700 Subject: converted timespec to use nanoseconds for fractional part --- host/CMakeLists.txt | 1 + host/examples/rx_timed_samples.cpp | 4 +- host/include/uhd/transport/vrt.hpp | 8 +++- host/include/uhd/types/metadata.hpp | 1 + host/include/uhd/types/time_spec.hpp | 36 +++++++++++------- host/lib/transport/gen_vrt.py | 10 +++-- host/lib/transport/vrt.cpp | 72 ++++++++++++++++++------------------ host/lib/types.cpp | 27 ++++++-------- host/lib/usrp/usrp2/dboard_impl.cpp | 1 + host/lib/usrp/usrp2/io_impl.cpp | 11 ++++-- host/lib/usrp/usrp2/mboard_impl.cpp | 8 +--- host/test/vrt_test.cpp | 12 +++--- 12 files changed, 105 insertions(+), 86 deletions(-) (limited to 'host/include') diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index d2889fe58..baae90861 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -145,6 +145,7 @@ ENDIF(DOXYGEN_FOUND) INSTALL(FILES ${CMAKE_SOURCE_DIR}/README ${CMAKE_SOURCE_DIR}/LICENSE + ${CMAKE_SOURCE_DIR}/AUTHORS DESTINATION ${PKG_DOC_DIR} ) diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index e971e9f6a..d49f7d182 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -86,8 +86,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ); if (num_rx_samps == 0) continue; //wait for packets with contents - std::cout << boost::format("Got packet: %u samples, %u secs, %u ticks") - % num_rx_samps % md.time_spec.secs % md.time_spec.ticks << std::endl; + std::cout << boost::format("Got packet: %u samples, %u secs, %u nsecs") + % num_rx_samps % md.time_spec.secs % md.time_spec.nsecs << std::endl; num_acc_samps += num_rx_samps; } diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp index 04945b347..137698e57 100644 --- a/host/include/uhd/transport/vrt.hpp +++ b/host/include/uhd/transport/vrt.hpp @@ -36,6 +36,7 @@ namespace vrt{ * \param num_payload_words32 the length of the payload * \param num_packet_words32 the length of the packet * \param packet_count the packet count sequence number + * \param tick_rate ticks per second used in time conversion */ UHD_API void pack( const tx_metadata_t &metadata, //input @@ -43,7 +44,8 @@ namespace vrt{ size_t &num_header_words32, //output size_t num_payload_words32, //input size_t &num_packet_words32, //output - size_t packet_count //input + size_t packet_count, //input + double tick_rate //input ); /*! @@ -54,6 +56,7 @@ namespace vrt{ * \param num_payload_words32 the length of the payload * \param num_packet_words32 the length of the packet * \param packet_count the packet count sequence number + * \param tick_rate ticks per second used in time conversion */ UHD_API void unpack( rx_metadata_t &metadata, //output @@ -61,7 +64,8 @@ namespace vrt{ size_t &num_header_words32, //output size_t &num_payload_words32, //output size_t num_packet_words32, //input - size_t &packet_count //output + size_t &packet_count, //output + double tick_rate //input ); } //namespace vrt diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index 20f483bed..d93b38b50 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -19,6 +19,7 @@ #define INCLUDED_UHD_TYPES_METADATA_HPP #include +#include #include namespace uhd{ diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp index 8c8f2bc25..f06d27118 100644 --- a/host/include/uhd/types/time_spec.hpp +++ b/host/include/uhd/types/time_spec.hpp @@ -20,33 +20,43 @@ #include #include -#include namespace uhd{ /*! - * A time_spec_t holds a seconds and ticks time value. - * The temporal width of a tick depends on the device's clock rate. - * The time_spec_t can be used when setting the time on devices + * A time_spec_t holds a seconds and fractional seconds time value. + * The time_spec_t can be used when setting the time on devices, + * and for dealing with time stamped samples though the metadata. * and for controlling the start of streaming for applicable dsps. */ struct UHD_API time_spec_t{ + + //! whole seconds count boost::uint32_t secs; - boost::uint32_t ticks; + + //! fractional seconds count in nano-seconds + double nsecs; /*! - * Create a time_spec_t from seconds and ticks. - * \param new_secs the new seconds (default = 0) - * \param new_ticks the new ticks (default = 0) + * Convert the fractional nsecs to clock ticks. + * \param tick_rate the number of ticks per second + * \return the number of ticks in this time spec */ - time_spec_t(boost::uint32_t new_secs = 0, boost::uint32_t new_ticks = 0); + boost::uint32_t get_ticks(double tick_rate) const; /*! - * Create a time_spec_t from boost posix time. - * \param time fine-grained boost posix time - * \param tick_rate the rate of ticks per second + * Set the fractional nsecs from clock ticks. + * \param ticks the fractional seconds tick count + * \param tick_rate the number of ticks per second + */ + void set_ticks(boost::uint32_t ticks, double tick_rate); + + /*! + * Create a time_spec_t from seconds and ticks. + * \param new_secs the new seconds (default = 0) + * \param new_nsecs the new nano-seconds (default = 0) */ - time_spec_t(boost::posix_time::ptime time, double tick_rate); + time_spec_t(boost::uint32_t new_secs = 0, double new_nsecs = 0); }; diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py index 918de3ad7..bc6635d78 100755 --- a/host/lib/transport/gen_vrt.py +++ b/host/lib/transport/gen_vrt.py @@ -54,7 +54,8 @@ void vrt::pack( size_t &num_header_words32, //output size_t num_payload_words32, //input size_t &num_packet_words32, //output - size_t packet_count //input + size_t packet_count, //input + double tick_rate //input ){ boost::uint32_t vrt_hdr_flags; @@ -91,7 +92,7 @@ void vrt::pack( #if $pred & $tsf_p header_buff[$num_header_words] = htonl(0); #set $num_header_words += 1 - header_buff[$num_header_words] = htonl(metadata.time_spec.ticks); + header_buff[$num_header_words] = htonl(metadata.time_spec.get_ticks(tick_rate)); #set $num_header_words += 1 #set $flags |= (0x1 << 20); #end if @@ -127,7 +128,8 @@ void vrt::unpack( size_t &num_header_words32, //output size_t &num_payload_words32, //output size_t num_packet_words32, //input - size_t &packet_count //output + size_t &packet_count, //output + double tick_rate //input ){ //clear the metadata metadata = rx_metadata_t(); @@ -180,7 +182,7 @@ void vrt::unpack( #set $set_has_time_spec = True #end if #set $num_header_words += 1 - metadata.time_spec.ticks = ntohl(header_buff[$num_header_words]); + metadata.time_spec.set_ticks(ntohl(header_buff[$num_header_words]), tick_rate); #set $num_header_words += 1 #end if ########## Trailer ########## diff --git a/host/lib/transport/vrt.cpp b/host/lib/transport/vrt.cpp index bebca5db9..78c3cf2cb 100644 --- a/host/lib/transport/vrt.cpp +++ b/host/lib/transport/vrt.cpp @@ -2,7 +2,7 @@ /*********************************************************************** - * This file was generated by ./gen_vrt.py on Fri Mar 26 15:33:00 2010 + * This file was generated by gen_vrt.py on 04/08/10 10:55:26 **********************************************************************/ #include @@ -18,7 +18,8 @@ void vrt::pack( size_t &num_header_words32, //output size_t num_payload_words32, //input size_t &num_packet_words32, //output - size_t packet_count //input + size_t packet_count, //input + double tick_rate //input ){ boost::uint32_t vrt_hdr_flags; @@ -85,7 +86,7 @@ void vrt::pack( break; case 8: header_buff[1] = htonl(0); - header_buff[2] = htonl(metadata.time_spec.ticks); + header_buff[2] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 3; num_packet_words32 = 3 + num_payload_words32; vrt_hdr_flags = 0x100000; @@ -93,7 +94,7 @@ void vrt::pack( case 9: header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 4 + num_payload_words32; vrt_hdr_flags = 0x10100000; @@ -102,7 +103,7 @@ void vrt::pack( header_buff[1] = htonl(0); header_buff[2] = htonl(0); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x8100000; @@ -112,7 +113,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(0); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0x18100000; @@ -120,7 +121,7 @@ void vrt::pack( case 12: header_buff[1] = htonl(metadata.time_spec.secs); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 4 + num_payload_words32; vrt_hdr_flags = 0xd00000; @@ -129,7 +130,7 @@ void vrt::pack( header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(metadata.time_spec.secs); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x10d00000; @@ -139,7 +140,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(metadata.time_spec.secs); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0x8d00000; @@ -150,7 +151,7 @@ void vrt::pack( header_buff[3] = htonl(0); header_buff[4] = htonl(metadata.time_spec.secs); header_buff[5] = htonl(0); - header_buff[6] = htonl(metadata.time_spec.ticks); + header_buff[6] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 7; num_packet_words32 = 7 + num_payload_words32; vrt_hdr_flags = 0x18d00000; @@ -213,7 +214,7 @@ void vrt::pack( break; case 24: header_buff[1] = htonl(0); - header_buff[2] = htonl(metadata.time_spec.ticks); + header_buff[2] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 3; num_packet_words32 = 4 + num_payload_words32; vrt_hdr_flags = 0x4100000; @@ -221,7 +222,7 @@ void vrt::pack( case 25: header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x14100000; @@ -230,7 +231,7 @@ void vrt::pack( header_buff[1] = htonl(0); header_buff[2] = htonl(0); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0xc100000; @@ -240,7 +241,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(0); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 7 + num_payload_words32; vrt_hdr_flags = 0x1c100000; @@ -248,7 +249,7 @@ void vrt::pack( case 28: header_buff[1] = htonl(metadata.time_spec.secs); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x4d00000; @@ -257,7 +258,7 @@ void vrt::pack( header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(metadata.time_spec.secs); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0x14d00000; @@ -267,7 +268,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(metadata.time_spec.secs); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 7 + num_payload_words32; vrt_hdr_flags = 0xcd00000; @@ -278,7 +279,7 @@ void vrt::pack( header_buff[3] = htonl(0); header_buff[4] = htonl(metadata.time_spec.secs); header_buff[5] = htonl(0); - header_buff[6] = htonl(metadata.time_spec.ticks); + header_buff[6] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 7; num_packet_words32 = 8 + num_payload_words32; vrt_hdr_flags = 0x1cd00000; @@ -302,7 +303,8 @@ void vrt::unpack( size_t &num_header_words32, //output size_t &num_payload_words32, //output size_t num_packet_words32, //input - size_t &packet_count //output + size_t &packet_count, //output + double tick_rate //input ){ //clear the metadata metadata = rx_metadata_t(); @@ -376,7 +378,7 @@ void vrt::unpack( break; case 8: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[2]); + metadata.time_spec.set_ticks(ntohl(header_buff[2]), tick_rate); num_header_words32 = 3; num_payload_words32 = packet_words32 - 3; break; @@ -384,13 +386,13 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 4; break; case 10: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 5; break; @@ -398,14 +400,14 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 6; break; case 12: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[1]); - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 4; break; @@ -414,14 +416,14 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[2]); - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 5; break; case 14: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[3]); - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 6; break; @@ -430,7 +432,7 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[4]); - metadata.time_spec.ticks = ntohl(header_buff[6]); + metadata.time_spec.set_ticks(ntohl(header_buff[6]), tick_rate); num_header_words32 = 7; num_payload_words32 = packet_words32 - 7; break; @@ -484,7 +486,7 @@ void vrt::unpack( break; case 24: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[2]); + metadata.time_spec.set_ticks(ntohl(header_buff[2]), tick_rate); num_header_words32 = 3; num_payload_words32 = packet_words32 - 4; break; @@ -492,13 +494,13 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 5; break; case 26: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 6; break; @@ -506,14 +508,14 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 7; break; case 28: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[1]); - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 5; break; @@ -522,14 +524,14 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[2]); - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 6; break; case 30: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[3]); - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 7; break; @@ -538,7 +540,7 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[4]); - metadata.time_spec.ticks = ntohl(header_buff[6]); + metadata.time_spec.set_ticks(ntohl(header_buff[6]), tick_rate); num_header_words32 = 7; num_payload_words32 = packet_words32 - 8; break; diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 61a63b710..cd688e73d 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -101,29 +102,26 @@ tx_metadata_t::tx_metadata_t(void){ /*********************************************************************** * time spec **********************************************************************/ -time_spec_t::time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks){ +time_spec_t::time_spec_t(boost::uint32_t new_secs, double new_nsecs){ secs = new_secs; - ticks = new_ticks; + nsecs = new_nsecs; } -static const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); -static double time_tick_rate = double(boost::posix_time::time_duration::ticks_per_second()); +boost::uint32_t time_spec_t::get_ticks(double tick_rate) const{ + return boost::math::iround(nsecs*tick_rate*1e-9); +} -time_spec_t::time_spec_t(boost::posix_time::ptime time, double tick_rate){ - boost::posix_time::time_duration td = time - epoch; - secs = boost::uint32_t(td.total_seconds()); - double time_ticks_per_device_ticks = time_tick_rate/tick_rate; - ticks = boost::uint32_t(td.fractional_seconds()/time_ticks_per_device_ticks); +void time_spec_t::set_ticks(boost::uint32_t ticks, double tick_rate){ + nsecs = double(ticks)*1e9/tick_rate; } /*********************************************************************** * device addr **********************************************************************/ std::string device_addr_t::to_string(void) const{ - const device_addr_t &device_addr = *this; std::stringstream ss; - BOOST_FOREACH(std::string key, device_addr.keys()){ - ss << boost::format("%s: %s") % key % device_addr[key] << std::endl; + BOOST_FOREACH(std::string key, this->keys()){ + ss << boost::format("%s: %s") % key % (*this)[key] << std::endl; } return ss.str(); } @@ -137,9 +135,8 @@ static std::string trim(const std::string &in){ std::string device_addr_t::to_args_str(void) const{ std::string args_str; - const device_addr_t &device_addr = *this; - BOOST_FOREACH(const std::string &key, device_addr.keys()){ - args_str += key + pair_delim + device_addr[key] + arg_delim; + BOOST_FOREACH(const std::string &key, this->keys()){ + args_str += key + pair_delim + (*this)[key] + arg_delim; } return args_str; } diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index d1515f2d5..3ac805421 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace uhd; using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a58e32619..eb6b5f7b9 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -15,9 +15,10 @@ // along with this program. If not, see . // -#include -#include #include "usrp2_impl.hpp" +#include +#include +#include using namespace uhd; using namespace uhd::usrp; @@ -144,7 +145,8 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){ num_header_words32_out, //output num_payload_words32_out, //output num_packet_words32, //input - packet_count_out //output + packet_count_out, //output + get_master_clock_freq() ); }catch(const std::exception &e){ std::cerr << "bad vrt header: " << e.what() << std::endl; @@ -196,7 +198,8 @@ size_t usrp2_impl::send( num_header_words32, //output num_samps, //input num_packet_words32, //output - packet_count //input + packet_count, //input + get_master_clock_freq() ); boost::uint32_t *items = tx_mem + num_header_words32; //offset for data diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 94ab88a6b..2fa2e5211 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -33,10 +33,6 @@ void usrp2_impl::mboard_init(void){ boost::bind(&usrp2_impl::mboard_get, this, _1, _2), boost::bind(&usrp2_impl::mboard_set, this, _1, _2) ); - - //set the time on the usrp2 as close as possible to the system utc time - boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time()); - set_time_spec(time_spec_t(now, get_master_clock_freq()), true); } void usrp2_impl::init_clock_config(void){ @@ -75,7 +71,7 @@ void usrp2_impl::update_clock_config(void){ 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.ticks); + this->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; @@ -88,7 +84,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO); out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0; out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs); - out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks); + out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.get_ticks(get_master_clock_freq())); //set these to defaults, then change in the switch statement out_data.data.stream_cmd.continuous = 0; diff --git a/host/test/vrt_test.cpp b/host/test/vrt_test.cpp index 40116e110..939a61eb4 100644 --- a/host/test/vrt_test.cpp +++ b/host/test/vrt_test.cpp @@ -36,7 +36,8 @@ static void pack_and_unpack( num_header_words32, //output num_payload_words32, //input num_packet_words32, //output - packet_count //input + packet_count, //input + 100e6 ); uhd::rx_metadata_t metadata_out; @@ -51,7 +52,8 @@ static void pack_and_unpack( num_header_words32_out, //output num_payload_words32_out, //output num_packet_words32, //input - packet_count_out //output + packet_count_out, //output + 100e6 ); //check the the unpacked metadata is the same @@ -65,7 +67,7 @@ static void pack_and_unpack( BOOST_CHECK_EQUAL(metadata.has_time_spec, metadata_out.has_time_spec); if (metadata.has_time_spec and metadata_out.has_time_spec){ BOOST_CHECK_EQUAL(metadata.time_spec.secs, metadata_out.time_spec.secs); - BOOST_CHECK_EQUAL(metadata.time_spec.ticks, metadata_out.time_spec.ticks); + BOOST_CHECK_EQUAL(metadata.time_spec.nsecs, metadata_out.time_spec.nsecs); } } @@ -85,7 +87,7 @@ BOOST_AUTO_TEST_CASE(test_with_time_spec){ uhd::tx_metadata_t metadata; metadata.has_time_spec = true; metadata.time_spec.secs = 7; - metadata.time_spec.ticks = 2000; + metadata.time_spec.nsecs = 2000; pack_and_unpack(metadata, 500, 3); } @@ -95,6 +97,6 @@ BOOST_AUTO_TEST_CASE(test_with_sid_and_time_spec){ metadata.stream_id = 2; metadata.has_time_spec = true; metadata.time_spec.secs = 5; - metadata.time_spec.ticks = 1000; + metadata.time_spec.nsecs = 1000; pack_and_unpack(metadata, 600, 4); } -- cgit v1.2.3 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/include/uhd/transport/CMakeLists.txt | 2 +- host/include/uhd/transport/smart_buffer.hpp | 45 --------- host/include/uhd/transport/udp_zero_copy.hpp | 28 +----- host/include/uhd/transport/zero_copy.hpp | 133 +++++++++++++++++++++++++++ host/lib/transport/udp_zero_copy_asio.cpp | 105 ++++++++++++++------- host/lib/usrp/usrp2/io_impl.cpp | 21 +++-- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 +- 7 files changed, 223 insertions(+), 113 deletions(-) delete mode 100644 host/include/uhd/transport/smart_buffer.hpp create mode 100644 host/include/uhd/transport/zero_copy.hpp (limited to 'host/include') diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 14b5ccd29..9a94ead1b 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -18,9 +18,9 @@ INSTALL(FILES if_addrs.hpp - smart_buffer.hpp udp_simple.hpp udp_zero_copy.hpp vrt.hpp + zero_copy.hpp DESTINATION ${INCLUDE_DIR}/uhd/transport ) diff --git a/host/include/uhd/transport/smart_buffer.hpp b/host/include/uhd/transport/smart_buffer.hpp deleted file mode 100644 index a9bc259e9..000000000 --- a/host/include/uhd/transport/smart_buffer.hpp +++ /dev/null @@ -1,45 +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_TRANSPORT_SMART_BUFFER_HPP -#define INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP - -#include -#include -#include - -namespace uhd{ namespace transport{ - -/*! - * A buffer that knows how to free itself: - * - * This is just the smart buffer interface. - * A transport implementation will have its own - * internal (custom) smart buffer implementation. - * - * A smart buffer contains a boost asio const buffer. - * On destruction, the buffer contents will be freed. - */ -class smart_buffer : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - virtual const boost::asio::const_buffer &get(void) const = 0; -}; - -}} //namespace - -#endif /* INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP */ diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index 0441a8e74..fd1cec46e 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -19,24 +19,22 @@ #define INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP #include -#include -#include -#include +#include #include namespace uhd{ namespace transport{ /*! * A zero copy udp transport provides an efficient way to handle data. - * by avoiding the extra copy when recv() is called on the socket. - * Rather, the zero copy transport gives the caller a memory reference. + * by avoiding the extra copy when recv() or send() is called on the socket. + * Rather, the zero copy transport gives the caller memory references. * The caller informs the transport when it is finished with the reference. * * On linux systems, the zero copy transport can use a kernel packet ring. * If no platform specific solution is available, make returns a boost asio - * implementation that wraps the functionality around a standard recv() call. + * implementation that wraps the functionality around a standard send/recv calls. */ -class UHD_API udp_zero_copy : boost::noncopyable{ +class UHD_API udp_zero_copy : public zero_copy_if{ public: typedef boost::shared_ptr sptr; @@ -54,22 +52,6 @@ public: * \param port a string representing the destination port */ static sptr make(const std::string &addr, const std::string &port); - - /*! - * Send a single buffer. - * Blocks until the data is sent. - * \param buff single asio buffer - * \return the number of bytes sent - */ - virtual size_t send(const boost::asio::const_buffer &buff) = 0; - - /*! - * Receive a buffer. - * Blocks until data is received or a timeout occurs. - * The memory is managed by the implementation. - * \return a smart buffer (empty on timeout) - */ - virtual smart_buffer::sptr recv(void) = 0; }; }} //namespace diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp new file mode 100644 index 000000000..4fc1df9de --- /dev/null +++ b/host/include/uhd/transport/zero_copy.hpp @@ -0,0 +1,133 @@ +// +// 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_ZERO_COPY_HPP +#define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP + +#include +#include +#include +#include + +namespace uhd{ namespace transport{ + +/*! + * A managed receive buffer: + * Contains a reference to transport-managed memory, + * and a method to release the memory after reading. + */ +class UHD_API managed_recv_buffer : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Signal to the transport that we are done with the buffer. + * This should be called to release the buffer to the transport. + * After calling, the referenced memory should be considered invalid. + */ + virtual void done(void) = 0; + + /*! + * Get the size of the underlying buffer. + * \return the number of bytes + */ + size_t size(void){ + return boost::asio::buffer_size(this->get()); + } + + /*! + * Get a pointer to the underlying buffer. + * \return a pointer into memory + */ + template T cast(void){ + return boost::asio::buffer_cast(this->get()); + } + +private: + /*! + * Get a reference to the internal const buffer. + * The buffer has a reference to memory and a size. + * \return a boost asio const buffer + */ + virtual const boost::asio::const_buffer &get(void) = 0; +}; + +/*! + * A managed send buffer: + * Contains a reference to transport-managed memory, + * and a method to release the memory after writing. + */ +class UHD_API managed_send_buffer : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Signal to the transport that we are done with the buffer. + * This should be called to commit the write to the transport object. + * After calling, the referenced memory should be considered invalid. + * \param num_bytes the number of bytes written into the buffer + */ + virtual void done(size_t num_bytes) = 0; + + /*! + * Get the size of the underlying buffer. + * \return the number of bytes + */ + size_t size(void){ + return boost::asio::buffer_size(this->get()); + } + + /*! + * Get a pointer to the underlying buffer. + * \return a pointer into memory + */ + template T cast(void){ + return boost::asio::buffer_cast(this->get()); + } + +private: + /*! + * Get a reference to the internal mutable buffer. + * The buffer has a reference to memory and a size. + * \return a boost asio mutable buffer + */ + virtual const boost::asio::mutable_buffer &get(void) = 0; +}; + +/*! + * A zero-copy interface for transport objects. + * Provides a way to get send and receive buffers + * with memory managed by the transport object. + */ +class UHD_API zero_copy_if : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Get a new receive buffer from this transport object. + */ + virtual managed_recv_buffer::sptr get_recv_buff(void) = 0; + + /*! + * Get a new send buffer from this transport object. + */ + virtual managed_send_buffer::sptr get_send_buff(void) = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP */ diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 1fc8ce14a..13fd50f65 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -25,39 +25,74 @@ using namespace uhd::transport; /*********************************************************************** - * Smart buffer implementation for udp zerocopy none - * - * This smart buffer implemention houses a const buffer. - * When the smart buffer is deleted, the buffer is freed. - * The memory in the const buffer is allocated with new [], - * and so the destructor frees the buffer with delete []. + * Managed receive buffer implementation for udp zero-copy asio: + * Frees the memory held by the const buffer on done. **********************************************************************/ -class smart_buffer_impl : public smart_buffer{ +class managed_recv_buffer_impl : public managed_recv_buffer{ public: - smart_buffer_impl(const boost::asio::const_buffer &buff){ - _buff = buff; + managed_recv_buffer_impl(const boost::asio::const_buffer &buff) : _buff(buff){ + _done = false; } - ~smart_buffer_impl(void){ + ~managed_recv_buffer_impl(void){ + if (not _done) this->done(); + } + + void done(void){ + _done = true; delete [] boost::asio::buffer_cast(_buff); } - const boost::asio::const_buffer &get(void) const{ +private: + const boost::asio::const_buffer &get(void){ return _buff; } + const boost::asio::const_buffer _buff; + bool _done; +}; + +/*********************************************************************** + * Managed send buffer implementation for udp zero-copy asio: + * Sends and frees the memory held by the mutable buffer on done. + **********************************************************************/ +class managed_send_buffer_impl : public managed_send_buffer{ +public: + managed_send_buffer_impl( + const boost::asio::mutable_buffer &buff, + boost::asio::ip::udp::socket *socket + ) : _buff(buff){ + _done = false; + _socket = socket; + } + + ~managed_send_buffer_impl(void){ + if (not _done) this->done(0); + } + + void done(size_t num_bytes){ + _done = true; + boost::uint32_t *mem = boost::asio::buffer_cast(_buff); + _socket->send(boost::asio::buffer(mem, num_bytes)); + delete [] mem; + } + private: - boost::asio::const_buffer _buff; + const boost::asio::mutable_buffer &get(void){ + return _buff; + } + + const boost::asio::mutable_buffer _buff; + boost::asio::ip::udp::socket *_socket; + bool _done; }; /*********************************************************************** - * UDP zero copy implementation class - * - * This is the portable zero copy implementation for systems - * where a faster, platform specific solution is not available. - * - * It uses boost asio udp sockets and the standard recv() class, - * and in-fact, is not actually doing a zero-copy implementation. + * Zero Copy UDP implementation with ASIO: + * This is the portable zero copy implementation for systems + * where a faster, platform specific solution is not available. + * However, it is not a true zero copy implementation as each + * send and recv requires a copy operation to/from userspace. **********************************************************************/ class udp_zero_copy_impl : public udp_zero_copy{ public: @@ -66,8 +101,8 @@ public: ~udp_zero_copy_impl(void); //send/recv - size_t send(const boost::asio::const_buffer &buff); - smart_buffer::sptr recv(void); + managed_recv_buffer::sptr get_recv_buff(void); + managed_send_buffer::sptr get_send_buff(void); private: boost::asio::ip::udp::socket *_socket; @@ -107,31 +142,33 @@ udp_zero_copy_impl::~udp_zero_copy_impl(void){ delete _socket; } -size_t udp_zero_copy_impl::send(const boost::asio::const_buffer &buff){ - return _socket->send(boost::asio::buffer(buff)); -} - -smart_buffer::sptr udp_zero_copy_impl::recv(void){ - size_t available = 0; +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)]; //implement timeout through polling and sleeping + size_t available = 0; boost::asio::deadline_timer timer(_socket->get_io_service()); timer.expires_from_now(boost::posix_time::milliseconds(100)); while (not ((available = _socket->available()) or timer.expires_from_now().is_negative())){ boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } - //allocate memory and create buffer - boost::uint32_t *buff_mem = new boost::uint32_t[available/sizeof(boost::uint32_t)]; - boost::asio::mutable_buffer buff(buff_mem, available); - //receive only if data is available if (available){ - _socket->receive(boost::asio::buffer(buff)); + available = _socket->receive(boost::asio::buffer(buff_mem, available)); } - //create a new smart buffer to house the data - return smart_buffer::sptr(new smart_buffer_impl(buff)); + //create a new managed buffer to house the data + return managed_recv_buffer::sptr( + new managed_recv_buffer_impl(boost::asio::buffer(buff_mem, available)) + ); +} + +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)]; + return managed_send_buffer::sptr( + new managed_send_buffer_impl(boost::asio::buffer(buff_mem, 1500), _socket) + ); } size_t udp_zero_copy_impl::get_recv_buff_size(void){ diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a58e32619..a54c0a409 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -42,11 +42,13 @@ void usrp2_impl::io_init(void){ //send a small data packet so the usrp2 knows the udp source port //and the maximum number of lines (32 bit words) per packet + managed_send_buffer::sptr send_buff = _data_transport->get_send_buff(); boost::uint32_t data[2] = { htonl(USRP2_INVALID_VRT_HEADER), htonl(_max_rx_samples_per_packet) }; - _data_transport->send(asio::buffer(&data, sizeof(data))); + memcpy(send_buff->cast(), data, sizeof(data)); + send_buff->done(sizeof(data)); } #define unrolled_loop(__inst, __len){ \ @@ -127,15 +129,15 @@ static inline void usrp2_items_to_host_items( **********************************************************************/ void usrp2_impl::recv_raw(rx_metadata_t &metadata){ //do a receive - _rx_smart_buff = _data_transport->recv(); + _rx_smart_buff = _data_transport->get_recv_buff(); //unpack the vrt header - size_t num_packet_words32 = asio::buffer_size(_rx_smart_buff->get())/sizeof(boost::uint32_t); + size_t num_packet_words32 = _rx_smart_buff->size()/sizeof(boost::uint32_t); if (num_packet_words32 == 0){ _rx_copy_buff = boost::asio::buffer("", 0); return; //must exit here after setting the buffer } - const boost::uint32_t *vrt_hdr = asio::buffer_cast(_rx_smart_buff->get()); + const boost::uint32_t *vrt_hdr = _rx_smart_buff->cast(); size_t num_header_words32_out, num_payload_words32_out, packet_count_out; try{ vrt::unpack( @@ -176,11 +178,12 @@ size_t usrp2_impl::send( ){ tx_metadata_t metadata = metadata_; //rw copy to change later - boost::uint32_t tx_mem[_mtu/sizeof(boost::uint32_t)]; + transport::managed_send_buffer::sptr send_buff = _data_transport->get_send_buff(); + boost::uint32_t *tx_mem = send_buff->cast(); size_t num_samps = std::min( - asio::buffer_size(buff)/io_type.size, - size_t(_max_tx_samples_per_packet) - ); + asio::buffer_size(buff), + send_buff->size() + )/io_type.size; //kill the end of burst flag if this is a fragment if (asio::buffer_size(buff)/io_type.size < num_samps) @@ -214,7 +217,7 @@ size_t usrp2_impl::send( } //send and return number of samples - _data_transport->send(asio::buffer(tx_mem, num_packet_words32*sizeof(boost::uint32_t))); + send_buff->done(num_packet_words32*sizeof(boost::uint32_t)); return num_samps; } 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/include') 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/include') 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 389a72ef592d9826eac67ab001da5734909dbfcd Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 12 Apr 2010 16:52:18 -0700 Subject: merged unit type and gpio bank for dboard interface into one type, expanded dboard clock config api --- host/include/uhd/usrp/dboard_interface.hpp | 79 ++++++++++++++----------- host/lib/usrp/dboard/db_rfx.cpp | 2 +- host/lib/usrp/dboard_manager.cpp | 8 +-- host/lib/usrp/usrp2/dboard_interface.cpp | 93 ++++++++++++++++-------------- host/lib/usrp/usrp2/io_impl.cpp | 1 - 5 files changed, 98 insertions(+), 85 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp index 43fd1f143..2fa05c09d 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -56,7 +56,7 @@ struct UHD_API spi_config_t{ * 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 dboard dboard_interface. + * Each mboard should have a specially tailored interface for its dboard. */ class UHD_API dboard_interface{ public: @@ -64,15 +64,9 @@ public: typedef std::vector byte_vector_t; //tells the host which unit to use - enum unit_type_t{ - UNIT_TYPE_RX = 'r', - UNIT_TYPE_TX = 't' - }; - - //tell the host which gpio bank - enum gpio_bank_t{ - GPIO_BANK_RX = 'r', - GPIO_BANK_TX = 't' + enum unit_t{ + UNIT_RX = 'r', + UNIT_TX = 't' }; //possible atr registers @@ -85,54 +79,58 @@ public: /*! * 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_type_t unit, int which_dac, int value) = 0; + 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_type_t unit, int which_adc) = 0; + virtual int read_aux_adc(unit_t unit, int which_adc) = 0; /*! * Set a daughterboard ATR register. * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \param reg which ATR register to set - * \param value 16-bits, 0=FPGA output low, 1=FPGA output high + * \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(gpio_bank_t bank, atr_reg_t reg, boost::uint16_t value) = 0; + virtual void set_atr_reg(unit_t unit, atr_reg_t reg, boost::uint16_t value) = 0; /*! * Set daughterboard GPIO data direction register. * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \param value 16-bits, 0=FPGA input, 1=FPGA output + * \param unit which unit rx or tx + * \param value 16-bits, 0=FPGA input, 1=FPGA output */ - virtual void set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value) = 0; + virtual void set_gpio_ddr(unit_t unit, boost::uint16_t value) = 0; /*! - * Read daughterboard GPIO pin values + * Read daughterboard GPIO pin values. * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \return the value of the gpio bank + * \param unit which unit rx or tx + * \return the value of the gpio unit */ - virtual boost::uint16_t read_gpio(gpio_bank_t bank) = 0; + virtual boost::uint16_t read_gpio(unit_t unit) = 0; /*! - * \brief Write to I2C peripheral + * 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; /*! - * \brief Read from I2C peripheral + * 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. @@ -140,7 +138,7 @@ public: virtual byte_vector_t read_i2c(int i2c_addr, size_t num_bytes) = 0; /*! - * \brief Write data to SPI bus peripheral. + * Write data to SPI bus peripheral. * * \param unit which unit, rx or tx * \param config configuration settings @@ -148,15 +146,14 @@ public: * \param num_bits the number of bits in data */ virtual void write_spi( - unit_type_t unit, + unit_t unit, const spi_config_t &config, boost::uint32_t data, 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. + * Read and write data to SPI bus peripheral. * * \param unit which unit, rx or tx * \param config configuration settings @@ -165,23 +162,35 @@ public: * \return the data that was read */ virtual boost::uint32_t read_write_spi( - unit_type_t unit, + unit_t unit, const spi_config_t &config, boost::uint32_t data, size_t num_bits ) = 0; /*! - * \brief Get the rate of the rx dboard clock. + * Get the rate of a dboard clock. + * + * \param unit which unit rx or tx * \return the clock rate in Hz */ - virtual double get_rx_clock_rate(void) = 0; + virtual double get_clock_rate(unit_t unit) = 0; /*! - * \brief Get the rate of the tx dboard clock. - * \return the clock rate in Hz + * 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; + + /*! + * Get the enabled status of a dboard block. + * + * \param unit which unit rx or tx + * \return true for enabled */ - virtual double get_tx_clock_rate(void) = 0; + virtual bool get_clock_enabled(unit_t unit) = 0; }; }} //namespace diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 4bf931660..60f6b1a60 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -137,7 +137,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::UNIT_TX, spi_config_t::EDGE_RISE, _adf4360_regs.get_reg(addr), 24 ); diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 4cf2e5820..f8ff38c39 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -276,9 +276,9 @@ wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){ void dboard_manager_impl::set_nice_gpio_pins(void){ //std::cout << "Set nice GPIO pins" << std::endl; - _interface->set_gpio_ddr(dboard_interface::GPIO_BANK_RX, 0x0000); //all inputs - _interface->set_atr_reg(dboard_interface::GPIO_BANK_RX, dboard_interface::ATR_REG_IDLE, 0x0000); //all low + _interface->set_gpio_ddr(dboard_interface::UNIT_RX, 0x0000); //all inputs + _interface->set_atr_reg(dboard_interface::UNIT_RX, dboard_interface::ATR_REG_IDLE, 0x0000); //all low - _interface->set_gpio_ddr(dboard_interface::GPIO_BANK_TX, 0x0000); //all inputs - _interface->set_atr_reg(dboard_interface::GPIO_BANK_TX, dboard_interface::ATR_REG_IDLE, 0x0000); //all low + _interface->set_gpio_ddr(dboard_interface::UNIT_TX, 0x0000); //all inputs + _interface->set_atr_reg(dboard_interface::UNIT_TX, dboard_interface::ATR_REG_IDLE, 0x0000); //all low } diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index d10cfa37e..db8679b9b 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -29,28 +29,29 @@ public: usrp2_dboard_interface(usrp2_impl *impl); ~usrp2_dboard_interface(void); - void write_aux_dac(unit_type_t, int, int); - int read_aux_adc(unit_type_t, int); + void write_aux_dac(unit_t, int, int); + int read_aux_adc(unit_t, int); - void set_atr_reg(gpio_bank_t, atr_reg_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t); - boost::uint16_t read_gpio(gpio_bank_t); + 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_rx_clock_rate(void); - double get_tx_clock_rate(void); + double get_clock_rate(unit_t); + void set_clock_enabled(unit_t, bool); + bool get_clock_enabled(unit_t); void write_spi( - unit_type_t unit, + unit_t unit, const spi_config_t &config, boost::uint32_t data, size_t num_bits ); boost::uint32_t read_write_spi( - unit_type_t unit, + unit_t unit, const spi_config_t &config, boost::uint32_t data, size_t num_bits @@ -89,57 +90,61 @@ usrp2_dboard_interface::~usrp2_dboard_interface(void){ } /*********************************************************************** - * Clock Rates + * Clocks **********************************************************************/ -double usrp2_dboard_interface::get_rx_clock_rate(void){ +double usrp2_dboard_interface::get_clock_rate(unit_t){ return _impl->get_master_clock_freq(); } -double usrp2_dboard_interface::get_tx_clock_rate(void){ - return _impl->get_master_clock_freq(); +void usrp2_dboard_interface::set_clock_enabled(unit_t, bool){ + //TODO +} + +bool usrp2_dboard_interface::get_clock_enabled(unit_t){ + return false; //TODO } /*********************************************************************** * GPIO **********************************************************************/ -static int bank_to_shift(dboard_interface::gpio_bank_t bank){ - switch(bank){ - case dboard_interface::GPIO_BANK_RX: return 0; - case dboard_interface::GPIO_BANK_TX: return 16; +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 gpio bank type"); + throw std::runtime_error("unknown unit type"); } -void usrp2_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){ +void usrp2_dboard_interface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ _ddr_shadow = \ - (_ddr_shadow & ~(0xffff << bank_to_shift(bank))) | - (boost::uint32_t(value) << bank_to_shift(bank)); + (_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(gpio_bank_t bank){ - return boost::uint16_t(_impl->peek32(FR_GPIO_IO) >> bank_to_shift(bank)); +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(gpio_bank_t bank, atr_reg_t atr, boost::uint16_t value){ - //define mapping of bank to atr regs to register address +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< - gpio_bank_t, uhd::dict - > bank_to_atr_to_addr = boost::assign::map_list_of - (GPIO_BANK_RX, boost::assign::map_list_of + 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) ) - (GPIO_BANK_TX, boost::assign::map_list_of + (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(bank_to_atr_to_addr[bank][atr], value); + _impl->poke16(unit_to_atr_to_addr[unit][atr], value); } /*********************************************************************** @@ -151,30 +156,30 @@ void usrp2_dboard_interface::set_atr_reg(gpio_bank_t bank, atr_reg_t atr, boost: * \param unit the dboard interface unit type enum * \return an over the wire representation */ -static boost::uint8_t unit_to_otw_dev(dboard_interface::unit_type_t unit){ +static boost::uint8_t unit_to_otw_spi_dev(dboard_interface::unit_t unit){ switch(unit){ - case dboard_interface::UNIT_TYPE_TX: return SPI_SS_TX_DB; - case dboard_interface::UNIT_TYPE_RX: return SPI_SS_RX_DB; + 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 type"); + throw std::invalid_argument("unknown unit type"); } void usrp2_dboard_interface::write_spi( - unit_type_t unit, + unit_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*/); + _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_type_t unit, + unit_t unit, const spi_config_t &config, boost::uint32_t data, size_t num_bits ){ - return _impl->transact_spi(unit_to_otw_dev(unit), config, data, num_bits, true /*rb*/); + return _impl->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); } /*********************************************************************** @@ -228,15 +233,15 @@ dboard_interface::byte_vector_t usrp2_dboard_interface::read_i2c(int i2c_addr, s * \param unit the dboard interface unit type enum * \return an over the wire representation */ -static boost::uint8_t unit_to_otw(dboard_interface::unit_type_t unit){ +static boost::uint8_t unit_to_otw(dboard_interface::unit_t unit){ switch(unit){ - case dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX; - case dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX; + 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 type"); + throw std::invalid_argument("unknown unit type"); } -void usrp2_dboard_interface::write_aux_dac(unit_type_t unit, int which, int value){ +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); @@ -249,7 +254,7 @@ void usrp2_dboard_interface::write_aux_dac(unit_type_t unit, int which, int valu ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_DAC_DUDE); } -int usrp2_dboard_interface::read_aux_adc(unit_type_t unit, int which){ +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); diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a760cbe3d..87fc88ceb 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -18,7 +18,6 @@ #include "usrp2_impl.hpp" #include #include -#include #include using namespace uhd; -- 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/include') 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 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/include') 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 From 36d81c56583f37e5304db885cc82637e30bff8f5 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 14 Apr 2010 11:47:55 -0700 Subject: renamed dxc to dsp for tune result --- host/include/uhd/types/tune_result.hpp | 6 +++--- host/include/uhd/usrp/CMakeLists.txt | 2 +- host/lib/types.cpp | 4 ++-- host/lib/usrp/tune_helper.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/types/tune_result.hpp b/host/include/uhd/types/tune_result.hpp index 31742e1af..c428a7692 100644 --- a/host/include/uhd/types/tune_result.hpp +++ b/host/include/uhd/types/tune_result.hpp @@ -26,15 +26,15 @@ namespace uhd{ * The tune result struct holds result of a 2-phase tuning: * The struct hold the result of tuning the dboard as * the target and actual intermediate frequency. - * The struct hold the result of tuning the DDC/DUC as + * The struct hold the result of tuning the DSP as * the target and actual digital converter frequency. * It also tell us weather or not the spectrum is inverted. */ struct UHD_API tune_result_t{ double target_inter_freq; double actual_inter_freq; - double target_dxc_freq; - double actual_dxc_freq; + double target_dsp_freq; + double actual_dsp_freq; bool spectrum_inverted; tune_result_t(void); }; diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt index 9140d98ca..23758041c 100644 --- a/host/include/uhd/usrp/CMakeLists.txt +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -27,7 +27,7 @@ INSTALL(FILES #### dboard headers ### dboard_base.hpp dboard_id.hpp - dboard_interface.hpp + dboard_iface.hpp dboard_manager.hpp ### usrp headers ### diff --git a/host/lib/types.cpp b/host/lib/types.cpp index cd688e73d..0fd2522cf 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -55,8 +55,8 @@ freq_range_t::freq_range_t(double min_, double max_){ tune_result_t::tune_result_t(void){ target_inter_freq = 0.0; actual_inter_freq = 0.0; - target_dxc_freq = 0.0; - actual_dxc_freq = 0.0; + target_dsp_freq = 0.0; + actual_dsp_freq = 0.0; spectrum_inverted = false; } diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 2fb15064c..a7d695b4e 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -74,8 +74,8 @@ static tune_result_t tune_xx_subdev_and_dxc( tune_result_t tune_result; tune_result.target_inter_freq = target_inter_freq; tune_result.actual_inter_freq = actual_inter_freq; - tune_result.target_dxc_freq = target_dxc_freq; - tune_result.actual_dxc_freq = actual_dxc_freq; + tune_result.target_dsp_freq = target_dxc_freq; + tune_result.actual_dsp_freq = actual_dxc_freq; tune_result.spectrum_inverted = inverted; return tune_result; } -- cgit v1.2.3 From 5ac7a9e5d0377a0cb34b88692fa74b5cc0ce545d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 14 Apr 2010 14:57:12 -0700 Subject: removed clock rate prop, we dont need to expose that since ticks are in nsecs --- host/include/uhd/usrp/mboard_props.hpp | 1 - host/include/uhd/usrp/simple_usrp.hpp | 1 - host/lib/usrp/simple_usrp.cpp | 4 ---- host/lib/usrp/usrp2/mboard_impl.cpp | 4 ---- 4 files changed, 10 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp index 55c11b822..7ff454472 100644 --- a/host/include/uhd/usrp/mboard_props.hpp +++ b/host/include/uhd/usrp/mboard_props.hpp @@ -31,7 +31,6 @@ namespace uhd{ namespace usrp{ enum mboard_prop_t{ MBOARD_PROP_NAME = 'n', //ro, std::string MBOARD_PROP_OTHERS = 'o', //ro, prop_names_t - MBOARD_PROP_CLOCK_RATE = 'c', //ro, double MBOARD_PROP_RX_DSP = 'd', //ro, wax::obj MBOARD_PROP_RX_DSP_NAMES = 'D', //ro, prop_names_t MBOARD_PROP_TX_DSP = 'u', //ro, wax::obj diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp index 6f74a406b..c4e0338f7 100644 --- a/host/include/uhd/usrp/simple_usrp.hpp +++ b/host/include/uhd/usrp/simple_usrp.hpp @@ -52,7 +52,6 @@ public: virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; virtual void set_clock_config(const clock_config_t &clock_config) = 0; - virtual double get_clock_rate(void) = 0; /******************************************************************* * RX methods diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp index fb3cc8eec..11ee3a798 100644 --- a/host/lib/usrp/simple_usrp.cpp +++ b/host/lib/usrp/simple_usrp.cpp @@ -83,10 +83,6 @@ public: _mboard[MBOARD_PROP_CLOCK_CONFIG] = clock_config; } - double get_clock_rate(void){ - return _mboard[MBOARD_PROP_CLOCK_RATE].as(); - } - /******************************************************************* * RX methods ******************************************************************/ diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 1521de1fe..d7728238c 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -225,10 +225,6 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); return; - case MBOARD_PROP_CLOCK_RATE: - val = double(get_master_clock_freq()); - return; - case MBOARD_PROP_RX_DSP: ASSERT_THROW(name == ""); val = _rx_dsp_proxy->get_link(); -- cgit v1.2.3 From f57f616cfd6406cd67681813d464695c8c160f9e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 14 Apr 2010 17:19:27 -0700 Subject: Added gain control to rfx. Switched string constants to caps (gains, antennas, subdevs). Made dboard interface for aux dac and adc use volts. --- host/include/uhd/usrp/dboard_iface.hpp | 8 +++--- host/include/uhd/utils/algorithm.hpp | 6 +++- host/lib/usrp/dboard/db_basic_and_lf.cpp | 6 ++-- host/lib/usrp/dboard/db_rfx.cpp | 47 ++++++++++++++++++++++++-------- host/lib/usrp/usrp2/dboard_iface.cpp | 13 +++++---- 5 files changed, 55 insertions(+), 25 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp index ca40bf778..71c7be200 100644 --- a/host/include/uhd/usrp/dboard_iface.hpp +++ b/host/include/uhd/usrp/dboard_iface.hpp @@ -82,18 +82,18 @@ public: * * \param unit which unit rx or tx * \param which_dac the dac index 0, 1, 2, 3... - * \param value the value to write + * \param value the value in volts */ - virtual void write_aux_dac(unit_t unit, int which_dac, int value) = 0; + virtual void write_aux_dac(unit_t unit, int which_dac, float 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 + * \return the value in volts */ - virtual int read_aux_adc(unit_t unit, int which_adc) = 0; + virtual float read_aux_adc(unit_t unit, int which_adc) = 0; /*! * Set a daughterboard ATR register. diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp index 6635c8a4a..cc935b226 100644 --- a/host/include/uhd/utils/algorithm.hpp +++ b/host/include/uhd/utils/algorithm.hpp @@ -49,12 +49,16 @@ namespace std{ return has(iterable.begin(), iterable.end(), elem); } - template T signum(T n){ + template T signum(T n){ if (n < 0) return -1; if (n > 0) return 1; return 0; } + template T clip(T val, T1 minVal, T2 maxVal){ + return std::min(std::max(val, minVal), maxVal); + } + }//namespace std #endif /* INCLUDED_UHD_UTILS_ALGORITHM_HPP */ diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 5a992339b..aad2398d8 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -77,9 +77,9 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){ UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){ dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX"); - dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("ab")("a")("b")); + dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("AB")("A")("B")); dboard_manager::register_dboard(0x000e, &make_lf_tx, "LF TX"); - dboard_manager::register_dboard(0x000f, &make_lf_rx, "LF RX", list_of("ab")("a")("b")); + dboard_manager::register_dboard(0x000f, &make_lf_rx, "LF RX", list_of("AB")("A")("B")); } /*********************************************************************** @@ -139,7 +139,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_QUADRATURE: - val = (get_subdev_name() == "ab"); //only quadrature in ab mode + val = (get_subdev_name() == "AB"); //only quadrature in ab mode return; case SUBDEV_PROP_IQ_SWAPPED: diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index b86546248..3f318d3ed 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,8 @@ using namespace boost::assign; /*********************************************************************** * The RFX series of dboards **********************************************************************/ +static const float _max_rx_pga0_gain = 45; + class rfx_xcvr : public xcvr_dboard_base{ public: rfx_xcvr(ctor_args_t const& args, const freq_range_t &freq_range); @@ -140,7 +143,7 @@ rfx_xcvr::rfx_xcvr( //set some default values set_lo_freq((_freq_range.min + _freq_range.max)/2.0); - set_rx_ant("rx2"); + set_rx_ant("RX2"); set_rx_pga0_gain(0); } @@ -152,20 +155,40 @@ rfx_xcvr::~rfx_xcvr(void){ * Helper Methods **********************************************************************/ void rfx_xcvr::set_lo_freq(double freq){ - /* NOP */ + //TODO !!! reload_adf4360_regs(); } void rfx_xcvr::set_rx_ant(const std::string &ant){ + //validate input + ASSERT_THROW(ant == "TX/RX" or ant == "RX2"); + //set the rx atr regs that change with antenna setting this->get_iface()->set_atr_reg( dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, - POWER_UP | MIX_EN | ((ant == "tx/rx")? ANT_TXRX : ANT_RX2) + POWER_UP | MIX_EN | ((ant == "TX/RX")? ANT_TXRX : ANT_RX2) ); + + //shadow the setting + _rx_ant = ant; } void rfx_xcvr::set_rx_pga0_gain(float gain){ - /* NOP */ + //clip the input + gain = std::clip(gain, 0, _max_rx_pga0_gain); + + //voltage level constants + static const float max_volts = .2, min_volts = 1.2; + static const float slope = (max_volts-min_volts)/_max_rx_pga0_gain; + + //calculate the voltage for the aux dac + float dac_volts = gain*slope + min_volts; + + //write the new voltage to the aux dac + this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, 1, dac_volts); + + //shadow the setting (does not account for precision loss) + _rx_pga0_gain = gain; } void rfx_xcvr::reload_adf4360_regs(void){ @@ -201,15 +224,17 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_GAIN: + ASSERT_THROW(name == "PGA0"); val = _rx_pga0_gain; return; case SUBDEV_PROP_GAIN_RANGE: - val = gain_range_t(0, 45, float(0.022)); + ASSERT_THROW(name == "PGA0"); + val = gain_range_t(0, _max_rx_pga0_gain, float(0.022)); return; case SUBDEV_PROP_GAIN_NAMES: - val = prop_names_t(1, "pga0"); + val = prop_names_t(1, "PGA0"); return; case SUBDEV_PROP_FREQ: @@ -225,7 +250,7 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_ANTENNA_NAMES:{ - prop_names_t ants = list_of("tx/rx")("rx2"); + prop_names_t ants = list_of("TX/RX")("RX2"); val = ants; } return; @@ -256,7 +281,7 @@ void rfx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ switch(key.as()){ case SUBDEV_PROP_GAIN: - ASSERT_THROW(name == "pga0"); + ASSERT_THROW(name == "PGA0"); set_rx_pga0_gain(val.as()); return; @@ -309,11 +334,11 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_ANTENNA: - val = std::string("tx/rx"); + val = std::string("TX/RX"); return; case SUBDEV_PROP_ANTENNA_NAMES: - val = prop_names_t(1, "tx/rx"); + val = prop_names_t(1, "TX/RX"); return; case SUBDEV_PROP_QUADRATURE: @@ -347,7 +372,7 @@ void rfx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ANTENNA: //its always set to tx/rx, so we only allow this value - ASSERT_THROW(val.as() == "tx/rx"); + ASSERT_THROW(val.as() == "TX/RX"); return; default: diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index f77dfc495..2859a7981 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -22,6 +22,7 @@ #include #include #include //htonl and ntohl +#include #include using namespace uhd::usrp; @@ -31,8 +32,8 @@ 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 write_aux_dac(unit_t, int, float); + float 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); @@ -251,20 +252,20 @@ static boost::uint8_t unit_to_otw(dboard_iface::unit_t unit){ throw std::invalid_argument("unknown unit type"); } -void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, int value){ +void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, float 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); + out_data.data.aux_args.value = htonl(boost::math::iround(4095*value/3.3)); //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){ +float 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); @@ -274,5 +275,5 @@ int usrp2_dboard_iface::read_aux_adc(unit_t unit, int 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); + return float(3.3*ntohl(in_data.data.aux_args.value)/4095); } -- cgit v1.2.3 From b9e7e38a84046fc345bcac12611205fbea0bef19 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 14 Apr 2010 17:42:39 -0700 Subject: removed some windows warnings --- host/include/uhd/utils/algorithm.hpp | 4 ++-- host/lib/ic_reg_maps/gen_ad9777_regs.py | 6 +++--- host/lib/usrp/dboard/db_rfx.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp index cc935b226..8fe9cde82 100644 --- a/host/include/uhd/utils/algorithm.hpp +++ b/host/include/uhd/utils/algorithm.hpp @@ -55,8 +55,8 @@ namespace std{ return 0; } - template T clip(T val, T1 minVal, T2 maxVal){ - return std::min(std::max(val, minVal), maxVal); + template T clip(T val, T minVal, T maxVal){ + return std::min(std::max(val, minVal), maxVal); } }//namespace std diff --git a/host/lib/ic_reg_maps/gen_ad9777_regs.py b/host/lib/ic_reg_maps/gen_ad9777_regs.py index 135d5c724..6077b61b6 100644 --- a/host/lib/ic_reg_maps/gen_ad9777_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9777_regs.py @@ -129,13 +129,13 @@ struct ad9777_regs_t{ #end for } - boost::uint32_t get_reg(boost::uint8_t addr){ - boost::uint32_t reg = 0; + boost::uint8_t get_reg(boost::uint8_t addr){ + boost::uint8_t reg = 0; switch(addr){ #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) case $addr: #for $reg in filter(lambda r: r.get_addr() == addr, $regs) - reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); + reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); #end for break; #end for diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 3f318d3ed..11a689b20 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -175,10 +175,10 @@ void rfx_xcvr::set_rx_ant(const std::string &ant){ void rfx_xcvr::set_rx_pga0_gain(float gain){ //clip the input - gain = std::clip(gain, 0, _max_rx_pga0_gain); + gain = std::clip(gain, 0, _max_rx_pga0_gain); //voltage level constants - static const float max_volts = .2, min_volts = 1.2; + static const float max_volts = float(.2), min_volts = float(1.2); static const float slope = (max_volts-min_volts)/_max_rx_pga0_gain; //calculate the voltage for the aux dac -- cgit v1.2.3