diff options
Diffstat (limited to 'host/lib/usrp/usrp2/mboard_impl.cpp')
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 98 |
1 files changed, 63 insertions, 35 deletions
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index a0e6adfad..805fd23db 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -20,6 +20,7 @@ #include <uhd/usrp/misc_utils.hpp> #include <uhd/usrp/dsp_utils.hpp> #include <uhd/usrp/mboard_props.hpp> +#include <uhd/usrp/mboard_rev.hpp> #include <uhd/utils/assert.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/types/mac_addr.hpp> @@ -28,9 +29,11 @@ #include <boost/assign/list_of.hpp> #include <boost/asio/ip/address_v4.hpp> #include <iostream> +#include <boost/date_time/posix_time/posix_time.hpp> using namespace uhd; using namespace uhd::usrp; +using namespace boost::posix_time; /*********************************************************************** * Structors @@ -45,15 +48,14 @@ usrp2_mboard_impl::usrp2_mboard_impl( { //make a new interface for usrp2 stuff _iface = usrp2_iface::make(ctrl_transport); - - //extract the mboard rev numbers - _rev_lo = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV_LSB, 1).at(0); - _rev_hi = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV_MSB, 1).at(0); - + //contruct the interfaces to mboard perifs _clock_ctrl = usrp2_clock_ctrl::make(_iface); _codec_ctrl = usrp2_codec_ctrl::make(_iface); _serdes_ctrl = usrp2_serdes_ctrl::make(_iface); + //_gps_ctrl = usrp2_gps_ctrl::make(_iface); + + //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 @@ -74,25 +76,25 @@ usrp2_mboard_impl::usrp2_mboard_impl( //most if not all junk packets will never make it to the socket. this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); - //init the rx control registers - _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _recv_frame_size); - _iface->poke32(U2_REG_RX_CTRL_NCHANNELS, 1); - _iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1); //reset - _iface->poke32(U2_REG_RX_CTRL_VRT_HEADER, 0 + //setup the vrt rx registers + _iface->poke32(_iface->regs.rx_ctrl_nsamps_per_pkt, _recv_frame_size); + _iface->poke32(_iface->regs.rx_ctrl_nchannels, 1); + _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //reset + _iface->poke32(_iface->regs.rx_ctrl_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(U2_REG_RX_CTRL_VRT_STREAM_ID, 0); - _iface->poke32(U2_REG_RX_CTRL_VRT_TRAILER, 0); - _iface->poke32(U2_REG_TIME64_TPS, size_t(get_master_clock_freq())); + _iface->poke32(_iface->regs.rx_ctrl_vrt_stream_id, 0); + _iface->poke32(_iface->regs.rx_ctrl_vrt_trailer, 0); + _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq())); //init the tx control registers - _iface->poke32(U2_REG_TX_CTRL_NUM_CHAN, 0); //1 channel - _iface->poke32(U2_REG_TX_CTRL_CLEAR_STATE, 1); //reset - _iface->poke32(U2_REG_TX_CTRL_REPORT_SID, 1); //sid 1 (different from rx) - _iface->poke32(U2_REG_TX_CTRL_POLICY, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); + _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0); //1 channel + _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset + _iface->poke32(_iface->regs.tx_ctrl_report_sid, 1); //sid 1 (different from rx) + _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); //init the ddc init_ddc_config(); @@ -149,39 +151,49 @@ void usrp2_mboard_impl::update_clock_config(void){ } //set the pps flags - _iface->poke32(U2_REG_TIME64_FLAGS, pps_flags); + _iface->poke32(_iface->regs.time64_flags, pps_flags); //clock source ref 10mhz - switch(_clock_config.ref_source){ - case clock_config_t::REF_INT : _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10); break; - case clock_config_t::REF_SMA : _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); break; - case clock_config_t::REF_MIMO: _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); break; - default: throw std::runtime_error("usrp2: unhandled clock configuration reference source"); + if(_iface->get_hw_rev().is_usrp2p()) { + switch(_clock_config.ref_source){ + case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break; + case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; + case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; + default: throw std::runtime_error("usrp2: unhandled clock configuration reference source"); + } + } else { + switch(_clock_config.ref_source){ + case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break; + case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; + case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; + default: throw std::runtime_error("usrp2: unhandled clock configuration reference source"); + } } //clock source ref 10mhz - bool use_external = _clock_config.ref_source != clock_config_t::REF_INT; + bool use_external = (_clock_config.ref_source != clock_config_t::REF_INT) + || (_iface->get_hw_rev().is_usrp2p()); //USRP2P has an internal 10MHz TCXO _clock_ctrl->enable_external_ref(use_external); } void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){ //set the ticks - _iface->poke32(U2_REG_TIME64_TICKS, time_spec.get_tick_count(get_master_clock_freq())); + _iface->poke32(_iface->regs.time64_ticks, time_spec.get_tick_count(get_master_clock_freq())); //set the flags register boost::uint32_t imm_flags = (now)? U2_FLAG_TIME64_LATCH_NOW : U2_FLAG_TIME64_LATCH_NEXT_PPS; - _iface->poke32(U2_REG_TIME64_IMM, imm_flags); + _iface->poke32(_iface->regs.time64_imm, imm_flags); //set the seconds (latches in all 3 registers) - _iface->poke32(U2_REG_TIME64_SECS, boost::uint32_t(time_spec.get_full_secs())); + _iface->poke32(_iface->regs.time64_secs, boost::uint32_t(time_spec.get_full_secs())); } void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ - _iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, dsp_type1::calc_stream_cmd_word( + _iface->poke32(_iface->regs.rx_ctrl_stream_cmd, dsp_type1::calc_stream_cmd_word( stream_cmd, _recv_frame_size )); - _iface->poke32(U2_REG_RX_CTRL_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); - _iface->poke32(U2_REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); + _iface->poke32(_iface->regs.rx_ctrl_time_secs, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); + _iface->poke32(_iface->regs.rx_ctrl_time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); } /*********************************************************************** @@ -206,12 +218,18 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ val = boost::asio::ip::address_v4(bytes).to_string(); return; } + + if (key.as<std::string>() == "hw-rev"){ + //extract the mboard rev number + val = _iface->get_hw_rev().to_string(); + return; + } } //handle the get request conditioned on the key switch(key.as<mboard_prop_t>()){ case MBOARD_PROP_NAME: - val = str(boost::format("usrp2 mboard%d - rev %d:%d") % _index % _rev_hi % _rev_lo); + val = str(boost::format("usrp2 mboard%d - rev %s") % _index % _iface->get_hw_rev().to_string()); return; case MBOARD_PROP_OTHERS:{ @@ -265,7 +283,7 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ case MBOARD_PROP_TIME_NOW:{ usrp2_iface::pair64 time64( - _iface->peek64(U2_REG_TIME64_SECS_RB, U2_REG_TIME64_TICKS_RB) + _iface->peek64(_iface->regs.time64_secs_rb, _iface->regs.time64_ticks_rb) ); val = time_spec_t( time64.first, time64.second, get_master_clock_freq() @@ -303,9 +321,19 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ _iface->write_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, bytes); return; } + + if (key.as<std::string>() == "hw-rev"){ + mboard_rev_t rev = mboard_rev_t::from_string(val.as<std::string>()); + byte_vector_t rev_bytes(2); + rev_bytes[1] = rev.to_uint16() >> 8; + rev_bytes[0] = rev.to_uint16() & 0xff; + _iface->write_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV, rev_bytes); + _iface->set_hw_rev(rev); //so the iface knows what rev it is + return; + } } - //handle the get request conditioned on the key + //handle the set request conditioned on the key switch(key.as<mboard_prop_t>()){ case MBOARD_PROP_CLOCK_CONFIG: @@ -331,7 +359,7 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ //sanity check UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1); //set the mux - _iface->poke32(U2_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( + _iface->poke32(_iface->regs.dsp_rx_mux, dsp_type1::calc_rx_mux_word( _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>() )); return; @@ -342,7 +370,7 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ //sanity check UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); //set the mux - _iface->poke32(U2_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( + _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<subdev_conn_t>() )); return; |