diff options
| author | Josh Blum <josh@joshknows.com> | 2010-05-18 17:46:34 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2010-05-18 17:46:34 -0700 | 
| commit | 21e9cf4bece884ced5b7294e012be971e941c511 (patch) | |
| tree | 634f4b8b27d9dc8a6ebfc2ab731bddf62d0bbe22 /host/lib/usrp | |
| parent | 7c98884eda041b676584059ca3a63b11f1bbd505 (diff) | |
| parent | 4ea8822a50073b01ede9e0b0f7c8c713767ea1b8 (diff) | |
| download | uhd-21e9cf4bece884ced5b7294e012be971e941c511.tar.gz uhd-21e9cf4bece884ced5b7294e012be971e941c511.tar.bz2 uhd-21e9cf4bece884ced5b7294e012be971e941c511.zip | |
Merge branch 'work'
Diffstat (limited to 'host/lib/usrp')
| -rw-r--r-- | host/lib/usrp/usrp2/clock_ctrl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 162 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 50 | 
5 files changed, 70 insertions, 160 deletions
| diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index db8d8a886..4c5207203 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -79,7 +79,9 @@ public:          _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; +        _ad9510_regs.bypass_divider_out7 = 1;          this->write_reg(0x43); +        this->write_reg(0x57);          this->update_regs();      } @@ -88,7 +90,9 @@ public:          _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; +        _ad9510_regs.bypass_divider_out6 = 1;          this->write_reg(0x42); +        this->write_reg(0x55);          this->update_regs();      } @@ -130,7 +134,9 @@ private:              ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_NORMAL :              ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_SAFE_PD;          _ad9510_regs.output_level_lvpecl_out3 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT3_810MV; +        _ad9510_regs.bypass_divider_out3 = 1;          this->write_reg(0x3F); +        this->write_reg(0x4F);          this->update_regs();      } @@ -139,7 +145,9 @@ private:          _ad9510_regs.power_down_lvds_cmos_out4 = enb? 0 : 1;          _ad9510_regs.lvds_cmos_select_out4 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS;          _ad9510_regs.output_level_lvds_out4 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA; +        _ad9510_regs.bypass_divider_out4 = 1;          this->write_reg(0x40); +        this->write_reg(0x51);          this->update_regs();      } diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 7c9d003ce..b6ab919e7 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -31,16 +31,15 @@ namespace asio = boost::asio;   * 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; +    //setup rx otw type +    _rx_otw_type.width = 16; +    _rx_otw_type.shift = 0; +    _rx_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; -    //initially empty copy buffer -    _rx_copy_buff = asio::buffer("", 0); - -    //init the expected rx seq number -    _rx_stream_id_to_packet_seq[0] = 0; +    //setup tx otw type +    _tx_otw_type.width = 16; +    _tx_otw_type.shift = 0; +    _tx_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN;      //send a small data packet so the usrp2 knows the udp source port      managed_send_buffer::sptr send_buff = _data_transport->get_send_buff(); @@ -49,7 +48,8 @@ void usrp2_impl::io_init(void){      send_buff->done(sizeof(data));      //setup RX DSP regs -    _iface->poke32(FR_RX_CTRL_NSAMPS_PER_PKT, _max_rx_samples_per_packet); +    std::cout << "RX samples per packet: " << get_max_recv_samps_per_packet() << std::endl; +    _iface->poke32(FR_RX_CTRL_NSAMPS_PER_PKT, get_max_recv_samps_per_packet());      _iface->poke32(FR_RX_CTRL_NCHANNELS, 1);      _iface->poke32(FR_RX_CTRL_CLEAR_OVERRUN, 1); //reset      _iface->poke32(FR_RX_CTRL_VRT_HEADER, 0 @@ -63,98 +63,22 @@ void usrp2_impl::io_init(void){  }  /*********************************************************************** - * Receive Raw Data - **********************************************************************/ -void usrp2_impl::recv_raw(rx_metadata_t &metadata){ -    //do a receive -    _rx_smart_buff = _data_transport->get_recv_buff(); - -    //unpack the vrt header -    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 = _rx_smart_buff->cast<const boost::uint32_t *>(); -    size_t num_header_words32_out, num_payload_words32_out, packet_count_out; -    try{ -        vrt::unpack( -            metadata,                //output -            vrt_hdr,                 //input -            num_header_words32_out,  //output -            num_payload_words32_out, //output -            num_packet_words32,      //input -            packet_count_out,        //output -            get_master_clock_freq() -        ); -    }catch(const std::exception &e){ -        std::cerr << "bad vrt header: " << e.what() << std::endl; -        _rx_copy_buff = boost::asio::buffer("", 0); -        return; //must exit here after setting the buffer -    } - -    //handle the packet count / sequence number -    size_t expected_packet_count = _rx_stream_id_to_packet_seq[metadata.stream_id]; -    if (packet_count_out != expected_packet_count){ -        std::cerr << "S" << (packet_count_out - expected_packet_count)%16; -    } -    _rx_stream_id_to_packet_seq[metadata.stream_id] = (packet_count_out+1)%16; - -    //setup the rx buffer to point to the data -    _rx_copy_buff = asio::buffer( -        vrt_hdr + num_header_words32_out, -        num_payload_words32_out*sizeof(boost::uint32_t) -    ); -} - -/***********************************************************************   * Send Data   **********************************************************************/  size_t usrp2_impl::send(      const asio::const_buffer &buff, -    const tx_metadata_t &metadata_, -    const io_type_t &io_type +    const tx_metadata_t &metadata, +    const io_type_t &io_type, +    send_mode_t send_mode  ){ -    tx_metadata_t metadata = metadata_; //rw copy to change later - -    transport::managed_send_buffer::sptr send_buff = _data_transport->get_send_buff(); -    boost::uint32_t *tx_mem = send_buff->cast<boost::uint32_t *>(); -    size_t num_samps = std::min(std::min( -        asio::buffer_size(buff)/io_type.size, -        size_t(_max_tx_samples_per_packet)), -        send_buff->size()/io_type.size +    return vrt_packet_handler::send( +        _packet_handler_send_state, //last state of the send handler +        buff, metadata, send_mode,  //buffer to empty and samples metadata +        io_type, _tx_otw_type,      //input and output types to convert +        get_master_clock_freq(),    //master clock tick rate +        _data_transport,            //zero copy interface +        get_max_send_samps_per_packet()      ); - -    //kill the end of burst flag if this is a fragment -    if (asio::buffer_size(buff)/io_type.size < num_samps) -        metadata.end_of_burst = false; - -    size_t num_header_words32, num_packet_words32; -    size_t packet_count = _tx_stream_id_to_packet_seq[metadata.stream_id]++; - -    //pack metadata into a vrt header -    vrt::pack( -        metadata,            //input -        tx_mem,              //output -        num_header_words32,  //output -        num_samps,           //input -        num_packet_words32,  //output -        packet_count,        //input -        get_master_clock_freq() -    ); - -    boost::uint32_t *items = tx_mem + num_header_words32; //offset for data - -    //copy-convert the samples into the send buffer -    convert_io_type_to_otw_type( -        asio::buffer_cast<const void*>(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)); -    return num_samps;  }  /*********************************************************************** @@ -163,44 +87,14 @@ size_t usrp2_impl::send(  size_t usrp2_impl::recv(      const asio::mutable_buffer &buff,      rx_metadata_t &metadata, -    const io_type_t &io_type +    const io_type_t &io_type, +    recv_mode_t recv_mode  ){ -    //perform a receive if no rx data is waiting to be copied -    if (asio::buffer_size(_rx_copy_buff) == 0){ -        _fragment_offset_in_samps = 0; -        recv_raw(metadata); -    } -    //otherwise flag the metadata to show that is is a fragment -    else{ -        metadata = rx_metadata_t(); -    } - -    //extract the number of samples available to copy -    //and a pointer into the usrp2 received items memory -    size_t bytes_to_copy = asio::buffer_size(_rx_copy_buff); -    if (bytes_to_copy == 0) return 0; //nothing to receive -    size_t num_samps = std::min( -        asio::buffer_size(buff)/io_type.size, -        bytes_to_copy/sizeof(boost::uint32_t) +    return vrt_packet_handler::recv( +        _packet_handler_recv_state, //last state of the recv handler +        buff, metadata, recv_mode,  //buffer to fill and samples metadata +        io_type, _rx_otw_type,      //input and output types to convert +        get_master_clock_freq(),    //master clock tick rate +        _data_transport             //zero copy interface      ); -    const boost::uint32_t *items = asio::buffer_cast<const boost::uint32_t*>(_rx_copy_buff); - -    //setup the fragment flags and offset -    metadata.more_fragments = asio::buffer_size(buff)/io_type.size < num_samps; -    metadata.fragment_offset = _fragment_offset_in_samps; -    _fragment_offset_in_samps += num_samps; //set for next time - -    //copy-convert the samples from the recv buffer -    convert_otw_type_to_io_type( -        (const void*)items, _otw_type, -        asio::buffer_cast<void*>(buff), io_type, -        num_samps -    ); - -    //update the rx copy buffer to reflect the bytes copied -    _rx_copy_buff = asio::buffer( -        items + num_samps, bytes_to_copy - num_samps*sizeof(boost::uint32_t) -    ); - -    return num_samps;  } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 9ae68d158..f17efd88e 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -111,7 +111,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){      //issue the stream command      _iface->poke32(FR_RX_CTRL_STREAM_CMD, FR_RX_CTRL_MAKE_CMD( -        (inst_samps)? stream_cmd.num_samps : ((inst_chain)? _max_rx_samples_per_packet : 1), +        (inst_samps)? stream_cmd.num_samps : ((inst_chain)? get_max_recv_samps_per_packet() : 1),          (stream_cmd.stream_now)? 1 : 0,          (inst_chain)? 1 : 0,          (inst_reload)? 1 : 0 diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 2b7bdeea2..af3ec216a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -210,14 +210,6 @@ void usrp2_impl::get(const wax::obj &key_, wax::obj &val){          val = prop_names_t(1, "");          return; -    case DEVICE_PROP_MAX_RX_SAMPLES: -        val = size_t(_max_rx_samples_per_packet); -        return; - -    case DEVICE_PROP_MAX_TX_SAMPLES: -        val = size_t(_max_tx_samples_per_packet); -        return; -      default: UHD_THROW_PROP_GET_ERROR();      }  } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index c5b6af810..afea9683c 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -33,6 +33,7 @@  #include <uhd/transport/vrt.hpp>  #include <uhd/transport/udp_zero_copy.hpp>  #include <uhd/usrp/dboard_manager.hpp> +#include "../../transport/vrt_packet_handler.hpp"  /*!   * Make a usrp2 dboard interface. @@ -103,8 +104,24 @@ public:      ~usrp2_impl(void);      //the io interface -    size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); -    size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); +    size_t get_max_send_samps_per_packet(void) const{ +        return _max_tx_bytes_per_packet/_tx_otw_type.get_sample_size(); +    } +    size_t send( +        const boost::asio::const_buffer &, +        const uhd::tx_metadata_t &, +        const uhd::io_type_t &, +        uhd::device::send_mode_t +    ); +    size_t get_max_recv_samps_per_packet(void) const{ +        return _max_rx_bytes_per_packet/_rx_otw_type.get_sample_size(); +    } +    size_t recv( +        const boost::asio::mutable_buffer &, +        uhd::rx_metadata_t &, +        const uhd::io_type_t &, +        uhd::device::recv_mode_t +    );  private:      double get_master_clock_freq(void){ @@ -121,25 +138,24 @@ private:      codec_ctrl::sptr _codec_ctrl;      serdes_ctrl::sptr _serdes_ctrl; -    //the raw io interface (samples are in the usrp2 native format) -    void recv_raw(uhd::rx_metadata_t &); -    uhd::dict<boost::uint32_t, size_t> _tx_stream_id_to_packet_seq; -    uhd::dict<boost::uint32_t, size_t> _rx_stream_id_to_packet_seq; +    /******************************************************************* +     * Deal with the rx and tx packet sizes +     ******************************************************************/      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) -    static const size_t _max_rx_samples_per_packet = -        (_mtu - _hdrs)/sizeof(boost::uint32_t) - -        USRP2_HOST_RX_VRT_HEADER_WORDS32 - -        USRP2_HOST_RX_VRT_TRAILER_WORDS32 +    static const size_t _max_rx_bytes_per_packet = +        _mtu - _hdrs - +        USRP2_HOST_RX_VRT_HEADER_WORDS32*sizeof(boost::uint32_t) - +        USRP2_HOST_RX_VRT_TRAILER_WORDS32*sizeof(boost::uint32_t)      ; -    static const size_t _max_tx_samples_per_packet = -        (_mtu - _hdrs)/sizeof(boost::uint32_t) - -        uhd::transport::vrt::max_header_words32 +    static const size_t _max_tx_bytes_per_packet = +        _mtu - _hdrs - +        uhd::transport::vrt::max_header_words32*sizeof(boost::uint32_t)      ; -    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; + +    vrt_packet_handler::recv_state _packet_handler_recv_state; +    vrt_packet_handler::send_state _packet_handler_send_state; +    uhd::otw_type_t _rx_otw_type, _tx_otw_type;      void io_init(void);      //udp transports for control and data | 
