diff options
Diffstat (limited to 'host/lib/usrp/usrp2')
-rw-r--r-- | host/lib/usrp/usrp2/dboard_impl.cpp | 3 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/dboard_interface.cpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 68 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/fw_common.h | 16 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 121 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 88 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 29 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 24 |
8 files changed, 181 insertions, 170 deletions
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 66e02d469..fd72aeaa4 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -15,7 +15,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/types/clock_config.hpp> #include <boost/format.hpp> #include "usrp2_impl.hpp" diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index d20465147..8fc7864b0 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> #include "usrp2_impl.hpp" using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 34cce0afb..0d43fac0e 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> #include <boost/format.hpp> #include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> @@ -35,7 +35,7 @@ template <class T> T log2(T num){ /*********************************************************************** * DDC Helper Methods **********************************************************************/ -static boost::uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t clock_freq){ +static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq, double clock_freq){ double scale_factor = std::pow(2.0, 32); //calculate the freq register word @@ -63,9 +63,8 @@ void usrp2_impl::init_ddc_config(void){ _ddc_freq = 0; update_ddc_config(); - _ddc_stream_at = time_spec_t(); - _ddc_enabled = false; - update_ddc_enabled(); + //initial command that kills streaming (in case if was left on) + //issue_ddc_stream_cmd(TODO) } void usrp2_impl::update_ddc_config(void){ @@ -86,21 +85,19 @@ void usrp2_impl::update_ddc_config(void){ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE); } -void usrp2_impl::update_ddc_enabled(void){ +void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ //setup the out data usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO); - out_data.data.streaming.enabled = (_ddc_enabled)? 1 : 0; - out_data.data.streaming.secs = htonl(_ddc_stream_at.secs); - out_data.data.streaming.ticks = htonl(_ddc_stream_at.ticks); - out_data.data.streaming.samples = htonl(_max_rx_samples_per_packet); + out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO); + out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0; + out_data.data.stream_cmd.continuous = (stream_cmd.continuous)? 1 : 0; + out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs); + out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks); + out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps); //send and recv usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE); - - //clear the stream at time spec (it must be set for the next round of enable/disable) - _ddc_stream_at = time_spec_t(); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE); } /*********************************************************************** @@ -116,12 +113,12 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ case DSP_PROP_OTHERS:{ prop_names_t others = boost::assign::list_of - ("rate") + ("if_rate") + ("bb_rate") ("decim") ("decims") ("freq") - ("enabled") - ("stream_at") + ("stream_cmd") ; val = others; } @@ -131,10 +128,14 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ //handle string-based properties specific to this dsp std::string key_name = key.as<std::string>(); - if (key_name == "rate"){ + if (key_name == "if_rate"){ val = get_master_clock_freq(); return; } + else if (key_name == "bb_rate"){ + val = get_master_clock_freq()/_ddc_decim; + return; + } else if (key_name == "decim"){ val = _ddc_decim; return; @@ -147,10 +148,6 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ val = _ddc_freq; return; } - else if (key_name == "enabled"){ - val = _ddc_enabled; - return; - } throw std::invalid_argument(str( boost::format("error getting: unknown key with name %s") % key_name @@ -171,23 +168,15 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){ return; } else if (key_name == "freq"){ - freq_t new_freq = val.as<freq_t>(); + double new_freq = val.as<double>(); ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _ddc_freq = new_freq; //shadow update_ddc_config(); return; } - else if (key_name == "enabled"){ - bool new_enabled = val.as<bool>(); - _ddc_enabled = new_enabled; //shadow - update_ddc_enabled(); - return; - } - else if (key_name == "stream_at"){ - time_spec_t new_stream_at = val.as<time_spec_t>(); - _ddc_stream_at = new_stream_at; //shadow - //update_ddc_enabled(); //dont update from here + else if (key_name == "stream_cmd"){ + issue_ddc_stream_cmd(val.as<stream_cmd_t>()); return; } @@ -250,7 +239,8 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){ case DSP_PROP_OTHERS:{ prop_names_t others = boost::assign::list_of - ("rate") + ("if_rate") + ("bb_rate") ("interp") ("interps") ("freq") @@ -263,10 +253,14 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){ //handle string-based properties specific to this dsp std::string key_name = key.as<std::string>(); - if (key_name == "rate"){ + if (key_name == "if_rate"){ val = get_master_clock_freq(); return; } + else if (key_name == "bb_rate"){ + val = get_master_clock_freq()/_duc_interp; + return; + } else if (key_name == "interp"){ val = _duc_interp; return; @@ -299,7 +293,7 @@ void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){ return; } else if (key_name == "freq"){ - freq_t new_freq = val.as<freq_t>(); + double new_freq = val.as<double>(); ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _duc_freq = new_freq; //shadow diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 7fcae6fb2..30fee6c32 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -32,6 +32,9 @@ extern "C" { #define _SINS_ #endif +//used to differentiate control packets over data port +#define USRP2_INVALID_VRT_HEADER 0 + // size of the vrt header and trailer to the host #define USRP2_HOST_RX_VRT_HEADER_WORDS32 5 #define USRP2_HOST_RX_VRT_TRAILER_WORDS32 1 //FIXME fpga sets wrong header size when no trailer present @@ -90,8 +93,8 @@ typedef enum{ USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO, USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE, - USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO, - USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE, + USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO, + USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE, USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO, USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE, @@ -186,12 +189,13 @@ typedef struct{ _SINS_ uint32_t scale_iq; } ddc_args; struct { - _SINS_ uint8_t enabled; - _SINS_ uint8_t _pad[3]; + _SINS_ uint8_t now; //stream now? + _SINS_ uint8_t continuous; //auto-reload commmands? + _SINS_ uint8_t _pad[2]; _SINS_ uint32_t secs; _SINS_ uint32_t ticks; - _SINS_ uint32_t samples; - } streaming; + _SINS_ uint32_t num_samps; + } stream_cmd; struct { _SINS_ uint32_t freq_word; _SINS_ uint32_t interp; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index dc8eea243..c87884ebb 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -16,7 +16,6 @@ // #include <complex> -#include <algorithm> #include <boost/format.hpp> #include "usrp2_impl.hpp" @@ -42,20 +41,22 @@ void usrp2_impl::io_init(void){ _rx_copy_buff = asio::buffer("", 0); //send a small data packet so the usrp2 knows the udp source port - boost::uint32_t zero_data = 0; - _data_transport->send(asio::buffer(&zero_data, sizeof(zero_data))); + //and the maximum number of lines (32 bit words) per packet + boost::uint32_t data[2] = { + htonl(USRP2_INVALID_VRT_HEADER), + htonl(_max_rx_samples_per_packet) + }; + _data_transport->send(asio::buffer(&data, sizeof(data))); } -#define unrolled_loop(__i, __len, __inst) {\ +#define unrolled_loop(__inst, __len){ \ size_t __i = 0; \ - while(__i < (__len & ~0x7)){ \ - __inst; __i++; __inst; __i++; \ - __inst; __i++; __inst; __i++; \ - __inst; __i++; __inst; __i++; \ - __inst; __i++; __inst; __i++; \ + for(; __i < (__len & ~0x3); __i+= 4){ \ + __inst(__i+0); __inst(__i+1); \ + __inst(__i+2); __inst(__i+3); \ } \ - while(__i < __len){ \ - __inst; __i++;\ + for(; __i < __len; __i++){ \ + __inst(__i); \ } \ } @@ -71,11 +72,12 @@ static inline void host_floats_to_usrp2_items( const fc32_t *host_floats, size_t num_samps ){ - unrolled_loop(i, num_samps,{ - boost::uint16_t real = boost::int16_t(host_floats[i].real()*shorts_per_float); - boost::uint16_t imag = boost::int16_t(host_floats[i].imag()*shorts_per_float); - usrp2_items[i] = htonl((real << 16) | (imag << 0)); - }); + #define host_floats_to_usrp2_items_i(i){ \ + boost::uint16_t real = boost::int16_t(host_floats[i].real()*shorts_per_float); \ + boost::uint16_t imag = boost::int16_t(host_floats[i].imag()*shorts_per_float); \ + usrp2_items[i] = htonl((real << 16) | (imag << 0)); \ + } + unrolled_loop(host_floats_to_usrp2_items_i, num_samps); } static inline void usrp2_items_to_host_floats( @@ -83,12 +85,13 @@ static inline void usrp2_items_to_host_floats( const boost::uint32_t *usrp2_items, size_t num_samps ){ - unrolled_loop(i, num_samps,{ - boost::uint32_t item = ntohl(usrp2_items[i]); - boost::int16_t real = boost::uint16_t(item >> 16); - boost::int16_t imag = boost::uint16_t(item >> 0); - host_floats[i] = fc32_t(float(real*floats_per_short), float(imag*floats_per_short)); - }); + #define usrp2_items_to_host_floats_i(i){ \ + boost::uint32_t item = ntohl(usrp2_items[i]); \ + boost::int16_t real = boost::uint16_t(item >> 16); \ + boost::int16_t imag = boost::uint16_t(item >> 0); \ + host_floats[i] = fc32_t(float(real*floats_per_short), float(imag*floats_per_short)); \ + } + unrolled_loop(usrp2_items_to_host_floats_i, num_samps); } static inline void host_items_to_usrp2_items( @@ -96,11 +99,12 @@ static inline void host_items_to_usrp2_items( const boost::uint32_t *host_items, size_t num_samps ){ + #define host_items_to_usrp2_items_i(i) usrp2_items[i] = htonl(host_items[i]) if (is_big_endian){ std::memcpy(usrp2_items, host_items, num_samps*sizeof(boost::uint32_t)); } else{ - unrolled_loop(i, num_samps, usrp2_items[i] = htonl(host_items[i])); + unrolled_loop(host_items_to_usrp2_items_i, num_samps); } } @@ -109,11 +113,12 @@ static inline void usrp2_items_to_host_items( const boost::uint32_t *usrp2_items, size_t num_samps ){ + #define usrp2_items_to_host_items_i(i) host_items[i] = ntohl(usrp2_items[i]) if (is_big_endian){ std::memcpy(host_items, usrp2_items, num_samps*sizeof(boost::uint32_t)); } else{ - unrolled_loop(i, num_samps, host_items[i] = ntohl(usrp2_items[i])); + unrolled_loop(usrp2_items_to_host_items_i, num_samps); } } @@ -167,46 +172,43 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){ size_t usrp2_impl::send( const asio::const_buffer &buff, const tx_metadata_t &metadata, - const std::string &type + const io_type_t &io_type ){ boost::uint32_t tx_mem[_mtu/sizeof(boost::uint32_t)]; - boost::uint32_t *items = tx_mem + vrt::max_header_words32; //offset for data - size_t num_samps = _max_tx_samples_per_packet; - - //calculate the number of samples to be copied - //and copy the samples into the send buffer - if (type == "32fc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps); - host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps); - } - else if (type == "16sc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps); - host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps); - } - else{ - throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%s\"") % type)); - } + size_t num_samps = std::min( + asio::buffer_size(buff)/io_type.size, + size_t(_max_tx_samples_per_packet) + ); - boost::uint32_t vrt_hdr[vrt::max_header_words32]; 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 - vrt_hdr, //output + tx_mem, //output num_header_words32, //output num_samps, //input num_packet_words32, //output packet_count //input ); - //copy in the vrt header (yes we left space) - items -= num_header_words32; - std::memcpy(items, vrt_hdr, num_header_words32*sizeof(boost::uint32_t)); + boost::uint32_t *items = tx_mem + num_header_words32; //offset for data + + //copy the samples into the send buffer + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: + host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps); + break; + case io_type_t::COMPLEX_INT16: + host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps); + break; + default: + throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%c\"") % io_type.tid)); + } //send and return number of samples - _data_transport->send(asio::buffer(items, num_packet_words32*sizeof(boost::uint32_t))); + _data_transport->send(asio::buffer(tx_mem, num_packet_words32*sizeof(boost::uint32_t))); return num_samps; } @@ -216,7 +218,7 @@ size_t usrp2_impl::send( size_t usrp2_impl::recv( const asio::mutable_buffer &buff, rx_metadata_t &metadata, - const std::string &type + const io_type_t &io_type ){ //perform a receive if no rx data is waiting to be copied if (asio::buffer_size(_rx_copy_buff) == 0){ @@ -232,21 +234,22 @@ size_t usrp2_impl::recv( //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 = bytes_to_copy/sizeof(boost::uint32_t); + size_t num_samps = std::min( + asio::buffer_size(buff)/io_type.size, + bytes_to_copy/sizeof(boost::uint32_t) + ); const boost::uint32_t *items = asio::buffer_cast<const boost::uint32_t*>(_rx_copy_buff); - //calculate the number of samples to be copied - //and copy the samples from the recv buffer - if (type == "32fc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps); + //copy the samples from the recv buffer + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: usrp2_items_to_host_floats(asio::buffer_cast<fc32_t*>(buff), items, num_samps); - } - else if (type == "16sc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps); + break; + case io_type_t::COMPLEX_INT16: usrp2_items_to_host_items(asio::buffer_cast<boost::uint32_t*>(buff), items, num_samps); - } - else{ - throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%s\"") % type)); + break; + default: + throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%c\"") % io_type.tid)); } //update the rx copy buffer to reflect the bytes copied diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index cbca8eec7..35dfd6287 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -15,7 +15,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/types/mac_addr.hpp> #include "usrp2_impl.hpp" using namespace uhd; @@ -35,27 +36,10 @@ void usrp2_impl::mboard_init(void){ } void usrp2_impl::init_clock_config(void){ - //init the ref source clock config - _ref_source_dict = boost::assign::map_list_of - ("int", USRP2_REF_SOURCE_INT) - ("sma", USRP2_REF_SOURCE_SMA) - ("mimo", USRP2_REF_SOURCE_MIMO) - ; - _clock_config.ref_source = "int"; - - //init the pps source clock config - _pps_source_dict = boost::assign::map_list_of - ("sma", USRP2_PPS_SOURCE_SMA) - ("mimo", USRP2_PPS_SOURCE_MIMO) - ; - _clock_config.pps_source = "sma"; - - //init the pps polarity clock config - _pps_polarity_dict = boost::assign::map_list_of - (clock_config_t::POLARITY_POS, USRP2_PPS_POLARITY_POS) - (clock_config_t::POLARITY_NEG, USRP2_PPS_POLARITY_NEG) - ; - _clock_config.pps_polarity = clock_config_t::POLARITY_NEG; + //setup the clock configuration settings + _clock_config.ref_source = clock_config_t::REF_INT; + _clock_config.pps_source = clock_config_t::PPS_SMA; + _clock_config.pps_polarity = clock_config_t::PPS_NEG; //update the clock config (sends a control packet) update_clock_config(); @@ -65,9 +49,35 @@ void usrp2_impl::update_clock_config(void){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_HERES_A_NEW_CLOCK_CONFIG_BRO); - out_data.data.clock_config.ref_source = _ref_source_dict [_clock_config.ref_source]; - out_data.data.clock_config.pps_source = _pps_source_dict [_clock_config.pps_source]; - out_data.data.clock_config.pps_polarity = _pps_polarity_dict[_clock_config.pps_polarity]; + + //translate ref source enums + switch(_clock_config.ref_source){ + case clock_config_t::REF_INT: + out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_INT; break; + case clock_config_t::REF_SMA: + out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_SMA; break; + case clock_config_t::REF_MIMO: + out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_MIMO; break; + default: throw std::runtime_error("usrp2: unhandled clock configuration ref source"); + } + + //translate pps source enums + switch(_clock_config.pps_source){ + case clock_config_t::PPS_SMA: + out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_SMA; break; + case clock_config_t::PPS_MIMO: + out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_MIMO; break; + default: throw std::runtime_error("usrp2: unhandled clock configuration pps source"); + } + + //translate pps polarity enums + switch(_clock_config.pps_polarity){ + case clock_config_t::PPS_POS: + out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_POS; break; + case clock_config_t::PPS_NEG: + out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_NEG; break; + default: throw std::runtime_error("usrp2: unhandled clock configuration pps polarity"); + } //send and recv usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); @@ -106,7 +116,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE); //extract the address - val = reinterpret_cast<mac_addr_t*>(in_data.data.mac_addr)->to_string(); + val = mac_addr_t::from_bytes(in_data.data.mac_addr).to_string(); return; } @@ -159,7 +169,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_CLOCK_RATE: - val = freq_t(get_master_clock_freq()); + val = double(get_master_clock_freq()); return; case MBOARD_PROP_RX_DSP: @@ -184,14 +194,6 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = _clock_config; return; - case MBOARD_PROP_PPS_SOURCE_NAMES: - val = prop_names_t(_pps_source_dict.get_keys()); - return; - - case MBOARD_PROP_REF_SOURCE_NAMES: - val = prop_names_t(_ref_source_dict.get_keys()); - return; - case MBOARD_PROP_TIME_NOW: case MBOARD_PROP_TIME_NEXT_PPS: throw std::runtime_error("Error: trying to get write-only property on usrp2 mboard"); @@ -209,8 +211,8 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_HERE_IS_A_NEW_MAC_ADDR_BRO); - mac_addr_t mac_addr(val.as<std::string>()); - std::memcpy(out_data.data.mac_addr, &mac_addr, sizeof(mac_addr_t)); + mac_addr_t mac_addr = mac_addr_t::from_string(val.as<std::string>()); + std::copy(mac_addr.to_bytes(), mac_addr.to_bytes()+mac_addr_t::hlen, out_data.data.mac_addr); //send and recv usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); @@ -234,13 +236,9 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //handle the get request conditioned on the key switch(key.as<mboard_prop_t>()){ - case MBOARD_PROP_CLOCK_CONFIG:{ - clock_config_t clock_config = val.as<clock_config_t>(); - assert_has(_pps_source_dict.get_keys(), clock_config.pps_source, "usrp2 pps source"); - assert_has(_ref_source_dict.get_keys(), clock_config.ref_source, "usrp2 ref source"); - _clock_config = clock_config; //shadow - update_clock_config(); - } + case MBOARD_PROP_CLOCK_CONFIG: + _clock_config = val.as<clock_config_t>(); + update_clock_config(); return; case MBOARD_PROP_TIME_NOW:{ @@ -264,8 +262,6 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ case MBOARD_PROP_RX_DBOARD_NAMES: case MBOARD_PROP_TX_DBOARD: case MBOARD_PROP_TX_DBOARD_NAMES: - case MBOARD_PROP_PPS_SOURCE_NAMES: - case MBOARD_PROP_REF_SOURCE_NAMES: throw std::runtime_error("Error: trying to set read-only property on usrp2 mboard"); } diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 85d73e83a..67fbdf8d2 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -15,9 +15,12 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // +#include <uhd/transport/if_addrs.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/utils/static.hpp> #include <boost/format.hpp> +#include <boost/foreach.hpp> #include <boost/bind.hpp> -#include <uhd/utils.hpp> #include <iostream> #include "usrp2_impl.hpp" @@ -27,16 +30,33 @@ using namespace uhd::transport; namespace asio = boost::asio; STATIC_BLOCK(register_usrp2_device){ - device::register_device(&usrp2::discover, &usrp2::make); + device::register_device(&usrp2::find, &usrp2::make); } /*********************************************************************** * Discovery over the udp transport **********************************************************************/ -uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ +uhd::device_addrs_t usrp2::find(const device_addr_t &hint){ device_addrs_t usrp2_addrs; - if (not hint.has_key("addr")) return usrp2_addrs; + //if no address was specified, send a broadcast on each interface + if (not hint.has_key("addr")){ + BOOST_FOREACH(const if_addrs_t &if_addrs, get_if_addrs()){ + //avoid the loopback device + if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue; + + //create a new hint with this broadcast address + device_addr_t new_hint = hint; + new_hint["addr"] = if_addrs.bcast; + + //call discover with the new hint and append results + device_addrs_t new_usrp2_addrs = usrp2::find(new_hint); + usrp2_addrs.insert(usrp2_addrs.begin(), + new_usrp2_addrs.begin(), new_usrp2_addrs.end() + ); + } + return usrp2_addrs; + } //create a udp transport to communicate //TODO if an addr is not provided, search all interfaces? @@ -63,7 +83,6 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in.data.ip_addr)); device_addr_t new_addr; new_addr["name"] = "USRP2"; - new_addr["transport"] = "udp"; new_addr["addr"] = ip_addr.to_string(); usrp2_addrs.push_back(new_addr); //dont break here, it will exit the while loop diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 55ac0b192..3468a0cf1 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -19,9 +19,10 @@ #define INCLUDED_USRP2_IMPL_HPP #include <uhd/usrp/usrp2.hpp> -#include <uhd/dict.hpp> -#include <uhd/types.hpp> -#include <uhd/time_spec.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/types/stream_cmd.hpp> +#include <uhd/types/clock_config.hpp> +#include <boost/asio.hpp> #include <boost/thread.hpp> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> @@ -105,8 +106,8 @@ public: double get_master_clock_freq(void); //the io interface - size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &); - size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); + 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 &); private: //device properties interface @@ -146,11 +147,6 @@ private: void update_clock_config(void); void set_time_spec(const uhd::time_spec_t &time_spec, bool now); - //mappings from clock config strings to over the wire enums - uhd::dict<std::string, usrp2_ref_source_t> _ref_source_dict; - uhd::dict<std::string, usrp2_pps_source_t> _pps_source_dict; - uhd::dict<uhd::clock_config_t::polarity_t, usrp2_pps_polarity_t> _pps_polarity_dict; - //rx and tx dboard methods and objects uhd::usrp::dboard_manager::sptr _dboard_manager; void dboard_init(void); @@ -177,16 +173,14 @@ private: //methods and shadows for the ddc dsp std::vector<size_t> _allowed_decim_and_interp_rates; size_t _ddc_decim; - uhd::freq_t _ddc_freq; - bool _ddc_enabled; - uhd::time_spec_t _ddc_stream_at; + double _ddc_freq; void init_ddc_config(void); void update_ddc_config(void); - void update_ddc_enabled(void); + void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd); //methods and shadows for the duc dsp size_t _duc_interp; - uhd::freq_t _duc_freq; + double _duc_freq; void init_duc_config(void); void update_duc_config(void); |