diff options
Diffstat (limited to 'host/lib/usrp/x300/x300_impl.cpp')
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 1692 |
1 files changed, 859 insertions, 833 deletions
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 7d2ce6b28..ed6678761 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -7,29 +7,28 @@ #include "x300_impl.hpp" #include "x300_lvbitx.hpp" -#include "x310_lvbitx.hpp" #include "x300_mb_eeprom_iface.hpp" -#include <uhdlib/usrp/common/apply_corrections.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/log.hpp> -#include <uhd/utils/paths.hpp> -#include <uhd/utils/safe_call.hpp> -#include <uhd/usrp/subdev_spec.hpp> +#include "x310_lvbitx.hpp" #include <uhd/transport/if_addrs.hpp> -#include <uhd/transport/udp_zero_copy.hpp> +#include <uhd/transport/nirio/niusrprio_session.h> +#include <uhd/transport/nirio_zero_copy.hpp> #include <uhd/transport/udp_constants.hpp> +#include <uhd/transport/udp_zero_copy.hpp> #include <uhd/transport/zero_copy_recv_offload.hpp> -#include <uhd/transport/nirio_zero_copy.hpp> -#include <uhd/transport/nirio/niusrprio_session.h> -#include <uhd/utils/platform.hpp> #include <uhd/types/sid.hpp> +#include <uhd/usrp/subdev_spec.hpp> +#include <uhd/utils/log.hpp> #include <uhd/utils/math.hpp> - +#include <uhd/utils/paths.hpp> +#include <uhd/utils/platform.hpp> +#include <uhd/utils/safe_call.hpp> +#include <uhd/utils/static.hpp> +#include <uhdlib/usrp/common/apply_corrections.hpp> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <boost/make_shared.hpp> -#include <fstream> #include <chrono> +#include <fstream> #include <thread> using namespace uhd; @@ -45,27 +44,28 @@ namespace asio = boost::asio; /****************************************************************************** * Helpers *****************************************************************************/ -static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) { - //Possible options: - //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM - //HA = {0:1G, 1:Aurora} w/ DRAM, XA = {0:10G, 1:Aurora} w/ DRAM +static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) +{ + // Possible options: + // 1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ + // DRAM HA = {0:1G, 1:Aurora} w/ DRAM, XA = {0:10G, 1:Aurora} w/ DRAM std::string option; uint32_t sfp0_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP0_TYPE)); uint32_t sfp1_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP1_TYPE)); - if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_1G_ETH) { + if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_1G_ETH) { option = "1G"; - } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_10G_ETH) { + } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_10G_ETH) { option = "HG"; - } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_10G_ETH) { + } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_10G_ETH) { option = "XG"; - } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_AURORA) { + } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_AURORA) { option = "HA"; - } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_AURORA) { + } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_AURORA) { option = "XA"; } else { - option = "HG"; //Default + option = "HG"; // Default } return option; } @@ -73,153 +73,150 @@ static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) { namespace { - /*! Return the correct motherboard type for a given product ID - * - * Note: In previous versions, we had two different mappings for PCIe and - * Ethernet in case the PIDs would conflict, but they never did and it was - * thus consolidated into one. - */ - x300_impl::x300_mboard_t map_pid_to_mb_type(const uint32_t pid) - { - switch (pid) { - case X300_USRP_PCIE_SSID_ADC_33: - case X300_USRP_PCIE_SSID_ADC_18: - return x300_impl::USRP_X300_MB; - case X310_USRP_PCIE_SSID_ADC_33: - case X310_2940R_40MHz_PCIE_SSID_ADC_33: - case X310_2940R_120MHz_PCIE_SSID_ADC_33: - case X310_2942R_40MHz_PCIE_SSID_ADC_33: - case X310_2942R_120MHz_PCIE_SSID_ADC_33: - case X310_2943R_40MHz_PCIE_SSID_ADC_33: - case X310_2943R_120MHz_PCIE_SSID_ADC_33: - case X310_2944R_40MHz_PCIE_SSID_ADC_33: - case X310_2950R_40MHz_PCIE_SSID_ADC_33: - case X310_2950R_120MHz_PCIE_SSID_ADC_33: - case X310_2952R_40MHz_PCIE_SSID_ADC_33: - case X310_2952R_120MHz_PCIE_SSID_ADC_33: - case X310_2953R_40MHz_PCIE_SSID_ADC_33: - case X310_2953R_120MHz_PCIE_SSID_ADC_33: - case X310_2954R_40MHz_PCIE_SSID_ADC_33: - case X310_USRP_PCIE_SSID_ADC_18: - case X310_2940R_40MHz_PCIE_SSID_ADC_18: - case X310_2940R_120MHz_PCIE_SSID_ADC_18: - case X310_2942R_40MHz_PCIE_SSID_ADC_18: - case X310_2942R_120MHz_PCIE_SSID_ADC_18: - case X310_2943R_40MHz_PCIE_SSID_ADC_18: - case X310_2943R_120MHz_PCIE_SSID_ADC_18: - case X310_2944R_40MHz_PCIE_SSID_ADC_18: - case X310_2945R_PCIE_SSID_ADC_18: - case X310_2950R_40MHz_PCIE_SSID_ADC_18: - case X310_2950R_120MHz_PCIE_SSID_ADC_18: - case X310_2952R_40MHz_PCIE_SSID_ADC_18: - case X310_2952R_120MHz_PCIE_SSID_ADC_18: - case X310_2953R_40MHz_PCIE_SSID_ADC_18: - case X310_2953R_120MHz_PCIE_SSID_ADC_18: - case X310_2954R_40MHz_PCIE_SSID_ADC_18: - case X310_2955R_PCIE_SSID_ADC_18: - return x300_impl::USRP_X310_MB; - case X310_2974_PCIE_SSID_ADC_18: - return x300_impl::USRP_X310_MB_NI_2974; - default: - return x300_impl::UNKNOWN; - } - UHD_THROW_INVALID_CODE_PATH(); +/*! Return the correct motherboard type for a given product ID + * + * Note: In previous versions, we had two different mappings for PCIe and + * Ethernet in case the PIDs would conflict, but they never did and it was + * thus consolidated into one. + */ +x300_impl::x300_mboard_t map_pid_to_mb_type(const uint32_t pid) +{ + switch (pid) { + case X300_USRP_PCIE_SSID_ADC_33: + case X300_USRP_PCIE_SSID_ADC_18: + return x300_impl::USRP_X300_MB; + case X310_USRP_PCIE_SSID_ADC_33: + case X310_2940R_40MHz_PCIE_SSID_ADC_33: + case X310_2940R_120MHz_PCIE_SSID_ADC_33: + case X310_2942R_40MHz_PCIE_SSID_ADC_33: + case X310_2942R_120MHz_PCIE_SSID_ADC_33: + case X310_2943R_40MHz_PCIE_SSID_ADC_33: + case X310_2943R_120MHz_PCIE_SSID_ADC_33: + case X310_2944R_40MHz_PCIE_SSID_ADC_33: + case X310_2950R_40MHz_PCIE_SSID_ADC_33: + case X310_2950R_120MHz_PCIE_SSID_ADC_33: + case X310_2952R_40MHz_PCIE_SSID_ADC_33: + case X310_2952R_120MHz_PCIE_SSID_ADC_33: + case X310_2953R_40MHz_PCIE_SSID_ADC_33: + case X310_2953R_120MHz_PCIE_SSID_ADC_33: + case X310_2954R_40MHz_PCIE_SSID_ADC_33: + case X310_USRP_PCIE_SSID_ADC_18: + case X310_2940R_40MHz_PCIE_SSID_ADC_18: + case X310_2940R_120MHz_PCIE_SSID_ADC_18: + case X310_2942R_40MHz_PCIE_SSID_ADC_18: + case X310_2942R_120MHz_PCIE_SSID_ADC_18: + case X310_2943R_40MHz_PCIE_SSID_ADC_18: + case X310_2943R_120MHz_PCIE_SSID_ADC_18: + case X310_2944R_40MHz_PCIE_SSID_ADC_18: + case X310_2945R_PCIE_SSID_ADC_18: + case X310_2950R_40MHz_PCIE_SSID_ADC_18: + case X310_2950R_120MHz_PCIE_SSID_ADC_18: + case X310_2952R_40MHz_PCIE_SSID_ADC_18: + case X310_2952R_120MHz_PCIE_SSID_ADC_18: + case X310_2953R_40MHz_PCIE_SSID_ADC_18: + case X310_2953R_120MHz_PCIE_SSID_ADC_18: + case X310_2954R_40MHz_PCIE_SSID_ADC_18: + case X310_2955R_PCIE_SSID_ADC_18: + return x300_impl::USRP_X310_MB; + case X310_2974_PCIE_SSID_ADC_18: + return x300_impl::USRP_X310_MB_NI_2974; + default: + return x300_impl::UNKNOWN; } + UHD_THROW_INVALID_CODE_PATH(); +} - /*! Map the motherboard type to a product name - */ - std::string map_mb_type_to_product_name( - const x300_impl::x300_mboard_t mb_type, - const std::string& default_name="") - { - switch (mb_type) { - case x300_impl::USRP_X300_MB: - return "X300"; - case x300_impl::USRP_X310_MB: - return "X310"; - case x300_impl::USRP_X310_MB_NI_2974: - return "NI-2974"; - default: - return default_name; - } +/*! Map the motherboard type to a product name + */ +std::string map_mb_type_to_product_name( + const x300_impl::x300_mboard_t mb_type, const std::string& default_name = "") +{ + switch (mb_type) { + case x300_impl::USRP_X300_MB: + return "X300"; + case x300_impl::USRP_X310_MB: + return "X310"; + case x300_impl::USRP_X310_MB_NI_2974: + return "NI-2974"; + default: + return default_name; } +} -} /* namespace anon */ +} // namespace /*********************************************************************** * Discovery over the udp and pcie transport **********************************************************************/ //@TODO: Refactor the find functions to collapse common code for ethernet and PCIe -static device_addrs_t x300_find_with_addr(const device_addr_t &hint) +static device_addrs_t x300_find_with_addr(const device_addr_t& hint) { - udp_simple::sptr comm = udp_simple::make_broadcast( - hint["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)); + udp_simple::sptr comm = + udp_simple::make_broadcast(hint["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)); - //load request struct + // load request struct x300_fw_comms_t request = x300_fw_comms_t(); - request.flags = uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK); - request.sequence = uhd::htonx<uint32_t>(std::rand()); + request.flags = uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK); + request.sequence = uhd::htonx<uint32_t>(std::rand()); - //send request + // send request comm->send(asio::buffer(&request, sizeof(request))); - //loop for replies until timeout + // loop for replies until timeout device_addrs_t addrs; - while (true) - { + while (true) { char buff[X300_FW_COMMS_MTU] = {}; - const size_t nbytes = comm->recv(asio::buffer(buff), 0.050); - if (nbytes == 0) break; - const x300_fw_comms_t *reply = (const x300_fw_comms_t *)buff; - if (request.flags != reply->flags) continue; - if (request.sequence != reply->sequence) continue; + const size_t nbytes = comm->recv(asio::buffer(buff), 0.050); + if (nbytes == 0) + break; + const x300_fw_comms_t* reply = (const x300_fw_comms_t*)buff; + if (request.flags != reply->flags) + continue; + if (request.sequence != reply->sequence) + continue; device_addr_t new_addr; new_addr["type"] = "x300"; new_addr["addr"] = comm->get_recv_addr(); - //Attempt to read the name from the EEPROM and perform filtering. - //This operation can throw due to compatibility mismatch. - try - { + // Attempt to read the name from the EEPROM and perform filtering. + // This operation can throw due to compatibility mismatch. + try { wb_iface::sptr zpu_ctrl = x300_make_ctrl_iface_enet( - udp_simple::make_connected(new_addr["addr"], - BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), + udp_simple::make_connected( + new_addr["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), false /* Suppress timeout errors */ ); new_addr["fpga"] = get_fpga_option(zpu_ctrl); - i2c_core_100_wb32::sptr zpu_i2c = i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); - x300_mb_eeprom_iface::sptr eeprom_iface = x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); - const mboard_eeprom_t mb_eeprom = - x300_impl::get_mb_eeprom(eeprom_iface); - if (mb_eeprom.size() == 0 or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) - { + i2c_core_100_wb32::sptr zpu_i2c = + i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); + x300_mb_eeprom_iface::sptr eeprom_iface = + x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); + const mboard_eeprom_t mb_eeprom = x300_impl::get_mb_eeprom(eeprom_iface); + if (mb_eeprom.size() == 0 + or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) { // Skip device claimed by another process continue; } - new_addr["name"] = mb_eeprom["name"]; - new_addr["serial"] = mb_eeprom["serial"]; + new_addr["name"] = mb_eeprom["name"]; + new_addr["serial"] = mb_eeprom["serial"]; const std::string product_name = map_mb_type_to_product_name( x300_impl::get_mb_type_from_eeprom(mb_eeprom)); if (!product_name.empty()) { new_addr["product"] = product_name; } - } - catch(const std::exception &) - { - //set these values as empty string so the device may still be found - //and the filter's below can still operate on the discovered device - new_addr["name"] = ""; + } catch (const std::exception&) { + // set these values as empty string so the device may still be found + // and the filter's below can still operate on the discovered device + new_addr["name"] = ""; new_addr["serial"] = ""; } - //filter the discovered device below by matching optional keys - if ( - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) and - (not hint.has_key("product") or hint["product"] == new_addr["product"]) - ){ + // filter the discovered device below by matching optional keys + if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) + and (not hint.has_key("product") or hint["product"] == new_addr["product"])) { addrs.push_back(new_addr); } } @@ -228,13 +225,13 @@ static device_addrs_t x300_find_with_addr(const device_addr_t &hint) } -//We need a zpu xport registry to ensure synchronization between the static finder method -//and the instances of the x300_impl class. -typedef uhd::dict< std::string, boost::weak_ptr<wb_iface> > pcie_zpu_iface_registry_t; +// We need a zpu xport registry to ensure synchronization between the static finder method +// and the instances of the x300_impl class. +typedef uhd::dict<std::string, boost::weak_ptr<wb_iface>> pcie_zpu_iface_registry_t; UHD_SINGLETON_FCN(pcie_zpu_iface_registry_t, get_pcie_zpu_iface_registry) static boost::mutex pcie_zpu_iface_registry_mutex; -static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_query) +static device_addrs_t x300_find_pcie(const device_addr_t& hint, bool explicit_query) { std::string rpc_port_name(std::to_string(NIUSRPRIO_DEFAULT_RPC_PORT)); if (hint.has_key("niusrpriorpc_port")) { @@ -244,12 +241,13 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu device_addrs_t addrs; niusrprio_session::device_info_vtr dev_info_vtr; nirio_status status = niusrprio_session::enumerate(rpc_port_name, dev_info_vtr); - if (explicit_query) nirio_status_to_exception(status, "x300_find_pcie: Error enumerating NI-RIO devices."); + if (explicit_query) + nirio_status_to_exception( + status, "x300_find_pcie: Error enumerating NI-RIO devices."); - for(niusrprio_session::device_info &dev_info: dev_info_vtr) - { + for (niusrprio_session::device_info& dev_info : dev_info_vtr) { device_addr_t new_addr; - new_addr["type"] = "x300"; + new_addr["type"] = "x300"; new_addr["resource"] = dev_info.resource_name; std::string resource_d(dev_info.resource_name); boost::to_upper(resource_d); @@ -262,157 +260,154 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu new_addr["product"] = product_name; } - niriok_proxy::sptr kernel_proxy = niriok_proxy::make_and_open(dev_info.interface_path); + niriok_proxy::sptr kernel_proxy = + niriok_proxy::make_and_open(dev_info.interface_path); - //Attempt to read the name from the EEPROM and perform filtering. - //This operation can throw due to compatibility mismatch. - try - { - //This block could throw an exception if the user is switching to using UHD - //after LabVIEW FPGA. In that case, skip reading the name and serial and pick - //a default FPGA flavor. During make, a new image will be loaded and everything - //will be OK + // Attempt to read the name from the EEPROM and perform filtering. + // This operation can throw due to compatibility mismatch. + try { + // This block could throw an exception if the user is switching to using UHD + // after LabVIEW FPGA. In that case, skip reading the name and serial and pick + // a default FPGA flavor. During make, a new image will be loaded and + // everything will be OK wb_iface::sptr zpu_ctrl; - //Hold on to the registry mutex as long as zpu_ctrl is alive - //to prevent any use by different threads while enumerating + // Hold on to the registry mutex as long as zpu_ctrl is alive + // to prevent any use by different threads while enumerating boost::mutex::scoped_lock lock(pcie_zpu_iface_registry_mutex); if (get_pcie_zpu_iface_registry().has_key(resource_d)) { zpu_ctrl = get_pcie_zpu_iface_registry()[resource_d].lock(); - if (!zpu_ctrl) - { + if (!zpu_ctrl) { get_pcie_zpu_iface_registry().pop(resource_d); } } // if the registry didn't have a key OR that key was an orphaned weak_ptr - if (!zpu_ctrl) - { - zpu_ctrl = x300_make_ctrl_iface_pcie(kernel_proxy, false /* suppress timeout errors */); - //We don't put this zpu_ctrl in the registry because we need - //a persistent niriok_proxy associated with the object + if (!zpu_ctrl) { + zpu_ctrl = x300_make_ctrl_iface_pcie( + kernel_proxy, false /* suppress timeout errors */); + // We don't put this zpu_ctrl in the registry because we need + // a persistent niriok_proxy associated with the object } - //Attempt to autodetect the FPGA type + // Attempt to autodetect the FPGA type if (not hint.has_key("fpga")) { new_addr["fpga"] = get_fpga_option(zpu_ctrl); } - i2c_core_100_wb32::sptr zpu_i2c = i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); - x300_mb_eeprom_iface::sptr eeprom_iface = x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); - const mboard_eeprom_t mb_eeprom = - x300_impl::get_mb_eeprom(eeprom_iface); - if (mb_eeprom.size() == 0 or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) - { + i2c_core_100_wb32::sptr zpu_i2c = + i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); + x300_mb_eeprom_iface::sptr eeprom_iface = + x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); + const mboard_eeprom_t mb_eeprom = x300_impl::get_mb_eeprom(eeprom_iface); + if (mb_eeprom.size() == 0 + or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) { // Skip device claimed by another process continue; } - new_addr["name"] = mb_eeprom["name"]; + new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = mb_eeprom["serial"]; - } - catch(const std::exception &) - { - //set these values as empty string so the device may still be found - //and the filter's below can still operate on the discovered device + } catch (const std::exception&) { + // set these values as empty string so the device may still be found + // and the filter's below can still operate on the discovered device if (not hint.has_key("fpga")) { new_addr["fpga"] = "HG"; } - new_addr["name"] = ""; + new_addr["name"] = ""; new_addr["serial"] = ""; } - //filter the discovered device below by matching optional keys + // filter the discovered device below by matching optional keys std::string resource_i = hint.has_key("resource") ? hint["resource"] : ""; boost::to_upper(resource_i); - if ( - (not hint.has_key("resource") or resource_i == resource_d) and - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) and - (not hint.has_key("product") or hint["product"] == new_addr["product"]) - ){ + if ((not hint.has_key("resource") or resource_i == resource_d) + and (not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) + and (not hint.has_key("product") or hint["product"] == new_addr["product"])) { addrs.push_back(new_addr); } } return addrs; } -device_addrs_t x300_find(const device_addr_t &hint_) +device_addrs_t x300_find(const device_addr_t& hint_) { - //handle the multi-device discovery + // handle the multi-device discovery device_addrs_t hints = separate_device_addr(hint_); - if (hints.size() > 1) - { + if (hints.size() > 1) { device_addrs_t found_devices; std::string error_msg; - for(const device_addr_t &hint_i: hints) - { + for (const device_addr_t& hint_i : hints) { device_addrs_t found_devices_i = x300_find(hint_i); - if (found_devices_i.size() != 1) error_msg += str(boost::format( - "Could not resolve device hint \"%s\" to a single device." - ) % hint_i.to_string()); - else found_devices.push_back(found_devices_i[0]); + if (found_devices_i.size() != 1) + error_msg += + str(boost::format( + "Could not resolve device hint \"%s\" to a single device.") + % hint_i.to_string()); + else + found_devices.push_back(found_devices_i[0]); } - if (found_devices.empty()) return device_addrs_t(); - if (not error_msg.empty()) throw uhd::value_error(error_msg); + if (found_devices.empty()) + return device_addrs_t(); + if (not error_msg.empty()) + throw uhd::value_error(error_msg); return device_addrs_t(1, combine_device_addrs(found_devices)); } - //initialize the hint for a single device case + // initialize the hint for a single device case UHD_ASSERT_THROW(hints.size() <= 1); - hints.resize(1); //in case it was empty + hints.resize(1); // in case it was empty device_addr_t hint = hints[0]; device_addrs_t addrs; - if (hint.has_key("type") and hint["type"] != "x300") return addrs; + if (hint.has_key("type") and hint["type"] != "x300") + return addrs; - //use the address given - if (hint.has_key("addr")) - { + // use the address given + if (hint.has_key("addr")) { device_addrs_t reply_addrs; - try - { + try { reply_addrs = x300_find_with_addr(hint); - } - catch(const std::exception &ex) - { - UHD_LOGGER_ERROR("X300") << "X300 Network discovery error " << ex.what() ; - } - catch(...) - { - UHD_LOGGER_ERROR("X300") << "X300 Network discovery unknown error " ; + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("X300") << "X300 Network discovery error " << ex.what(); + } catch (...) { + UHD_LOGGER_ERROR("X300") << "X300 Network discovery unknown error "; } return reply_addrs; } - if (!hint.has_key("resource")) - { - //otherwise, no address was specified, send a broadcast on each interface - for(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; + if (!hint.has_key("resource")) { + // otherwise, no address was specified, send a broadcast on each interface + for (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 + // create a new hint with this broadcast address device_addr_t new_hint = hint; - new_hint["addr"] = if_addrs.bcast; + new_hint["addr"] = if_addrs.bcast; - //call discover with the new hint and append results + // call discover with the new hint and append results device_addrs_t new_addrs = x300_find(new_hint); - //if we are looking for a serial, only add the one device with a matching serial + // if we are looking for a serial, only add the one device with a matching + // serial if (hint.has_key("serial")) { - bool found_serial = false; //signal to break out of the interface loop - for (device_addrs_t::iterator new_addr_it=new_addrs.begin(); new_addr_it != new_addrs.end(); new_addr_it++) { + bool found_serial = false; // signal to break out of the interface loop + for (device_addrs_t::iterator new_addr_it = new_addrs.begin(); + new_addr_it != new_addrs.end(); + new_addr_it++) { if ((*new_addr_it)["serial"] == hint["serial"]) { addrs.insert(addrs.begin(), *new_addr_it); found_serial = true; break; } } - if (found_serial) break; + if (found_serial) + break; } else { // Otherwise, add all devices we find addrs.insert(addrs.begin(), new_addrs.begin(), new_addrs.end()); @@ -421,7 +416,8 @@ device_addrs_t x300_find(const device_addr_t &hint_) } device_addrs_t pcie_addrs = x300_find_pcie(hint, hint.has_key("resource")); - if (not pcie_addrs.empty()) addrs.insert(addrs.end(), pcie_addrs.begin(), pcie_addrs.end()); + if (not pcie_addrs.empty()) + addrs.insert(addrs.end(), pcie_addrs.begin(), pcie_addrs.end()); return addrs; } @@ -429,7 +425,7 @@ device_addrs_t x300_find(const device_addr_t &hint_) /*********************************************************************** * Make **********************************************************************/ -static device::sptr x300_make(const device_addr_t &device_addr) +static device::sptr x300_make(const device_addr_t& device_addr) { return device::sptr(new x300_impl(device_addr)); } @@ -439,33 +435,33 @@ UHD_STATIC_BLOCK(register_x300_device) device::register_device(&x300_find, &x300_make, device::USRP); } -static void x300_load_fw(wb_iface::sptr fw_reg_ctrl, const std::string &file_name) +static void x300_load_fw(wb_iface::sptr fw_reg_ctrl, const std::string& file_name) { UHD_LOGGER_INFO("X300") << "Loading firmware " << file_name; - //load file into memory + // load file into memory std::ifstream fw_file(file_name.c_str()); - uint32_t fw_file_buff[X300_FW_NUM_BYTES/sizeof(uint32_t)]; - fw_file.read((char *)fw_file_buff, sizeof(fw_file_buff)); + uint32_t fw_file_buff[X300_FW_NUM_BYTES / sizeof(uint32_t)]; + fw_file.read((char*)fw_file_buff, sizeof(fw_file_buff)); fw_file.close(); - //Poke the fw words into the WB boot loader + // Poke the fw words into the WB boot loader fw_reg_ctrl->poke32(SR_ADDR(BOOT_LDR_BASE, BL_ADDRESS), 0); - for (size_t i = 0; i < X300_FW_NUM_BYTES; i+=sizeof(uint32_t)) - { - //@TODO: FIXME: Since x300_ctrl_iface acks each write and traps exceptions, the first try for the last word - // written will print an error because it triggers a FW reload and fails to reply. - fw_reg_ctrl->poke32(SR_ADDR(BOOT_LDR_BASE, BL_DATA), uhd::byteswap(fw_file_buff[i/sizeof(uint32_t)])); + for (size_t i = 0; i < X300_FW_NUM_BYTES; i += sizeof(uint32_t)) { + //@TODO: FIXME: Since x300_ctrl_iface acks each write and traps exceptions, the + // first try for the last word + // written will print an error because it triggers a FW reload and + // fails to reply. + fw_reg_ctrl->poke32(SR_ADDR(BOOT_LDR_BASE, BL_DATA), + uhd::byteswap(fw_file_buff[i / sizeof(uint32_t)])); } - //Wait for fimrware to reboot. 3s is an upper bound + // Wait for fimrware to reboot. 3s is an upper bound std::this_thread::sleep_for(std::chrono::milliseconds(3000)); - UHD_LOGGER_INFO("X300") << "Firmware loaded!" ; + UHD_LOGGER_INFO("X300") << "Firmware loaded!"; } -x300_impl::x300_impl(const uhd::device_addr_t &dev_addr) - : device3_impl() - , _sid_framer(0) +x300_impl::x300_impl(const uhd::device_addr_t& dev_addr) : device3_impl(), _sid_framer(0) { UHD_LOGGER_INFO("X300") << "X300 initialization sequence..."; _tree->create<std::string>("/name").set("X-Series Device"); @@ -475,8 +471,7 @@ x300_impl::x300_impl(const uhd::device_addr_t &dev_addr) // Serialize the initialization process if (dev_addr.has_key("serialize_init") or device_args.size() == 1) { - for (size_t i = 0; i < device_args.size(); i++) - { + for (size_t i = 0; i < device_args.size(); i++) { this->setup_mb(i, device_args[i]); } return; @@ -486,26 +481,22 @@ x300_impl::x300_impl(const uhd::device_addr_t &dev_addr) // Initialize groups of USRPs in parallel size_t total_usrps = device_args.size(); size_t num_usrps = 0; - while (num_usrps < total_usrps) - { + while (num_usrps < total_usrps) { size_t init_usrps = std::min(total_usrps - num_usrps, x300::MAX_INIT_THREADS); boost::thread_group setup_threads; - for (size_t i = 0; i < init_usrps; i++) - { + for (size_t i = 0; i < init_usrps; i++) { const size_t index = num_usrps + i; - setup_threads.create_thread([this, index, device_args](){ + setup_threads.create_thread([this, index, device_args]() { this->setup_mb(index, device_args[index]); }); } setup_threads.join_all(); num_usrps += init_usrps; } - } void x300_impl::mboard_members_t::discover_eth( - const mboard_eeprom_t mb_eeprom, - const std::vector<std::string> &ip_addrs) + const mboard_eeprom_t mb_eeprom, const std::vector<std::string>& ip_addrs) { // Clear any previous addresses added eth_conns.clear(); @@ -517,16 +508,19 @@ void x300_impl::mboard_members_t::discover_eth( const std::string key = "ip-addr" + boost::to_string(i); // Show a warning if there exists duplicate addresses in the mboard eeprom - if (std::find(mb_eeprom_addrs.begin(), mb_eeprom_addrs.end(), mb_eeprom[key]) != mb_eeprom_addrs.end()) { - UHD_LOGGER_WARNING("X300") << str(boost::format( - "Duplicate IP address %s found in mboard EEPROM. " - "Device may not function properly. View and reprogram the values " - "using the usrp_burn_mb_eeprom utility.") % mb_eeprom[key]); + if (std::find(mb_eeprom_addrs.begin(), mb_eeprom_addrs.end(), mb_eeprom[key]) + != mb_eeprom_addrs.end()) { + UHD_LOGGER_WARNING("X300") << str( + boost::format( + "Duplicate IP address %s found in mboard EEPROM. " + "Device may not function properly. View and reprogram the values " + "using the usrp_burn_mb_eeprom utility.") + % mb_eeprom[key]); } mb_eeprom_addrs.push_back(mb_eeprom[key]); } - for(const std::string& addr: ip_addrs) { + for (const std::string& addr : ip_addrs) { x300_eth_conn_t conn_iface; conn_iface.addr = addr; conn_iface.type = X300_IFACE_NONE; @@ -537,10 +531,12 @@ void x300_impl::mboard_members_t::discover_eth( if (addr == mb_eeprom_addrs[i]) { // Choose the interface based on the index parity if (i % 2 == 0) { - conn_iface.type = X300_IFACE_ETH0; - conn_iface.link_rate = loaded_fpga_image == "HG" ? x300::MAX_RATE_1GIGE : x300::MAX_RATE_10GIGE; + conn_iface.type = X300_IFACE_ETH0; + conn_iface.link_rate = loaded_fpga_image == "HG" + ? x300::MAX_RATE_1GIGE + : x300::MAX_RATE_10GIGE; } else { - conn_iface.type = X300_IFACE_ETH1; + conn_iface.type = X300_IFACE_ETH1; conn_iface.link_rate = x300::MAX_RATE_10GIGE; } break; @@ -550,45 +546,49 @@ void x300_impl::mboard_members_t::discover_eth( // Check default IP addresses if we couldn't // determine the IP from the mboard eeprom if (conn_iface.type == X300_IFACE_NONE) { - UHD_LOGGER_WARNING("X300") << str(boost::format( - "Address %s not found in mboard EEPROM. Address may be wrong or " - "the EEPROM may be corrupt. Attempting to continue with default " - "IP addresses.") % conn_iface.addr - ); - - if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH0_1G)).to_string()) { - conn_iface.type = X300_IFACE_ETH0; + UHD_LOGGER_WARNING("X300") << str( + boost::format( + "Address %s not found in mboard EEPROM. Address may be wrong or " + "the EEPROM may be corrupt. Attempting to continue with default " + "IP addresses.") + % conn_iface.addr); + + if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH0_1G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH0; conn_iface.link_rate = x300::MAX_RATE_1GIGE; - } else if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH1_1G)).to_string()) { - conn_iface.type = X300_IFACE_ETH1; + } else if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH1_1G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH1; conn_iface.link_rate = x300::MAX_RATE_1GIGE; - } else if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH0_10G)).to_string()) { - conn_iface.type = X300_IFACE_ETH0; + } else if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH0_10G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH0; conn_iface.link_rate = x300::MAX_RATE_10GIGE; - } else if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH1_10G)).to_string()) { - conn_iface.type = X300_IFACE_ETH1; + } else if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH1_10G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH1; conn_iface.link_rate = x300::MAX_RATE_10GIGE; } else { - throw uhd::assertion_error(str(boost::format( - "X300 Initialization Error: Failed to match address %s with " - "any addresses for the device. Please check the address.") - % conn_iface.addr - )); + throw uhd::assertion_error( + str(boost::format( + "X300 Initialization Error: Failed to match address %s with " + "any addresses for the device. Please check the address.") + % conn_iface.addr)); } } // Save to a vector of connections if (conn_iface.type != X300_IFACE_NONE) { // Check the address before we add it - try - { + try { wb_iface::sptr zpu_ctrl = x300_make_ctrl_iface_enet( - udp_simple::make_connected(conn_iface.addr, - BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), + udp_simple::make_connected( + conn_iface.addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), false /* Suppress timeout errors */ ); @@ -597,42 +597,40 @@ void x300_impl::mboard_members_t::discover_eth( } // If the address does not work, throw an error - catch(std::exception &) - { - throw uhd::io_error(str(boost::format( - "X300 Initialization Error: Invalid address %s") - % conn_iface.addr)); + catch (std::exception&) { + throw uhd::io_error( + str(boost::format("X300 Initialization Error: Invalid address %s") + % conn_iface.addr)); } eth_conns.push_back(conn_iface); } } if (eth_conns.size() == 0) - throw uhd::assertion_error("X300 Initialization Error: No ethernet interfaces specified."); + throw uhd::assertion_error( + "X300 Initialization Error: No ethernet interfaces specified."); } -void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) +void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t& dev_addr) { - const fs_path mb_path = fs_path("/mboards") / mb_i; - mboard_members_t &mb = _mb[mb_i]; + const fs_path mb_path = fs_path("/mboards") / mb_i; + mboard_members_t& mb = _mb[mb_i]; mb.initialization_done = false; const std::string thread_id( - boost::lexical_cast<std::string>(boost::this_thread::get_id()) - ); + boost::lexical_cast<std::string>(boost::this_thread::get_id())); const std::string thread_msg( - "Thread ID " + thread_id + " for motherboard " - + std::to_string(mb_i) - ); + "Thread ID " + thread_id + " for motherboard " + std::to_string(mb_i)); mb.args.parse(dev_addr); std::vector<std::string> eth_addrs; // Not choosing eth0 based on resource might cause user issues - std::string eth0_addr = dev_addr.has_key("resource") ? dev_addr["resource"] : dev_addr["addr"]; + std::string eth0_addr = dev_addr.has_key("resource") ? dev_addr["resource"] + : dev_addr["addr"]; eth_addrs.push_back(eth0_addr); - mb.next_src_addr = 0; //Host source address for blocks + mb.next_src_addr = 0; // Host source address for blocks mb.next_tx_src_addr = 0; mb.next_rx_src_addr = 0; if (not mb.args.get_second_addr().empty()) { @@ -649,19 +647,18 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) init.addr = eth_addrs[0]; mb.eth_conns.push_back(init); - mb.xport_path = dev_addr.has_key("resource") ? "nirio" : "eth"; + mb.xport_path = dev_addr.has_key("resource") ? "nirio" : "eth"; mb.if_pkt_is_big_endian = mb.xport_path != "nirio"; - if (mb.xport_path == "nirio") - { + if (mb.xport_path == "nirio") { nirio_status status = 0; const std::string rpc_port_name = mb.args.get_niusrprio_rpc_port(); UHD_LOGGER_INFO("X300") << boost::format("Connecting to niusrpriorpc at localhost:%s...") - % rpc_port_name; + % rpc_port_name; - //Instantiate the correct lvbitx object + // Instantiate the correct lvbitx object nifpga_lvbitx::sptr lvbitx; switch (get_mb_type_from_pcie(mb.args.get_resource(), rpc_port_name)) { case USRP_X300_MB: @@ -672,85 +669,95 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) lvbitx.reset(new x310_lvbitx(dev_addr["fpga"])); break; default: - nirio_status_to_exception(status, "Motherboard detection error. Please ensure that you \ + nirio_status_to_exception( + status, "Motherboard detection error. Please ensure that you \ have a valid USRP X3x0, NI USRP-294xR, NI USRP-295xR or NI USRP-2974 device and that all the device \ drivers have loaded successfully."); } - //Load the lvbitx onto the device - UHD_LOGGER_INFO("X300") << boost::format("Using LVBITX bitfile %s...") % lvbitx->get_bitfile_path(); - mb.rio_fpga_interface.reset(new niusrprio_session(dev_addr["resource"], rpc_port_name)); - nirio_status_chain(mb.rio_fpga_interface->open(lvbitx, dev_addr.has_key("download-fpga")), status); + // Load the lvbitx onto the device + UHD_LOGGER_INFO("X300") + << boost::format("Using LVBITX bitfile %s...") % lvbitx->get_bitfile_path(); + mb.rio_fpga_interface.reset( + new niusrprio_session(dev_addr["resource"], rpc_port_name)); + nirio_status_chain( + mb.rio_fpga_interface->open(lvbitx, dev_addr.has_key("download-fpga")), + status); nirio_status_to_exception(status, "x300_impl: Could not initialize RIO session."); - //Tell the quirks object which FIFOs carry TX stream data - const uint32_t tx_data_fifos[2] = {x300::RADIO_DEST_PREFIX_TX, x300::RADIO_DEST_PREFIX_TX + 3}; - mb.rio_fpga_interface->get_kernel_proxy()->get_rio_quirks().register_tx_streams(tx_data_fifos, 2); + // Tell the quirks object which FIFOs carry TX stream data + const uint32_t tx_data_fifos[2] = { + x300::RADIO_DEST_PREFIX_TX, x300::RADIO_DEST_PREFIX_TX + 3}; + mb.rio_fpga_interface->get_kernel_proxy()->get_rio_quirks().register_tx_streams( + tx_data_fifos, 2); _tree->create<size_t>(mb_path / "mtu/recv").set(x300::PCIE_RX_DATA_FRAME_SIZE); _tree->create<size_t>(mb_path / "mtu/send").set(x300::PCIE_TX_DATA_FRAME_SIZE); _tree->create<double>(mb_path / "link_max_rate").set(x300::MAX_RATE_PCIE); } - for(const std::string &key: dev_addr.keys()) - { - if (key.find("recv") != std::string::npos) mb.recv_args[key] = dev_addr[key]; - if (key.find("send") != std::string::npos) mb.send_args[key] = dev_addr[key]; + for (const std::string& key : dev_addr.keys()) { + if (key.find("recv") != std::string::npos) + mb.recv_args[key] = dev_addr[key]; + if (key.find("send") != std::string::npos) + mb.send_args[key] = dev_addr[key]; } - //create basic communication + // create basic communication UHD_LOGGER_DEBUG("X300") << "Setting up basic communication..."; if (mb.xport_path == "nirio") { boost::mutex::scoped_lock lock(pcie_zpu_iface_registry_mutex); if (get_pcie_zpu_iface_registry().has_key(mb.get_pri_eth().addr)) { - throw uhd::assertion_error("Someone else has a ZPU transport to the device open. Internal error!"); + throw uhd::assertion_error( + "Someone else has a ZPU transport to the device open. Internal error!"); } else { - mb.zpu_ctrl = x300_make_ctrl_iface_pcie(mb.rio_fpga_interface->get_kernel_proxy()); - get_pcie_zpu_iface_registry()[mb.get_pri_eth().addr] = boost::weak_ptr<wb_iface>(mb.zpu_ctrl); + mb.zpu_ctrl = + x300_make_ctrl_iface_pcie(mb.rio_fpga_interface->get_kernel_proxy()); + get_pcie_zpu_iface_registry()[mb.get_pri_eth().addr] = + boost::weak_ptr<wb_iface>(mb.zpu_ctrl); } } else { mb.zpu_ctrl = x300_make_ctrl_iface_enet(udp_simple::make_connected( - mb.get_pri_eth().addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT))); + mb.get_pri_eth().addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT))); } // Claim device if (not try_to_claim(mb.zpu_ctrl)) { throw uhd::runtime_error("Failed to claim device"); } - mb.claimer_task = uhd::task::make([this, mb](){ - this->claimer_loop(mb.zpu_ctrl); - }, "x300_claimer"); + mb.claimer_task = uhd::task::make( + [this, mb]() { this->claimer_loop(mb.zpu_ctrl); }, "x300_claimer"); - //extract the FW path for the X300 - //and live load fw over ethernet link + // extract the FW path for the X300 + // and live load fw over ethernet link if (mb.args.has_fw_file()) { - const std::string x300_fw_image = - find_image_path(mb.args.get_fw_file()); + const std::string x300_fw_image = find_image_path(mb.args.get_fw_file()); x300_load_fw(mb.zpu_ctrl, x300_fw_image); } - //check compat numbers - //check fpga compat before fw compat because the fw is a subset of the fpga image + // check compat numbers + // check fpga compat before fw compat because the fw is a subset of the fpga image this->check_fpga_compat(mb_path, mb); this->check_fw_compat(mb_path, mb); mb.fw_regmap = boost::make_shared<fw_regmap_t>(); mb.fw_regmap->initialize(*mb.zpu_ctrl.get(), true); - //store which FPGA image is loaded + // store which FPGA image is loaded mb.loaded_fpga_image = get_fpga_option(mb.zpu_ctrl); - //low speed perif access - mb.zpu_spi = spi_core_3000::make(mb.zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_SPI), - SR_ADDR(SET0_BASE, ZPU_RB_SPI)); + // low speed perif access + mb.zpu_spi = spi_core_3000::make( + mb.zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_SPI), SR_ADDR(SET0_BASE, ZPU_RB_SPI)); mb.zpu_i2c = i2c_core_100_wb32::make(mb.zpu_ctrl, I2C1_BASE); - mb.zpu_i2c->set_clock_rate(x300::BUS_CLOCK_RATE/2); + mb.zpu_i2c->set_clock_rate(x300::BUS_CLOCK_RATE / 2); //////////////////////////////////////////////////////////////////// // print network routes mapping //////////////////////////////////////////////////////////////////// /* - const uint32_t routes_addr = mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_ROUTE_MAP_ADDR)); - const uint32_t routes_len = mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_ROUTE_MAP_LEN)); + const uint32_t routes_addr = mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, + X300_FW_SHMEM_ROUTE_MAP_ADDR)); const uint32_t routes_len = + mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_ROUTE_MAP_LEN)); UHD_VAR(routes_len); for (size_t i = 0; i < routes_len; i+=1) { @@ -778,29 +785,28 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) } const mboard_eeprom_t mb_eeprom = get_mb_eeprom(eeprom16); - _tree->create<mboard_eeprom_t>(mb_path / "eeprom") + _tree + ->create<mboard_eeprom_t>(mb_path / "eeprom") // Initialize the property with a current copy of the EEPROM contents .set(mb_eeprom) // Whenever this property is written, update the chip - .add_coerced_subscriber( - [this, eeprom16](const mboard_eeprom_t &mb_eeprom){ - this->set_mb_eeprom(eeprom16, mb_eeprom); - } - ) - ; + .add_coerced_subscriber([this, eeprom16](const mboard_eeprom_t& mb_eeprom) { + this->set_mb_eeprom(eeprom16, mb_eeprom); + }); if (mb.args.get_recover_mb_eeprom()) { - UHD_LOGGER_WARNING("X300") << "UHD is operating in EEPROM Recovery Mode which disables hardware version " - "checks.\nOperating in this mode may cause hardware damage and unstable " - "radio performance!"; + UHD_LOGGER_WARNING("X300") + << "UHD is operating in EEPROM Recovery Mode which disables hardware version " + "checks.\nOperating in this mode may cause hardware damage and unstable " + "radio performance!"; return; } //////////////////////////////////////////////////////////////////// // parse the product number //////////////////////////////////////////////////////////////////// - const std::string product_name = map_mb_type_to_product_name( - get_mb_type_from_eeprom(mb_eeprom), "X300?"); + const std::string product_name = + map_mb_type_to_product_name(get_mb_type_from_eeprom(mb_eeprom), "X300?"); if (product_name == "X300?") { if (not mb.args.get_recover_mb_eeprom()) { throw uhd::runtime_error( @@ -818,7 +824,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) //////////////////////////////////////////////////////////////////// // discover ethernet interfaces, frame sizes, and link rates //////////////////////////////////////////////////////////////////// - if (mb.xport_path == "eth" ) { + if (mb.xport_path == "eth") { double link_max_rate = 0.0; // Discover ethernet interfaces @@ -836,101 +842,104 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) * multiple transmission units - this is why the limits passed into the * 'determine_max_frame_size' function are actually frame sizes. */ frame_size_t req_max_frame_size; - req_max_frame_size.recv_frame_size = (mb.recv_args.has_key("recv_frame_size")) \ - ? boost::lexical_cast<size_t>(mb.recv_args["recv_frame_size"]) \ - : x300::DATA_FRAME_MAX_SIZE; - req_max_frame_size.send_frame_size = (mb.send_args.has_key("send_frame_size")) \ - ? boost::lexical_cast<size_t>(mb.send_args["send_frame_size"]) \ - : x300::DATA_FRAME_MAX_SIZE; - - #if defined UHD_PLATFORM_LINUX - const std::string mtu_tool("ip link"); - #elif defined UHD_PLATFORM_WIN32 - const std::string mtu_tool("netsh"); - #else - const std::string mtu_tool("ifconfig"); - #endif + req_max_frame_size.recv_frame_size = + (mb.recv_args.has_key("recv_frame_size")) + ? boost::lexical_cast<size_t>(mb.recv_args["recv_frame_size"]) + : x300::DATA_FRAME_MAX_SIZE; + req_max_frame_size.send_frame_size = + (mb.send_args.has_key("send_frame_size")) + ? boost::lexical_cast<size_t>(mb.send_args["send_frame_size"]) + : x300::DATA_FRAME_MAX_SIZE; + +#if defined UHD_PLATFORM_LINUX + const std::string mtu_tool("ip link"); +#elif defined UHD_PLATFORM_WIN32 + const std::string mtu_tool("netsh"); +#else + const std::string mtu_tool("ifconfig"); +#endif // Detect the frame size on the path to the USRP try { - frame_size_t pri_frame_sizes = determine_max_frame_size( - eth_addrs.at(0), req_max_frame_size - ); + frame_size_t pri_frame_sizes = + determine_max_frame_size(eth_addrs.at(0), req_max_frame_size); _max_frame_sizes = pri_frame_sizes; if (eth_addrs.size() > 1) { - frame_size_t sec_frame_sizes = determine_max_frame_size( - eth_addrs.at(1), req_max_frame_size - ); + frame_size_t sec_frame_sizes = + determine_max_frame_size(eth_addrs.at(1), req_max_frame_size); // Choose the minimum of the max frame sizes // to ensure we don't exceed any one of the links' MTU _max_frame_sizes.recv_frame_size = std::min( - pri_frame_sizes.recv_frame_size, - sec_frame_sizes.recv_frame_size - ); + pri_frame_sizes.recv_frame_size, sec_frame_sizes.recv_frame_size); _max_frame_sizes.send_frame_size = std::min( - pri_frame_sizes.send_frame_size, - sec_frame_sizes.send_frame_size - ); + pri_frame_sizes.send_frame_size, sec_frame_sizes.send_frame_size); } - } catch(std::exception &e) { - UHD_LOGGER_ERROR("X300") << e.what() ; + } catch (std::exception& e) { + UHD_LOGGER_ERROR("X300") << e.what(); } if ((mb.recv_args.has_key("recv_frame_size")) - && (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) { + && (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) { UHD_LOGGER_WARNING("X300") - << boost::format("You requested a receive frame size of (%lu) but your NIC's max frame size is (%lu).") - % req_max_frame_size.recv_frame_size - % _max_frame_sizes.recv_frame_size - << boost::format("Please verify your NIC's MTU setting using '%s' or set the recv_frame_size argument appropriately.") - % mtu_tool - << "UHD will use the auto-detected max frame size for this connection." - ; + << boost::format("You requested a receive frame size of (%lu) but your " + "NIC's max frame size is (%lu).") + % req_max_frame_size.recv_frame_size + % _max_frame_sizes.recv_frame_size + << boost::format("Please verify your NIC's MTU setting using '%s' or set " + "the recv_frame_size argument appropriately.") + % mtu_tool + << "UHD will use the auto-detected max frame size for this connection."; } if ((mb.send_args.has_key("send_frame_size")) - && (req_max_frame_size.send_frame_size > _max_frame_sizes.send_frame_size)) { + && (req_max_frame_size.send_frame_size > _max_frame_sizes.send_frame_size)) { UHD_LOGGER_WARNING("X300") - << boost::format("You requested a send frame size of (%lu) but your NIC's max frame size is (%lu).") - % req_max_frame_size.send_frame_size - % _max_frame_sizes.send_frame_size - << boost::format("Please verify your NIC's MTU setting using '%s' or set the send_frame_size argument appropriately.") - % mtu_tool - << "UHD will use the auto-detected max frame size for this connection." - ; + << boost::format("You requested a send frame size of (%lu) but your " + "NIC's max frame size is (%lu).") + % req_max_frame_size.send_frame_size + % _max_frame_sizes.send_frame_size + << boost::format("Please verify your NIC's MTU setting using '%s' or set " + "the send_frame_size argument appropriately.") + % mtu_tool + << "UHD will use the auto-detected max frame size for this connection."; } // Check frame sizes - for (auto conn : mb.eth_conns) - { + for (auto conn : mb.eth_conns) { link_max_rate += conn.link_rate; - size_t rec_send_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_SEND_SIZE : x300::XGE_DATA_FRAME_SEND_SIZE; - size_t rec_recv_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_RECV_SIZE : x300::XGE_DATA_FRAME_RECV_SIZE; + size_t rec_send_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_SEND_SIZE + : x300::XGE_DATA_FRAME_SEND_SIZE; + size_t rec_recv_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_RECV_SIZE + : x300::XGE_DATA_FRAME_RECV_SIZE; - if (_max_frame_sizes.send_frame_size < rec_send_frame_size) - { + if (_max_frame_sizes.send_frame_size < rec_send_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("For the %s connection, UHD recommends a send frame size of at least %lu for best\nperformance, but your configuration will only allow %lu.") - % conn.addr - % rec_send_frame_size - % _max_frame_sizes.send_frame_size - << "This may negatively impact your maximum achievable sample rate.\nCheck the MTU on the interface and/or the send_frame_size argument." - ; + << boost::format("For the %s connection, UHD recommends a send frame " + "size of at least %lu for best\nperformance, but " + "your configuration will only allow %lu.") + % conn.addr % rec_send_frame_size + % _max_frame_sizes.send_frame_size + << "This may negatively impact your maximum achievable sample " + "rate.\nCheck the MTU on the interface and/or the send_frame_size " + "argument."; } - if (_max_frame_sizes.recv_frame_size < rec_recv_frame_size) - { + if (_max_frame_sizes.recv_frame_size < rec_recv_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("For the %s connection, UHD recommends a receive frame size of at least %lu for best\nperformance, but your configuration will only allow %lu.") - % conn.addr - % rec_recv_frame_size - % _max_frame_sizes.recv_frame_size - << "This may negatively impact your maximum achievable sample rate.\nCheck the MTU on the interface and/or the recv_frame_size argument." - ; + << boost::format("For the %s connection, UHD recommends a receive " + "frame size of at least %lu for best\nperformance, " + "but your configuration will only allow %lu.") + % conn.addr % rec_recv_frame_size + % _max_frame_sizes.recv_frame_size + << "This may negatively impact your maximum achievable sample " + "rate.\nCheck the MTU on the interface and/or the recv_frame_size " + "argument."; } } @@ -943,40 +952,48 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) // read hardware revision and compatibility number //////////////////////////////////////////////////////////////////// mb.hw_rev = 0; - if(mb_eeprom.has_key("revision") and not mb_eeprom["revision"].empty()) { + if (mb_eeprom.has_key("revision") and not mb_eeprom["revision"].empty()) { try { mb.hw_rev = boost::lexical_cast<size_t>(mb_eeprom["revision"]); - } catch(...) { - throw uhd::runtime_error("Revision in EEPROM is invalid! Please reprogram your EEPROM."); + } catch (...) { + throw uhd::runtime_error( + "Revision in EEPROM is invalid! Please reprogram your EEPROM."); } } else { throw uhd::runtime_error("No revision detected. MB EEPROM must be reprogrammed!"); } size_t hw_rev_compat = 0; - if (mb.hw_rev >= 7) { //Revision compat was added with revision 7 - if (mb_eeprom.has_key("revision_compat") and not mb_eeprom["revision_compat"].empty()) { + if (mb.hw_rev >= 7) { // Revision compat was added with revision 7 + if (mb_eeprom.has_key("revision_compat") + and not mb_eeprom["revision_compat"].empty()) { try { hw_rev_compat = boost::lexical_cast<size_t>(mb_eeprom["revision_compat"]); - } catch(...) { - throw uhd::runtime_error("Revision compat in EEPROM is invalid! Please reprogram your EEPROM."); + } catch (...) { + throw uhd::runtime_error("Revision compat in EEPROM is invalid! Please " + "reprogram your EEPROM."); } } else { - throw uhd::runtime_error("No revision compat detected. MB EEPROM must be reprogrammed!"); + throw uhd::runtime_error( + "No revision compat detected. MB EEPROM must be reprogrammed!"); } } else { - //For older HW just assume that revision_compat = revision + // For older HW just assume that revision_compat = revision hw_rev_compat = mb.hw_rev; } if (hw_rev_compat > X300_REVISION_COMPAT) { - throw uhd::runtime_error(str(boost::format( - "Hardware is too new for this software. Please upgrade to a driver that supports hardware revision %d.") - % mb.hw_rev)); - } else if (mb.hw_rev < X300_REVISION_MIN) { //Compare min against the revision (and not compat) to give us more leeway for partial support for a compat - throw uhd::runtime_error(str(boost::format( - "Software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.") - % mb.hw_rev)); + throw uhd::runtime_error( + str(boost::format("Hardware is too new for this software. Please upgrade to " + "a driver that supports hardware revision %d.") + % mb.hw_rev)); + } else if (mb.hw_rev < X300_REVISION_MIN) { // Compare min against the revision (and + // not compat) to give us more leeway for + // partial support for a compat + throw uhd::runtime_error( + str(boost::format("Software is too new for this hardware. Please downgrade " + "to a driver that supports hardware revision %d.") + % mb.hw_rev)); } //////////////////////////////////////////////////////////////////// @@ -984,63 +1001,55 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) //////////////////////////////////////////////////////////////////// UHD_LOGGER_DEBUG("X300") << "Setting up RF frontend clocking..."; - //Initialize clock control registers. NOTE: This does not configure the LMK yet. + // Initialize clock control registers. NOTE: This does not configure the LMK yet. mb.clock = x300_clock_ctrl::make(mb.zpu_spi, 1 /*slaveno*/, mb.hw_rev, mb.args.get_master_clock_rate(), mb.args.get_dboard_clock_rate(), - mb.args.get_system_ref_rate() - ); + mb.args.get_system_ref_rate()); mb.fw_regmap->ref_freq_reg.write( - fw_regmap_t::ref_freq_reg_t::REF_FREQ, - uint32_t(mb.args.get_system_ref_rate()) - ); + fw_regmap_t::ref_freq_reg_t::REF_FREQ, uint32_t(mb.args.get_system_ref_rate())); - //Initialize clock source to use internal reference and generate - //a valid radio clock. This may change after configuration is done. - //This will configure the LMK and wait for lock + // Initialize clock source to use internal reference and generate + // a valid radio clock. This may change after configuration is done. + // This will configure the LMK and wait for lock update_clock_source(mb, mb.args.get_clock_source()); //////////////////////////////////////////////////////////////////// // create clock properties //////////////////////////////////////////////////////////////////// - _tree->create<double>(mb_path / "master_clock_rate") - .set_publisher([mb](){ return mb.clock->get_master_clock_rate(); }) - ; + _tree->create<double>(mb_path / "master_clock_rate").set_publisher([mb]() { + return mb.clock->get_master_clock_rate(); + }); - UHD_LOGGER_INFO("X300") - << "Radio 1x clock: " << (mb.clock->get_master_clock_rate()/1e6) - << " MHz"; + UHD_LOGGER_INFO("X300") << "Radio 1x clock: " + << (mb.clock->get_master_clock_rate() / 1e6) << " MHz"; //////////////////////////////////////////////////////////////////// // Create the GPSDO control //////////////////////////////////////////////////////////////////// static const uint32_t dont_look_for_gpsdo = 0x1234abcdul; - //otherwise if not disabled, look for the internal GPSDO - if (mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS)) != dont_look_for_gpsdo) - { + // otherwise if not disabled, look for the internal GPSDO + if (mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS)) + != dont_look_for_gpsdo) { UHD_LOG_DEBUG("X300", "Detecting internal GPSDO...."); try { // gps_ctrl will print its own log statements if a GPSDO was found mb.gps = gps_ctrl::make(x300_make_uart_iface(mb.zpu_ctrl)); - } - catch(std::exception &e) { + } catch (std::exception& e) { UHD_LOGGER_ERROR("X300") << "An error occurred making GPSDO control: " << e.what(); } if (mb.gps and mb.gps->gps_detected()) { - for(const std::string& name : mb.gps->get_sensors()) { + for (const std::string& name : mb.gps->get_sensors()) { _tree->create<sensor_value_t>(mb_path / "sensors" / name) - .set_publisher([&mb, name](){ - return mb.gps->get_sensor(name); - }) - ; + .set_publisher([&mb, name]() { return mb.gps->get_sensor(name); }); } - } - else { - mb.zpu_ctrl->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS), dont_look_for_gpsdo); + } else { + mb.zpu_ctrl->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS), + dont_look_for_gpsdo); } } @@ -1049,97 +1058,88 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) //////////////////////////////////////////////////////////////////// _tree->create<std::string>(mb_path / "time_source" / "value") .set(mb.args.get_time_source()) - .add_coerced_subscriber([this, &mb](const std::string& time_source){ + .add_coerced_subscriber([this, &mb](const std::string& time_source) { this->update_time_source(mb, time_source); - }) - ; - static const std::vector<std::string> time_sources = - {"internal", "external", "gpsdo"}; + }); + static const std::vector<std::string> time_sources = { + "internal", "external", "gpsdo"}; _tree->create<std::vector<std::string>>(mb_path / "time_source" / "options") .set(time_sources); - //setup the time output, default to ON + // setup the time output, default to ON _tree->create<bool>(mb_path / "time_source" / "output") - .add_coerced_subscriber([this, &mb](const bool time_output){ + .add_coerced_subscriber([this, &mb](const bool time_output) { this->set_time_source_out(mb, time_output); }) - .set(true) - ; + .set(true); //////////////////////////////////////////////////////////////////// // setup clock sources and properties //////////////////////////////////////////////////////////////////// _tree->create<std::string>(mb_path / "clock_source" / "value") .set(mb.args.get_clock_source()) - .add_coerced_subscriber([this, &mb](const std::string& clock_source){ + .add_coerced_subscriber([this, &mb](const std::string& clock_source) { this->update_clock_source(mb, clock_source); - }) - ; - static const std::vector<std::string> clock_source_options = - {"internal", "external", "gpsdo"}; + }); + static const std::vector<std::string> clock_source_options = { + "internal", "external", "gpsdo"}; _tree->create<std::vector<std::string>>(mb_path / "clock_source" / "options") .set(clock_source_options); - //setup external reference options. default to 10 MHz input reference + // setup external reference options. default to 10 MHz input reference _tree->create<std::string>(mb_path / "clock_source" / "external"); - _tree->create<std::vector<double>>(mb_path / "clock_source" / "external" / "freq" / "options") + _tree + ->create<std::vector<double>>( + mb_path / "clock_source" / "external" / "freq" / "options") .set(x300::EXTERNAL_FREQ_OPTIONS); _tree->create<double>(mb_path / "clock_source" / "external" / "value") .set(mb.clock->get_sysref_clock_rate()); // FIXME the external clock source settings need to be more robust - //setup the clock output, default to ON + // setup the clock output, default to ON _tree->create<bool>(mb_path / "clock_source" / "output") - .add_coerced_subscriber([&mb](const bool clock_output){ - mb.clock->set_ref_out(clock_output); - }) - ; + .add_coerced_subscriber( + [&mb](const bool clock_output) { mb.clock->set_ref_out(clock_output); }); // Initialize tick rate (must be done before setting time) // Note: The master tick rate can't be changed at runtime! const double master_clock_rate = mb.clock->get_master_clock_rate(); _tree->create<double>(mb_path / "tick_rate") - .set_coercer([master_clock_rate](const double rate){ + .set_coercer([master_clock_rate](const double rate) { // The contract of multi_usrp::set_master_clock_rate() is to coerce // and not throw, so we'll follow that behaviour here. if (!uhd::math::frequencies_are_equal(rate, master_clock_rate)) { - UHD_LOGGER_WARNING("X300") << - "Cannot update master clock rate! X300 Series does not " - "allow changing the clock rate during runtime." - ; + UHD_LOGGER_WARNING("X300") + << "Cannot update master clock rate! X300 Series does not " + "allow changing the clock rate during runtime."; } return master_clock_rate; }) - .add_coerced_subscriber([this](const double rate){ - this->update_tx_streamers(rate); - }) - .add_coerced_subscriber([this](const double rate){ - this->update_rx_streamers(rate); - }) - .set(master_clock_rate) - ; + .add_coerced_subscriber( + [this](const double rate) { this->update_tx_streamers(rate); }) + .add_coerced_subscriber( + [this](const double rate) { this->update_rx_streamers(rate); }) + .set(master_clock_rate); //////////////////////////////////////////////////////////////////// // and do the misc mboard sensors //////////////////////////////////////////////////////////////////// _tree->create<sensor_value_t>(mb_path / "sensors" / "ref_locked") - .set_publisher([this, &mb](){ return this->get_ref_locked(mb); }); + .set_publisher([this, &mb]() { return this->get_ref_locked(mb); }); //////////////// RFNOC ///////////////// const size_t n_rfnoc_blocks = mb.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_NUM_CE)); - enumerate_rfnoc_blocks( - mb_i, + enumerate_rfnoc_blocks(mb_i, n_rfnoc_blocks, x300::XB_DST_PCI + 1, /* base port */ uhd::sid_t(x300::SRC_ADDR0, 0, x300::DST_ADDR + mb_i, 0), - dev_addr - ); + dev_addr); //////////////// RFNOC ///////////////// // If we have a radio, we must configure its codec control: const std::string radio_blockid_hint = str(boost::format("%d/Radio") % mb_i); std::vector<rfnoc::block_id_t> radio_ids = - find_blocks<rfnoc::x300_radio_ctrl_impl>(radio_blockid_hint); + find_blocks<rfnoc::x300_radio_ctrl_impl>(radio_blockid_hint); if (not radio_ids.empty()) { if (radio_ids.size() > 2) { UHD_LOGGER_WARNING("X300") @@ -1147,33 +1147,31 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) radio_ids.resize(2); } - for(const rfnoc::block_id_t &id: radio_ids) { - rfnoc::x300_radio_ctrl_impl::sptr radio(get_block_ctrl<rfnoc::x300_radio_ctrl_impl>(id)); + for (const rfnoc::block_id_t& id : radio_ids) { + rfnoc::x300_radio_ctrl_impl::sptr radio( + get_block_ctrl<rfnoc::x300_radio_ctrl_impl>(id)); mb.radios.push_back(radio); - radio->setup_radio( - mb.zpu_i2c, - mb.clock, - mb.args.get_ignore_cal_file(), - mb.args.get_self_cal_adc_delay() - ); + radio->setup_radio(mb.zpu_i2c, + mb.clock, + mb.args.get_ignore_cal_file(), + mb.args.get_self_cal_adc_delay()); } //////////////////////////////////////////////////////////////////// // ADC test and cal //////////////////////////////////////////////////////////////////// if (mb.args.get_self_cal_adc_delay()) { - rfnoc::x300_radio_ctrl_impl::self_cal_adc_xfer_delay( - mb.radios, mb.clock, - [this, &mb](const double timeout){ - return this->wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout); + rfnoc::x300_radio_ctrl_impl::self_cal_adc_xfer_delay(mb.radios, + mb.clock, + [this, &mb](const double timeout) { + return this->wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout); }, true /* Apply ADC delay */); } if (mb.args.get_ext_adc_self_test()) { rfnoc::x300_radio_ctrl_impl::extended_adc_test( - mb.radios, - mb.args.get_ext_adc_self_test_duration() - ); + mb.radios, mb.args.get_ext_adc_self_test_duration()); } else { for (size_t i = 0; i < mb.radios.size(); i++) { mb.radios.at(i)->self_test_adc(); @@ -1188,8 +1186,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) } } else { - UHD_LOGGER_INFO("X300") - << "No Radio Block found. Assuming radio-less operation."; + UHD_LOGGER_INFO("X300") << "No Radio Block found. Assuming radio-less operation."; } /* end of radio block(s) initialization */ mb.initialization_done = true; @@ -1197,30 +1194,27 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) x300_impl::~x300_impl(void) { - try - { - for(mboard_members_t &mb: _mb) - { - //kill the claimer task and unclaim the device + try { + for (mboard_members_t& mb : _mb) { + // kill the claimer task and unclaim the device mb.claimer_task.reset(); - { //Critical section + { // Critical section boost::mutex::scoped_lock lock(pcie_zpu_iface_registry_mutex); release(mb.zpu_ctrl); - //If the process is killed, the entire registry will disappear so we - //don't need to worry about unclean shutdowns here. + // If the process is killed, the entire registry will disappear so we + // don't need to worry about unclean shutdowns here. if (get_pcie_zpu_iface_registry().has_key(mb.get_pri_eth().addr)) { get_pcie_zpu_iface_registry().pop(mb.get_pri_eth().addr); } } } - } - catch(...) - { + } catch (...) { UHD_SAFE_CALL(throw;) } } -uint32_t x300_impl::mboard_members_t::allocate_pcie_dma_chan(const uhd::sid_t &tx_sid, const xport_type_t xport_type) +uint32_t x300_impl::mboard_members_t::allocate_pcie_dma_chan( + const uhd::sid_t& tx_sid, const xport_type_t xport_type) { static const uint32_t CTRL_CHANNEL = 0; static const uint32_t ASYNC_MSG_CHANNEL = 1; @@ -1236,28 +1230,29 @@ uint32_t x300_impl::mboard_members_t::allocate_pcie_dma_chan(const uhd::sid_t &t if (_dma_chan_pool.count(raw_sid) == 0) { size_t channel = _dma_chan_pool.size() + FIRST_DATA_CHANNEL; if (channel > x300::PCIE_MAX_CHANNELS) { - throw uhd::runtime_error("Trying to allocate more DMA channels than are available"); + throw uhd::runtime_error( + "Trying to allocate more DMA channels than are available"); } _dma_chan_pool[raw_sid] = channel; UHD_LOGGER_DEBUG("X300") - << "Assigning PCIe DMA channel " << _dma_chan_pool[raw_sid] - << " to SID " << tx_sid.to_pp_string_hex(); + << "Assigning PCIe DMA channel " << _dma_chan_pool[raw_sid] << " to SID " + << tx_sid.to_pp_string_hex(); } return _dma_chan_pool[raw_sid]; } } -static uint32_t extract_sid_from_pkt(void* pkt, size_t) { +static uint32_t extract_sid_from_pkt(void* pkt, size_t) +{ return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])).get_dst(); } -static uhd::transport::muxed_zero_copy_if::sptr make_muxed_pcie_msg_xport -( +static uhd::transport::muxed_zero_copy_if::sptr make_muxed_pcie_msg_xport( uhd::niusrprio::niusrprio_session::sptr rio_fpga_interface, uint32_t dma_channel_num, - size_t max_muxed_ports -) { + size_t max_muxed_ports) +{ zero_copy_xport_params buff_args; buff_args.send_frame_size = x300::PCIE_MSG_FRAME_SIZE; buff_args.recv_frame_size = x300::PCIE_MSG_FRAME_SIZE; @@ -1265,77 +1260,70 @@ static uhd::transport::muxed_zero_copy_if::sptr make_muxed_pcie_msg_xport buff_args.num_recv_frames = x300::PCIE_MSG_NUM_FRAMES * max_muxed_ports; zero_copy_if::sptr base_xport = nirio_zero_copy::make( - rio_fpga_interface, dma_channel_num, - buff_args, uhd::device_addr_t()); + rio_fpga_interface, dma_channel_num, buff_args, uhd::device_addr_t()); return muxed_zero_copy_if::make(base_xport, extract_sid_from_pkt, max_muxed_ports); } -uhd::both_xports_t x300_impl::make_transport( - const uhd::sid_t &address, +uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address, const xport_type_t xport_type, - const uhd::device_addr_t& args -) { - const size_t mb_index = address.get_dst_addr() - x300::DST_ADDR; - mboard_members_t &mb = _mb[mb_index]; - const uhd::device_addr_t& xport_args = (xport_type == CTRL) ? uhd::device_addr_t() : args; + const uhd::device_addr_t& args) +{ + const size_t mb_index = address.get_dst_addr() - x300::DST_ADDR; + mboard_members_t& mb = _mb[mb_index]; + const uhd::device_addr_t& xport_args = (xport_type == CTRL) ? uhd::device_addr_t() + : args; zero_copy_xport_params default_buff_args; both_xports_t xports; xports.endianness = mb.if_pkt_is_big_endian ? ENDIANNESS_BIG : ENDIANNESS_LITTLE; if (mb.xport_path == "nirio") { - xports.send_sid = this->allocate_sid(mb, address, x300::SRC_ADDR0, x300::XB_DST_PCI); + xports.send_sid = + this->allocate_sid(mb, address, x300::SRC_ADDR0, x300::XB_DST_PCI); xports.recv_sid = xports.send_sid.reversed(); uint32_t dma_channel_num = mb.allocate_pcie_dma_chan(xports.send_sid, xport_type); if (xport_type == CTRL) { - //Transport for control stream + // Transport for control stream if (not mb.ctrl_dma_xport) { - //One underlying DMA channel will handle - //all control traffic - mb.ctrl_dma_xport = make_muxed_pcie_msg_xport( - mb.rio_fpga_interface, + // One underlying DMA channel will handle + // all control traffic + mb.ctrl_dma_xport = make_muxed_pcie_msg_xport(mb.rio_fpga_interface, dma_channel_num, x300::PCIE_MAX_MUXED_CTRL_XPORTS); } - //Create a virtual control transport + // Create a virtual control transport xports.recv = mb.ctrl_dma_xport->make_stream(xports.recv_sid.get_dst()); } else if (xport_type == ASYNC_MSG) { - //Transport for async message stream + // Transport for async message stream if (not mb.async_msg_dma_xport) { - //One underlying DMA channel will handle - //all async message traffic - mb.async_msg_dma_xport = make_muxed_pcie_msg_xport( - mb.rio_fpga_interface, + // One underlying DMA channel will handle + // all async message traffic + mb.async_msg_dma_xport = make_muxed_pcie_msg_xport(mb.rio_fpga_interface, dma_channel_num, x300::PCIE_MAX_MUXED_ASYNC_XPORTS); } - //Create a virtual async message transport + // Create a virtual async message transport xports.recv = mb.async_msg_dma_xport->make_stream(xports.recv_sid.get_dst()); } else { - //Transport for data stream - default_buff_args.send_frame_size = - (xport_type == TX_DATA) - ? x300::PCIE_TX_DATA_FRAME_SIZE - : x300::PCIE_MSG_FRAME_SIZE; - - default_buff_args.recv_frame_size = - (xport_type == RX_DATA) - ? x300::PCIE_RX_DATA_FRAME_SIZE - : x300::PCIE_MSG_FRAME_SIZE; - - default_buff_args.num_send_frames = - (xport_type == TX_DATA) - ? x300::PCIE_TX_DATA_NUM_FRAMES - : x300::PCIE_MSG_NUM_FRAMES; + // Transport for data stream + default_buff_args.send_frame_size = (xport_type == TX_DATA) + ? x300::PCIE_TX_DATA_FRAME_SIZE + : x300::PCIE_MSG_FRAME_SIZE; - default_buff_args.num_recv_frames = - (xport_type == RX_DATA) - ? x300::PCIE_RX_DATA_NUM_FRAMES - : x300::PCIE_MSG_NUM_FRAMES; + default_buff_args.recv_frame_size = (xport_type == RX_DATA) + ? x300::PCIE_RX_DATA_FRAME_SIZE + : x300::PCIE_MSG_FRAME_SIZE; + + default_buff_args.num_send_frames = (xport_type == TX_DATA) + ? x300::PCIE_TX_DATA_NUM_FRAMES + : x300::PCIE_MSG_NUM_FRAMES; + + default_buff_args.num_recv_frames = (xport_type == RX_DATA) + ? x300::PCIE_RX_DATA_NUM_FRAMES + : x300::PCIE_MSG_NUM_FRAMES; xports.recv = nirio_zero_copy::make( - mb.rio_fpga_interface, dma_channel_num, - default_buff_args, xport_args); + mb.rio_fpga_interface, dma_channel_num, default_buff_args, xport_args); } xports.send = xports.recv; @@ -1344,23 +1332,27 @@ uhd::both_xports_t x300_impl::make_transport( // - Upper 16 bits: Destination address (e.g. 0.0) // - Lower 16 bits: DMA channel uint32_t router_config_word = (xports.recv_sid.get_dst() << 16) | dma_channel_num; - mb.rio_fpga_interface->get_kernel_proxy()->poke(PCIE_ROUTER_REG(0), router_config_word); + mb.rio_fpga_interface->get_kernel_proxy()->poke( + PCIE_ROUTER_REG(0), router_config_word); - //For the nirio transport, buffer size is depends on the frame size and num frames - xports.recv_buff_size = xports.recv->get_num_recv_frames() * xports.recv->get_recv_frame_size(); - xports.send_buff_size = xports.send->get_num_send_frames() * xports.send->get_send_frame_size(); + // For the nirio transport, buffer size is depends on the frame size and num + // frames + xports.recv_buff_size = + xports.recv->get_num_recv_frames() * xports.recv->get_recv_frame_size(); + xports.send_buff_size = + xports.send->get_num_send_frames() * xports.send->get_send_frame_size(); } else if (mb.xport_path == "eth") { // Decide on the IP/Interface pair based on the endpoint index - size_t &next_src_addr = - xport_type == TX_DATA ? mb.next_tx_src_addr : - xport_type == RX_DATA ? mb.next_rx_src_addr : - mb.next_src_addr; - x300_eth_conn_t conn = mb.eth_conns[next_src_addr]; - const uint32_t xbar_src_addr = - next_src_addr==0 ? x300::SRC_ADDR0 : x300::SRC_ADDR1; - const uint32_t xbar_src_dst = - conn.type==X300_IFACE_ETH0 ? x300::XB_DST_E0 : x300::XB_DST_E1; + size_t& next_src_addr = xport_type == TX_DATA + ? mb.next_tx_src_addr + : xport_type == RX_DATA ? mb.next_rx_src_addr + : mb.next_src_addr; + x300_eth_conn_t conn = mb.eth_conns[next_src_addr]; + const uint32_t xbar_src_addr = next_src_addr == 0 ? x300::SRC_ADDR0 + : x300::SRC_ADDR1; + const uint32_t xbar_src_dst = conn.type == X300_IFACE_ETH0 ? x300::XB_DST_E0 + : x300::XB_DST_E1; // Do not increment src addr for tx_data by default, using dual ethernet // with the DMA FIFO causes sequence errors to DMA FIFO bandwidth @@ -1373,119 +1365,125 @@ uhd::both_xports_t x300_impl::make_transport( xports.recv_sid = xports.send_sid.reversed(); // Set size and number of frames - size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size; - size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size; - default_buff_args.send_frame_size = std::min(system_max_send_frame_size, x300::ETH_MSG_FRAME_SIZE); - default_buff_args.recv_frame_size = std::min(system_max_recv_frame_size, x300::ETH_MSG_FRAME_SIZE); + size_t system_max_send_frame_size = (size_t)_max_frame_sizes.send_frame_size; + size_t system_max_recv_frame_size = (size_t)_max_frame_sizes.recv_frame_size; + default_buff_args.send_frame_size = + std::min(system_max_send_frame_size, x300::ETH_MSG_FRAME_SIZE); + default_buff_args.recv_frame_size = + std::min(system_max_recv_frame_size, x300::ETH_MSG_FRAME_SIZE); default_buff_args.send_buff_size = conn.link_rate / 50; // 20ms - default_buff_args.recv_buff_size = std::max(conn.link_rate / 50, x300::ETH_MSG_NUM_FRAMES * x300::ETH_MSG_FRAME_SIZE); // enough to hold greater of 20ms or number of msg frames - if (xport_type == TX_DATA) - { - size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_SEND_SIZE : x300::XGE_DATA_FRAME_SEND_SIZE; - default_buff_args.send_frame_size = args.cast<size_t>("send_frame_size", std::min(default_frame_size, system_max_send_frame_size)); - if (default_buff_args.send_frame_size > system_max_send_frame_size) - { + default_buff_args.recv_buff_size = std::max(conn.link_rate / 50, + x300::ETH_MSG_NUM_FRAMES + * x300::ETH_MSG_FRAME_SIZE); // enough to hold greater of 20ms or number + // of msg frames + if (xport_type == TX_DATA) { + size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_SEND_SIZE + : x300::XGE_DATA_FRAME_SEND_SIZE; + default_buff_args.send_frame_size = args.cast<size_t>("send_frame_size", + std::min(default_frame_size, system_max_send_frame_size)); + if (default_buff_args.send_frame_size > system_max_send_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("Requested send_frame_size of %d exceeds the maximum allowed on the %s connection. Using %d.") - % default_buff_args.send_frame_size - % conn.addr - % system_max_send_frame_size - ; + << boost::format("Requested send_frame_size of %d exceeds the " + "maximum allowed on the %s connection. Using %d.") + % default_buff_args.send_frame_size % conn.addr + % system_max_send_frame_size; default_buff_args.send_frame_size = system_max_send_frame_size; } - } - else if (xport_type == RX_DATA) - { - size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_RECV_SIZE : x300::XGE_DATA_FRAME_RECV_SIZE; - default_buff_args.recv_frame_size = args.cast<size_t>("recv_frame_size", std::min(default_frame_size, system_max_recv_frame_size)); - if (default_buff_args.recv_frame_size > system_max_recv_frame_size) - { + } else if (xport_type == RX_DATA) { + size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_RECV_SIZE + : x300::XGE_DATA_FRAME_RECV_SIZE; + default_buff_args.recv_frame_size = args.cast<size_t>("recv_frame_size", + std::min(default_frame_size, system_max_recv_frame_size)); + if (default_buff_args.recv_frame_size > system_max_recv_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("Requested recv_frame_size of %d exceeds the maximum allowed on the %s connection. Using %d.") - % default_buff_args.recv_frame_size - % conn.addr - % system_max_recv_frame_size - ; + << boost::format("Requested recv_frame_size of %d exceeds the " + "maximum allowed on the %s connection. Using %d.") + % default_buff_args.recv_frame_size % conn.addr + % system_max_recv_frame_size; default_buff_args.recv_frame_size = system_max_recv_frame_size; } - default_buff_args.num_recv_frames = 2; // set some buffers so the offload thread actually offloads the socket I/O + default_buff_args.num_recv_frames = + 2; // set some buffers so the offload thread actually offloads the socket + // I/O } - //make a new transport - fpga has no idea how to talk to us on this yet + // make a new transport - fpga has no idea how to talk to us on this yet udp_zero_copy::buff_params buff_params; - xports.recv = udp_zero_copy::make( - conn.addr, - BOOST_STRINGIZE(X300_VITA_UDP_PORT), - default_buff_args, - buff_params, - xport_args); + xports.recv = udp_zero_copy::make(conn.addr, + BOOST_STRINGIZE(X300_VITA_UDP_PORT), + default_buff_args, + buff_params, + xport_args); // Create a threaded transport for the receive chain only // Note that this shouldn't affect PCIe if (xport_type == RX_DATA) { xports.recv = zero_copy_recv_offload::make( - xports.recv, - x300::RECV_OFFLOAD_BUFFER_TIMEOUT - ); + xports.recv, x300::RECV_OFFLOAD_BUFFER_TIMEOUT); } xports.send = xports.recv; - //For the UDP transport the buffer size is the size of the socket buffer - //in the kernel + // For the UDP transport the buffer size is the size of the socket buffer + // in the kernel xports.recv_buff_size = buff_params.recv_buff_size; xports.send_buff_size = buff_params.send_buff_size; - //clear the ethernet dispatcher's udp port - //NOT clearing this, the dispatcher is now intelligent + // clear the ethernet dispatcher's udp port + // NOT clearing this, the dispatcher is now intelligent //_zpu_ctrl->poke32(SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT0+8+3)), 0); - //send a mini packet with SID into the ZPU - //ZPU will reprogram the ethernet framer - UHD_LOGGER_DEBUG("X300") << "programming packet for new xport on " - << conn.addr << " sid " << xports.send_sid ; - //YES, get a __send__ buffer from the __recv__ socket + // send a mini packet with SID into the ZPU + // ZPU will reprogram the ethernet framer + UHD_LOGGER_DEBUG("X300") << "programming packet for new xport on " << conn.addr + << " sid " << xports.send_sid; + // YES, get a __send__ buffer from the __recv__ socket //-- this is the only way to program the framer for recv: managed_send_buffer::sptr buff = xports.recv->get_send_buff(); - buff->cast<uint32_t *>()[0] = 0; //eth dispatch looks for != 0 - buff->cast<uint32_t *>()[1] = uhd::htonx(xports.send_sid.get()); + buff->cast<uint32_t*>()[0] = 0; // eth dispatch looks for != 0 + buff->cast<uint32_t*>()[1] = uhd::htonx(xports.send_sid.get()); buff->commit(8); buff.reset(); - //reprogram the ethernet dispatcher's udp port (should be safe to always set) - UHD_LOGGER_TRACE("X300") - << "reprogram the ethernet dispatcher's udp port" ; - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT0+8+3)), X300_VITA_UDP_PORT); - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT1+8+3)), X300_VITA_UDP_PORT); + // reprogram the ethernet dispatcher's udp port (should be safe to always set) + UHD_LOGGER_TRACE("X300") << "reprogram the ethernet dispatcher's udp port"; + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT0 + 8 + 3)), X300_VITA_UDP_PORT); + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT1 + 8 + 3)), X300_VITA_UDP_PORT); - //Do a peek to an arbitrary address to guarantee that the - //ethernet framer has been programmed before we return. + // Do a peek to an arbitrary address to guarantee that the + // ethernet framer has been programmed before we return. mb.zpu_ctrl->peek32(0); } return xports; } -uhd::sid_t x300_impl::allocate_sid( - mboard_members_t &mb, - const uhd::sid_t &address, - const uint32_t src_addr, - const uint32_t src_dst -) { +uhd::sid_t x300_impl::allocate_sid(mboard_members_t& mb, + const uhd::sid_t& address, + const uint32_t src_addr, + const uint32_t src_dst) +{ uhd::sid_t sid = address; sid.set_src_addr(src_addr); - sid.set_src_endpoint(_sid_framer++); //increment for next setup + sid.set_src_endpoint(_sid_framer++); // increment for next setup // TODO Move all of this setup_mb() // Program the X300 to recognise it's own local address. mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_XB_LOCAL), address.get_dst_addr()); - // Program CAM entry for outgoing packets matching a X300 resource (for example a Radio) - // This type of packet matches the XB_LOCAL address and is looked up in the upper half of the CAM - mb.zpu_ctrl->poke32(SR_ADDR(SETXB_BASE, 256 + address.get_dst_endpoint()), address.get_dst_xbarport()); + // Program CAM entry for outgoing packets matching a X300 resource (for example a + // Radio) This type of packet matches the XB_LOCAL address and is looked up in the + // upper half of the CAM + mb.zpu_ctrl->poke32(SR_ADDR(SETXB_BASE, 256 + address.get_dst_endpoint()), + address.get_dst_xbarport()); // Program CAM entry for returning packets to us (for example GR host via Eth0) - // This type of packet does not match the XB_LOCAL address and is looked up in the lower half of the CAM + // This type of packet does not match the XB_LOCAL address and is looked up in the + // lower half of the CAM mb.zpu_ctrl->poke32(SR_ADDR(SETXB_BASE, 0 + src_addr), src_dst); - UHD_LOGGER_TRACE("X300") << "done router config for sid " << sid ; + UHD_LOGGER_TRACE("X300") << "done router config for sid " << sid; return sid; } @@ -1493,95 +1491,123 @@ uhd::sid_t x300_impl::allocate_sid( /*********************************************************************** * clock and time control logic **********************************************************************/ -void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb) +void x300_impl::set_time_source_out(mboard_members_t& mb, const bool enb) { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_OUT_EN, enb?1:0); + mb.fw_regmap->clock_ctrl_reg.write( + fw_regmap_t::clk_ctrl_reg_t::PPS_OUT_EN, enb ? 1 : 0); } -void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source) +void x300_impl::update_clock_source(mboard_members_t& mb, const std::string& source) { - //Optimize for the case when the current source is internal and we are trying - //to set it to internal. This is the only case where we are guaranteed that - //the clock has not gone away so we can skip setting the MUX and reseting the LMK. - const bool reconfigure_clks = (mb.current_refclk_src != "internal") or (source != "internal"); + // Optimize for the case when the current source is internal and we are trying + // to set it to internal. This is the only case where we are guaranteed that + // the clock has not gone away so we can skip setting the MUX and reseting the LMK. + const bool reconfigure_clks = (mb.current_refclk_src != "internal") + or (source != "internal"); if (reconfigure_clks) { - //Update the clock MUX on the motherboard to select the requested source + // Update the clock MUX on the motherboard to select the requested source if (source == "internal") { - mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); + mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, + fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 1); } else if (source == "external") { - mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); + mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, + fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0); } else if (source == "gpsdo") { - mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); + mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, + fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0); } else { throw uhd::key_error("update_clock_source: unknown source: " + source); } mb.fw_regmap->clock_ctrl_reg.flush(); - //Reset the LMK to make sure it re-locks to the new reference + // Reset the LMK to make sure it re-locks to the new reference mb.clock->reset_clocks(); } - //Wait for the LMK to lock (always, as a sanity check that the clock is useable) - //* Currently the LMK can take as long as 30 seconds to lock to a reference but we don't + // Wait for the LMK to lock (always, as a sanity check that the clock is useable) + //* Currently the LMK can take as long as 30 seconds to lock to a reference but we + // don't //* want to wait that long during initialization. - //TODO: Need to verify timeout and settings to make sure lock can be achieved in < 1.0 seconds + // TODO: Need to verify timeout and settings to make sure lock can be achieved in + // < 1.0 seconds double timeout = mb.initialization_done ? 30.0 : 1.0; - //The programming code in x300_clock_ctrl is not compatible with revs <= 4 and may - //lead to locking issues. So, disable the ref-locked check for older (unsupported) boards. + // The programming code in x300_clock_ctrl is not compatible with revs <= 4 and may + // lead to locking issues. So, disable the ref-locked check for older (unsupported) + // boards. if (mb.hw_rev > 4) { - if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout)) { - //failed to lock on reference + if (not wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout)) { + // failed to lock on reference if (mb.initialization_done) { - throw uhd::runtime_error((boost::format("Reference Clock PLL failed to lock to %s source.") % source).str()); + throw uhd::runtime_error( + (boost::format("Reference Clock PLL failed to lock to %s source.") + % source) + .str()); } else { - //TODO: Re-enable this warning when we figure out a reliable lock time - //UHD_LOGGER_WARNING("X300") << "Reference clock failed to lock to " + source + " during device initialization. " << - // "Check for the lock before operation or ignore this warning if using another clock source." ; + // TODO: Re-enable this warning when we figure out a reliable lock time + // UHD_LOGGER_WARNING("X300") << "Reference clock failed to lock to " + + // source + " during device initialization. " << + // "Check for the lock before operation or ignore this warning if using + // another clock source." ; } } } if (reconfigure_clks) { - //Reset the radio clock PLL in the FPGA - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_RADIO_CLK_PLL); + // Reset the radio clock PLL in the FPGA + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_RADIO_CLK_PLL); mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0); - //Wait for radio clock PLL to lock - if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK, 0.01)) { - throw uhd::runtime_error((boost::format("Reference Clock PLL in FPGA failed to lock to %s source.") % source).str()); + // Wait for radio clock PLL to lock + if (not wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK, 0.01)) { + throw uhd::runtime_error( + (boost::format("Reference Clock PLL in FPGA failed to lock to %s source.") + % source) + .str()); } - //Reset the IDELAYCTRL used to calibrate the data interface delays - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_ADC_IDELAYCTRL); + // Reset the IDELAYCTRL used to calibrate the data interface delays + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_ADC_IDELAYCTRL); mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0); - //Wait for the ADC IDELAYCTRL to be ready - if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK, 0.01)) { - throw uhd::runtime_error((boost::format("ADC Calibration Clock in FPGA failed to lock to %s source.") % source).str()); + // Wait for the ADC IDELAYCTRL to be ready + if (not wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK, 0.01)) { + throw uhd::runtime_error( + (boost::format( + "ADC Calibration Clock in FPGA failed to lock to %s source.") + % source) + .str()); } // Reset ADCs and DACs - for(rfnoc::x300_radio_ctrl_impl::sptr r: mb.radios) { + for (rfnoc::x300_radio_ctrl_impl::sptr r : mb.radios) { r->reset_codec(); } } - //Update cache value + // Update cache value mb.current_refclk_src = source; } -void x300_impl::update_time_source(mboard_members_t &mb, const std::string &source) +void x300_impl::update_time_source(mboard_members_t& mb, const std::string& source) { if (source == "internal") { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); + mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, + fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); } else if (source == "external") { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); + mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, + fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); } else if (source == "gpsdo") { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); + mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, + fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); } else { throw uhd::key_error("update_time_source: unknown source: " + source); } @@ -1589,15 +1615,17 @@ void x300_impl::update_time_source(mboard_members_t &mb, const std::string &sour /* TODO - Implement intelligent PPS detection //check for valid pps if (!is_pps_present(mb)) { - throw uhd::runtime_error((boost::format("The %d PPS was not detected. Please check the PPS source and try again.") % source).str()); + throw uhd::runtime_error((boost::format("The %d PPS was not detected. Please + check the PPS source and try again.") % source).str()); } */ } -void x300_impl::sync_times(mboard_members_t &mb, const uhd::time_spec_t& t) +void x300_impl::sync_times(mboard_members_t& mb, const uhd::time_spec_t& t) { - std::vector<rfnoc::block_id_t> radio_ids = find_blocks<rfnoc::x300_radio_ctrl_impl>("Radio"); - for(const rfnoc::block_id_t &id: radio_ids) { + std::vector<rfnoc::block_id_t> radio_ids = + find_blocks<rfnoc::x300_radio_ctrl_impl>("Radio"); + for (const rfnoc::block_id_t& id : radio_ids) { get_block_ctrl<rfnoc::x300_radio_ctrl_impl>(id)->set_time_sync(t); } @@ -1608,9 +1636,8 @@ void x300_impl::sync_times(mboard_members_t &mb, const uhd::time_spec_t& t) bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, uint32_t which, double timeout) { - const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(int64_t(timeout * 1000)); + const auto timeout_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(int64_t(timeout * 1000)); do { if (mb.fw_regmap->clock_status_reg.read(which) == 1) { return true; @@ -1618,16 +1645,21 @@ bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, uint32_t which, double std::this_thread::sleep_for(std::chrono::milliseconds(1)); } while (std::chrono::steady_clock::now() < timeout_time); - //Check one last time - return (mb.fw_regmap->clock_status_reg.read(which)==1); + // Check one last time + return (mb.fw_regmap->clock_status_reg.read(which) == 1); } sensor_value_t x300_impl::get_ref_locked(mboard_members_t& mb) { mb.fw_regmap->clock_status_reg.refresh(); - const bool lock = (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::LMK_LOCK)==1) && - (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK)==1) && - (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK)==1); + const bool lock = + (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::LMK_LOCK) == 1) + && (mb.fw_regmap->clock_status_reg.get( + fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK) + == 1) + && (mb.fw_regmap->clock_status_reg.get( + fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK) + == 1); return sensor_value_t("Ref", lock, "locked", "unlocked"); } @@ -1635,11 +1667,13 @@ bool x300_impl::is_pps_present(mboard_members_t& mb) { // The ZPU_RB_CLK_STATUS_PPS_DETECT bit toggles with each rising edge of the PPS. // We monitor it for up to 1.5 seconds looking for it to toggle. - uint32_t pps_detect = mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT); - for (int i = 0; i < 15; i++) - { + uint32_t pps_detect = + mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT); + for (int i = 0; i < 15; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (pps_detect != mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT)) + if (pps_detect + != mb.fw_regmap->clock_status_reg.read( + fw_regmap_t::clk_status_reg_t::PPS_DETECT)) return true; } return false; @@ -1658,22 +1692,18 @@ void x300_impl::claimer_loop(wb_iface::sptr iface) x300_impl::claim_status_t x300_impl::claim_status(wb_iface::sptr iface) { claim_status_t claim_status = CLAIMED_BY_OTHER; // Default to most restrictive - auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::seconds(1); - while (std::chrono::steady_clock::now() < timeout_time) - { - //If timed out, then device is definitely unclaimed - if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) - { + auto timeout_time = std::chrono::steady_clock::now() + std::chrono::seconds(1); + while (std::chrono::steady_clock::now() < timeout_time) { + // If timed out, then device is definitely unclaimed + if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) { claim_status = UNCLAIMED; break; } - //otherwise check claim src to determine if another thread with the same src has claimed the device + // otherwise check claim src to determine if another thread with the same src has + // claimed the device uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); - if (hash == 0) - { + if (hash == 0) { // A non-zero claim status and an empty hash means the claim might // be in the process of being released. This is possible because // older firmware takes a long time to update the status. Wait and @@ -1696,20 +1726,17 @@ void x300_impl::claim(wb_iface::sptr iface) bool x300_impl::try_to_claim(wb_iface::sptr iface, long timeout_ms) { const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(timeout_ms); - while (1) - { + std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms); + while (1) { claim_status_t status = claim_status(iface); - if (status == UNCLAIMED) - { + if (status == UNCLAIMED) { claim(iface); - // It takes the claimer 10ms to update status, so wait 20ms before verifying claim + // It takes the claimer 10ms to update status, so wait 20ms before verifying + // claim std::this_thread::sleep_for(std::chrono::milliseconds(20)); continue; } - if (status == CLAIMED_BY_US) - { + if (status == CLAIMED_BY_US) { break; } if (std::chrono::steady_clock::now() > timeout_time) { @@ -1730,57 +1757,62 @@ void x300_impl::release(wb_iface::sptr iface) /*********************************************************************** * Frame size detection **********************************************************************/ -x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &addr, - const frame_size_t &user_frame_size) +x300_impl::frame_size_t x300_impl::determine_max_frame_size( + const std::string& addr, const frame_size_t& user_frame_size) { - udp_simple::sptr udp = udp_simple::make_connected(addr, - BOOST_STRINGIZE(X300_MTU_DETECT_UDP_PORT)); + udp_simple::sptr udp = + udp_simple::make_connected(addr, BOOST_STRINGIZE(X300_MTU_DETECT_UDP_PORT)); - std::vector<uint8_t> buffer(std::max(user_frame_size.recv_frame_size, user_frame_size.send_frame_size)); - x300_mtu_t *request = reinterpret_cast<x300_mtu_t *>(&buffer.front()); - static const double echo_timeout = 0.020; //20 ms + std::vector<uint8_t> buffer( + std::max(user_frame_size.recv_frame_size, user_frame_size.send_frame_size)); + x300_mtu_t* request = reinterpret_cast<x300_mtu_t*>(&buffer.front()); + static const double echo_timeout = 0.020; // 20 ms - //test holler - check if its supported in this fw version + // test holler - check if its supported in this fw version request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); - request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); + request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); udp->send(boost::asio::buffer(buffer, sizeof(x300_mtu_t))); udp->recv(boost::asio::buffer(buffer), echo_timeout); if (!(uhd::ntohx<uint32_t>(request->flags) & X300_MTU_DETECT_ECHO_REPLY)) throw uhd::not_implemented_error("Holler protocol not implemented"); - //Reducing range of (min,max) by setting max value to 10gig max_frame_size as larger sizes are not supported + // Reducing range of (min,max) by setting max value to 10gig max_frame_size as larger + // sizes are not supported size_t min_recv_frame_size = sizeof(x300_mtu_t); - size_t max_recv_frame_size = std::min(user_frame_size.recv_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); + size_t max_recv_frame_size = + std::min(user_frame_size.recv_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); size_t min_send_frame_size = sizeof(x300_mtu_t); - size_t max_send_frame_size = std::min(user_frame_size.send_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); + size_t max_send_frame_size = + std::min(user_frame_size.send_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); UHD_LOGGER_DEBUG("X300") << "Determining maximum frame size... "; - while (min_recv_frame_size < max_recv_frame_size) - { - size_t test_frame_size = (max_recv_frame_size/2 + min_recv_frame_size/2 + 3) & ~3; + while (min_recv_frame_size < max_recv_frame_size) { + size_t test_frame_size = (max_recv_frame_size / 2 + min_recv_frame_size / 2 + 3) + & ~3; - request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); - request->size = uhd::htonx<uint32_t>(test_frame_size); - udp->send(boost::asio::buffer(buffer, sizeof(x300_mtu_t))); + request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); + request->size = uhd::htonx<uint32_t>(test_frame_size); + udp->send(boost::asio::buffer(buffer, sizeof(x300_mtu_t))); - size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout); + size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout); - if (len >= test_frame_size) - min_recv_frame_size = test_frame_size; - else - max_recv_frame_size = test_frame_size - 4; + if (len >= test_frame_size) + min_recv_frame_size = test_frame_size; + else + max_recv_frame_size = test_frame_size - 4; } - if(min_recv_frame_size < IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER) { - throw uhd::runtime_error("System receive MTU size is less than the minimum required by the IP protocol."); + if (min_recv_frame_size < IP_PROTOCOL_MIN_MTU_SIZE - IP_PROTOCOL_UDP_PLUS_IP_HEADER) { + throw uhd::runtime_error("System receive MTU size is less than the minimum " + "required by the IP protocol."); } - while (min_send_frame_size < max_send_frame_size) - { - size_t test_frame_size = (max_send_frame_size/2 + min_send_frame_size/2 + 3) & ~3; + while (min_send_frame_size < max_send_frame_size) { + size_t test_frame_size = (max_send_frame_size / 2 + min_send_frame_size / 2 + 3) + & ~3; request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); - request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); + request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); udp->send(boost::asio::buffer(buffer, test_frame_size)); size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout); @@ -1793,8 +1825,9 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &a max_send_frame_size = test_frame_size - 4; } - if(min_send_frame_size < IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER) { - throw uhd::runtime_error("System send MTU size is less than the minimum required by the IP protocol."); + if (min_send_frame_size < IP_PROTOCOL_MIN_MTU_SIZE - IP_PROTOCOL_UDP_PLUS_IP_HEADER) { + throw uhd::runtime_error( + "System send MTU size is less than the minimum required by the IP protocol."); } frame_size_t frame_size; @@ -1803,8 +1836,8 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &a // of the recv and send frame sizes. frame_size.recv_frame_size = std::min(min_recv_frame_size, min_send_frame_size); frame_size.send_frame_size = std::min(min_recv_frame_size, min_send_frame_size); - UHD_LOGGER_INFO("X300") - << "Maximum frame size: " << frame_size.send_frame_size << " bytes."; + UHD_LOGGER_INFO("X300") << "Maximum frame size: " << frame_size.send_frame_size + << " bytes."; return frame_size; } @@ -1812,10 +1845,8 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &a * compat checks **********************************************************************/ -void x300_impl::check_fw_compat( - const fs_path &mb_path, - const mboard_members_t &members -) { +void x300_impl::check_fw_compat(const fs_path& mb_path, const mboard_members_t& members) +{ auto iface = members.zpu_ctrl; const uint32_t compat_num = iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_COMPAT_NUM)); @@ -1826,78 +1857,75 @@ void x300_impl::check_fw_compat( const std::string image_loader_path = (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); const std::string image_loader_cmd = - str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") - % image_loader_path - % (members.xport_path == "eth" ? "addr" - : "resource") - % members.get_pri_eth().addr); - - throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number %d, but got %d:\n" - "The FPGA/firmware image on your device is not compatible with this host code build.\n" - "Download the appropriate FPGA images for this version of UHD.\n" - "%s\n\n" - "Then burn a new image to the on-board flash storage of your\n" - "USRP X3xx device using the image loader utility. " - "Use this command:\n\n%s\n\n" - "For more information, refer to the UHD manual:\n\n" - " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash" - ) % int(X300_FW_COMPAT_MAJOR) % compat_major - % print_utility_error("uhd_images_downloader.py") - % image_loader_cmd)); + str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") % image_loader_path + % (members.xport_path == "eth" ? "addr" : "resource") + % members.get_pri_eth().addr); + + throw uhd::runtime_error( + str(boost::format( + "Expected firmware compatibility number %d, but got %d:\n" + "The FPGA/firmware image on your device is not compatible with this " + "host code build.\n" + "Download the appropriate FPGA images for this version of UHD.\n" + "%s\n\n" + "Then burn a new image to the on-board flash storage of your\n" + "USRP X3xx device using the image loader utility. " + "Use this command:\n\n%s\n\n" + "For more information, refer to the UHD manual:\n\n" + " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash") + % int(X300_FW_COMPAT_MAJOR) % compat_major + % print_utility_error("uhd_images_downloader.py") % image_loader_cmd)); } _tree->create<std::string>(mb_path / "fw_version") .set(str(boost::format("%u.%u") % compat_major % compat_minor)); } -void x300_impl::check_fpga_compat(const fs_path &mb_path, const mboard_members_t &members) +void x300_impl::check_fpga_compat(const fs_path& mb_path, const mboard_members_t& members) { uint32_t compat_num = members.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_COMPAT_NUM)); uint32_t compat_major = (compat_num >> 16); uint32_t compat_minor = (compat_num & 0xffff); - if (compat_major != X300_FPGA_COMPAT_MAJOR) - { - std::string image_loader_path = (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); - std::string image_loader_cmd = str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") - % image_loader_path - % (members.xport_path == "eth" ? "addr" - : "resource") - % members.get_pri_eth().addr); - - throw uhd::runtime_error(str(boost::format( - "Expected FPGA compatibility number %d, but got %d:\n" - "The FPGA image on your device is not compatible with this host code build.\n" - "Download the appropriate FPGA images for this version of UHD.\n" - "%s\n\n" - "Then burn a new image to the on-board flash storage of your\n" - "USRP X3xx device using the image loader utility. Use this command:\n\n%s\n\n" - "For more information, refer to the UHD manual:\n\n" - " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash" - ) % int(X300_FPGA_COMPAT_MAJOR) % compat_major - % print_utility_error("uhd_images_downloader.py") - % image_loader_cmd)); + if (compat_major != X300_FPGA_COMPAT_MAJOR) { + std::string image_loader_path = + (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); + std::string image_loader_cmd = + str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") % image_loader_path + % (members.xport_path == "eth" ? "addr" : "resource") + % members.get_pri_eth().addr); + + throw uhd::runtime_error( + str(boost::format( + "Expected FPGA compatibility number %d, but got %d:\n" + "The FPGA image on your device is not compatible with this host code " + "build.\n" + "Download the appropriate FPGA images for this version of UHD.\n" + "%s\n\n" + "Then burn a new image to the on-board flash storage of your\n" + "USRP X3xx device using the image loader utility. Use this " + "command:\n\n%s\n\n" + "For more information, refer to the UHD manual:\n\n" + " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash") + % int(X300_FPGA_COMPAT_MAJOR) % compat_major + % print_utility_error("uhd_images_downloader.py") % image_loader_cmd)); } - _tree->create<std::string>(mb_path / "fpga_version").set(str(boost::format("%u.%u") - % compat_major % compat_minor)); - - const uint32_t git_hash = members.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, - ZPU_RB_GIT_HASH)); - const std::string git_hash_str = str( - boost::format("%07x%s") - % (git_hash & 0x0FFFFFFF) - % ((git_hash & 0xF0000000) ? "-dirty" : "") - ); + _tree->create<std::string>(mb_path / "fpga_version") + .set(str(boost::format("%u.%u") % compat_major % compat_minor)); + + const uint32_t git_hash = + members.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_GIT_HASH)); + const std::string git_hash_str = str(boost::format("%07x%s") % (git_hash & 0x0FFFFFFF) + % ((git_hash & 0xF0000000) ? "-dirty" : "")); _tree->create<std::string>(mb_path / "fpga_version_hash").set(git_hash_str); UHD_LOG_DEBUG("X300", "Using FPGA version: " << compat_major << "." << compat_minor - << " git hash: " << git_hash_str); + << " git hash: " << git_hash_str); } x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie( - const std::string& resource, const std::string& rpc_port) + const std::string& resource, const std::string& rpc_port) { - //Detect the PCIe product ID to distinguish between X300 and X310 + // Detect the PCIe product ID to distinguish between X300 and X310 nirio_status status = NiRio_Status_Success; uint32_t pid; niriok_proxy::sptr discovery_proxy = @@ -1911,20 +1939,18 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie( } } - UHD_LOGGER_WARNING("X300") << - "NI-RIO Error -- unable to determine motherboard type!"; + UHD_LOGGER_WARNING("X300") << "NI-RIO Error -- unable to determine motherboard type!"; return UNKNOWN; } x300_impl::x300_mboard_t x300_impl::get_mb_type_from_eeprom( - const uhd::usrp::mboard_eeprom_t& mb_eeprom) + const uhd::usrp::mboard_eeprom_t& mb_eeprom) { - if (not mb_eeprom["product"].empty()) - { + if (not mb_eeprom["product"].empty()) { uint16_t product_num = 0; try { product_num = boost::lexical_cast<uint16_t>(mb_eeprom["product"]); - } catch (const boost::bad_lexical_cast &) { + } catch (const boost::bad_lexical_cast&) { product_num = 0; } |