diff options
Diffstat (limited to 'host/include')
-rw-r--r-- | host/include/uhd/transport/CMakeLists.txt | 3 | ||||
-rw-r--r-- | host/include/uhd/transport/convert_types.hpp | 59 | ||||
-rw-r--r-- | host/include/uhd/transport/smart_buffer.hpp | 45 | ||||
-rw-r--r-- | host/include/uhd/transport/udp_zero_copy.hpp | 28 | ||||
-rw-r--r-- | host/include/uhd/transport/vrt.hpp | 10 | ||||
-rw-r--r-- | host/include/uhd/transport/zero_copy.hpp | 133 | ||||
-rw-r--r-- | host/include/uhd/types/metadata.hpp | 1 | ||||
-rw-r--r-- | host/include/uhd/types/time_spec.hpp | 36 | ||||
-rw-r--r-- | host/include/uhd/usrp/dboard_interface.hpp | 165 | ||||
-rw-r--r-- | host/include/uhd/usrp/subdev_props.hpp | 2 |
10 files changed, 316 insertions, 166 deletions
diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 14b5ccd29..4cefffa24 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -17,10 +17,11 @@ INSTALL(FILES + convert_types.hpp 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/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 <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP +#define INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP + +#include <uhd/config.hpp> +#include <uhd/types/io_type.hpp> +#include <uhd/types/otw_type.hpp> + +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/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 <http://www.gnu.org/licenses/>. -// - -#ifndef INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP -#define INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP - -#include <boost/asio/buffer.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> - -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<smart_buffer> 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 <uhd/config.hpp> -#include <uhd/transport/smart_buffer.hpp> -#include <boost/asio/buffer.hpp> -#include <boost/utility.hpp> +#include <uhd/transport/zero_copy.hpp> #include <boost/shared_ptr.hpp> 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<udp_zero_copy> 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/vrt.hpp b/host/include/uhd/transport/vrt.hpp index 04945b347..f2f42f9eb 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. @@ -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/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 <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP +#define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP + +#include <uhd/config.hpp> +#include <boost/asio/buffer.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> + +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<managed_recv_buffer> 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 <class T> T cast(void){ + return boost::asio::buffer_cast<T>(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<managed_send_buffer> 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 <class T> T cast(void){ + return boost::asio::buffer_cast<T>(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<zero_copy_if> 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/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 <uhd/config.hpp> +#include <boost/cstdint.hpp> #include <uhd/types/time_spec.hpp> 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 <uhd/config.hpp> #include <boost/cstdint.hpp> -#include <boost/date_time/posix_time/posix_time.hpp> 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/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp index b3bab131d..2fa05c09d 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -25,11 +25,38 @@ 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 dboard dboard_interface. + * Each mboard should have a specially tailored interface for its dboard. */ class UHD_API dboard_interface{ public: @@ -37,27 +64,9 @@ public: typedef std::vector<boost::uint8_t> byte_vector_t; //tells the host which unit to use - enum unit_type_t{ - UNIT_TYPE_RX = 'r', - 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' - }; - - //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 @@ -68,60 +77,60 @@ 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 * \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. @@ -129,63 +138,59 @@ 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 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_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; /*! - * \brief Read data to SPI bus peripheral. + * Read and write 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 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_spi(spi_dev_t dev, spi_edge_t edge, size_t num_bytes); + virtual boost::uint32_t read_write_spi( + 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. + * Get the rate of a dboard clock. * - * \param dev which spi device - * \param edge args for format - * \param buf the data to write - * \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); - - /*! - * \brief Get the rate of the rx dboard clock. - * \return the clock rate + * \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 + * Enable or disable a dboard clock. + * + * \param unit which unit rx or tx + * \param enb true for enabled */ - virtual double get_tx_clock_rate(void) = 0; + virtual void set_clock_enabled(unit_t unit, bool enb) = 0; -private: /*! - * \brief Read and write data to SPI bus peripheral. + * Get the enabled status of a dboard block. * - * \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 + * \param unit which unit rx or tx + * \return true for enabled */ - virtual byte_vector_t transact_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf, - bool readback - ) = 0; + virtual bool get_clock_enabled(unit_t unit) = 0; }; }} //namespace diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp index d35793c6b..cd6b14ef5 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 |