diff options
author | Josh Blum <josh@joshknows.com> | 2011-03-03 19:26:32 -0800 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-03-03 19:26:32 -0800 |
commit | d93a2cf7c904964ba7f41f4d654b18e099df7451 (patch) | |
tree | a55f8d56904a8a4f8fe96dbf7c38177b4c662c5c /host/lib/usrp/usrp2 | |
parent | 942c69b710510e6143a6f3c22bbe3ff0687f4bc6 (diff) | |
download | uhd-d93a2cf7c904964ba7f41f4d654b18e099df7451.tar.gz uhd-d93a2cf7c904964ba7f41f4d654b18e099df7451.tar.bz2 uhd-d93a2cf7c904964ba7f41f4d654b18e099df7451.zip |
usrp2: work on mtu discovery
added echo routine to the firmware and discovery routine to host
the implementation is integrated into the factory function and appears to work on linux
Diffstat (limited to 'host/lib/usrp/usrp2')
-rw-r--r-- | host/lib/usrp/usrp2/fw_common.h | 6 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 96 |
3 files changed, 95 insertions, 15 deletions
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 6eb047454..68c49cafc 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -89,6 +89,9 @@ typedef enum{ USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO = 'v', USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE = 'V', + USRP2_CTRL_ID_HOLLER_AT_ME_BRO = 'l', + USRP2_CTRL_ID_HOLLER_BACK_DUDE = 'L', + USRP2_CTRL_ID_PEACE_OUT = '~' } usrp2_ctrl_id_t; @@ -133,6 +136,9 @@ typedef struct{ uint8_t bytes; uint8_t data[20]; } uart_args; + struct { + uint32_t len; + } echo_args; } data; } usrp2_ctrl_data_t; diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 5cb4e4d34..0a6fefca6 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -62,25 +62,25 @@ usrp2_mboard_impl::usrp2_mboard_impl( ): _index(index), _device(device), _iface(usrp2_iface::make(udp_simple::make_connected( - device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT) + device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) ))) { //construct transports for dsp and async errors std::cout << "Making transport for DSP0..." << std::endl; device.dsp_xports.push_back(udp_zero_copy::make( - device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_DSP0_PORT), device_addr + device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_DSP0_PORT), device_addr )); init_xport(device.dsp_xports.back()); std::cout << "Making transport for DSP1..." << std::endl; device.dsp_xports.push_back(udp_zero_copy::make( - device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_DSP1_PORT), device_addr + device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_DSP1_PORT), device_addr )); init_xport(device.dsp_xports.back()); std::cout << "Making transport for ERR0..." << std::endl; device.err_xports.push_back(udp_zero_copy::make( - device_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_ERR0_PORT), device_addr_t() + device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_ERR0_PORT), device_addr_t() )); init_xport(device.err_xports.back()); diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 651e9a89b..164253f96 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -143,7 +143,75 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){ /*********************************************************************** * Make **********************************************************************/ -static device::sptr usrp2_make(const device_addr_t &_device_addr){ +static device::sptr usrp2_make(const device_addr_t &device_addr){ + return device::sptr(new usrp2_impl(device_addr)); +} + +UHD_STATIC_BLOCK(register_usrp2_device){ + device::register_device(&usrp2_find, &usrp2_make); +} + +/*********************************************************************** + * MTU Discovery + **********************************************************************/ +struct mtu_result_t{ + size_t recv_mtu, send_mtu; +}; + +static mtu_result_t determine_mtu(const std::string &addr){ + udp_simple::sptr udp_sock = udp_simple::make_connected( + addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) + ); + + mtu_result_t mtu; + boost::uint8_t buffer[2000]; //FIXME use real FPGA buffer maximum + usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(buffer); + static const double echo_timeout = 0.010; //10 ms + + size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = sizeof(buffer); + size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = sizeof(buffer); + + while (min_recv_mtu + 4 < max_recv_mtu){ + + mtu.recv_mtu = (max_recv_mtu + min_recv_mtu)/2 & ~(4-1); + //std::cout << "recv_mtu " << mtu.recv_mtu << std::endl; + + ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); + ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); + ctrl_data->data.echo_args.len = htonl(mtu.recv_mtu); + udp_sock->send(boost::asio::buffer(buffer, sizeof(usrp2_ctrl_data_t))); + + size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout); + + if (len >= mtu.recv_mtu) min_recv_mtu = mtu.recv_mtu; + else max_recv_mtu = mtu.recv_mtu; + + } + + while (min_send_mtu + 4 < max_send_mtu){ + + mtu.send_mtu = (max_send_mtu + min_send_mtu)/2 & ~(4-1); + //std::cout << "send_mtu " << mtu.send_mtu << std::endl; + + ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); + ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); + ctrl_data->data.echo_args.len = htonl(sizeof(usrp2_ctrl_data_t)); + udp_sock->send(boost::asio::buffer(buffer, mtu.send_mtu)); + + size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout); + if (len >= sizeof(usrp2_ctrl_data_t)) len = ntohl(ctrl_data->data.echo_args.len); + + if (len >= mtu.send_mtu) min_send_mtu = mtu.send_mtu; + else max_send_mtu = mtu.send_mtu; + } + + return mtu; +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){ device_addr_t device_addr = _device_addr; //setup the dsp transport hints (default to a large recv buff) @@ -157,18 +225,24 @@ static device::sptr usrp2_make(const device_addr_t &_device_addr){ #endif } - return device::sptr(new usrp2_impl(device_addr)); -} + device_addrs_t device_args = separate_device_addr(device_addr); -UHD_STATIC_BLOCK(register_usrp2_device){ - device::register_device(&usrp2_find, &usrp2_make); -} + //calculate the minimum send and recv mtu of all devices + mtu_result_t mtu = determine_mtu(device_args[0]["addr"]); + for (size_t i = 1; i < device_args.size(); i++){ + mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"]); + mtu.recv_mtu = std::min(mtu.recv_mtu, mtu_i.recv_mtu); + mtu.send_mtu = std::min(mtu.send_mtu, mtu_i.send_mtu); + } -/*********************************************************************** - * Structors - **********************************************************************/ -usrp2_impl::usrp2_impl(const device_addr_t &device_addr){ - device_addrs_t device_args = separate_device_addr(device_addr); + std::cout << "mtu recv bytes " << mtu.recv_mtu << std::endl; + std::cout << "mtu send bytes " << mtu.send_mtu << std::endl; + + //use the discovered mtu if not specified by the user + if (not device_addr.has_key("recv_frame_size")) + device_addr["recv_frame_size"] = boost::lexical_cast<std::string>(mtu.recv_mtu); + if (not device_addr.has_key("send_frame_size")) + device_addr["send_frame_size"] = boost::lexical_cast<std::string>(mtu.send_mtu); //setup rx otw type _rx_otw_type.width = 16; |