aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/fx3/README.md10
-rw-r--r--firmware/fx3/b200/b200_main.c35
-rw-r--r--firmware/fx3/b200/b200_main.h4
-rw-r--r--firmware/fx3/b200/b200_usb_descriptors.c84
-rw-r--r--host/lib/transport/libusb1_base.cpp1
-rw-r--r--host/lib/usrp/b200/b200_iface.hpp45
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp111
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp14
8 files changed, 239 insertions, 65 deletions
diff --git a/firmware/fx3/README.md b/firmware/fx3/README.md
index 84a895059..29d72a9ad 100644
--- a/firmware/fx3/README.md
+++ b/firmware/fx3/README.md
@@ -19,16 +19,16 @@ distributed by the FX3 manufacturer, Cypress Semiconductor. You can download the
[FX3 SDK from here](http://www.cypress.com/?rID=57990).
*Note*: You *must* use SDK version 1.2.3!
-Once you have downloaded it, extract the ARM cross-compiler sub-directory from
-the zip file and put it somewhere useful. The highest level directory you need
-is `arm-2011.03/`.
+Once you have downloaded it, extract the ARM cross-compiler from the tarball
+`ARM_GCC.tar.gz` and put it somewhere useful. The highest level directory you
+need is `arm-2013.03/`.
Now that you have extracted the cross compilation toolchain, you need to set up
some environment variables to tell the B2xx `makefile` where to look for the
tools. These variables are:
```
- $ export ARMGCC_INSTALL_PATH=<your path>/arm-2011.03
+ $ export ARMGCC_INSTALL_PATH=<your path>/arm-2013.03
$ export ARMGCC_VERSION=4.5.2
```
@@ -61,7 +61,7 @@ into the `common/` directory you just copied from the Cypress SDK, and apply the
patch `b200/fx3_mem_map.patch`.
```
- # cd uhd.git/firmware/common/
+ # cd uhd.git/firmware/fx3/common/
$ patch -p2 < ../b200/fx3_mem_map.patch
```
diff --git a/firmware/fx3/b200/b200_main.c b/firmware/fx3/b200/b200_main.c
index 077ee251b..cb0172af3 100644
--- a/firmware/fx3/b200/b200_main.c
+++ b/firmware/fx3/b200/b200_main.c
@@ -2034,6 +2034,7 @@ void b200_usb_init(void) {
/* Check to see if a VID/PID is in the EEPROM that we should use. */
uint8_t valid[4];
+ uint8_t vidpid[4];
CyU3PMemSet(valid, 0, 4);
CyFxUsbI2cTransfer(0x0, 0xA0, 4, valid, CyTrue);
if(*((uint32_t *) &(valid[0])) == 0xB2145943) {
@@ -2041,7 +2042,6 @@ void b200_usb_init(void) {
/* Pull the programmed device serial out of the i2c EEPROM, and copy the
* characters into the device serial string, which is then advertised as
* part of the USB descriptors. */
- uint8_t vidpid[4];
CyU3PMemSet(vidpid, 0, 4);
CyFxUsbI2cTransfer(0x4, 0xA0, 4, vidpid, CyTrue);
b200_usb2_dev_desc[8] = vidpid[2];
@@ -2055,6 +2055,35 @@ void b200_usb_init(void) {
b200_usb3_dev_desc[11] = vidpid[1];
}
+ /* We support two VIDs:
+ * Ettus Research: 0x2500
+ * National Instruments: 0x3923
+ *
+ * We support three PIDs:
+ * Ettus B200/B210: 0x0020
+ * NI USRP-2900: 0x7813
+ * NI USRP-2901: 0x7814
+ */
+ uint8_t *mfr_string = NULL;
+ uint8_t *product_string = NULL;
+ if((vidpid[3] == 0x25) && (vidpid[2] == 0x00)) {
+ mfr_string = b200_usb_manufacture_desc;
+ product_string = b200_usb_product_desc;
+ } else if((vidpid[3] == 0x39) && (vidpid[2] == 0x23)) {
+ mfr_string = niusrp_usb_manufacture_desc;
+
+ if((vidpid[1] == 0x78) && (vidpid[0] == 0x13)) {
+ product_string = niusrp_2900_usb_product_desc;
+ } else if((vidpid[1] == 0x78) && (vidpid[0] == 0x14)) {
+ product_string = niusrp_2901_usb_product_desc;
+ } else {
+ product_string = unknown_desc;
+ }
+ } else {
+ mfr_string = unknown_desc;
+ product_string = unknown_desc;
+ }
+
uint8_t ascii_serial[9];
CyU3PMemSet(ascii_serial, 0, 9);
CyFxUsbI2cTransfer(0x4f7, 0xA0, 9, ascii_serial, CyTrue);
@@ -2101,10 +2130,10 @@ void b200_usb_init(void) {
(uint8_t *) b200_string_lang_id_desc);
CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 1,
- (uint8_t *) b200_usb_manufacture_desc);
+ (uint8_t *) mfr_string);
CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 2,
- (uint8_t *) b200_usb_product_desc);
+ (uint8_t *) product_string);
CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 3,
(uint8_t *) dev_serial);
diff --git a/firmware/fx3/b200/b200_main.h b/firmware/fx3/b200/b200_main.h
index 2c6f178ec..61048abc9 100644
--- a/firmware/fx3/b200/b200_main.h
+++ b/firmware/fx3/b200/b200_main.h
@@ -128,6 +128,10 @@ extern const uint8_t b200_usb_ss_config_desc[];
extern const uint8_t b200_string_lang_id_desc[];
extern const uint8_t b200_usb_manufacture_desc[];
extern const uint8_t b200_usb_product_desc[];
+extern const uint8_t niusrp_usb_manufacture_desc[];
+extern const uint8_t niusrp_2900_usb_product_desc[];
+extern const uint8_t niusrp_2901_usb_product_desc[];
+extern const uint8_t unknown_desc[];
extern uint8_t dev_serial[];
diff --git a/firmware/fx3/b200/b200_usb_descriptors.c b/firmware/fx3/b200/b200_usb_descriptors.c
index e8a765b24..03dbce74a 100644
--- a/firmware/fx3/b200/b200_usb_descriptors.c
+++ b/firmware/fx3/b200/b200_usb_descriptors.c
@@ -458,6 +458,39 @@ const uint8_t b200_usb_manufacture_desc[] __attribute__ ((aligned (32))) =
'C',0x00
};
+/* NI Manufacturer String Descriptor */
+const uint8_t niusrp_usb_manufacture_desc[] __attribute__ ((aligned (32))) =
+ {
+ 0x36, /* Descriptor Size */
+ CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */
+ 'N',0x00,
+ 'a',0x00,
+ 't',0x00,
+ 'i',0x00,
+ 'o',0x00,
+ 'n',0x00,
+ 'a',0x00,
+ 'l',0x00,
+ ' ',0x00,
+ 'I',0x00,
+ 'n',0x00,
+ 's',0x00,
+ 't',0x00,
+ 'r',0x00,
+ 'u',0x00,
+ 'm',0x00,
+ 'e',0x00,
+ 'n',0x00,
+ 't',0x00,
+ 's',0x00,
+ ' ',0x00,
+ 'C',0x00,
+ 'o',0x00,
+ 'r',0x00,
+ 'p',0x00,
+ '.',0x00
+ };
+
/* Standard Product String Descriptor */
const uint8_t b200_usb_product_desc[] __attribute__ ((aligned (32))) =
@@ -475,6 +508,57 @@ const uint8_t b200_usb_product_desc[] __attribute__ ((aligned (32))) =
'0',0x00
};
+/* NI-USRP 2900 Product String Descriptor */
+const uint8_t niusrp_2900_usb_product_desc[] __attribute__ ((aligned (32))) =
+ {
+ 0x1A, /* Descriptor Size */
+ CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */
+ 'N',0x00,
+ 'I',0x00,
+ ' ',0x00,
+ 'U',0x00,
+ 'S',0x00,
+ 'R',0x00,
+ 'P',0x00,
+ '-',0x00,
+ '2',0x00,
+ '9',0x00,
+ '0',0x00,
+ '0',0x00
+ };
+
+/* NI-USRP 2901 Product String Descriptor */
+const uint8_t niusrp_2901_usb_product_desc[] __attribute__ ((aligned (32))) =
+ {
+ 0x1A, /* Descriptor Size */
+ CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */
+ 'N',0x00,
+ 'I',0x00,
+ ' ',0x00,
+ 'U',0x00,
+ 'S',0x00,
+ 'R',0x00,
+ 'P',0x00,
+ '-',0x00,
+ '2',0x00,
+ '9',0x00,
+ '0',0x00,
+ '1',0x00
+ };
+
+const uint8_t unknown_desc[] __attribute__ ((aligned (32))) =
+ {
+ 0x10, /* Descriptor Size */
+ CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */
+ 'U',0x00,
+ 'n',0x00,
+ 'k',0x00,
+ 'n',0x00,
+ 'o',0x00,
+ 'w',0x00,
+ 'n',0x00
+ };
+
/* Microsoft OS Descriptor. */
const uint8_t CyFxUsbOSDscr[] __attribute__ ((aligned (32))) =
{
diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp
index 375cfe92d..ae33cc036 100644
--- a/host/lib/transport/libusb1_base.cpp
+++ b/host/lib/transport/libusb1_base.cpp
@@ -327,6 +327,7 @@ public:
bool firmware_loaded() {
return (get_manufacturer() == "Ettus Research LLC") or
+ (get_manufacturer() == "National Instruments Corp.") or
(get_manufacturer() == "Free Software Folks");
}
diff --git a/host/lib/usrp/b200/b200_iface.hpp b/host/lib/usrp/b200/b200_iface.hpp
index 83adfdd64..1d123439a 100644
--- a/host/lib/usrp/b200/b200_iface.hpp
+++ b/host/lib/usrp/b200/b200_iface.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2012-2013,2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -21,19 +21,48 @@
#include <stdint.h>
#include <uhd/transport/usb_control.hpp>
#include <uhd/types/serial.hpp> //i2c iface
+#include <uhd/types/dict.hpp>
+#include <boost/assign/list_of.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include "ad9361_ctrl.hpp"
-const static boost::uint16_t B200_VENDOR_ID = 0x2500;
-const static boost::uint16_t B200_PRODUCT_ID = 0x0020;
-const static boost::uint16_t FX3_VID = 0x04b4;
-const static boost::uint16_t FX3_DEFAULT_PID = 0x00f3;
-const static boost::uint16_t FX3_REENUM_PID = 0x00f0;
+enum b200_type_t {
+ B200,
+ B210
+};
+
+const static boost::uint16_t B200_VENDOR_ID = 0x2500;
+const static boost::uint16_t B200_VENDOR_NI_ID = 0x3923;
+const static boost::uint16_t B200_PRODUCT_ID = 0x0020;
+const static boost::uint16_t B200_PRODUCT_NI_ID = 0x7813;
+const static boost::uint16_t B210_PRODUCT_NI_ID = 0x7814;
+const static boost::uint16_t FX3_VID = 0x04b4;
+const static boost::uint16_t FX3_DEFAULT_PID = 0x00f3;
+const static boost::uint16_t FX3_REENUM_PID = 0x00f0;
static const std::string B200_FW_FILE_NAME = "usrp_b200_fw.hex";
-static const std::string B200_FPGA_FILE_NAME = "usrp_b200_fpga.bin";
-static const std::string B210_FPGA_FILE_NAME = "usrp_b210_fpga.bin";
+
+//! Map the product ID (in the EEPROM) to a device type
+static const uhd::dict<boost::uint16_t, b200_type_t> B2X0_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)
+;
+
+static const uhd::dict<b200_type_t, std::string> B2X0_STR_NAMES = boost::assign::map_list_of
+ (B200, "B200")
+ (B210, "B210")
+;
+
+static const uhd::dict<b200_type_t, std::string> B2X0_FPGA_FILE_NAME = boost::assign::map_list_of
+ (B200, "usrp_b200_fpga.bin")
+ (B210, "usrp_b210_fpga.bin")
+;
+
class UHD_API b200_iface: boost::noncopyable, public virtual uhd::i2c_iface {
public:
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index e567ff434..273153c16 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -43,10 +43,6 @@ using namespace uhd::transport;
static const boost::posix_time::milliseconds REENUMERATION_TIMEOUT_MS(3000);
-//! mapping of frontend to radio perif index
-static const size_t FE1 = 1;
-static const size_t FE2 = 0;
-
class b200_ad9361_client_t : public ad9361_params {
public:
~b200_ad9361_client_t() {}
@@ -77,6 +73,24 @@ public:
/***********************************************************************
* Discovery
**********************************************************************/
+//! Look up the type of B-Series device we're currently running.
+// If the product ID stored in mb_eeprom is invalid, throws a
+// uhd::runtime_error.
+static b200_type_t get_b200_type(const mboard_eeprom_t &mb_eeprom)
+{
+ if (mb_eeprom["product"].empty()) {
+ throw uhd::runtime_error("B200: Missing product ID on EEPROM.");
+ }
+ boost::uint16_t product_id = boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]);
+ if (not B2X0_PRODUCT_ID.has_key(product_id)) {
+ throw uhd::runtime_error(str(
+ boost::format("B200 unknown product code: 0x%04x")
+ % product_id
+ ));
+ }
+ return B2X0_PRODUCT_ID[product_id];
+}
+
static device_addrs_t b200_find(const device_addr_t &hint)
{
device_addrs_t b200_addrs;
@@ -152,20 +166,14 @@ static device_addrs_t b200_find(const device_addr_t &hint)
new_addr["type"] = "b200";
new_addr["name"] = mb_eeprom["name"];
new_addr["serial"] = handle->get_serial();
- if (not mb_eeprom["product"].empty())
- {
- switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]))
- {
- case 0x0001:
- case 0x7737:
- new_addr["product"] = "B200";
- break;
- case 0x7738:
- case 0x0002:
- new_addr["product"] = "B210";
- break;
- default: UHD_MSG(error) << "B200 unknown product code: " << mb_eeprom["product"] << std::endl;
- }
+ try {
+ // Turn the 16-Bit product ID into a string representation
+ new_addr["product"] = B2X0_STR_NAMES[get_b200_type(mb_eeprom)];
+ } catch (const uhd::runtime_error &e) {
+ // No problem if this fails -- this is just device discovery, after all.
+ UHD_MSG(error) << e.what() << std::endl;
+ // Skip this loop.
+ continue;
}
//this is a found b200 when the hint serial and name match or blank
if (
@@ -238,32 +246,41 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
.subscribe(boost::bind(&b200_impl::set_mb_eeprom, this, _1));
////////////////////////////////////////////////////////////////////
- // Load the FPGA image, then reset GPIF
+ // Identify the device type
////////////////////////////////////////////////////////////////////
std::string default_file_name;
- std::string product_name = "B200?";
- if (not mb_eeprom["product"].empty())
- {
- switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]))
- {
- case 0x0001:
- case 0x7737:
- product_name = "B200";
- default_file_name = B200_FPGA_FILE_NAME;
- break;
- case 0x7738:
- case 0x0002:
- product_name = "B210";
- default_file_name = B210_FPGA_FILE_NAME;
- break;
- default: UHD_MSG(error) << "B200 unknown product code: " << mb_eeprom["product"] << std::endl;
+ std::string product_name;
+ try {
+ // This will throw if the product ID is invalid:
+ _b200_type = get_b200_type(mb_eeprom);
+ default_file_name = B2X0_FPGA_FILE_NAME.get(_b200_type);
+ product_name = B2X0_STR_NAMES.get(_b200_type);
+ } catch (const uhd::runtime_error &e) {
+ // The only reason we may let this pass is if the user specified
+ // the FPGA file name:
+ if (not device_addr.has_key("fpga")) {
+ throw e;
}
+ // In this case, we must provide a default product name:
+ product_name = "B200?";
+ _b200_type = B200;
}
- if (default_file_name.empty())
+
+ //set up frontend mapping
+ _fe1 = 1;
+ _fe2 = 0;
+ if (_b200_type == B200 and
+ not mb_eeprom["revision"].empty() and
+ boost::lexical_cast<size_t>(mb_eeprom["revision"]) >= 5)
{
- UHD_ASSERT_THROW(device_addr.has_key("fpga"));
+ _fe1 = 0; //map radio0 to FE1
+ _fe2 = 1; //map radio1 to FE2
+ _gpio_state.atr_sel = 1; //map radio0 ATR pins to FE2
}
+ ////////////////////////////////////////////////////////////////////
+ // Load the FPGA image, then reset GPIF
+ ////////////////////////////////////////////////////////////////////
//extract the FPGA path for the B200
std::string b200_fpga_image = find_image_path(
device_addr.has_key("fpga")? device_addr["fpga"] : default_file_name
@@ -316,7 +333,6 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
/* Initialize the GPIOs, set the default bandsels to the lower range. Note
* that calling update_bandsel calls update_gpio_state(). */
- _gpio_state = gpio_state();
update_bandsel("RX", 800e6);
update_bandsel("TX", 850e6);
@@ -628,7 +644,7 @@ void b200_impl::setup_radio(const size_t dspno)
for(size_t direction = 0; direction < 2; direction++)
{
const std::string x = direction? "rx" : "tx";
- const std::string key = std::string((direction? "RX" : "TX")) + std::string(((dspno == FE1)? "1" : "2"));
+ const std::string key = std::string((direction? "RX" : "TX")) + std::string(((dspno == _fe1)? "1" : "2"));
const fs_path rf_fe_path = mb_path / "dboards" / "A" / (x+"_frontends") / (dspno? "B" : "A");
_tree->create<std::string>(rf_fe_path / "name").set("FE-"+key);
@@ -900,6 +916,7 @@ void b200_impl::update_bandsel(const std::string& which, double freq)
void b200_impl::update_gpio_state(void)
{
const boost::uint32_t misc_word = 0
+ | (_gpio_state.atr_sel << 8)
| (_gpio_state.tx_bandsel_a << 7)
| (_gpio_state.tx_bandsel_b << 6)
| (_gpio_state.rx_bandsel_a << 5)
@@ -924,9 +941,9 @@ void b200_impl::reset_codec_dcm(void)
void b200_impl::update_atrs(void)
{
- if (_radio_perifs.size() > FE1 and _radio_perifs[FE1].atr)
+ if (_radio_perifs.size() > _fe1 and _radio_perifs[_fe1].atr)
{
- radio_perifs_t &perif = _radio_perifs[FE1];
+ radio_perifs_t &perif = _radio_perifs[_fe1];
const bool enb_rx = bool(perif.rx_streamer.lock());
const bool enb_tx = bool(perif.tx_streamer.lock());
const bool is_rx2 = perif.ant_rx2;
@@ -942,9 +959,9 @@ void b200_impl::update_atrs(void)
atr->set_atr_reg(dboard_iface::ATR_REG_TX_ONLY, txonly);
atr->set_atr_reg(dboard_iface::ATR_REG_FULL_DUPLEX, fd);
}
- if (_radio_perifs.size() > FE2 and _radio_perifs[FE2].atr)
+ if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr)
{
- radio_perifs_t &perif = _radio_perifs[FE2];
+ radio_perifs_t &perif = _radio_perifs[_fe2];
const bool enb_rx = bool(perif.rx_streamer.lock());
const bool enb_tx = bool(perif.tx_streamer.lock());
const bool is_rx2 = perif.ant_rx2;
@@ -972,10 +989,10 @@ void b200_impl::update_antenna_sel(const size_t which, const std::string &ant)
void b200_impl::update_enables(void)
{
//extract settings from state variables
- const bool enb_tx1 = (_radio_perifs.size() > FE1) and bool(_radio_perifs[FE1].tx_streamer.lock());
- const bool enb_rx1 = (_radio_perifs.size() > FE1) and bool(_radio_perifs[FE1].rx_streamer.lock());
- const bool enb_tx2 = (_radio_perifs.size() > FE2) and bool(_radio_perifs[FE2].tx_streamer.lock());
- const bool enb_rx2 = (_radio_perifs.size() > FE2) and bool(_radio_perifs[FE2].rx_streamer.lock());
+ const bool enb_tx1 = (_radio_perifs.size() > _fe1) and bool(_radio_perifs[_fe1].tx_streamer.lock());
+ const bool enb_rx1 = (_radio_perifs.size() > _fe1) and bool(_radio_perifs[_fe1].rx_streamer.lock());
+ const bool enb_tx2 = (_radio_perifs.size() > _fe2) and bool(_radio_perifs[_fe2].tx_streamer.lock());
+ const bool enb_rx2 = (_radio_perifs.size() > _fe2) and bool(_radio_perifs[_fe2].rx_streamer.lock());
const size_t num_rx = (enb_rx1?1:0) + (enb_rx2?1:0);
const size_t num_tx = (enb_tx1?1:0) + (enb_tx2?1:0);
const bool mimo = num_rx == 2 or num_tx == 2;
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index 396819f9a..8d0c637d7 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -47,7 +47,7 @@
#include "recv_packet_demuxer_3000.hpp"
static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 7;
static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0;
-static const boost::uint16_t B200_FPGA_COMPAT_NUM = 4;
+static const boost::uint16_t B200_FPGA_COMPAT_NUM = 5;
static const double B200_BUS_CLOCK_RATE = 100e6;
static const double B200_DEFAULT_TICK_RATE = 32e6;
static const double B200_DEFAULT_FREQ = 100e6; // Hz
@@ -101,6 +101,8 @@ public:
void check_streamer_args(const uhd::stream_args_t &args, double tick_rate, const char* direction = NULL);
private:
+ b200_type_t _b200_type;
+
//controllers
b200_iface::sptr _iface;
radio_ctrl_core_3000::sptr _local_ctrl;
@@ -161,6 +163,13 @@ private:
};
std::vector<radio_perifs_t> _radio_perifs;
+ //mapping of AD936x frontends (FE1 and FE2) to radio perif index (0 and 1)
+ //FE1 corresponds to the ports labeled "RF B" on the B200/B210
+ //FE2 corresponds to the ports labeled "RF A" on the B200/B210
+ //the mapping is product and revision specific
+ size_t _fe1;
+ size_t _fe2;
+
/*! \brief Setup the DSP chain for one radio front-end.
*
*/
@@ -168,7 +177,7 @@ private:
void handle_overflow(const size_t radio_index);
struct gpio_state {
- boost::uint32_t tx_bandsel_a, tx_bandsel_b, rx_bandsel_a, rx_bandsel_b, rx_bandsel_c, codec_arst, mimo, ref_sel;
+ boost::uint32_t tx_bandsel_a, tx_bandsel_b, rx_bandsel_a, rx_bandsel_b, rx_bandsel_c, codec_arst, mimo, ref_sel, atr_sel;
gpio_state() {
tx_bandsel_a = 0;
@@ -179,6 +188,7 @@ private:
codec_arst = 0;
mimo = 0;
ref_sel = 0;
+ atr_sel = 0;
}
} _gpio_state;