From ede85c10ae74221ba4a715df2b45f27935503393 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 17 Feb 2011 23:06:48 -0800 Subject: uhd: got all compiling w/ changes, changes to channel calculation in multi usrp --- host/lib/usrp/usrp2/io_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host/lib/usrp/usrp2/io_impl.cpp') diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index b20b6652e..acd520b0b 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -265,7 +265,7 @@ void usrp2_impl::io_init(void){ _io_impl = UHD_PIMPL_MAKE(io_impl, (send_frame_size, _data_transports)); //create a new pirate thread for each zc if (yarr!!) - for (size_t i = 0; i < _data_transports.size(); i++){ + for (size_t i = 0; i < _err0_transports.size(); i++){ //lock the unlocked mutex (non-blocking) _io_impl->spawn_mutex.lock(); //spawn a new pirate to plunder the recv booty -- cgit v1.2.3 From b1313c9f65ea89c3aa9707538af027da337dcba8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 18 Feb 2011 10:43:47 -0800 Subject: usrp2: moved all dsp related code into dsp_impl and split for multiple dsps --- host/lib/usrp/usrp2/dsp_impl.cpp | 149 ++++++++++++++++++++++++------------ host/lib/usrp/usrp2/io_impl.cpp | 3 +- host/lib/usrp/usrp2/mboard_impl.cpp | 81 ++++---------------- host/lib/usrp/usrp2/usrp2_impl.hpp | 35 ++++----- 4 files changed, 131 insertions(+), 137 deletions(-) (limited to 'host/lib/usrp/usrp2/io_impl.cpp') diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index c83565875..ef9b5064c 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -28,12 +28,79 @@ using namespace uhd; using namespace uhd::usrp; -static const size_t default_decim = 16; -static const size_t default_interp = 16; - /*********************************************************************** - * DDC Helper Methods + * DSP impl and methods **********************************************************************/ +struct usrp2_mboard_impl::dsp_impl{ + uhd::dict ddc_decim; + uhd::dict ddc_freq; + uhd::dict duc_interp; + uhd::dict duc_freq; + std::vector decim_and_interp_rates; + uhd::dict continuous_streaming; +}; + +void usrp2_mboard_impl::dsp_init(size_t recv_samps_per_packet){ + //create new dsp impl + _dsp_impl = UHD_PIMPL_MAKE(dsp_impl, ()); + + //load the allowed decim/interp rates + //range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4) + for (size_t i = 4; i <= 128; i+=1){ + _dsp_impl->decim_and_interp_rates.push_back(i); + } + for (size_t i = 130; i <= 256; i+=2){ + _dsp_impl->decim_and_interp_rates.push_back(i); + } + for (size_t i = 260; i <= 512; i+=4){ + _dsp_impl->decim_and_interp_rates.push_back(i); + } + + //bind and initialize the rx dsps + for (size_t i = 0; i < NUM_RX_DSPS; i++){ + _rx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( + boost::bind(&usrp2_mboard_impl::ddc_get, this, _1, _2, i), + boost::bind(&usrp2_mboard_impl::ddc_set, this, _1, _2, i) + ); + + //initial config and update + ddc_set(DSP_PROP_FREQ_SHIFT, double(0), i); + ddc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/16), i); + + //setup the rx control registers + _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //reset + _iface->poke32(_iface->regs.rx_ctrl[i].nsamps_per_pkt, recv_samps_per_packet); + _iface->poke32(_iface->regs.rx_ctrl[i].nchannels, 1); + _iface->poke32(_iface->regs.rx_ctrl[i].vrt_header, 0 + | (0x1 << 28) //if data with stream id + | (0x1 << 26) //has trailer + | (0x3 << 22) //integer time other + | (0x1 << 20) //fractional time sample count + ); + _iface->poke32(_iface->regs.rx_ctrl[i].vrt_stream_id, usrp2_impl::RECV_SID); + _iface->poke32(_iface->regs.rx_ctrl[i].vrt_trailer, 0); + _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq())); + } + + //bind and initialize the tx dsps + for (size_t i = 0; i < NUM_TX_DSPS; i++){ + _tx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( + boost::bind(&usrp2_mboard_impl::duc_get, this, _1, _2, i), + boost::bind(&usrp2_mboard_impl::duc_set, this, _1, _2, i) + ); + + //initial config and update + duc_set(DSP_PROP_FREQ_SHIFT, double(0), i); + duc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/16), i); + + //init the tx control registers + _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset + _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0); //1 channel + _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID); + _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); + } +} + template static rate_type pick_closest_rate(double exact_rate, const std::vector &rates){ unsigned closest_match = rates.front(); @@ -44,27 +111,28 @@ static rate_type pick_closest_rate(double exact_rate, const std::vectorcontinuous_streaming[which_dsp] = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + _iface->poke32(_iface->regs.rx_ctrl[which_dsp].stream_cmd, dsp_type1::calc_stream_cmd_word(stream_cmd)); + _iface->poke32(_iface->regs.rx_ctrl[which_dsp].time_secs, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); + _iface->poke32(_iface->regs.rx_ctrl[which_dsp].time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); +} - //initial config and update - ddc_set(DSP_PROP_FREQ_SHIFT, double(0)); - ddc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/default_decim)); +void usrp2_mboard_impl::handle_overflow(size_t which_dsp){ + if (_dsp_impl->continuous_streaming[which_dsp]){ //re-issue the stream command if already continuous + this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS, which_dsp); + } } /*********************************************************************** * DDC Properties **********************************************************************/ -void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){ +void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ case DSP_PROP_NAME: - val = _iface->get_cname() + " ddc0"; + val = str(boost::format("%s ddc%d") % _iface->get_cname() % which_dsp); return; case DSP_PROP_OTHERS: @@ -72,7 +140,7 @@ void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_FREQ_SHIFT: - val = _ddc_freq; + val = _dsp_impl->ddc_freq[which_dsp]; return; case DSP_PROP_CODEC_RATE: @@ -80,41 +148,41 @@ void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_HOST_RATE: - val = get_master_clock_freq()/_ddc_decim; + val = get_master_clock_freq()/_dsp_impl->ddc_decim[which_dsp]; return; default: UHD_THROW_PROP_GET_ERROR(); } } -void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){ +void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ case DSP_PROP_STREAM_CMD: - issue_ddc_stream_cmd(val.as()); + issue_ddc_stream_cmd(val.as(), which_dsp); return; case DSP_PROP_FREQ_SHIFT:{ double new_freq = val.as(); - _iface->poke32(_iface->regs.dsp_rx[0].freq, + _iface->poke32(_iface->regs.dsp_rx[which_dsp].freq, dsp_type1::calc_cordic_word_and_update(new_freq, get_master_clock_freq()) ); - _ddc_freq = new_freq; //shadow + _dsp_impl->ddc_freq[which_dsp] = new_freq; //shadow } return; case DSP_PROP_HOST_RATE:{ double extact_rate = get_master_clock_freq()/val.as(); - _ddc_decim = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); + _dsp_impl->ddc_decim[which_dsp] = pick_closest_rate(extact_rate, _dsp_impl->decim_and_interp_rates); //set the decimation - _iface->poke32(_iface->regs.dsp_rx[0].decim_rate, dsp_type1::calc_cic_filter_word(_ddc_decim)); + _iface->poke32(_iface->regs.dsp_rx[which_dsp].decim_rate, dsp_type1::calc_cic_filter_word(_dsp_impl->ddc_decim[which_dsp])); //set the scaling static const boost::int16_t default_rx_scale_iq = 1024; - _iface->poke32(_iface->regs.dsp_rx[0].scale_iq, + _iface->poke32(_iface->regs.dsp_rx[which_dsp].scale_iq, dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) ); } @@ -124,30 +192,15 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){ } } -/*********************************************************************** - * DUC Helper Methods - **********************************************************************/ -void usrp2_mboard_impl::init_duc_config(void){ - //create the duc in the tx dsp dict - _tx_dsp_proxy = wax_obj_proxy::make( - boost::bind(&usrp2_mboard_impl::duc_get, this, _1, _2), - boost::bind(&usrp2_mboard_impl::duc_set, this, _1, _2) - ); - - //initial config and update - duc_set(DSP_PROP_FREQ_SHIFT, double(0)); - duc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/default_interp)); -} - /*********************************************************************** * DUC Properties **********************************************************************/ -void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){ +void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ case DSP_PROP_NAME: - val = _iface->get_cname() + " duc0"; + val = str(boost::format("%s duc%d") % _iface->get_cname() % which_dsp); return; case DSP_PROP_OTHERS: @@ -155,7 +208,7 @@ void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_FREQ_SHIFT: - val = _duc_freq; + val = _dsp_impl->duc_freq[which_dsp]; return; case DSP_PROP_CODEC_RATE: @@ -163,14 +216,14 @@ void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_HOST_RATE: - val = get_master_clock_freq()/_duc_interp; + val = get_master_clock_freq()/_dsp_impl->duc_interp[which_dsp]; return; default: UHD_THROW_PROP_GET_ERROR(); } } -void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){ +void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ @@ -192,19 +245,19 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){ _iface->poke32(_iface->regs.dsp_tx_freq, dsp_type1::calc_cordic_word_and_update(new_freq, codec_rate) ); - _duc_freq = new_freq + dac_shift; //shadow + _dsp_impl->duc_freq[which_dsp] = new_freq + dac_shift; //shadow } return; case DSP_PROP_HOST_RATE:{ double extact_rate = get_master_clock_freq()/val.as(); - _duc_interp = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); + _dsp_impl->duc_interp[which_dsp] = pick_closest_rate(extact_rate, _dsp_impl->decim_and_interp_rates); //set the interpolation - _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_duc_interp)); + _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_dsp_impl->duc_interp[which_dsp])); //set the scaling - _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_duc_interp)); + _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_dsp_impl->duc_interp[which_dsp])); } return; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index acd520b0b..816f1859a 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -464,7 +464,8 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{ static void handle_overflow(std::vector &mboards, size_t chan){ std::cerr << "O" << std::flush; - mboards.at(chan/mboards.size())->handle_overflow(); + //TODO this is wrong way to determine the index... + mboards.at(chan/mboards.size())->handle_overflow(chan%mboards.size()); } size_t usrp2_impl::recv( diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index a3de8673e..d95ad4a7a 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -56,40 +56,8 @@ usrp2_mboard_impl::usrp2_mboard_impl( //if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl; - //TODO move to dsp impl... - //load the allowed decim/interp rates - //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4) - _allowed_decim_and_interp_rates.clear(); - for (size_t i = 4; i <= 128; i+=1){ - _allowed_decim_and_interp_rates.push_back(i); - } - for (size_t i = 130; i <= 256; i+=2){ - _allowed_decim_and_interp_rates.push_back(i); - } - for (size_t i = 260; i <= 512; i+=4){ - _allowed_decim_and_interp_rates.push_back(i); - } - - //setup the vrt rx registers - //TODO loop for 0, 1, in NUM_RX_DSPS - _iface->poke32(_iface->regs.rx_ctrl[0].clear_overrun, 1); //reset - _iface->poke32(_iface->regs.rx_ctrl[0].nsamps_per_pkt, recv_samps_per_packet); - _iface->poke32(_iface->regs.rx_ctrl[0].nchannels, 1); - _iface->poke32(_iface->regs.rx_ctrl[0].vrt_header, 0 - | (0x1 << 28) //if data with stream id - | (0x1 << 26) //has trailer - | (0x3 << 22) //integer time other - | (0x1 << 20) //fractional time sample count - ); - _iface->poke32(_iface->regs.rx_ctrl[0].vrt_stream_id, usrp2_impl::RECV_SID); - _iface->poke32(_iface->regs.rx_ctrl[0].vrt_trailer, 0); - _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq())); - - //init the tx control registers - _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset - _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0); //1 channel - _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID); - _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); + //init the dsp stuff (before setting update packets) + dsp_init(recv_samps_per_packet); //setting the cycles per update (disabled by default) const double ups_per_sec = device_args.cast("ups_per_sec", 0.0); @@ -105,12 +73,6 @@ usrp2_mboard_impl::usrp2_mboard_impl( _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up); } - //init the ddc - init_ddc_config(); - - //init the duc - init_duc_config(); - //initialize the clock configuration if (device_args.has_key("mimo_mode")){ if (device_args["mimo_mode"] == "master"){ @@ -144,12 +106,14 @@ usrp2_mboard_impl::usrp2_mboard_impl( (*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t(); //This is a hack/fix for the lingering packet problem. + /* stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = 1; this->issue_ddc_stream_cmd(stream_cmd); data_transport->get_recv_buff().get(); //recv with timeout for lingering data_transport->get_recv_buff().get(); //recv with timeout for expected _iface->poke32(_iface->regs.rx_ctrl[0].clear_overrun, 1); //resets sequence + */ } usrp2_mboard_impl::~usrp2_mboard_impl(void){ @@ -250,19 +214,6 @@ void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){ _iface->poke32(_iface->regs.time64_secs, boost::uint32_t(time_spec.get_full_secs())); } -void usrp2_mboard_impl::handle_overflow(void){ - if (_continuous_streaming){ //re-issue the stream command if already continuous - this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - } -} - -void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ - _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - _iface->poke32(_iface->regs.rx_ctrl[0].stream_cmd, dsp_type1::calc_stream_cmd_word(stream_cmd)); - _iface->poke32(_iface->regs.rx_ctrl[0].time_secs, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); - _iface->poke32(_iface->regs.rx_ctrl[0].time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); -} - /*********************************************************************** * MBoard Get Properties **********************************************************************/ @@ -299,21 +250,19 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_RX_DSP: - UHD_ASSERT_THROW(key.name == ""); - val = _rx_dsp_proxy->get_link(); + val = _rx_dsp_proxies[key.name]->get_link(); return; case MBOARD_PROP_RX_DSP_NAMES: - val = prop_names_t(1, ""); + val = _rx_dsp_proxies.keys(); return; case MBOARD_PROP_TX_DSP: - UHD_ASSERT_THROW(key.name == ""); - val = _tx_dsp_proxy->get_link(); + val = _tx_dsp_proxies[key.name]->get_link(); return; case MBOARD_PROP_TX_DSP_NAMES: - val = prop_names_t(1, ""); + val = _tx_dsp_proxies.keys(); return; case MBOARD_PROP_CLOCK_CONFIG: @@ -380,15 +329,13 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ _rx_subdev_spec = val.as(); verify_rx_subdev_spec(_rx_subdev_spec, this->get_link()); //sanity check - UHD_ASSERT_THROW(_rx_subdev_spec.size() <= 2); + UHD_ASSERT_THROW(_rx_subdev_spec.size() <= NUM_RX_DSPS); //set the mux - if (_rx_subdev_spec.size() >= 1) _iface->poke32(_iface->regs.dsp_rx[0].mux, dsp_type1::calc_rx_mux_word( - _dboard_manager->get_rx_subdev(_rx_subdev_spec[0].sd_name)[SUBDEV_PROP_CONNECTION].as() - )); - //TODO - //if (_rx_subdev_spec.size() >= 2) _iface->poke32(_iface->regs.dsp1_rx_mux, dsp_type1::calc_rx_mux_word( - // _dboard_manager->get_rx_subdev(_rx_subdev_spec[1].sd_name)[SUBDEV_PROP_CONNECTION].as() - //)); + for (size_t i = 0; i < _rx_subdev_spec.size(); i++){ + if (_rx_subdev_spec.size() >= 1) _iface->poke32(_iface->regs.dsp_rx[i].mux, dsp_type1::calc_rx_mux_word( + _dboard_manager->get_rx_subdev(_rx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as() + )); + } return; case MBOARD_PROP_TX_SUBDEV_SPEC: diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 9a406bc87..cb049f876 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -80,6 +80,9 @@ class usrp2_mboard_impl : public wax::obj{ public: typedef boost::shared_ptr sptr; + static const size_t NUM_RX_DSPS = 2; + static const size_t NUM_TX_DSPS = 1; + //structors usrp2_mboard_impl( size_t index, @@ -95,11 +98,10 @@ public: return _clock_ctrl->get_master_clock_rate(); } - void handle_overflow(void); + void handle_overflow(size_t); private: size_t _index; - bool _continuous_streaming; bool _mimo_clocking_mode_is_master; //interfaces @@ -147,27 +149,20 @@ private: wax_obj_proxy::sptr _tx_dboard_proxy; uhd::usrp::dboard_eeprom_t _tx_db_eeprom; - //methods and shadows for the ddc dsp - std::vector _allowed_decim_and_interp_rates; - size_t _ddc_decim; - double _ddc_freq; - void init_ddc_config(void); - void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd); - - //methods and shadows for the duc dsp - size_t _duc_interp; - double _duc_freq; - void init_duc_config(void); + //methods and shadows for the dsps + UHD_PIMPL_DECL(dsp_impl) _dsp_impl; + void dsp_init(size_t recv_samps_per_packet); + void issue_ddc_stream_cmd(const uhd::stream_cmd_t &, size_t); //properties interface for ddc - void ddc_get(const wax::obj &, wax::obj &); - void ddc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_dsp_proxy; + void ddc_get(const wax::obj &, wax::obj &, size_t); + void ddc_set(const wax::obj &, const wax::obj &, size_t); + uhd::dict _rx_dsp_proxies; //properties interface for duc - void duc_get(const wax::obj &, wax::obj &); - void duc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_dsp_proxy; + void duc_get(const wax::obj &, wax::obj &, size_t); + void duc_set(const wax::obj &, const wax::obj &, size_t); + uhd::dict _tx_dsp_proxies; }; @@ -181,8 +176,6 @@ public: static const size_t sram_bytes = size_t(1 << 20); static const boost::uint32_t RECV_SID = 1; static const boost::uint32_t ASYNC_SID = 2; - static const size_t NUM_RX_DSPS = 2; - static const size_t NUM_TX_DSPS = 1; /*! * Create a new usrp2 impl base. -- cgit v1.2.3 From e558283f9ff2550d164d868c8e66a5561c781474 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 19 Feb 2011 10:30:50 -0800 Subject: usrp2: lot of work on dual dsp, grep for TODOs before continuing --- host/lib/usrp/usrp2/dsp_impl.cpp | 4 +- host/lib/usrp/usrp2/io_impl.cpp | 71 +++++++++++++++++---------- host/lib/usrp/usrp2/mboard_impl.cpp | 98 +++++++++++++++++++++++++++++-------- host/lib/usrp/usrp2/usrp2_impl.cpp | 82 +++++-------------------------- host/lib/usrp/usrp2/usrp2_impl.hpp | 36 ++++++-------- 5 files changed, 150 insertions(+), 141 deletions(-) (limited to 'host/lib/usrp/usrp2/io_impl.cpp') diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index ef9b5064c..cdd559e94 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -40,7 +40,7 @@ struct usrp2_mboard_impl::dsp_impl{ uhd::dict continuous_streaming; }; -void usrp2_mboard_impl::dsp_init(size_t recv_samps_per_packet){ +void usrp2_mboard_impl::dsp_init(void){ //create new dsp impl _dsp_impl = UHD_PIMPL_MAKE(dsp_impl, ()); @@ -69,7 +69,7 @@ void usrp2_mboard_impl::dsp_init(size_t recv_samps_per_packet){ //setup the rx control registers _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //reset - _iface->poke32(_iface->regs.rx_ctrl[i].nsamps_per_pkt, recv_samps_per_packet); + _iface->poke32(_iface->regs.rx_ctrl[i].nsamps_per_pkt, _device.get_max_recv_samps_per_packet()); _iface->poke32(_iface->regs.rx_ctrl[i].nchannels, 1); _iface->poke32(_iface->regs.rx_ctrl[i].vrt_header, 0 | (0x1 << 28) //if data with stream id diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 816f1859a..179c2401d 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -18,6 +18,7 @@ #include "../../transport/vrt_packet_handler.hpp" #include "usrp2_impl.hpp" #include "usrp2_regs.hpp" +#include #include #include #include @@ -119,16 +120,16 @@ private: **********************************************************************/ struct usrp2_impl::io_impl{ - io_impl(size_t send_frame_size, const std::vector &xports): - xports(xports), + io_impl(size_t num_mboards, size_t send_frame_size): + //the assumption is that all data transports should be identical get_recv_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_recv_buffs, this, _1)), get_send_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_send_buffs, this, _1)), - packet_handler_recv_state(xports.size()), - packet_handler_send_state(xports.size()), + packet_handler_recv_state(num_mboards*usrp2_mboard_impl::NUM_RX_DSPS), //max chans + packet_handler_send_state(num_mboards*usrp2_mboard_impl::NUM_RX_DSPS), //max chans async_msg_fifo(100/*messages deep*/) { - for (size_t i = 0; i < xports.size(); i++){ - fc_mons.push_back(flow_control_monitor::sptr( + for (size_t i = 0; i < num_mboards; i++){ //only one monitor per mboard (only 1 tx dsp so far) + fc_mons.push_back(flow_control_monitor::sptr( //OMG TODO this will not be mapped right when a tx is disabled new flow_control_monitor(usrp2_impl::sram_bytes/send_frame_size) )); //init empty packet infos @@ -149,7 +150,7 @@ struct usrp2_impl::io_impl{ } bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs){ - UHD_ASSERT_THROW(xports.size() == buffs.size()); + UHD_ASSERT_THROW(send_xports.size() == buffs.size()); //calculate the flow control word const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq; @@ -157,7 +158,7 @@ struct usrp2_impl::io_impl{ //grab a managed buffer for each index for (size_t i = 0; i < buffs.size(); i++){ if (not fc_mons[i]->check_fc_condition(fc_word32, send_timeout)) return false; - buffs[i] = xports[i]->get_send_buff(send_timeout); + buffs[i] = send_xports[i]->get_send_buff(send_timeout); if (not buffs[i].get()) return false; buffs[i]->cast()[0] = uhd::htonx(fc_word32); } @@ -166,7 +167,8 @@ struct usrp2_impl::io_impl{ bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs); - const std::vector &xports; + //vector of send and recv xports to be mapped to channels + std::vector recv_xports, send_xports; //timeouts set on calls to recv/send (passed into get buffs methods) double recv_timeout, send_timeout; @@ -186,7 +188,7 @@ struct usrp2_impl::io_impl{ vrt_packet_handler::send_state packet_handler_send_state; //methods and variables for the pirate crew - void recv_pirate_loop(zero_copy_if::sptr, usrp2_mboard_impl::sptr, size_t); + void recv_pirate_loop(usrp2_mboard_impl::sptr, size_t); boost::thread_group recv_pirate_crew; bool recv_pirate_crew_raiding; bounded_buffer async_msg_fifo; @@ -200,9 +202,7 @@ struct usrp2_impl::io_impl{ * - put async message packets into queue **********************************************************************/ void usrp2_impl::io_impl::recv_pirate_loop( - zero_copy_if::sptr zc_if_err0, - usrp2_mboard_impl::sptr mboard, - size_t index + usrp2_mboard_impl::sptr mboard, size_t index ){ set_thread_priority_safe(); recv_pirate_crew_raiding = true; @@ -210,7 +210,7 @@ void usrp2_impl::io_impl::recv_pirate_loop( spawn_mutex.unlock(); while(recv_pirate_crew_raiding){ - managed_recv_buffer::sptr buff = zc_if_err0->get_recv_buff(); + managed_recv_buffer::sptr buff = mboard->err_xports[0]->get_recv_buff(); if (not buff.get()) continue; //ignore timeout/error buffers try{ @@ -258,27 +258,46 @@ void usrp2_impl::io_impl::recv_pirate_loop( **********************************************************************/ void usrp2_impl::io_init(void){ - //the assumption is that all data transports should be identical - const size_t send_frame_size = _data_transports.front()->get_send_frame_size(); - //create new io impl - _io_impl = UHD_PIMPL_MAKE(io_impl, (send_frame_size, _data_transports)); + _io_impl = UHD_PIMPL_MAKE(io_impl, (_mboards.size(), this->send_frame_size)); //create a new pirate thread for each zc if (yarr!!) - for (size_t i = 0; i < _err0_transports.size(); i++){ + for (size_t i = 0; i < _mboards.size(); i++){ //lock the unlocked mutex (non-blocking) _io_impl->spawn_mutex.lock(); //spawn a new pirate to plunder the recv booty _io_impl->recv_pirate_crew.create_thread(boost::bind( &usrp2_impl::io_impl::recv_pirate_loop, - _io_impl.get(), _err0_transports.at(i), - _mboards.at(i), i + _io_impl.get(), _mboards.at(i), i )); //block here until the spawned thread unlocks _io_impl->spawn_mutex.lock(); //exit loop iteration in an unlocked condition _io_impl->spawn_mutex.unlock(); } + + //update mapping here since it didnt b4 when io init not called first + update_xport_channel_mapping(); +} + +void usrp2_impl::update_xport_channel_mapping(void){ + if (_io_impl.get() == NULL) return; //not inited yet + + _io_impl->recv_xports.clear(); + _io_impl->send_xports.clear(); + BOOST_FOREACH(usrp2_mboard_impl::sptr mboard, _mboards){ + + subdev_spec_t rx_subdev_spec = mboard->get_link()[MBOARD_PROP_RX_SUBDEV_SPEC].as(); + for (size_t j = 0; j < rx_subdev_spec.size(); j++){ + _io_impl->recv_xports.push_back(mboard->dsp_xports.at(j)); + } + + subdev_spec_t tx_subdev_spec = mboard->get_link()[MBOARD_PROP_TX_SUBDEV_SPEC].as(); + for (size_t j = 0; j < tx_subdev_spec.size(); j++){ + _io_impl->send_xports.push_back(mboard->dsp_xports.at(j)); + } + + } } /*********************************************************************** @@ -300,7 +319,7 @@ size_t usrp2_impl::get_max_send_samps_per_packet(void) const{ + vrt_send_header_offset_words32*sizeof(boost::uint32_t) - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - const size_t bpp = _data_transports.front()->get_send_frame_size() - hdr_size; + const size_t bpp = this->send_frame_size - hdr_size; return bpp/_tx_otw_type.get_sample_size(); } @@ -383,7 +402,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( vrt_packet_handler::managed_recv_buffs_t &buffs ){ if (buffs.size() == 1){ - buffs[0] = xports[0]->get_recv_buff(recv_timeout); + buffs[0] = recv_xports[0]->get_recv_buff(recv_timeout); if (buffs[0].get() == NULL) return false; bool clear, msg; time_spec_t time; //unused variables //call extract_packet_info to handle printing the overflows @@ -404,7 +423,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( //do an initial pop to load an initial sequence id size_t index = indexes_to_do.front(); - buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); + buff_tmp = recv_xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); if (buff_tmp.get() == NULL) return false; extract_packet_info(buff_tmp, this->prev_infos[index], expected_time, clear, msg); if (clear) goto got_clear; @@ -417,7 +436,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( //pop an element off for this index index = indexes_to_do.front(); - buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); + buff_tmp = recv_xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); if (buff_tmp.get() == NULL) return false; time_spec_t this_time; extract_packet_info(buff_tmp, this->prev_infos[index], this_time, clear, msg); @@ -458,7 +477,7 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{ + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - const size_t bpp = _data_transports.front()->get_recv_frame_size() - hdr_size; + const size_t bpp = this->recv_frame_size - hdr_size; return bpp/_rx_otw_type.get_sample_size(); } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index d95ad4a7a..8db295042 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -32,21 +33,72 @@ static const size_t mimo_clock_sync_delay_cycles = 137; using namespace uhd; using namespace uhd::usrp; +using namespace uhd::transport; + +/*********************************************************************** + * Helpers + **********************************************************************/ +static void init_xport(zero_copy_if::sptr xport){ + //Send a small data packet so the usrp2 knows the udp source port. + //This setup must happen before further initialization occurs + //or the async update packets will cause ICMP destination unreachable. + static const boost::uint32_t data[2] = { + uhd::htonx(boost::uint32_t(0 /* don't care seq num */)), + uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER)) + }; + + transport::managed_send_buffer::sptr send_buff = xport->get_send_buff(); + std::memcpy(send_buff->cast(), &data, sizeof(data)); + send_buff->commit(sizeof(data)); +} /*********************************************************************** * Structors **********************************************************************/ usrp2_mboard_impl::usrp2_mboard_impl( - size_t index, - transport::udp_simple::sptr ctrl_transport, - transport::zero_copy_if::sptr data_transport, - transport::zero_copy_if::sptr err0_transport, - const device_addr_t &device_args, - size_t recv_samps_per_packet + const device_addr_t &device_addr, //global args passed into make + const device_addr_t &device_args, //separated mboard specific args + size_t index, usrp2_impl &device ): - _index(index), - _iface(usrp2_iface::make(ctrl_transport)) + _index(index), _device(device), + _iface(usrp2_iface::make(udp_simple::make_connected( + device_addr["addr"], boost::lexical_cast(USRP2_UDP_CTRL_PORT) + ))) { + + //setup the dsp transport hints (default to a large recv buff) + device_addr_t dsp_xport_hints = device_addr; + if (not dsp_xport_hints.has_key("recv_buff_size")){ + //only enable on platforms that are happy with the large buffer resize + #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) + //set to half-a-second of buffering at max rate + dsp_xport_hints["recv_buff_size"] = "50e6"; + #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/ + } + + //construct transports for dsp and async errors + std::cout << "Making transport for DSP0..." << std::endl; + dsp_xports.push_back(udp_zero_copy::make( + device_addr["addr"], boost::lexical_cast(USRP2_UDP_DSP0_PORT), dsp_xport_hints + )); + init_xport(dsp_xports.back()); + + std::cout << "Making transport for DSP1..." << std::endl; + dsp_xports.push_back(udp_zero_copy::make( + device_addr["addr"], boost::lexical_cast(USRP2_UDP_DSP1_PORT), dsp_xport_hints + )); + init_xport(dsp_xports.back()); + + std::cout << "Making transport for ERR0..." << std::endl; + err_xports.push_back(udp_zero_copy::make( + device_addr["addr"], boost::lexical_cast(USRP2_UDP_ERR0_PORT), device_addr_t() + )); + init_xport(err_xports.back()); + + //set the frame sizes (assume homogeneous) + device.recv_frame_size = dsp_xports.front()->get_recv_frame_size(); + device.send_frame_size = dsp_xports.front()->get_send_frame_size(); + //contruct the interfaces to mboard perifs _clock_ctrl = usrp2_clock_ctrl::make(_iface); _codec_ctrl = usrp2_codec_ctrl::make(_iface); @@ -57,7 +109,7 @@ usrp2_mboard_impl::usrp2_mboard_impl( //if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl; //init the dsp stuff (before setting update packets) - dsp_init(recv_samps_per_packet); + dsp_init(); //setting the cycles per update (disabled by default) const double ups_per_sec = device_args.cast("ups_per_sec", 0.0); @@ -69,7 +121,7 @@ usrp2_mboard_impl::usrp2_mboard_impl( //setting the packets per update (enabled by default) const double ups_per_fifo = device_args.cast("ups_per_fifo", 8.0); if (ups_per_fifo > 0.0){ - const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/data_transport->get_send_frame_size()); + const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/dsp_xports[0]->get_send_frame_size()); _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up); } @@ -106,14 +158,14 @@ usrp2_mboard_impl::usrp2_mboard_impl( (*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t(); //This is a hack/fix for the lingering packet problem. - /* stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = 1; - this->issue_ddc_stream_cmd(stream_cmd); - data_transport->get_recv_buff().get(); //recv with timeout for lingering - data_transport->get_recv_buff().get(); //recv with timeout for expected - _iface->poke32(_iface->regs.rx_ctrl[0].clear_overrun, 1); //resets sequence - */ + for (size_t i = 0; i < NUM_RX_DSPS; i++){ + stream_cmd.num_samps = 1; + this->issue_ddc_stream_cmd(stream_cmd, i); + dsp_xports[i]->get_recv_buff().get(); //recv with timeout for lingering + dsp_xports[i]->get_recv_buff().get(); //recv with timeout for expected + _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //resets sequence + } } usrp2_mboard_impl::~usrp2_mboard_impl(void){ @@ -336,17 +388,21 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ _dboard_manager->get_rx_subdev(_rx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as() )); } + _device.update_xport_channel_mapping(); return; case MBOARD_PROP_TX_SUBDEV_SPEC: _tx_subdev_spec = val.as(); verify_tx_subdev_spec(_tx_subdev_spec, this->get_link()); //sanity check - UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); + UHD_ASSERT_THROW(_tx_subdev_spec.size() <= NUM_TX_DSPS); //set the mux - _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word( - _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as() - )); + for (size_t i = 0; i < _rx_subdev_spec.size(); i++){ + _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word( + _dboard_manager->get_tx_subdev(_tx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as() + )); + } + _device.update_xport_channel_mapping(); return; case MBOARD_PROP_EEPROM_MAP: diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 78eda4f62..4ff56eb5b 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -42,9 +42,6 @@ namespace asio = boost::asio; /*********************************************************************** * Helper Functions **********************************************************************/ -template std::string num2str(T num){ - return boost::lexical_cast(num); -} //! separate indexed device addresses into a vector of device addresses device_addrs_t sep_indexed_dev_addrs(const device_addr_t &dev_addr){ @@ -168,9 +165,9 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){ //This operation can throw due to compatibility mismatch. //In this case, the discovered device will be ignored. try{ - mboard_eeprom_t mb_eeprom = usrp2_iface::make( - udp_simple::make_connected(new_addr["addr"], num2str(USRP2_UDP_CTRL_PORT)) - )->mb_eeprom; + mboard_eeprom_t mb_eeprom = usrp2_iface::make(udp_simple::make_connected( + new_addr["addr"], boost::lexical_cast(USRP2_UDP_CTRL_PORT) + ))->mb_eeprom; new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = mb_eeprom["serial"]; if ( @@ -199,56 +196,7 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){ * Make **********************************************************************/ static device::sptr usrp2_make(const device_addr_t &device_addr){ - - //setup the dsp transport hints (default to a large recv buff) - device_addr_t dsp_xport_hints = device_addr; - if (not dsp_xport_hints.has_key("recv_buff_size")){ - //only enable on platforms that are happy with the large buffer resize - #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) - //set to half-a-second of buffering at max rate - dsp_xport_hints["recv_buff_size"] = "50e6"; - #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/ - } - - //create a ctrl and data transport for each address - std::vector ctrl_transports; - std::vector data_transports; - std::vector err0_transports; - const device_addrs_t device_addrs = sep_indexed_dev_addrs(device_addr); - - //Send a small data packet so the usrp2 knows the udp source port. - //This setup must happen before further initialization occurs - //or the async update packets will cause ICMP destination unreachable. - transport::managed_send_buffer::sptr send_buff; - static const boost::uint32_t data[2] = { - uhd::htonx(boost::uint32_t(0 /* don't care seq num */)), - uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER)) - }; - - BOOST_FOREACH(const device_addr_t &dev_addr_i, device_addrs){ - ctrl_transports.push_back(udp_simple::make_connected( - dev_addr_i["addr"], num2str(USRP2_UDP_CTRL_PORT) - )); - - data_transports.push_back(udp_zero_copy::make( - dev_addr_i["addr"], num2str(USRP2_UDP_DSP0_PORT), dsp_xport_hints - )); - send_buff = data_transports.back()->get_send_buff(); - std::memcpy(send_buff->cast(), &data, sizeof(data)); - send_buff->commit(sizeof(data)); - - err0_transports.push_back(udp_zero_copy::make( - dev_addr_i["addr"], num2str(USRP2_UDP_ERR0_PORT), device_addr_t() - )); - send_buff = err0_transports.back()->get_send_buff(); - std::memcpy(send_buff->cast(), &data, sizeof(data)); - send_buff->commit(sizeof(data)); - } - - //create the usrp2 implementation guts - return device::sptr(new usrp2_impl( - ctrl_transports, data_transports, err0_transports, device_addrs - )); + return device::sptr(new usrp2_impl(device_addr)); } UHD_STATIC_BLOCK(register_usrp2_device){ @@ -258,15 +206,9 @@ UHD_STATIC_BLOCK(register_usrp2_device){ /*********************************************************************** * Structors **********************************************************************/ -usrp2_impl::usrp2_impl( - std::vector ctrl_transports, - std::vector data_transports, - std::vector err0_transports, - const device_addrs_t &device_args -): - _data_transports(data_transports), - _err0_transports(err0_transports) -{ +usrp2_impl::usrp2_impl(const device_addr_t &device_addr){ + device_addrs_t device_args = sep_indexed_dev_addrs(device_addr); + //setup rx otw type _rx_otw_type.width = 16; _rx_otw_type.shift = 0; @@ -281,13 +223,11 @@ usrp2_impl::usrp2_impl( //create a new mboard handler for each control transport for(size_t i = 0; i < device_args.size(); i++){ - _mboards.push_back(usrp2_mboard_impl::sptr(new usrp2_mboard_impl( - i, ctrl_transports[i], data_transports[i], - err0_transports[i], device_args[i], - this->get_max_recv_samps_per_packet() - ))); + _mboards.push_back(usrp2_mboard_impl::sptr( + new usrp2_mboard_impl(device_addr, device_args[i], i, *this) + )); //use an empty name when there is only one mboard - std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast(i) : ""; + std::string name = (device_args.size() > 1)? boost::lexical_cast(i) : ""; _mboard_dict[name] = _mboards.back(); } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index cb049f876..4f68b630e 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -71,6 +71,8 @@ private: void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} }; +class usrp2_impl; + /*! * USRP2 mboard implementation guts: * The implementation details are encapsulated here. @@ -85,12 +87,9 @@ public: //structors usrp2_mboard_impl( - size_t index, - uhd::transport::udp_simple::sptr, - uhd::transport::zero_copy_if::sptr, - uhd::transport::zero_copy_if::sptr, + const uhd::device_addr_t &device_addr, const uhd::device_addr_t &device_args, - size_t recv_samps_per_packet + size_t index, usrp2_impl &device ); ~usrp2_mboard_impl(void); @@ -100,8 +99,12 @@ public: void handle_overflow(size_t); + std::vector dsp_xports; + std::vector err_xports; + private: size_t _index; + usrp2_impl &_device; bool _mimo_clocking_mode_is_master; //interfaces @@ -151,7 +154,7 @@ private: //methods and shadows for the dsps UHD_PIMPL_DECL(dsp_impl) _dsp_impl; - void dsp_init(size_t recv_samps_per_packet); + void dsp_init(void); void issue_ddc_stream_cmd(const uhd::stream_cmd_t &, size_t); //properties interface for ddc @@ -177,19 +180,7 @@ public: static const boost::uint32_t RECV_SID = 1; static const boost::uint32_t ASYNC_SID = 2; - /*! - * Create a new usrp2 impl base. - * \param ctrl_transports the udp transports for control - * \param data_transports the udp transports for data - * \param err0_transports the udp transports for error - * \param device_args optional misc device parameters - */ - usrp2_impl( - std::vector ctrl_transports, - std::vector data_transports, - std::vector err0_transports, - const uhd::device_addrs_t &device_args - ); + usrp2_impl(const uhd::device_addr_t &); ~usrp2_impl(void); @@ -208,6 +199,11 @@ public: size_t get_max_recv_samps_per_packet(void) const; bool recv_async_msg(uhd::async_metadata_t &, double); + void update_xport_channel_mapping(void); + + //public frame sizes, set by mboard, used by io impl + size_t recv_frame_size, send_frame_size; + private: //device properties interface void get(const wax::obj &, wax::obj &); @@ -218,8 +214,6 @@ private: uhd::dict _mboard_dict; //io impl methods and members - std::vector _data_transports; - std::vector _err0_transports; uhd::otw_type_t _rx_otw_type, _tx_otw_type; UHD_PIMPL_DECL(io_impl) _io_impl; void io_init(void); -- cgit v1.2.3 From 607f5df7013810e94bbe049e457858ec68f8dd0e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 20 Feb 2011 19:57:04 -0800 Subject: usrp2: code working again in a completed form but did not test dual dsp --- host/lib/transport/vrt_packet_handler.hpp | 4 +- host/lib/usrp/usrp2/fw_common.h | 2 +- host/lib/usrp/usrp2/io_impl.cpp | 67 +++++++++++++++++-------------- host/lib/usrp/usrp2/mboard_impl.cpp | 24 +++++------ host/lib/usrp/usrp2/usrp2_impl.hpp | 7 ++-- 5 files changed, 55 insertions(+), 49 deletions(-) (limited to 'host/lib/usrp/usrp2/io_impl.cpp') diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index 6f3ac0421..4f8ce7e52 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -300,18 +300,18 @@ template UHD_INLINE T get_context_code( typedef boost::function get_send_buffs_t; typedef boost::function vrt_packer_t; + static const boost::uint64_t zeros = 0; + struct send_state{ //init the expected seq number size_t next_packet_seq; managed_send_buffs_t managed_buffs; - const boost::uint64_t zeros; std::vector zero_buffs; std::vector io_buffs; send_state(size_t width = 1): next_packet_seq(0), managed_buffs(width), - zeros(0), zero_buffs(width, &zeros), io_buffs(0) //resized later { diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 33c0b728a..6eb047454 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -30,7 +30,7 @@ extern "C" { #endif //fpga and firmware compatibility numbers -#define USRP2_FPGA_COMPAT_NUM 4 +#define USRP2_FPGA_COMPAT_NUM 5 #define USRP2_FW_COMPAT_NUM 9 //used to differentiate control packets over data port diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 179c2401d..e931778fa 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -120,18 +120,17 @@ private: **********************************************************************/ struct usrp2_impl::io_impl{ - io_impl(size_t num_mboards, size_t send_frame_size): - //the assumption is that all data transports should be identical + io_impl(std::vector &dsp_xports): + dsp_xports(dsp_xports), //the assumption is that all data transports should be identical get_recv_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_recv_buffs, this, _1)), get_send_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_send_buffs, this, _1)), - packet_handler_recv_state(num_mboards*usrp2_mboard_impl::NUM_RX_DSPS), //max chans - packet_handler_send_state(num_mboards*usrp2_mboard_impl::NUM_RX_DSPS), //max chans async_msg_fifo(100/*messages deep*/) { - for (size_t i = 0; i < num_mboards; i++){ //only one monitor per mboard (only 1 tx dsp so far) - fc_mons.push_back(flow_control_monitor::sptr( //OMG TODO this will not be mapped right when a tx is disabled - new flow_control_monitor(usrp2_impl::sram_bytes/send_frame_size) - )); + size_t num_monitors = dsp_xports.size()/usrp2_mboard_impl::MAX_NUM_DSPS*usrp2_mboard_impl::NUM_TX_DSPS; + for (size_t i = 0; i < num_monitors; i++){ + fc_mons.push_back(flow_control_monitor::sptr(new flow_control_monitor( + usrp2_impl::sram_bytes/dsp_xports.front()->get_send_frame_size() + ))); //init empty packet infos vrt::if_packet_info_t packet_info; packet_info.packet_count = 0xf; @@ -150,15 +149,15 @@ struct usrp2_impl::io_impl{ } bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs){ - UHD_ASSERT_THROW(send_xports.size() == buffs.size()); + UHD_ASSERT_THROW(send_map.size() == buffs.size()); //calculate the flow control word const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq; //grab a managed buffer for each index for (size_t i = 0; i < buffs.size(); i++){ - if (not fc_mons[i]->check_fc_condition(fc_word32, send_timeout)) return false; - buffs[i] = send_xports[i]->get_send_buff(send_timeout); + if (not fc_mons[send_map[i]]->check_fc_condition(fc_word32, send_timeout)) return false; + buffs[i] = dsp_xports[send_map[i]]->get_send_buff(send_timeout); if (not buffs[i].get()) return false; buffs[i]->cast()[0] = uhd::htonx(fc_word32); } @@ -167,8 +166,10 @@ struct usrp2_impl::io_impl{ bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs); - //vector of send and recv xports to be mapped to channels - std::vector recv_xports, send_xports; + std::vector &dsp_xports; + + //mappings from channel index to dsp xport + std::vector send_map, recv_map; //timeouts set on calls to recv/send (passed into get buffs methods) double recv_timeout, send_timeout; @@ -188,7 +189,7 @@ struct usrp2_impl::io_impl{ vrt_packet_handler::send_state packet_handler_send_state; //methods and variables for the pirate crew - void recv_pirate_loop(usrp2_mboard_impl::sptr, size_t); + void recv_pirate_loop(usrp2_mboard_impl::sptr, zero_copy_if::sptr, size_t); boost::thread_group recv_pirate_crew; bool recv_pirate_crew_raiding; bounded_buffer async_msg_fifo; @@ -202,7 +203,7 @@ struct usrp2_impl::io_impl{ * - put async message packets into queue **********************************************************************/ void usrp2_impl::io_impl::recv_pirate_loop( - usrp2_mboard_impl::sptr mboard, size_t index + usrp2_mboard_impl::sptr mboard, zero_copy_if::sptr err_xport, size_t index ){ set_thread_priority_safe(); recv_pirate_crew_raiding = true; @@ -210,7 +211,7 @@ void usrp2_impl::io_impl::recv_pirate_loop( spawn_mutex.unlock(); while(recv_pirate_crew_raiding){ - managed_recv_buffer::sptr buff = mboard->err_xports[0]->get_recv_buff(); + managed_recv_buffer::sptr buff = err_xport->get_recv_buff(); if (not buff.get()) continue; //ignore timeout/error buffers try{ @@ -259,7 +260,7 @@ void usrp2_impl::io_impl::recv_pirate_loop( void usrp2_impl::io_init(void){ //create new io impl - _io_impl = UHD_PIMPL_MAKE(io_impl, (_mboards.size(), this->send_frame_size)); + _io_impl = UHD_PIMPL_MAKE(io_impl, (dsp_xports)); //create a new pirate thread for each zc if (yarr!!) for (size_t i = 0; i < _mboards.size(); i++){ @@ -268,7 +269,7 @@ void usrp2_impl::io_init(void){ //spawn a new pirate to plunder the recv booty _io_impl->recv_pirate_crew.create_thread(boost::bind( &usrp2_impl::io_impl::recv_pirate_loop, - _io_impl.get(), _mboards.at(i), i + _io_impl.get(), _mboards.at(i), err_xports.at(i), i )); //block here until the spawned thread unlocks _io_impl->spawn_mutex.lock(); @@ -283,21 +284,27 @@ void usrp2_impl::io_init(void){ void usrp2_impl::update_xport_channel_mapping(void){ if (_io_impl.get() == NULL) return; //not inited yet - _io_impl->recv_xports.clear(); - _io_impl->send_xports.clear(); - BOOST_FOREACH(usrp2_mboard_impl::sptr mboard, _mboards){ + _io_impl->recv_map.clear(); + _io_impl->send_map.clear(); + + for (size_t i = 0; i < _mboards.size(); i++){ - subdev_spec_t rx_subdev_spec = mboard->get_link()[MBOARD_PROP_RX_SUBDEV_SPEC].as(); + subdev_spec_t rx_subdev_spec = _mboards[i]->get_link()[MBOARD_PROP_RX_SUBDEV_SPEC].as(); for (size_t j = 0; j < rx_subdev_spec.size(); j++){ - _io_impl->recv_xports.push_back(mboard->dsp_xports.at(j)); + _io_impl->recv_map.push_back(i*usrp2_mboard_impl::MAX_NUM_DSPS+j); + //std::cout << "recv_map.back() " << _io_impl->recv_map.back() << std::endl; } - subdev_spec_t tx_subdev_spec = mboard->get_link()[MBOARD_PROP_TX_SUBDEV_SPEC].as(); + subdev_spec_t tx_subdev_spec = _mboards[i]->get_link()[MBOARD_PROP_TX_SUBDEV_SPEC].as(); for (size_t j = 0; j < tx_subdev_spec.size(); j++){ - _io_impl->send_xports.push_back(mboard->dsp_xports.at(j)); + _io_impl->send_map.push_back(i*usrp2_mboard_impl::MAX_NUM_DSPS+j); + //std::cout << "send_map.back() " << _io_impl->send_map.back() << std::endl; } } + + _io_impl->packet_handler_recv_state = vrt_packet_handler::recv_state(_io_impl->recv_map.size()); + _io_impl->packet_handler_send_state = vrt_packet_handler::send_state(_io_impl->send_map.size()); } /*********************************************************************** @@ -319,7 +326,7 @@ size_t usrp2_impl::get_max_send_samps_per_packet(void) const{ + vrt_send_header_offset_words32*sizeof(boost::uint32_t) - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - const size_t bpp = this->send_frame_size - hdr_size; + const size_t bpp = dsp_xports.front()->get_send_frame_size() - hdr_size; return bpp/_tx_otw_type.get_sample_size(); } @@ -402,7 +409,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( vrt_packet_handler::managed_recv_buffs_t &buffs ){ if (buffs.size() == 1){ - buffs[0] = recv_xports[0]->get_recv_buff(recv_timeout); + buffs[0] = dsp_xports[recv_map[0]]->get_recv_buff(recv_timeout); if (buffs[0].get() == NULL) return false; bool clear, msg; time_spec_t time; //unused variables //call extract_packet_info to handle printing the overflows @@ -423,7 +430,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( //do an initial pop to load an initial sequence id size_t index = indexes_to_do.front(); - buff_tmp = recv_xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); + buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); if (buff_tmp.get() == NULL) return false; extract_packet_info(buff_tmp, this->prev_infos[index], expected_time, clear, msg); if (clear) goto got_clear; @@ -436,7 +443,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( //pop an element off for this index index = indexes_to_do.front(); - buff_tmp = recv_xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); + buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); if (buff_tmp.get() == NULL) return false; time_spec_t this_time; extract_packet_info(buff_tmp, this->prev_infos[index], this_time, clear, msg); @@ -477,7 +484,7 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{ + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; - const size_t bpp = this->recv_frame_size - hdr_size; + const size_t bpp = dsp_xports.front()->get_recv_frame_size() - hdr_size; return bpp/_rx_otw_type.get_sample_size(); } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 8db295042..e8e3ecd31 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -78,26 +78,22 @@ usrp2_mboard_impl::usrp2_mboard_impl( //construct transports for dsp and async errors std::cout << "Making transport for DSP0..." << std::endl; - dsp_xports.push_back(udp_zero_copy::make( + device.dsp_xports.push_back(udp_zero_copy::make( device_addr["addr"], boost::lexical_cast(USRP2_UDP_DSP0_PORT), dsp_xport_hints )); - init_xport(dsp_xports.back()); + init_xport(device.dsp_xports.back()); std::cout << "Making transport for DSP1..." << std::endl; - dsp_xports.push_back(udp_zero_copy::make( + device.dsp_xports.push_back(udp_zero_copy::make( device_addr["addr"], boost::lexical_cast(USRP2_UDP_DSP1_PORT), dsp_xport_hints )); - init_xport(dsp_xports.back()); + init_xport(device.dsp_xports.back()); std::cout << "Making transport for ERR0..." << std::endl; - err_xports.push_back(udp_zero_copy::make( + device.err_xports.push_back(udp_zero_copy::make( device_addr["addr"], boost::lexical_cast(USRP2_UDP_ERR0_PORT), device_addr_t() )); - init_xport(err_xports.back()); - - //set the frame sizes (assume homogeneous) - device.recv_frame_size = dsp_xports.front()->get_recv_frame_size(); - device.send_frame_size = dsp_xports.front()->get_send_frame_size(); + init_xport(device.err_xports.back()); //contruct the interfaces to mboard perifs _clock_ctrl = usrp2_clock_ctrl::make(_iface); @@ -119,9 +115,10 @@ usrp2_mboard_impl::usrp2_mboard_impl( } //setting the packets per update (enabled by default) + size_t send_frame_size = device.dsp_xports[0]->get_send_frame_size(); const double ups_per_fifo = device_args.cast("ups_per_fifo", 8.0); if (ups_per_fifo > 0.0){ - const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/dsp_xports[0]->get_send_frame_size()); + const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/send_frame_size); _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up); } @@ -160,10 +157,11 @@ usrp2_mboard_impl::usrp2_mboard_impl( //This is a hack/fix for the lingering packet problem. stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); for (size_t i = 0; i < NUM_RX_DSPS; i++){ + size_t index = device.dsp_xports.size() - NUM_RX_DSPS + i; stream_cmd.num_samps = 1; this->issue_ddc_stream_cmd(stream_cmd, i); - dsp_xports[i]->get_recv_buff().get(); //recv with timeout for lingering - dsp_xports[i]->get_recv_buff().get(); //recv with timeout for expected + device.dsp_xports.at(index)->get_recv_buff(0.01).get(); //recv with timeout for lingering + device.dsp_xports.at(index)->get_recv_buff(0.01).get(); //recv with timeout for expected _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //resets sequence } } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 4f68b630e..df55e6a99 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -84,6 +84,7 @@ public: static const size_t NUM_RX_DSPS = 2; static const size_t NUM_TX_DSPS = 1; + static const size_t MAX_NUM_DSPS = 2; //structors usrp2_mboard_impl( @@ -99,9 +100,6 @@ public: void handle_overflow(size_t); - std::vector dsp_xports; - std::vector err_xports; - private: size_t _index; usrp2_impl &_device; @@ -204,6 +202,9 @@ public: //public frame sizes, set by mboard, used by io impl size_t recv_frame_size, send_frame_size; + std::vector dsp_xports; + std::vector err_xports; + private: //device properties interface void get(const wax::obj &, wax::obj &); -- cgit v1.2.3 From 3261b89eeb96a6b87bc35c86be3faf78aee569b0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 21 Feb 2011 15:56:48 -0800 Subject: usrp2: 2nd dsp working, tweaks regs map and other bugs --- host/lib/usrp/usrp2/io_impl.cpp | 34 ++++++++++++++++++---------------- host/lib/usrp/usrp2/mboard_impl.cpp | 2 ++ host/lib/usrp/usrp2/usrp2_impl.hpp | 1 + host/lib/usrp/usrp2/usrp2_regs.cpp | 4 ++-- 4 files changed, 23 insertions(+), 18 deletions(-) (limited to 'host/lib/usrp/usrp2/io_impl.cpp') diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index e931778fa..e59ee2d24 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -130,16 +130,17 @@ struct usrp2_impl::io_impl{ for (size_t i = 0; i < num_monitors; i++){ fc_mons.push_back(flow_control_monitor::sptr(new flow_control_monitor( usrp2_impl::sram_bytes/dsp_xports.front()->get_send_frame_size() - ))); - //init empty packet infos - vrt::if_packet_info_t packet_info; - packet_info.packet_count = 0xf; - packet_info.has_tsi = true; - packet_info.tsi = 0; - packet_info.has_tsf = true; - packet_info.tsf = 0; - prev_infos.push_back(packet_info); + )));; } + + //init empty packet infos + vrt::if_packet_info_t packet_info = vrt::if_packet_info_t(); + packet_info.packet_count = 0xf; + packet_info.has_tsi = true; + packet_info.tsi = 0; + packet_info.has_tsf = true; + packet_info.tsf = 0; + prev_infos.resize(dsp_xports.size(), packet_info); } ~io_impl(void){ @@ -413,10 +414,11 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( if (buffs[0].get() == NULL) return false; bool clear, msg; time_spec_t time; //unused variables //call extract_packet_info to handle printing the overflows - extract_packet_info(buffs[0], this->prev_infos[0], time, clear, msg); + extract_packet_info(buffs[0], this->prev_infos[recv_map[0]], time, clear, msg); return true; } //-------------------- begin alignment logic ---------------------// + UHD_ASSERT_THROW(recv_map.size() == buffs.size()); boost::system_time exit_time = boost::get_system_time() + to_time_dur(recv_timeout); managed_recv_buffer::sptr buff_tmp; alignment_indexes indexes_to_do; @@ -432,7 +434,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( size_t index = indexes_to_do.front(); buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); if (buff_tmp.get() == NULL) return false; - extract_packet_info(buff_tmp, this->prev_infos[index], expected_time, clear, msg); + extract_packet_info(buff_tmp, this->prev_infos[recv_map[index]], expected_time, clear, msg); if (clear) goto got_clear; buffs[index] = buff_tmp; if (msg) return handle_msg_packet(buffs, index); @@ -446,7 +448,7 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); if (buff_tmp.get() == NULL) return false; time_spec_t this_time; - extract_packet_info(buff_tmp, this->prev_infos[index], this_time, clear, msg); + extract_packet_info(buff_tmp, this->prev_infos[recv_map[index]], this_time, clear, msg); if (clear) goto got_clear; buffs[index] = buff_tmp; if (msg) return handle_msg_packet(buffs, index); @@ -488,10 +490,10 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{ return bpp/_rx_otw_type.get_sample_size(); } -static void handle_overflow(std::vector &mboards, size_t chan){ +void usrp2_impl::handle_overflow(size_t chan){ std::cerr << "O" << std::flush; - //TODO this is wrong way to determine the index... - mboards.at(chan/mboards.size())->handle_overflow(chan%mboards.size()); + div_t indexes = div(chan, usrp2_mboard_impl::NUM_RX_DSPS); + _mboards.at(indexes.quot)->handle_overflow(indexes.rem); } size_t usrp2_impl::recv( @@ -508,6 +510,6 @@ size_t usrp2_impl::recv( _mboards.front()->get_master_clock_freq(), //master clock tick rate uhd::transport::vrt::if_hdr_unpack_be, _io_impl->get_recv_buffs_fcn, - boost::bind(&handle_overflow, boost::ref(_mboards), _1) + boost::bind(&usrp2_impl::handle_overflow, this, _1) ); } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index c7a91c69b..b8849f65b 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -153,6 +153,7 @@ usrp2_mboard_impl::usrp2_mboard_impl( (*this)[MBOARD_PROP_RX_SUBDEV_SPEC] = subdev_spec_t(); (*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t(); + //------------------------------------------------------------------ //This is a hack/fix for the lingering packet problem. stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); for (size_t i = 0; i < NUM_RX_DSPS; i++){ @@ -163,6 +164,7 @@ usrp2_mboard_impl::usrp2_mboard_impl( device.dsp_xports.at(index)->get_recv_buff(0.01).get(); //recv with timeout for expected _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //resets sequence } + //------------------------------------------------------------------ } usrp2_mboard_impl::~usrp2_mboard_impl(void){ diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index dbddd2ec0..0676cecf2 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -217,6 +217,7 @@ private: uhd::otw_type_t _rx_otw_type, _tx_otw_type; UHD_PIMPL_DECL(io_impl) _io_impl; void io_init(void); + void handle_overflow(size_t); }; #endif /* INCLUDED_USRP2_IMPL_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp index 31c904960..66c3ac137 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.cpp +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -76,7 +76,7 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) { x.dsp_rx[0].dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp0 + 3); x.dsp_rx[0].dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp0 + 4); x.dsp_rx[0].mux = sr_addr(misc_output_base, x.sr_rx_dsp0 + 5); - x.dsp_rx[1].freq = sr_addr(misc_output_base, x.sr_rx_dsp1 + 1); + x.dsp_rx[1].freq = sr_addr(misc_output_base, x.sr_rx_dsp1 + 0); x.dsp_rx[1].scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp1 + 1); x.dsp_rx[1].decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp1 + 2); x.dsp_rx[1].dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp1 + 3); @@ -103,7 +103,7 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) { x.rx_ctrl[0].vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 6); x.rx_ctrl[0].nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 7); x.rx_ctrl[0].nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 8); - x.rx_ctrl[1].stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 1); + x.rx_ctrl[1].stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 0); x.rx_ctrl[1].time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 1); x.rx_ctrl[1].time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 2); x.rx_ctrl[1].clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 3); -- cgit v1.2.3 From a75f38f971d36424b261bc3fbe571e5b9efbf3f1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 22 Feb 2011 14:36:30 -0800 Subject: usrp2: div->ldiv fix for overloaded types w/ msvc --- host/lib/usrp/usrp2/io_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host/lib/usrp/usrp2/io_impl.cpp') diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index e59ee2d24..6d7f0cce8 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -492,7 +492,7 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{ void usrp2_impl::handle_overflow(size_t chan){ std::cerr << "O" << std::flush; - div_t indexes = div(chan, usrp2_mboard_impl::NUM_RX_DSPS); + ldiv_t indexes = ldiv(chan, usrp2_mboard_impl::NUM_RX_DSPS); _mboards.at(indexes.quot)->handle_overflow(indexes.rem); } -- cgit v1.2.3 From fecb6365d8c547362f62ecfb36ea85140f1e9290 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 22 Feb 2011 14:53:47 -0800 Subject: usrp2: fixed flow control monitors indexing, fixed multi-usrp send bug --- host/lib/usrp/usrp2/io_impl.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'host/lib/usrp/usrp2/io_impl.cpp') diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 6d7f0cce8..b4f3e0873 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -126,8 +126,7 @@ struct usrp2_impl::io_impl{ get_send_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_send_buffs, this, _1)), async_msg_fifo(100/*messages deep*/) { - size_t num_monitors = dsp_xports.size()/usrp2_mboard_impl::MAX_NUM_DSPS*usrp2_mboard_impl::NUM_TX_DSPS; - for (size_t i = 0; i < num_monitors; i++){ + for (size_t i = 0; i < dsp_xports.size(); i++){ fc_mons.push_back(flow_control_monitor::sptr(new flow_control_monitor( usrp2_impl::sram_bytes/dsp_xports.front()->get_send_frame_size() )));; @@ -211,6 +210,9 @@ void usrp2_impl::io_impl::recv_pirate_loop( spawn_mutex.unlock(); + //store a reference to the flow control monitor (offset by max dsps) + flow_control_monitor &fc_mon = *(this->fc_mons[index*usrp2_mboard_impl::MAX_NUM_DSPS]); + while(recv_pirate_crew_raiding){ managed_recv_buffer::sptr buff = err_xport->get_recv_buff(); if (not buff.get()) continue; //ignore timeout/error buffers @@ -237,7 +239,7 @@ void usrp2_impl::io_impl::recv_pirate_loop( //catch the flow control packets and react if (metadata.event_code == 0){ boost::uint32_t fc_word32 = (vrt_hdr + if_packet_info.num_header_words32)[1]; - this->fc_mons[index]->update_fc_condition(uhd::ntohx(fc_word32)); + fc_mon.update_fc_condition(uhd::ntohx(fc_word32)); continue; } -- cgit v1.2.3