host: b200: Add support for B206i (as a variant of B205i)

- Added B206MINI_PRODUCT_ID and extend various defines
  to enable B206 support in driver code
- Extend B200 devtest definition to include B206mini
- Extend B200Calibrator class to support B206mini

Co-authored-by: Lars Amsel <lars.amsel@emerson.com>
Co-authored-by: Abhishek Verma <abhishek.verma@emerson.com>
Co-authored-by: Marian Koop <marian.koop@emerson.com>
This commit is contained in:
Lars Amsel 2025-01-10 15:21:15 +01:00 committed by Jörg Hofrichter
parent 2ddc080605
commit b8e2e70675
10 changed files with 42 additions and 28 deletions

View File

@ -3,6 +3,8 @@ Change Log for Releases
## 004.next
* Highlights / Main Changes
- Support for USRP B206mini-i
* New Features
- X3x0: Add support for the gps_iface feature. This allows sending arbitrary
commands to the GPS module.

View File

@ -17,7 +17,7 @@
#include <boost/assign/list_of.hpp>
#include <memory>
enum b200_product_t { B200, B210, B200MINI, B205MINI };
enum b200_product_t { B200, B210, B200MINI, B205MINI, B206MINI };
// These are actual USB PIDs (not Ettus Product IDs)
const static uint16_t B200_VENDOR_ID = 0x2500;
@ -25,6 +25,7 @@ const static uint16_t B200_VENDOR_NI_ID = 0x3923;
const static uint16_t B200_PRODUCT_ID = 0x0020;
const static uint16_t B200MINI_PRODUCT_ID = 0x0021;
const static uint16_t B205MINI_PRODUCT_ID = 0x0022;
const static uint16_t B206MINI_PRODUCT_ID = 0x0023;
const static uint16_t B200_PRODUCT_NI_ID = 0x7813;
const static uint16_t B210_PRODUCT_NI_ID = 0x7814;
const static uint16_t FX3_VID = 0x04b4;
@ -34,7 +35,8 @@ const static uint16_t FX3_REENUM_PID = 0x00f0;
//! Map the USB PID to the product (only for PIDs that map to a single product)
static const uhd::dict<uint16_t, b200_product_t> B2XX_PID_TO_PRODUCT =
boost::assign::map_list_of(B200_PRODUCT_NI_ID, B200)(B210_PRODUCT_NI_ID, B210)(
B200MINI_PRODUCT_ID, B200MINI)(B205MINI_PRODUCT_ID, B205MINI);
B200MINI_PRODUCT_ID, B200MINI)(B205MINI_PRODUCT_ID, B205MINI)(
B206MINI_PRODUCT_ID, B206MINI);
static const std::string B200_FW_FILE_NAME = "usrp_b200_fw.hex";
static const std::string B200_BL_FILE_NAME = "usrp_b200_bl.img";
@ -42,18 +44,17 @@ static const std::string B200_BL_FILE_NAME = "usrp_b200_bl.img";
//! Map the EEPROM product ID codes to the product
static const uhd::dict<uint16_t, b200_product_t> B2XX_PRODUCT_ID =
boost::assign::map_list_of(0x0001, B200)(0x7737, B200)(B200_PRODUCT_NI_ID, B200)(
0x0002, B210)(0x7738, B210)(B210_PRODUCT_NI_ID, B210)(0x0003, B200MINI)(
0x7739, B200MINI)(0x0004, B205MINI)(0x773a, B205MINI);
0x0002, B210)(0x7738, B210)(B210_PRODUCT_NI_ID, B210)(0x0003, B200MINI)(0x7739,
B200MINI)(0x0004, B205MINI)(0x773a, B205MINI)(0x0005, B206MINI)(0x773b, B206MINI);
static const uhd::dict<b200_product_t, std::string> B2XX_STR_NAMES =
boost::assign::map_list_of(B200, "B200")(B210, "B210")(B200MINI, "B200mini")(
B205MINI, "B205mini");
B205MINI, "B205mini")(B206MINI, "B206mini");
static const uhd::dict<b200_product_t, std::string> B2XX_FPGA_FILE_NAME =
boost::assign::map_list_of(B200, "usrp_b200_fpga.bin")(B210, "usrp_b210_fpga.bin")(
B200MINI, "usrp_b200mini_fpga.bin")(B205MINI, "usrp_b205mini_fpga.bin");
B200MINI, "usrp_b200mini_fpga.bin")(B205MINI, "usrp_b205mini_fpga.bin")(
B206MINI, "usrp_b205mini_fpga.bin");
class UHD_API b200_iface : uhd::noncopyable, public virtual uhd::i2c_iface
{

View File

@ -38,6 +38,10 @@ using namespace uhd::transport;
namespace {
constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000;
}
constexpr bool is_b2xx_mini(const b200_product_t& product)
{
return product == B200MINI || product == B205MINI || product == B206MINI;
}
// B200 + B210:
class b200_ad9361_client_t : public ad9361_params
@ -340,6 +344,8 @@ b200_impl::b200_impl(
usb_device_handle::vid_pid_pair_t(vid, B200MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(
usb_device_handle::vid_pid_pair_t(vid, B205MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(
usb_device_handle::vid_pid_pair_t(vid, B206MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(
usb_device_handle::vid_pid_pair_t(vid, B200_PRODUCT_NI_ID));
vid_pid_pair_list.push_back(
@ -360,6 +366,8 @@ b200_impl::b200_impl(
usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(
usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(
usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B206MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(
usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID));
vid_pid_pair_list.push_back(
@ -421,7 +429,7 @@ b200_impl::b200_impl(
UHD_LOGGER_INFO("B200") << "Detected Device: " << B2XX_STR_NAMES[_product];
_gpsdo_capable = (not(_product == B200MINI or _product == B205MINI));
_gpsdo_capable = not is_b2xx_mini(_product);
////////////////////////////////////////////////////////////////////
// Set up frontend mapping
@ -440,8 +448,7 @@ b200_impl::b200_impl(
_fe2 = 0;
_gpio_state.swap_atr = 1;
// Unswapped setup:
if (_product == B200MINI or _product == B205MINI
or (_product == B200 and _revision >= 5)) {
if (is_b2xx_mini(_product) or (_product == B200 and _revision >= 5)) {
_fe1 = 0; // map radio0 to FE1
_fe2 = 1; // map radio1 to FE2
_gpio_state.swap_atr = 0; // ATRs for radio0 are mapped to FE1
@ -545,7 +552,7 @@ b200_impl::b200_impl(
_tree->create<std::string>("/name").set("B-Series Device");
_tree->create<std::string>(mb_path / "name").set(product_name);
_tree->create<std::string>(mb_path / "codename")
.set((_product == B200MINI or _product == B205MINI) ? "Pixie" : "Sasquatch");
.set(is_b2xx_mini(_product) ? "Pixie" : "Sasquatch");
////////////////////////////////////////////////////////////////////
// Create data transport
@ -610,7 +617,7 @@ b200_impl::b200_impl(
// create time and clock control objects
////////////////////////////////////////////////////////////////////
_spi_iface = b200_local_spi_core::make(_local_ctrl);
if (not(_product == B200MINI or _product == B205MINI)) {
if (not is_b2xx_mini(_product)) {
_adf4001_iface = std::make_shared<b200_ref_pll_ctrl>(_spi_iface);
}
@ -620,7 +627,7 @@ b200_impl::b200_impl(
UHD_LOGGER_INFO("B200") << "Initialize CODEC control...";
reset_codec();
ad9361_params::sptr client_settings;
if (_product == B200MINI or _product == B205MINI) {
if (is_b2xx_mini(_product)) {
client_settings = std::make_shared<b2xxmini_ad9361_client_t>();
} else {
client_settings = std::make_shared<b200_ad9361_client_t>();
@ -985,8 +992,8 @@ void b200_impl::setup_radio(const size_t dspno)
// b2xx_power_cal_$dir_$ant, depending on the form factor.
// $dir is either "tx" or "rx", and "ant" is either "tx_rx" or "rx2" (i.e.,
// sanitized version of the antenna names that work in filenames.
const std::string cal_key_base =
(_product == B200MINI or _product == B205MINI) ? "b2xxmini_pwr_" : "b2xx_pwr_";
const std::string cal_key_base = (is_b2xx_mini(_product)) ? "b2xxmini_pwr_"
: "b2xx_pwr_";
for (direction_t dir : std::vector<direction_t>{RX_DIRECTION, TX_DIRECTION}) {
const std::string dir_key = (dir == RX_DIRECTION) ? "rx" : "tx";
const std::string key = std::string(((dir == RX_DIRECTION) ? "RX" : "TX"))
@ -1203,9 +1210,8 @@ void b200_impl::check_fpga_compat(void)
throw uhd::runtime_error(
"b200::check_fpga_compat signature register readback failed");
const uint16_t expected = ((_product == B200MINI or _product == B205MINI)
? B205_FPGA_COMPAT_NUM
: B200_FPGA_COMPAT_NUM);
const uint16_t expected =
(is_b2xx_mini(_product) ? B205_FPGA_COMPAT_NUM : B200_FPGA_COMPAT_NUM);
if (compat_major != expected) {
throw uhd::runtime_error(str(
boost::format("Expected FPGA compatibility number %d, but got %d:\n"
@ -1225,7 +1231,7 @@ void b200_impl::check_fpga_compat(void)
void b200_impl::update_clock_source(const std::string& source)
{
// For B205, ref_sel selects whether or not to lock to the external clock source
if (_product == B200MINI or _product == B205MINI) {
if (is_b2xx_mini(_product)) {
if (source == "external" and _time_source == EXTERNAL) {
throw uhd::value_error(
"external reference cannot be both a clock source and a time source");
@ -1274,8 +1280,7 @@ void b200_impl::update_clock_source(const std::string& source)
void b200_impl::update_time_source(const std::string& source)
{
if ((_product == B200MINI or _product == B205MINI) and source == "external"
and _gpio_state.ref_sel == 1) {
if (is_b2xx_mini(_product) and source == "external" and _gpio_state.ref_sel == 1) {
throw uhd::value_error(
"external reference cannot be both a time source and a clock source");
}
@ -1336,7 +1341,7 @@ void b200_impl::sync_times()
void b200_impl::update_bandsel(const std::string& which, double freq)
{
// B205 does not have bandsels
if (_product == B200MINI or _product == B205MINI) {
if (is_b2xx_mini(_product)) {
return;
}

View File

@ -44,7 +44,7 @@
static const uint8_t B200_FW_COMPAT_NUM_MAJOR = 8;
static const uint8_t B200_FW_COMPAT_NUM_MINOR = 0;
static const uint16_t B200_FPGA_COMPAT_NUM = 16;
static const uint16_t B205_FPGA_COMPAT_NUM = 7;
static const uint16_t B205_FPGA_COMPAT_NUM = 7; // applies to all B2xxminis
static const double B200_BUS_CLOCK_RATE = 100e6;
static const uint32_t B200_GPSDO_ST_NONE = 0x83;
static constexpr double B200_MAX_RATE_USB2 = 53248000; // bytes/s
@ -99,6 +99,8 @@ static std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> b200_vid_p
B200_VENDOR_ID, B200MINI_PRODUCT_ID))(
uhd::transport::usb_device_handle::vid_pid_pair_t(
B200_VENDOR_ID, B205MINI_PRODUCT_ID))(
uhd::transport::usb_device_handle::vid_pid_pair_t(
B200_VENDOR_ID, B206MINI_PRODUCT_ID))(
uhd::transport::usb_device_handle::vid_pid_pair_t(
B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID))(
uhd::transport::usb_device_handle::vid_pid_pair_t(

View File

@ -257,7 +257,8 @@ uhd::usrp::subdev_spec_t b200_impl::coerce_subdev_spec(
// Any other spec is probably illegal and will be caught by
// validate_subdev_spec().
if (!spec.empty()
and (_product == B200 or _product == B200MINI or _product == B205MINI)
and (_product == B200 or _product == B200MINI or _product == B205MINI
or _product == B206MINI)
and spec[0].sd_name == "B") {
spec[0].sd_name = "A";
}

View File

@ -353,7 +353,7 @@ class B200Calibrator(USRPCalibratorBase):
"""
B200 calibration
"""
mboard_ids = ('B200', 'B210', 'B200mini', 'B205mini')
mboard_ids = ('B200', 'B210', 'B200mini', 'B205mini', 'B206mini')
# Choosing 5 MHz: It is a small rate, but carries enough bandwidth to receive
# a tone. By default, the auto MCR will kick in and set the MCR to 40 Msps,
# thus engaging all halfbands.

View File

@ -748,7 +748,7 @@ def get_device_config(usrp_type, device_config_path=None):
if device_config_path:
with open(device_config_path, "r") as yaml_f:
return yaml.load(yaml_f)
if usrp_type in ("B205mini", "B200mini", "B200", "B210"):
if usrp_type in ("B206mini", "B205mini", "B200mini", "B200", "B210"):
return {
"skip": [
"set_rx_lo_export_enabled",

View File

@ -45,6 +45,7 @@ const vid_pid_t known_vid_pids[] = {{FX3_VID, FX3_DEFAULT_PID},
{B200_VENDOR_ID, B200_PRODUCT_ID},
{B200_VENDOR_ID, B200MINI_PRODUCT_ID},
{B200_VENDOR_ID, B205MINI_PRODUCT_ID},
{B200_VENDOR_ID, B206MINI_PRODUCT_ID},
{B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID},
{B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID}};
const std::vector<vid_pid_t> known_vid_pid_vector(known_vid_pids,

View File

@ -15,5 +15,6 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0002", MODE:="066
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0020", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0021", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0022", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0023", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="3923", ATTRS{idProduct}=="7813", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="3923", ATTRS{idProduct}=="7814", MODE:="0666"

View File

@ -55,7 +55,8 @@ b2xx_b200_fpga_default uhd-c37b318 b2xx/uhd-c37b318/b2xx_b200_fpg
b2xx_b200mini_fpga_default uhd-c37b318 b2xx/uhd-c37b318/b2xx_b200mini_fpga_default-gc37b318.zip c1865c6e574cf453a688c6bfb8fe5e3646cd53458ae403cf11d3eeb7dc6a9918
b2xx_b210_fpga_default uhd-c37b318 b2xx/uhd-c37b318/b2xx_b210_fpga_default-gc37b318.zip ab1cdbe93090fdcf590a79cbe938749f8a5fbd7b45422b7833b8c841aa2106b4
b2xx_b205mini_fpga_default uhd-c37b318 b2xx/uhd-c37b318/b2xx_b205mini_fpga_default-gc37b318.zip dce96120e3512d6e21bb061811c4021cbc90ac4d787248ad821337b7389ff3c4
b2xx_common_fw_default uhd-7f7d016 b2xx/uhd-7f7d016/b2xx_common_fw_default-g7f7d016.zip 22ac0e54cc90d53d8494d481439447a0c89b9bbaced6fabe24df260eda3ce3a3
b2xx_b206mini_fpga_default uhd-c37b318 b2xx/uhd-c37b318/b2xx_b205mini_fpga_default-gc37b318.zip dce96120e3512d6e21bb061811c4021cbc90ac4d787248ad821337b7389ff3c4
b2xx_common_fw_default uhd-7f7d016 b2xx/uhd-7f7d016/b2xx_common_fw_default-g7f7d016.zip 22ac0e54cc90d53d8494d481439447a0c89b9bbaced6fabe24df260eda3ce3a3
# USRP2 Devices
usrp2_usrp2_fw_default fpga-6bea23d usrp2/fpga-6bea23d/usrp2_usrp2_fw_default-g6bea23d.zip d523a18318cb6a7637be40484bf03a6f54766410fee2c1a1f72e8971ea9a9cb6