diff options
Diffstat (limited to 'host/lib/usrp/b200/b200_impl.hpp')
-rw-r--r-- | host/lib/usrp/b200/b200_impl.hpp | 103 |
1 files changed, 87 insertions, 16 deletions
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp index 65796d1a4..cbd51426d 100644 --- a/host/lib/usrp/b200/b200_impl.hpp +++ b/host/lib/usrp/b200/b200_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright 2012-2013 Ettus Research LLC +// Copyright 2012-2015 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,6 +22,7 @@ #include "b200_uart.hpp" #include "b200_cores.hpp" #include "ad9361_ctrl.hpp" +#include "ad936x_manager.hpp" #include "adf4001_ctrl.hpp" #include "rx_vita_core_3000.hpp" #include "tx_vita_core_3000.hpp" @@ -43,18 +44,13 @@ #include <uhd/usrp/gps_ctrl.hpp> #include <uhd/transport/usb_zero_copy.hpp> #include <uhd/transport/bounded_buffer.hpp> +#include <boost/assign.hpp> #include <boost/weak_ptr.hpp> #include "recv_packet_demuxer_3000.hpp" -static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 7; +static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 8; static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0; -static const boost::uint16_t B200_FPGA_COMPAT_NUM = 8; +static const boost::uint16_t B200_FPGA_COMPAT_NUM = 9; static const double B200_BUS_CLOCK_RATE = 100e6; -static const double B200_DEFAULT_TICK_RATE = 32e6; -static const double B200_DEFAULT_FREQ = 100e6; // Hz -static const double B200_DEFAULT_DECIM = 128; -static const double B200_DEFAULT_INTERP = 128; -static const double B200_DEFAULT_RX_GAIN = 0; // dB -static const double B200_DEFAULT_TX_GAIN = 0; // dB static const boost::uint32_t B200_GPSDO_ST_NONE = 0x83; static const size_t B200_MAX_RATE_USB2 = 53248000; // bytes/s static const size_t B200_MAX_RATE_USB3 = 500000000; // bytes/s @@ -82,23 +78,48 @@ static const boost::uint32_t B200_RX_GPS_UART_SID = FLIP_SID(B200_TX_GPS_UART_SI static const boost::uint32_t B200_LOCAL_CTRL_SID = 0x00000040; static const boost::uint32_t B200_LOCAL_RESP_SID = FLIP_SID(B200_LOCAL_CTRL_SID); -/*********************************************************************** - * The B200 Capability Constants - **********************************************************************/ +static const unsigned char B200_USB_CTRL_RECV_INTERFACE = 4; +static const unsigned char B200_USB_CTRL_RECV_ENDPOINT = 8; +static const unsigned char B200_USB_CTRL_SEND_INTERFACE = 3; +static const unsigned char B200_USB_CTRL_SEND_ENDPOINT = 4; + +static const unsigned char B200_USB_DATA_RECV_INTERFACE = 2; +static const unsigned char B200_USB_DATA_RECV_ENDPOINT = 6; +static const unsigned char B200_USB_DATA_SEND_INTERFACE = 1; +static const unsigned char B200_USB_DATA_SEND_ENDPOINT = 2; + +/* + * VID/PID pairs for all B2xx products + */ +static std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> b200_vid_pid_pairs = + boost::assign::list_of + (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200_PRODUCT_ID)) + (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID)) + (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID)) + ; + +b200_type_t get_b200_type(const uhd::usrp::mboard_eeprom_t &mb_eeprom); +std::vector<uhd::transport::usb_device_handle::sptr> get_b200_device_handles(const uhd::device_addr_t &hint); //! Implementation guts class b200_impl : public uhd::device { public: //structors - b200_impl(const uhd::device_addr_t &); + b200_impl(const uhd::device_addr_t &, uhd::transport::usb_device_handle::sptr &handle); ~b200_impl(void); //the io interface uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args); uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args); bool recv_async_msg(uhd::async_metadata_t &, double); - void check_streamer_args(const uhd::stream_args_t &args, double tick_rate, const char* direction = NULL); + + //! Check that the combination of stream args and tick rate are valid. + // + // Basically figures out the arguments for enforce_tick_rate_limits() + // and calls said method. If arguments are invalid, throws a + // uhd::value_error. + void check_streamer_args(const uhd::stream_args_t &args, double tick_rate, const std::string &direction = ""); private: b200_type_t _b200_type; @@ -108,6 +129,7 @@ private: b200_iface::sptr _iface; radio_ctrl_core_3000::sptr _local_ctrl; uhd::usrp::ad9361_ctrl::sptr _codec_ctrl; + uhd::usrp::ad936x_manager::sptr _codec_mgr; b200_local_spi_core::sptr _spi_iface; boost::shared_ptr<uhd::usrp::adf4001_ctrl> _adf4001_iface; uhd::gps_ctrl::sptr _gps; @@ -136,7 +158,6 @@ private: boost::optional<uhd::msg_task::msg_type_t> handle_async_task(uhd::transport::zero_copy_if::sptr, boost::shared_ptr<AsyncTaskData>); void register_loopback_self_test(uhd::wb_iface::sptr iface); - void codec_loopback_self_test(uhd::wb_iface::sptr iface); void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &); void check_fw_compat(void); void check_fpga_compat(void); @@ -154,6 +175,7 @@ private: { radio_ctrl_core_3000::sptr ctrl; gpio_core_200_32wo::sptr atr; + gpio_core_200::sptr fp_gpio; time_core_3000::sptr time64; rx_vita_core_3000::sptr framer; rx_dsp_core_3000::sptr ddc; @@ -200,14 +222,63 @@ private: void update_enables(void); void update_atrs(void); + boost::uint32_t get_fp_gpio(gpio_core_200::sptr); + void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t); + double _tick_rate; double get_tick_rate(void){return _tick_rate;} double set_tick_rate(const double rate); + + /*! \brief Choose a tick rate (master clock rate) that works well for the given sampling rate. + * + * This function will try and choose a master clock rate automatically. + * See the function definition for details on the algorithm. + * + * The chosen tick rate is the largest multiple of two that is smaler + * than the max tick rate. + * The base rate is either given explicitly, or is the lcm() of the tx + * and rx sampling rates. In that case, it reads the rates directly + * from the property tree. It also tries to guess the number of channels + * (for the max possible tick rate) by checking the available streamers. + * This value, too, can explicitly be given. + * + * \param rate If this is given, it will be used as a minimum rate, or + * argument to lcm(). + * \param tree_dsp_path The sampling rate from this property tree path + * will be ignored. + * \param num_chans If given, specifies the number of channels. + */ + void set_auto_tick_rate( + const double rate=0, + const uhd::fs_path &tree_dsp_path="", + size_t num_chans=0 + ); + void update_tick_rate(const double); - void enforce_tick_rate_limits(size_t chan_count, double tick_rate, const char* direction = NULL); + + /*! Check if \p tick_rate works with \p chan_count channels. + * + * Throws a uhd::value_error if not. + */ + void enforce_tick_rate_limits(size_t chan_count, double tick_rate, const std::string &direction = ""); void check_tick_rate_with_current_streamers(double rate); + /*! Return the max number of channels on active rx_streamer or tx_streamer objects associated with this device. + * + * \param direction Set to "TX" to only check tx_streamers, "RX" to only check + * rx_streamers. Any other value will check if \e any active + * streamers are available. + * \return Return the number of tx streamers (direction=="TX"), the number of rx + * streamers (direction=="RX") or the total number of streamers. + */ + size_t max_chan_count(const std::string &direction=""); + + //! Coercer, attached to the "rate/value" property on the rx dsps. + double coerce_rx_samp_rate(rx_dsp_core_3000::sptr, size_t, const double); void update_rx_samp_rate(const size_t, const double); + + //! Coercer, attached to the "rate/value" property on the tx dsps. + double coerce_tx_samp_rate(tx_dsp_core_3000::sptr, size_t, const double); void update_tx_samp_rate(const size_t, const double); }; |