diff options
18 files changed, 111 insertions, 59 deletions
diff --git a/firmware/usrp3/lib/fw_comm_protocol.c b/firmware/usrp3/lib/fw_comm_protocol.c index bb0297e8d..0cc931a76 100644 --- a/firmware/usrp3/lib/fw_comm_protocol.c +++ b/firmware/usrp3/lib/fw_comm_protocol.c @@ -15,7 +15,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <fw_comm_protocol.h> +#include "../../../host/lib/usrp/common/fw_comm_protocol.h" + #include <trace.h> #include <string.h> //memcmp diff --git a/firmware/usrp3/n230/n230_eeprom.c b/firmware/usrp3/n230/n230_eeprom.c index 116f87985..767289efa 100644 --- a/firmware/usrp3/n230/n230_eeprom.c +++ b/firmware/usrp3/n230/n230_eeprom.c @@ -22,8 +22,9 @@ #include <flash/spi_flash.h> #include <flash/spif_spsn_s25flxx.h> #include <string.h> //memcpy -#include "n230_fw_defs.h" -#include "n230_fw_host_iface.h" + +#include "../../../host/lib/usrp/n230/n230_fw_defs.h" +#include "../../../host/lib/usrp/n230/n230_fw_host_iface.h" static const wb_spi_slave_t flash_spi_slave = { .base = (void*) 0xB000, diff --git a/firmware/usrp3/n230/n230_eeprom.h b/firmware/usrp3/n230/n230_eeprom.h index 5513d4239..b6c2a0c76 100644 --- a/firmware/usrp3/n230/n230_eeprom.h +++ b/firmware/usrp3/n230/n230_eeprom.h @@ -35,7 +35,7 @@ extern "C" { #endif #define N230_EEPROM_VER_MAJOR 1 -#define N230_EEPROM_VER_MINOR 0 +#define N230_EEPROM_VER_MINOR 1 #define N230_EEPROM_SERIAL_LEN 9 #define N230_EEPROM_NAME_LEN 32 @@ -57,7 +57,9 @@ typedef struct uint16_t hw_revision; uint16_t hw_product; uint8_t serial[N230_EEPROM_SERIAL_LEN]; - uint8_t _pad0[20 - N230_EEPROM_SERIAL_LEN]; + uint8_t _pad_serial; + uint16_t hw_revision_compat; + uint8_t _pad0[18 - (N230_EEPROM_SERIAL_LEN + 1)]; //Ethernet specific uint32_t gateway; diff --git a/firmware/usrp3/n230/n230_eth_handlers.c b/firmware/usrp3/n230/n230_eth_handlers.c index 98b8bc326..bb07be51b 100644 --- a/firmware/usrp3/n230/n230_eth_handlers.c +++ b/firmware/usrp3/n230/n230_eth_handlers.c @@ -17,15 +17,15 @@ #include "n230_eth_handlers.h" -#include <fw_comm_protocol.h> #include <wb_utils.h> #include <string.h> //memcmp #include <u3_net_stack.h> #include <print_addrs.h> #include <trace.h> +#include "../../../host/lib/usrp/common/fw_comm_protocol.h" +#include "../../../host/lib/usrp/n230/n230_fw_defs.h" #include "../n230/n230_fw_host_iface.h" #include "n230_eeprom.h" -#include "n230_fw_defs.h" static n230_host_shared_mem_t* host_shared_mem_ptr; diff --git a/firmware/usrp3/n230/n230_eth_handlers.h b/firmware/usrp3/n230/n230_eth_handlers.h index 86130e361..67afbb246 100644 --- a/firmware/usrp3/n230/n230_eth_handlers.h +++ b/firmware/usrp3/n230/n230_eth_handlers.h @@ -23,7 +23,7 @@ #include <stdbool.h> #include <lwip/ip_addr.h> #include <wb_soft_reg.h> -#include "../n230/n230_fw_host_iface.h" +#include "../../../host/lib/usrp/n230/n230_fw_host_iface.h" /*! * Registrar for host firmware communications handler. diff --git a/firmware/usrp3/n230/n230_init.c b/firmware/usrp3/n230/n230_init.c index 4602f8338..0054c1bbc 100644 --- a/firmware/usrp3/n230/n230_init.c +++ b/firmware/usrp3/n230/n230_init.c @@ -25,8 +25,8 @@ #include <print_addrs.h> #include <trace.h> #include "n230_eeprom.h" -#include "n230_fw_defs.h" #include "n230_init.h" +#include "../../../host/lib/usrp/n230/n230_fw_defs.h" static wb_pkt_iface64_config_t pkt_config; diff --git a/firmware/usrp3/n230/n230_main.c b/firmware/usrp3/n230/n230_main.c index ceb896514..a6c12e56d 100644 --- a/firmware/usrp3/n230/n230_main.c +++ b/firmware/usrp3/n230/n230_main.c @@ -19,9 +19,9 @@ #include <wb_soft_reg.h> #include <u3_net_stack.h> #include <trace.h> +#include "../../../host/lib/usrp/n230/n230_fw_defs.h" +#include "../../../host/lib/usrp/n230/n230_fw_host_iface.h" #include "n230_eth_handlers.h" -#include "n230_fw_defs.h" -#include "n230_fw_host_iface.h" #include "n230_init.h" //The version hash should come from a cmake build variable diff --git a/firmware/usrp3/include/fw_comm_protocol.h b/host/lib/usrp/common/fw_comm_protocol.h index 14adb33a9..14adb33a9 100644 --- a/firmware/usrp3/include/fw_comm_protocol.h +++ b/host/lib/usrp/common/fw_comm_protocol.h diff --git a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp b/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp index d3f11b9ee..aefd84882 100644 --- a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp +++ b/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp @@ -17,13 +17,13 @@ #include "usrp3_fw_ctrl_iface.hpp" -#include "../../../firmware/usrp3/include/fw_comm_protocol.h" #include <uhd/utils/byteswap.hpp> #include <uhd/utils/msg.hpp> #include <uhd/exception.hpp> #include <boost/format.hpp> #include <boost/asio.hpp> //used for htonl and ntohl #include <boost/foreach.hpp> +#include "fw_comm_protocol.h" namespace uhd { namespace usrp { namespace usrp3 { diff --git a/host/lib/usrp/n230/n230_cores.cpp b/host/lib/usrp/n230/n230_cores.cpp index 14e99b692..58c702ec1 100644 --- a/host/lib/usrp/n230/n230_cores.cpp +++ b/host/lib/usrp/n230/n230_cores.cpp @@ -15,9 +15,9 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include "../../../firmware/usrp3/n230/n230_fw_defs.h" #include "n230_cores.hpp" #include "n230_fpga_defs.h" +#include "n230_fw_defs.h" namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/n230/n230_eeprom_manager.cpp b/host/lib/usrp/n230/n230_eeprom_manager.cpp index ed40b47be..40f501ef9 100644 --- a/host/lib/usrp/n230/n230_eeprom_manager.cpp +++ b/host/lib/usrp/n230/n230_eeprom_manager.cpp @@ -65,10 +65,22 @@ const mboard_eeprom_t& n230_eeprom_manager::read_mb_eeprom() const n230_eeprom_map_t* map_ptr = reinterpret_cast<const n230_eeprom_map_t*>(_response.data); const n230_eeprom_map_t& map = *map_ptr; + uint16_t ver_major = uhd::htonx<boost::uint16_t>(map.data_version_major); + uint16_t ver_minor = uhd::htonx<boost::uint16_t>(map.data_version_minor); + _mb_eeprom["product"] = boost::lexical_cast<std::string>( uhd::htonx<boost::uint16_t>(map.hw_product)); _mb_eeprom["revision"] = boost::lexical_cast<std::string>( uhd::htonx<boost::uint16_t>(map.hw_revision)); + //The revision_compat field does not exist in version 1.0 + //EEPROM version 1.0 will only exist on HW revision 1 so it is safe to set + //revision_compat = revision + if (ver_major == 1 and ver_minor == 0) { + _mb_eeprom["revision_compat"] = _mb_eeprom["revision"]; + } else { + _mb_eeprom["revision_compat"] = boost::lexical_cast<std::string>( + uhd::htonx<boost::uint16_t>(map.hw_revision_compat)); + } _mb_eeprom["serial"] = _bytes_to_string( map.serial, N230_EEPROM_SERIAL_LEN); @@ -104,6 +116,15 @@ void n230_eeprom_manager::write_mb_eeprom(const mboard_eeprom_t& eeprom) memcpy(map_ptr, _response.data, sizeof(n230_eeprom_map_t)); n230_eeprom_map_t& map = *map_ptr; + // Automatic version upgrade handling + uint16_t old_ver_major = uhd::htonx<boost::uint16_t>(map.data_version_major); + uint16_t old_ver_minor = uhd::htonx<boost::uint16_t>(map.data_version_minor); + + //The revision_compat field does not exist for version 1.0 so force write it + //EEPROM version 1.0 will only exist on HW revision 1 so it is safe to set + //revision_compat = revision for the upgrade + bool force_write_version_compat = (old_ver_major == 1 and old_ver_minor == 0); + map.data_version_major = uhd::htonx<boost::uint16_t>(N230_EEPROM_VER_MAJOR); map.data_version_minor = uhd::htonx<boost::uint16_t>(N230_EEPROM_VER_MINOR); @@ -115,6 +136,12 @@ void n230_eeprom_manager::write_mb_eeprom(const mboard_eeprom_t& eeprom) map.hw_revision = uhd::htonx<boost::uint16_t>( boost::lexical_cast<boost::uint16_t>(_mb_eeprom["revision"])); } + if (_mb_eeprom.has_key("revision_compat")) { + map.hw_revision_compat = uhd::htonx<boost::uint16_t>( + boost::lexical_cast<boost::uint16_t>(_mb_eeprom["revision_compat"])); + } else if (force_write_version_compat) { + map.hw_revision_compat = map.hw_revision; + } if (_mb_eeprom.has_key("serial")) { _string_to_bytes(_mb_eeprom["serial"], N230_EEPROM_SERIAL_LEN, map.serial); } diff --git a/host/lib/usrp/n230/n230_eeprom_manager.hpp b/host/lib/usrp/n230/n230_eeprom_manager.hpp index 612124d89..cc5aee9f3 100644 --- a/host/lib/usrp/n230/n230_eeprom_manager.hpp +++ b/host/lib/usrp/n230/n230_eeprom_manager.hpp @@ -18,11 +18,11 @@ #ifndef INCLUDED_N230_EEPROM_MANAGER_HPP #define INCLUDED_N230_EEPROM_MANAGER_HPP -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" #include <boost/thread/mutex.hpp> #include <uhd/transport/udp_simple.hpp> #include <uhd/types/dict.hpp> #include <uhd/usrp/mboard_eeprom.hpp> +#include "n230_fw_host_iface.h" namespace uhd { namespace usrp { namespace n230 { diff --git a/firmware/usrp3/n230/n230_fw_defs.h b/host/lib/usrp/n230/n230_fw_defs.h index fbdc67ebb..fbdc67ebb 100644 --- a/firmware/usrp3/n230/n230_fw_defs.h +++ b/host/lib/usrp/n230/n230_fw_defs.h diff --git a/firmware/usrp3/n230/n230_fw_host_iface.h b/host/lib/usrp/n230/n230_fw_host_iface.h index 2d510bf1f..dc82df2fc 100644 --- a/firmware/usrp3/n230/n230_fw_host_iface.h +++ b/host/lib/usrp/n230/n230_fw_host_iface.h @@ -115,6 +115,10 @@ typedef struct // //-------------------------------------------------- +#define N230_HW_REVISION_COMPAT 1 +#define N230_HW_REVISION_MIN 1 + + #define N230_CLAIMER_TIMEOUT_IN_MS 2000 #ifdef __cplusplus diff --git a/host/lib/usrp/n230/n230_image_loader.cpp b/host/lib/usrp/n230/n230_image_loader.cpp index 48b41c7a9..f8a6ba092 100644 --- a/host/lib/usrp/n230/n230_image_loader.cpp +++ b/host/lib/usrp/n230/n230_image_loader.cpp @@ -24,8 +24,9 @@ #include <uhd/transport/udp_simple.hpp> #include <boost/algorithm/string.hpp> #include <boost/filesystem.hpp> + +#include "n230_fw_host_iface.h" #include "n230_impl.hpp" -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" using namespace uhd; using namespace uhd::usrp; diff --git a/host/lib/usrp/n230/n230_impl.cpp b/host/lib/usrp/n230/n230_impl.cpp index b3cc4ab59..ab7fa6fe6 100644 --- a/host/lib/usrp/n230/n230_impl.cpp +++ b/host/lib/usrp/n230/n230_impl.cpp @@ -17,9 +17,6 @@ #include "n230_impl.hpp" -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" -#include "../../../firmware/usrp3/n230/n230_fw_defs.h" -#include "../../../firmware/usrp3/include/fw_comm_protocol.h" #include "usrp3_fw_ctrl_iface.hpp" #include "validate_subdev_spec.hpp" #include <uhd/utils/static.hpp> @@ -31,6 +28,7 @@ #include <uhd/utils/msg.hpp> #include <uhd/types/sensors.hpp> #include <uhd/types/ranges.hpp> +#include <uhd/types/direction.hpp> #include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/gps_ctrl.hpp> @@ -43,8 +41,12 @@ #include <boost/asio/ip/address_v4.hpp> #include <boost/asio.hpp> //used for htonl and ntohl #include <boost/make_shared.hpp> + +#include "../common/fw_comm_protocol.h" #include "n230_defaults.h" #include "n230_fpga_defs.h" +#include "n230_fw_defs.h" +#include "n230_fw_host_iface.h" namespace uhd { namespace usrp { namespace n230 { @@ -180,13 +182,37 @@ n230_impl::n230_impl(const uhd::device_addr_t& dev_addr) //TODO: Only supports one motherboard per device class. const fs_path mb_path = "/mboards/0"; - //Initialize subsystems + //Initialize addresses std::vector<std::string> ip_addrs(1, dev_addr["addr"]); if (dev_addr.has_key("secondary-addr")) { ip_addrs.push_back(dev_addr["secondary-addr"]); } - _resource_mgr = boost::make_shared<n230_resource_manager>(ip_addrs, _dev_args.get_safe_mode()); + + //Read EEPROM and perform version checks before talking to HW _eeprom_mgr = boost::make_shared<n230_eeprom_manager>(ip_addrs[0]); + const mboard_eeprom_t& mb_eeprom = _eeprom_mgr->get_mb_eeprom(); + bool recover_mb_eeprom = dev_addr.has_key("recover_mb_eeprom"); + if (recover_mb_eeprom) { + UHD_MSG(warning) << "UHD is operating in EEPROM Recovery Mode which disables hardware version " + "checks.\nOperating in this mode may cause hardware damage and unstable " + "radio performance!"<< std::endl; + } + boost::uint16_t hw_rev = boost::lexical_cast<boost::uint16_t>(mb_eeprom["revision"]); + boost::uint16_t hw_rev_compat = boost::lexical_cast<boost::uint16_t>(mb_eeprom["revision_compat"]); + if (not recover_mb_eeprom) { + if (hw_rev_compat > N230_HW_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.") + % hw_rev)); + } else if (hw_rev < N230_HW_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.") + % hw_rev)); + } + } + + //Initialize all subsystems + _resource_mgr = boost::make_shared<n230_resource_manager>(ip_addrs, _dev_args.get_safe_mode()); _stream_mgr = boost::make_shared<n230_stream_manager>(_dev_args, _resource_mgr, _tree); //Build property tree @@ -459,38 +485,14 @@ void n230_impl::_initialize_radio_properties(const fs_path& mb_path, size_t inst .publish(boost::bind(&tx_dsp_core_3000::get_freq_range, perif.duc)); //RF Frontend Interfacing - static const std::vector<std::string> data_directions = boost::assign::list_of("tx")("rx"); - BOOST_FOREACH(const std::string& direction, data_directions) { - const std::string key = boost::to_upper_copy(direction) + str(boost::format("%u") % (instance + 1)); - const fs_path rf_fe_path = mb_path / "dboards" / "A" / (direction + "_frontends") / ((instance==0)?"A":"B"); - - _tree->create<std::string>(rf_fe_path / "name") - .set("FE-" + key); - _tree->create<int>(rf_fe_path / "sensors"); //empty TODO - BOOST_FOREACH(const std::string &name, ad9361_ctrl::get_gain_names(key)) { - _tree->create<meta_range_t>(rf_fe_path / "gains" / name / "range") - .set(ad9361_ctrl::get_gain_range(key)); - _tree->create<double>(rf_fe_path / "gains" / name / "value") - .coerce(boost::bind(&ad9361_ctrl::set_gain, _resource_mgr->get_codec_ctrl_sptr(), key, _1)) - .set(n230::DEFAULT_FE_GAIN); - } - _tree->create<std::string>(rf_fe_path / "connection") - .set("IQ"); - _tree->create<bool>(rf_fe_path / "enabled") - .set(true); - _tree->create<bool>(rf_fe_path / "use_lo_offset") - .set(false); - _tree->create<double>(rf_fe_path / "bandwidth" / "value") - .coerce(boost::bind(&ad9361_ctrl::set_bw_filter, _resource_mgr->get_codec_ctrl_sptr(), key, _1)) - .set(n230::DEFAULT_FE_BW); - _tree->create<meta_range_t>(rf_fe_path / "bandwidth" / "range") - .publish(boost::bind(&ad9361_ctrl::get_bw_filter_range, key)); - _tree->create<double>(rf_fe_path / "freq" / "value") - .set(n230::DEFAULT_FE_FREQ) - .coerce(boost::bind(&ad9361_ctrl::tune, _resource_mgr->get_codec_ctrl_sptr(), key, _1)) - .subscribe(boost::bind(&n230_frontend_ctrl::set_bandsel, _resource_mgr->get_frontend_ctrl_sptr(), key, _1)); - _tree->create<meta_range_t>(rf_fe_path / "freq" / "range") - .publish(boost::bind(&ad9361_ctrl::get_rf_freq_range)); + static const std::vector<direction_t> data_directions = boost::assign::list_of(RX_DIRECTION)(TX_DIRECTION); + BOOST_FOREACH(direction_t direction, data_directions) { + const std::string dir_str = (direction == RX_DIRECTION) ? "rx" : "tx"; + const std::string key = boost::to_upper_copy(dir_str) + str(boost::format("%u") % (instance + 1)); + const fs_path rf_fe_path = mb_path / "dboards" / "A" / (dir_str + "_frontends") / ((instance==0)?"A":"B"); + + //CODEC subtree + _resource_mgr->get_codec_mgr().populate_frontend_subtree(_tree->subtree(rf_fe_path), key, direction); //User settings _tree->create<uhd::wb_iface::sptr>(rf_fe_path / "user_settings" / "iface") diff --git a/host/lib/usrp/n230/n230_resource_manager.cpp b/host/lib/usrp/n230/n230_resource_manager.cpp index 38e689533..4db494302 100644 --- a/host/lib/usrp/n230/n230_resource_manager.cpp +++ b/host/lib/usrp/n230/n230_resource_manager.cpp @@ -17,8 +17,6 @@ #include "n230_resource_manager.hpp" -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" -#include "../../../firmware/usrp3/n230/n230_fw_defs.h" #include "usrp3_fw_ctrl_iface.hpp" #include <uhd/transport/if_addrs.hpp> #include <uhd/transport/udp_zero_copy.hpp> @@ -32,6 +30,8 @@ #include <boost/functional/hash.hpp> #include <boost/lexical_cast.hpp> #include <boost/make_shared.hpp> +#include "n230_fw_defs.h" +#include "n230_fw_host_iface.h" #define IF_DATA_I_MASK 0xFFF00000 #define IF_DATA_Q_MASK 0x0000FFF0 @@ -88,12 +88,19 @@ n230_resource_manager::n230_resource_manager( n230_eth_conn_t conn_iface; conn_iface.ip_addr = addr; - boost::uint32_t iface_id = usrp3::usrp3_fw_ctrl_iface::get_iface_id( - conn_iface.ip_addr, BOOST_STRINGIZE(N230_FW_COMMS_UDP_PORT), N230_FW_PRODUCT_ID); + boost::uint32_t iface_id = 0xFFFFFFFF; + try { + iface_id = usrp3::usrp3_fw_ctrl_iface::get_iface_id( + conn_iface.ip_addr, BOOST_STRINGIZE(N230_FW_COMMS_UDP_PORT), N230_FW_PRODUCT_ID); + } catch (uhd::io_error&) { + throw uhd::io_error(str(boost::format( + "Could not communicate with the device over address %s") % + conn_iface.ip_addr)); + } switch (iface_id) { case N230_ETH0_IFACE_ID: conn_iface.type = ETH0; break; case N230_ETH1_IFACE_ID: conn_iface.type = ETH1; break; - default: throw uhd::runtime_error("N230 Initialization Error: Could not detect iface.)"); + default: throw uhd::runtime_error("N230 Initialization Error: Could not detect ethernet port number.)"); } _eth_conns.push_back(conn_iface); } @@ -143,7 +150,7 @@ n230_resource_manager::n230_resource_manager( throw uhd::runtime_error("N230 Initialization Error: Could not create SPI ctrl.)"); } - //Create Catalina interface + //Create AD9361 interface UHD_MSG(status) << "Initializing CODEC...\n"; _codec_ctrl = ad9361_ctrl::make_spi( boost::make_shared<n230_ad9361_client_t>(), _core_spi_ctrl, fpga::AD9361_SPI_SLAVE_NUM); @@ -151,6 +158,8 @@ n230_resource_manager::n230_resource_manager( throw uhd::runtime_error("N230 Initialization Error: Could not create Catalina ctrl.)"); } _codec_ctrl->set_clock_rate(fpga::CODEC_DEFAULT_CLK_RATE); + _codec_mgr = ad936x_manager::make(_codec_ctrl, fpga::NUM_RADIOS); + _codec_mgr->init_codec(); //Create AD4001 interface _ref_pll_ctrl = boost::make_shared<n230_ref_pll_ctrl>(_core_spi_ctrl); diff --git a/host/lib/usrp/n230/n230_resource_manager.hpp b/host/lib/usrp/n230/n230_resource_manager.hpp index c98140141..3a0b13329 100644 --- a/host/lib/usrp/n230/n230_resource_manager.hpp +++ b/host/lib/usrp/n230/n230_resource_manager.hpp @@ -28,6 +28,7 @@ #include "tx_dsp_core_3000.hpp" #include "user_settings_core_3000.hpp" #include "ad9361_ctrl.hpp" +#include "ad936x_manager.hpp" #include <uhd/utils/tasks.hpp> #include <uhd/types/sid.hpp> #include <uhd/types/device_addr.hpp> @@ -139,13 +140,16 @@ public: //Methods return _core_ctrl; } - //Catalina control interface + //AD931 control interface inline ad9361_ctrl& get_codec_ctrl() const { return *_codec_ctrl; } inline ad9361_ctrl::sptr get_codec_ctrl_sptr() { return _codec_ctrl; } + inline uhd::usrp::ad936x_manager& get_codec_mgr() const { + return *_codec_mgr; + } //Clock PPS controls inline n230_ref_pll_ctrl& get_ref_pll_ctrl() const { @@ -282,6 +286,7 @@ private: radio_ctrl_core_3000::sptr _core_ctrl; n230_core_spi_core::sptr _core_spi_ctrl; ad9361_ctrl::sptr _codec_ctrl; + uhd::usrp::ad936x_manager::sptr _codec_mgr; //Core Registers fpga::core_radio_ctrl_reg_t _core_radio_ctrl_reg; |