diff options
Diffstat (limited to 'host/lib/usrp/b100')
-rw-r--r-- | host/lib/usrp/b100/b100_impl.cpp | 546 | ||||
-rw-r--r-- | host/lib/usrp/b100/b100_impl.hpp | 98 | ||||
-rw-r--r-- | host/lib/usrp/b100/b100_regs.hpp | 49 | ||||
-rw-r--r-- | host/lib/usrp/b100/clock_ctrl.cpp | 6 | ||||
-rw-r--r-- | host/lib/usrp/b100/clock_ctrl.hpp | 14 | ||||
-rw-r--r-- | host/lib/usrp/b100/codec_ctrl.cpp | 279 | ||||
-rw-r--r-- | host/lib/usrp/b100/codec_ctrl.hpp | 11 | ||||
-rw-r--r-- | host/lib/usrp/b100/dboard_iface.cpp | 233 | ||||
-rw-r--r-- | host/lib/usrp/b100/fifo_ctrl_excelsior.cpp | 224 | ||||
-rw-r--r-- | host/lib/usrp/b100/fifo_ctrl_excelsior.hpp | 16 | ||||
-rw-r--r-- | host/lib/usrp/b100/io_impl.cpp | 210 | ||||
-rw-r--r-- | host/lib/usrp/b100/mb_eeprom.cpp | 103 | ||||
-rw-r--r-- | host/lib/usrp/b100/usb_zero_copy_wrapper.cpp | 170 |
13 files changed, 1068 insertions, 891 deletions
diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 3cd166507..9f0c3bdd2 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -26,28 +26,31 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace { - constexpr uint16_t B100_VENDOR_ID = 0x2500; - constexpr uint16_t B100_PRODUCT_ID = 0x0002; - constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; -} +constexpr uint16_t B100_VENDOR_ID = 0x2500; +constexpr uint16_t B100_PRODUCT_ID = 0x0002; +constexpr int64_t REENUMERATION_TIMEOUT_MS = 3000; +} // namespace /*********************************************************************** * Discovery **********************************************************************/ -static device_addrs_t b100_find(const device_addr_t &hint) +static device_addrs_t b100_find(const device_addr_t& hint) { device_addrs_t b100_addrs; - //return an empty list of addresses when type is set to non-b100 - if (hint.has_key("type") and hint["type"] != "b100") return b100_addrs; + // return an empty list of addresses when type is set to non-b100 + if (hint.has_key("type") and hint["type"] != "b100") + return b100_addrs; - //Return an empty list of addresses when an address or resource is specified, - //since an address and resource is intended for a different, non-USB, device. - if (hint.has_key("addr") || hint.has_key("resource")) return b100_addrs; + // Return an empty list of addresses when an address or resource is specified, + // since an address and resource is intended for a different, non-USB, device. + if (hint.has_key("addr") || hint.has_key("resource")) + return b100_addrs; uint16_t vid, pid; - if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "b100") { + if (hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") + && hint["type"] == "b100") { vid = uhd::cast::hexstr_cast<uint16_t>(hint.get("vid")); pid = uhd::cast::hexstr_cast<uint16_t>(hint.get("pid")); } else { @@ -61,60 +64,60 @@ static device_addrs_t b100_find(const device_addr_t &hint) // so that re-enumeration after fw load can occur successfully. // This requirement is a courtesy of libusb1.0 on windows. - //find the usrps and load firmware + // find the usrps and load firmware size_t found = 0; - for(usb_device_handle::sptr handle: usb_device_handle::get_device_list(vid, pid)) { - //extract the firmware path for the b100 + for (usb_device_handle::sptr handle : usb_device_handle::get_device_list(vid, pid)) { + // extract the firmware path for the b100 std::string b100_fw_image; - try{ + try { b100_fw_image = find_image_path(hint.get("fw", B100_FW_FILE_NAME)); - } - catch(...){ - UHD_LOGGER_WARNING("B100") << boost::format("Could not locate B100 firmware. %s\n") % print_utility_error("uhd_images_downloader.py"); + } catch (...) { + UHD_LOGGER_WARNING("B100") + << boost::format("Could not locate B100 firmware. %s\n") + % print_utility_error("uhd_images_downloader.py"); return b100_addrs; } - UHD_LOGGER_DEBUG("B100") << "the firmware image: " << b100_fw_image ; + UHD_LOGGER_DEBUG("B100") << "the firmware image: " << b100_fw_image; usb_control::sptr control; - try{control = usb_control::make(handle, 0);} - catch(const uhd::exception &){continue;} //ignore claimed + try { + control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; + } // ignore claimed fx2_ctrl::make(control)->usrp_load_firmware(b100_fw_image); found++; } - //get descriptors again with serial number, but using the initialized VID/PID now since we have firmware + // get descriptors again with serial number, but using the initialized VID/PID now + // since we have firmware vid = B100_VENDOR_ID; pid = B100_PRODUCT_ID; - const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); + const auto timeout_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(REENUMERATION_TIMEOUT_MS); - //search for the device until found or timeout - while (std::chrono::steady_clock::now() < timeout_time - and b100_addrs.empty() - and found != 0) { + // search for the device until found or timeout + while (std::chrono::steady_clock::now() < timeout_time and b100_addrs.empty() + and found != 0) { for (auto handle : usb_device_handle::get_device_list(vid, pid)) { usb_control::sptr control; try { control = usb_control::make(handle, 0); + } catch (const uhd::exception&) { + continue; // ignore claimed } - catch (const uhd::exception &) { - continue; //ignore claimed - } - fx2_ctrl::sptr fx2_ctrl = fx2_ctrl::make(control); - const mboard_eeprom_t mb_eeprom = - b100_impl::get_mb_eeprom(fx2_ctrl); + fx2_ctrl::sptr fx2_ctrl = fx2_ctrl::make(control); + const mboard_eeprom_t mb_eeprom = b100_impl::get_mb_eeprom(fx2_ctrl); device_addr_t new_addr; - new_addr["type"] = "b100"; - new_addr["name"] = mb_eeprom["name"]; + new_addr["type"] = "b100"; + new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = handle->get_serial(); - //this is a found b100 when the hint serial and name match or blank - if ( - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) - ) { + // this is a found b100 when the hint serial and name match or blank + if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") + or hint["serial"] == new_addr["serial"])) { b100_addrs.push_back(new_addr); } } @@ -126,81 +129,85 @@ static device_addrs_t b100_find(const device_addr_t &hint) /*********************************************************************** * Make **********************************************************************/ -static device::sptr b100_make(const device_addr_t &device_addr){ +static device::sptr b100_make(const device_addr_t& device_addr) +{ return device::sptr(new b100_impl(device_addr)); } -UHD_STATIC_BLOCK(register_b100_device){ +UHD_STATIC_BLOCK(register_b100_device) +{ device::register_device(&b100_find, &b100_make, device::USRP); } /*********************************************************************** * Structors **********************************************************************/ -b100_impl::b100_impl(const device_addr_t &device_addr){ +b100_impl::b100_impl(const device_addr_t& device_addr) +{ size_t initialization_count = 0; - b100_impl_constructor_begin: +b100_impl_constructor_begin: initialization_count++; - _type = device::USRP; - _tree = property_tree::make(); + _type = device::USRP; + _tree = property_tree::make(); _ignore_cal_file = device_addr.has_key("ignore-cal-file"); - //extract the FPGA path for the B100 + // extract the FPGA path for the B100 std::string b100_fpga_image = find_image_path( - device_addr.has_key("fpga")? device_addr["fpga"] : B100_FPGA_FILE_NAME - ); + device_addr.has_key("fpga") ? device_addr["fpga"] : B100_FPGA_FILE_NAME); - //try to match the given device address with something on the USB bus + // try to match the given device address with something on the USB bus std::vector<usb_device_handle::sptr> device_list = usb_device_handle::get_device_list(B100_VENDOR_ID, B100_PRODUCT_ID); - //locate the matching handle in the device list + // locate the matching handle in the device list usb_device_handle::sptr handle; - for(usb_device_handle::sptr dev_handle: device_list) { - if (dev_handle->get_serial() == device_addr["serial"]){ + for (usb_device_handle::sptr dev_handle : device_list) { + if (dev_handle->get_serial() == device_addr["serial"]) { handle = dev_handle; break; } } - UHD_ASSERT_THROW(handle.get() != NULL); //better be found + UHD_ASSERT_THROW(handle.get() != NULL); // better be found - //create control objects + // create control objects usb_control::sptr fx2_transport = usb_control::make(handle, 0); - _fx2_ctrl = fx2_ctrl::make(fx2_transport); - this->check_fw_compat(); //check after making fx2 + _fx2_ctrl = fx2_ctrl::make(fx2_transport); + this->check_fw_compat(); // check after making fx2 //-- setup clock after making fx2 and before loading fpga --// - _clock_ctrl = b100_clock_ctrl::make(_fx2_ctrl, device_addr.cast<double>("master_clock_rate", B100_DEFAULT_TICK_RATE)); + _clock_ctrl = b100_clock_ctrl::make( + _fx2_ctrl, device_addr.cast<double>("master_clock_rate", B100_DEFAULT_TICK_RATE)); - //load FPGA image, slave xfers are disabled while loading + // load FPGA image, slave xfers are disabled while loading this->enable_gpif(false); _fx2_ctrl->usrp_load_fpga(b100_fpga_image); - _fx2_ctrl->usrp_fpga_reset(false); //active low reset + _fx2_ctrl->usrp_fpga_reset(false); // active low reset _fx2_ctrl->usrp_fpga_reset(true); - //create the control transport + // create the control transport device_addr_t ctrl_xport_args; ctrl_xport_args["recv_frame_size"] = "512"; ctrl_xport_args["num_recv_frames"] = "16"; ctrl_xport_args["send_frame_size"] = "512"; ctrl_xport_args["num_send_frames"] = "16"; - //try to open ctrl transport - //this could fail with libusb_submit_transfer under some conditions - try{ - _ctrl_transport = usb_zero_copy::make( - handle, - 4, 8, //interface, endpoint - 3, 4, //interface, endpoint - ctrl_xport_args - ); + // try to open ctrl transport + // this could fail with libusb_submit_transfer under some conditions + try { + _ctrl_transport = usb_zero_copy::make(handle, + 4, + 8, // interface, endpoint + 3, + 4, // interface, endpoint + ctrl_xport_args); } - //try reset once in the case of failure - catch(const uhd::exception &ex){ - if (initialization_count > 1) throw; - UHD_LOGGER_WARNING("B100") << - "The control endpoint was left in a bad state.\n" - "Attempting endpoint re-enumeration...\n" << ex.what() ; + // try reset once in the case of failure + catch (const uhd::exception& ex) { + if (initialization_count > 1) + throw; + UHD_LOGGER_WARNING("B100") << "The control endpoint was left in a bad state.\n" + "Attempting endpoint re-enumeration...\n" + << ex.what(); _fifo_ctrl.reset(); _ctrl_transport.reset(); _fx2_ctrl->usrp_fx2_reset(); @@ -214,27 +221,27 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ fifo_ctrl_excelsior_config fifo_ctrl_config; fifo_ctrl_config.async_sid_base = B100_TX_ASYNC_SID; fifo_ctrl_config.num_async_chan = 1; - fifo_ctrl_config.ctrl_sid_base = B100_CTRL_MSG_SID; - fifo_ctrl_config.spi_base = TOREG(SR_SPI); - fifo_ctrl_config.spi_rb = REG_RB_SPI; + fifo_ctrl_config.ctrl_sid_base = B100_CTRL_MSG_SID; + fifo_ctrl_config.spi_base = TOREG(SR_SPI); + fifo_ctrl_config.spi_rb = REG_RB_SPI; _fifo_ctrl = fifo_ctrl_excelsior::make(_ctrl_transport, fifo_ctrl_config); - //perform a test peek operation - try{ + // perform a test peek operation + try { _fifo_ctrl->peek32(0); } - //try reset once in the case of failure - catch(const uhd::exception &){ - if (initialization_count > 1) throw; - UHD_LOGGER_WARNING("B100") << - "The control endpoint was left in a bad state.\n" - "Attempting endpoint re-enumeration...\n" ; + // try reset once in the case of failure + catch (const uhd::exception&) { + if (initialization_count > 1) + throw; + UHD_LOGGER_WARNING("B100") << "The control endpoint was left in a bad state.\n" + "Attempting endpoint re-enumeration...\n"; _fifo_ctrl.reset(); _ctrl_transport.reset(); _fx2_ctrl->usrp_fx2_reset(); goto b100_impl_constructor_begin; } - this->check_fpga_compat(); //check after reset and making control + this->check_fpga_compat(); // check after reset and making control //////////////////////////////////////////////////////////////////// // Initialize peripherals after reset @@ -253,19 +260,19 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ data_xport_args["send_frame_size"] = device_addr.get("send_frame_size", "16384"); data_xport_args["num_send_frames"] = device_addr.get("num_send_frames", "16"); - //let packet padder know the LUT size in number of words32 - const size_t rx_lut_size = size_t(data_xport_args.cast<double>("recv_frame_size", 0.0)); - _fifo_ctrl->poke32(TOREG(SR_PADDER+0), rx_lut_size/sizeof(uint32_t)); + // let packet padder know the LUT size in number of words32 + const size_t rx_lut_size = + size_t(data_xport_args.cast<double>("recv_frame_size", 0.0)); + _fifo_ctrl->poke32(TOREG(SR_PADDER + 0), rx_lut_size / sizeof(uint32_t)); - _data_transport = usb_zero_copy_make_wrapper( - usb_zero_copy::make( - handle, // identifier - 2, 6, // IN interface, endpoint - 1, 2, // OUT interface, endpoint - data_xport_args // param hints - ), - B100_MAX_PKT_BYTE_LIMIT - ); + _data_transport = usb_zero_copy_make_wrapper(usb_zero_copy::make(handle, // identifier + 2, + 6, // IN interface, endpoint + 1, + 2, // OUT interface, endpoint + data_xport_args // param hints + ), + B100_MAX_PKT_BYTE_LIMIT); //////////////////////////////////////////////////////////////////// // Initialize the properties tree @@ -275,7 +282,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ _tree->create<std::string>(mb_path / "name").set("B100"); _tree->create<std::string>(mb_path / "codename").set("B-Hundo"); _tree->create<std::string>(mb_path / "load_eeprom") - .add_coerced_subscriber(std::bind(&fx2_ctrl::usrp_load_eeprom, _fx2_ctrl, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&fx2_ctrl::usrp_load_eeprom, _fx2_ctrl, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // setup the mboard eeprom @@ -283,7 +291,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ const mboard_eeprom_t mb_eeprom = this->get_mb_eeprom(_fx2_ctrl); _tree->create<mboard_eeprom_t>(mb_path / "eeprom") .set(mb_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_mb_eeprom, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::set_mb_eeprom, this, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create clock control objects @@ -291,28 +300,35 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ //^^^ clock created up top, just reg props here... ^^^ _tree->create<double>(mb_path / "tick_rate") .set_publisher(std::bind(&b100_clock_ctrl::get_fpga_clock_rate, _clock_ctrl)) - .add_coerced_subscriber(std::bind(&fifo_ctrl_excelsior::set_tick_rate, _fifo_ctrl, std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b100_impl::update_tick_rate, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &fifo_ctrl_excelsior::set_tick_rate, _fifo_ctrl, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&b100_impl::update_tick_rate, this, std::placeholders::_1)); - //add_coerced_subscriber the command time while we are at it + // add_coerced_subscriber the command time while we are at it _tree->create<time_spec_t>(mb_path / "time/cmd") - .add_coerced_subscriber(std::bind(&fifo_ctrl_excelsior::set_time, _fifo_ctrl, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&fifo_ctrl_excelsior::set_time, _fifo_ctrl, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create codec control objects //////////////////////////////////////////////////////////////////// - _codec_ctrl = b100_codec_ctrl::make(_fifo_ctrl); + _codec_ctrl = b100_codec_ctrl::make(_fifo_ctrl); const fs_path rx_codec_path = mb_path / "rx_codecs/A"; const fs_path tx_codec_path = mb_path / "tx_codecs/A"; _tree->create<std::string>(rx_codec_path / "name").set("ad9522"); - _tree->create<meta_range_t>(rx_codec_path / "gains/pga/range").set(b100_codec_ctrl::rx_pga_gain_range); + _tree->create<meta_range_t>(rx_codec_path / "gains/pga/range") + .set(b100_codec_ctrl::rx_pga_gain_range); _tree->create<double>(rx_codec_path / "gains/pga/value") - .set_coercer(std::bind(&b100_impl::update_rx_codec_gain, this, std::placeholders::_1)) + .set_coercer( + std::bind(&b100_impl::update_rx_codec_gain, this, std::placeholders::_1)) .set(0.0); _tree->create<std::string>(tx_codec_path / "name").set("ad9522"); - _tree->create<meta_range_t>(tx_codec_path / "gains/pga/range").set(b100_codec_ctrl::tx_pga_gain_range); + _tree->create<meta_range_t>(tx_codec_path / "gains/pga/range") + .set(b100_codec_ctrl::tx_pga_gain_range); _tree->create<double>(tx_codec_path / "gains/pga/value") - .add_coerced_subscriber(std::bind(&b100_codec_ctrl::set_tx_pga_gain, _codec_ctrl, std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &b100_codec_ctrl::set_tx_pga_gain, _codec_ctrl, std::placeholders::_1)) .set_publisher(std::bind(&b100_codec_ctrl::get_tx_pga_gain, _codec_ctrl)) .set(0.0); @@ -329,78 +345,91 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ _tx_fe = tx_frontend_core_200::make(_fifo_ctrl, TOREG(SR_TX_FE)); _tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec") - .add_coerced_subscriber(std::bind(&b100_impl::update_rx_subdev_spec, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::update_rx_subdev_spec, this, std::placeholders::_1)); _tree->create<subdev_spec_t>(mb_path / "tx_subdev_spec") - .add_coerced_subscriber(std::bind(&b100_impl::update_tx_subdev_spec, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::update_tx_subdev_spec, this, std::placeholders::_1)); const fs_path rx_fe_path = mb_path / "rx_frontends" / "A"; const fs_path tx_fe_path = mb_path / "tx_frontends" / "A"; - _tree->create<std::complex<double> >(rx_fe_path / "dc_offset" / "value") - .set_coercer(std::bind(&rx_frontend_core_200::set_dc_offset, _rx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(rx_fe_path / "dc_offset" / "value") + .set_coercer(std::bind( + &rx_frontend_core_200::set_dc_offset, _rx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); _tree->create<bool>(rx_fe_path / "dc_offset" / "enable") - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_dc_offset_auto, _rx_fe, std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &rx_frontend_core_200::set_dc_offset_auto, _rx_fe, std::placeholders::_1)) .set(true); - _tree->create<std::complex<double> >(rx_fe_path / "iq_balance" / "value") - .add_coerced_subscriber(std::bind(&rx_frontend_core_200::set_iq_balance, _rx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(rx_fe_path / "iq_balance" / "value") + .add_coerced_subscriber(std::bind( + &rx_frontend_core_200::set_iq_balance, _rx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); - _tree->create<std::complex<double> >(tx_fe_path / "dc_offset" / "value") - .set_coercer(std::bind(&tx_frontend_core_200::set_dc_offset, _tx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(tx_fe_path / "dc_offset" / "value") + .set_coercer(std::bind( + &tx_frontend_core_200::set_dc_offset, _tx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); - _tree->create<std::complex<double> >(tx_fe_path / "iq_balance" / "value") - .add_coerced_subscriber(std::bind(&tx_frontend_core_200::set_iq_balance, _tx_fe, std::placeholders::_1)) + _tree->create<std::complex<double>>(tx_fe_path / "iq_balance" / "value") + .add_coerced_subscriber(std::bind( + &tx_frontend_core_200::set_iq_balance, _tx_fe, std::placeholders::_1)) .set(std::complex<double>(0.0, 0.0)); //////////////////////////////////////////////////////////////////// // create rx dsp control objects //////////////////////////////////////////////////////////////////// const size_t num_rx_dsps = _fifo_ctrl->peek32(REG_RB_NUM_RX_DSP); - for (size_t dspno = 0; dspno < num_rx_dsps; dspno++) - { - const size_t sr_off = dspno*32; - _rx_dsps.push_back(rx_dsp_core_200::make( - _fifo_ctrl, - TOREG(SR_RX_DSP0+sr_off), - TOREG(SR_RX_CTRL0+sr_off), - B100_RX_SID_BASE + dspno - )); + for (size_t dspno = 0; dspno < num_rx_dsps; dspno++) { + const size_t sr_off = dspno * 32; + _rx_dsps.push_back(rx_dsp_core_200::make(_fifo_ctrl, + TOREG(SR_RX_DSP0 + sr_off), + TOREG(SR_RX_CTRL0 + sr_off), + B100_RX_SID_BASE + dspno)); _rx_dsps[dspno]->set_link_rate(B100_LINK_RATE_BPS); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&rx_dsp_core_200::set_tick_rate, _rx_dsps[dspno], std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &rx_dsp_core_200::set_tick_rate, _rx_dsps[dspno], std::placeholders::_1)); fs_path rx_dsp_path = mb_path / str(boost::format("rx_dsps/%u") % dspno); _tree->create<meta_range_t>(rx_dsp_path / "rate/range") .set_publisher(std::bind(&rx_dsp_core_200::get_host_rates, _rx_dsps[dspno])); _tree->create<double>(rx_dsp_path / "rate/value") - .set(1e6) //some default - .set_coercer(std::bind(&rx_dsp_core_200::set_host_rate, _rx_dsps[dspno], std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b100_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)); + .set(1e6) // some default + .set_coercer(std::bind( + &rx_dsp_core_200::set_host_rate, _rx_dsps[dspno], std::placeholders::_1)) + .add_coerced_subscriber(std::bind( + &b100_impl::update_rx_samp_rate, this, dspno, std::placeholders::_1)); _tree->create<double>(rx_dsp_path / "freq/value") - .set_coercer(std::bind(&rx_dsp_core_200::set_freq, _rx_dsps[dspno], std::placeholders::_1)); + .set_coercer(std::bind( + &rx_dsp_core_200::set_freq, _rx_dsps[dspno], std::placeholders::_1)); _tree->create<meta_range_t>(rx_dsp_path / "freq/range") .set_publisher(std::bind(&rx_dsp_core_200::get_freq_range, _rx_dsps[dspno])); _tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd") - .add_coerced_subscriber(std::bind(&rx_dsp_core_200::issue_stream_command, _rx_dsps[dspno], std::placeholders::_1)); + .add_coerced_subscriber(std::bind(&rx_dsp_core_200::issue_stream_command, + _rx_dsps[dspno], + std::placeholders::_1)); } //////////////////////////////////////////////////////////////////// // create tx dsp control objects //////////////////////////////////////////////////////////////////// _tx_dsp = tx_dsp_core_200::make( - _fifo_ctrl, TOREG(SR_TX_DSP), TOREG(SR_TX_CTRL), B100_TX_ASYNC_SID - ); + _fifo_ctrl, TOREG(SR_TX_DSP), TOREG(SR_TX_CTRL), B100_TX_ASYNC_SID); _tx_dsp->set_link_rate(B100_LINK_RATE_BPS); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&tx_dsp_core_200::set_tick_rate, _tx_dsp, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&tx_dsp_core_200::set_tick_rate, _tx_dsp, std::placeholders::_1)); _tree->create<meta_range_t>(mb_path / "tx_dsps/0/rate/range") .set_publisher(std::bind(&tx_dsp_core_200::get_host_rates, _tx_dsp)); _tree->create<double>(mb_path / "tx_dsps/0/rate/value") - .set(1e6) //some default - .set_coercer(std::bind(&tx_dsp_core_200::set_host_rate, _tx_dsp, std::placeholders::_1)) - .add_coerced_subscriber(std::bind(&b100_impl::update_tx_samp_rate, this, 0, std::placeholders::_1)); + .set(1e6) // some default + .set_coercer( + std::bind(&tx_dsp_core_200::set_host_rate, _tx_dsp, std::placeholders::_1)) + .add_coerced_subscriber( + std::bind(&b100_impl::update_tx_samp_rate, this, 0, std::placeholders::_1)); _tree->create<double>(mb_path / "tx_dsps/0/freq/value") - .set_coercer(std::bind(&tx_dsp_core_200::set_freq, _tx_dsp, std::placeholders::_1)); + .set_coercer( + std::bind(&tx_dsp_core_200::set_freq, _tx_dsp, std::placeholders::_1)); _tree->create<meta_range_t>(mb_path / "tx_dsps/0/freq/range") .set_publisher(std::bind(&tx_dsp_core_200::get_freq_range, _tx_dsp)); @@ -412,202 +441,241 @@ b100_impl::b100_impl(const device_addr_t &device_addr){ time64_rb_bases.rb_lo_now = REG_RB_TIME_NOW_LO; time64_rb_bases.rb_hi_pps = REG_RB_TIME_PPS_HI; time64_rb_bases.rb_lo_pps = REG_RB_TIME_PPS_LO; - _time64 = time64_core_200::make( - _fifo_ctrl, TOREG(SR_TIME64), time64_rb_bases - ); + _time64 = time64_core_200::make(_fifo_ctrl, TOREG(SR_TIME64), time64_rb_bases); _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(std::bind(&time64_core_200::set_tick_rate, _time64, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&time64_core_200::set_tick_rate, _time64, std::placeholders::_1)); _tree->create<time_spec_t>(mb_path / "time/now") .set_publisher(std::bind(&time64_core_200::get_time_now, _time64)) - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_now, _time64, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&time64_core_200::set_time_now, _time64, std::placeholders::_1)); _tree->create<time_spec_t>(mb_path / "time/pps") .set_publisher(std::bind(&time64_core_200::get_time_last_pps, _time64)) - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_next_pps, _time64, std::placeholders::_1)); - //setup time source props + .add_coerced_subscriber(std::bind( + &time64_core_200::set_time_next_pps, _time64, std::placeholders::_1)); + // setup time source props _tree->create<std::string>(mb_path / "time_source/value") - .add_coerced_subscriber(std::bind(&time64_core_200::set_time_source, _time64, std::placeholders::_1)); - _tree->create<std::vector<std::string> >(mb_path / "time_source/options") + .add_coerced_subscriber( + std::bind(&time64_core_200::set_time_source, _time64, std::placeholders::_1)); + _tree->create<std::vector<std::string>>(mb_path / "time_source/options") .set_publisher(std::bind(&time64_core_200::get_time_sources, _time64)); - //setup reference source props + // setup reference source props _tree->create<std::string>(mb_path / "clock_source/value") - .add_coerced_subscriber(std::bind(&b100_impl::update_clock_source, this, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::update_clock_source, this, std::placeholders::_1)); static const std::vector<std::string> clock_sources = { - "internal", "external", "auto" - }; - _tree->create<std::vector<std::string> >(mb_path / "clock_source/options").set(clock_sources); + "internal", "external", "auto"}; + _tree->create<std::vector<std::string>>(mb_path / "clock_source/options") + .set(clock_sources); //////////////////////////////////////////////////////////////////// // create user-defined control objects //////////////////////////////////////////////////////////////////// _user = user_settings_core_200::make(_fifo_ctrl, TOREG(SR_USER_REGS)); _tree->create<user_settings_core_200::user_reg_t>(mb_path / "user/regs") - .add_coerced_subscriber(std::bind(&user_settings_core_200::set_reg, _user, std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&user_settings_core_200::set_reg, _user, std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // create dboard control objects //////////////////////////////////////////////////////////////////// - //read the dboard eeprom to extract the dboard ids + // read the dboard eeprom to extract the dboard ids dboard_eeprom_t rx_db_eeprom, tx_db_eeprom, gdb_eeprom; rx_db_eeprom.load(*_fpga_i2c_ctrl, I2C_ADDR_RX_A); tx_db_eeprom.load(*_fpga_i2c_ctrl, I2C_ADDR_TX_A); gdb_eeprom.load(*_fpga_i2c_ctrl, I2C_ADDR_TX_A ^ 5); - //disable rx dc offset if LFRX - if (rx_db_eeprom.id == 0x000f) _tree->access<bool>(rx_fe_path / "dc_offset" / "enable").set(false); + // disable rx dc offset if LFRX + if (rx_db_eeprom.id == 0x000f) + _tree->access<bool>(rx_fe_path / "dc_offset" / "enable").set(false); - //create the properties and register subscribers + // create the properties and register subscribers _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/rx_eeprom") .set(rx_db_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_db_eeprom, this, "rx", std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::set_db_eeprom, this, "rx", std::placeholders::_1)); _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/tx_eeprom") .set(tx_db_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_db_eeprom, this, "tx", std::placeholders::_1)); + .add_coerced_subscriber( + std::bind(&b100_impl::set_db_eeprom, this, "tx", std::placeholders::_1)); _tree->create<dboard_eeprom_t>(mb_path / "dboards/A/gdb_eeprom") .set(gdb_eeprom) - .add_coerced_subscriber(std::bind(&b100_impl::set_db_eeprom, this, "gdb", std::placeholders::_1)); - - //create a new dboard interface and manager - _dboard_manager = dboard_manager::make( - rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id, - make_b100_dboard_iface(_fifo_ctrl, _fpga_i2c_ctrl, _fifo_ctrl/*spi*/, _clock_ctrl, _codec_ctrl), - _tree->subtree(mb_path / "dboards/A") - ); - - //bind frontend corrections to the dboard freq props + .add_coerced_subscriber( + std::bind(&b100_impl::set_db_eeprom, this, "gdb", std::placeholders::_1)); + + // create a new dboard interface and manager + _dboard_manager = dboard_manager::make(rx_db_eeprom.id, + tx_db_eeprom.id, + gdb_eeprom.id, + make_b100_dboard_iface( + _fifo_ctrl, _fpga_i2c_ctrl, _fifo_ctrl /*spi*/, _clock_ctrl, _codec_ctrl), + _tree->subtree(mb_path / "dboards/A")); + + // bind frontend corrections to the dboard freq props const fs_path db_tx_fe_path = mb_path / "dboards" / "A" / "tx_frontends"; - for(const std::string &name: _tree->list(db_tx_fe_path)){ + for (const std::string& name : _tree->list(db_tx_fe_path)) { _tree->access<double>(db_tx_fe_path / name / "freq" / "value") - .add_coerced_subscriber(std::bind(&b100_impl::set_tx_fe_corrections, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &b100_impl::set_tx_fe_corrections, this, std::placeholders::_1)); } const fs_path db_rx_fe_path = mb_path / "dboards" / "A" / "rx_frontends"; - for(const std::string &name: _tree->list(db_rx_fe_path)){ + for (const std::string& name : _tree->list(db_rx_fe_path)) { _tree->access<double>(db_rx_fe_path / name / "freq" / "value") - .add_coerced_subscriber(std::bind(&b100_impl::set_rx_fe_corrections, this, std::placeholders::_1)); + .add_coerced_subscriber(std::bind( + &b100_impl::set_rx_fe_corrections, this, std::placeholders::_1)); } - //initialize io handling + // initialize io handling _recv_demuxer.reset(new recv_packet_demuxer_3000(_data_transport)); - //allocate streamer weak ptrs containers + // allocate streamer weak ptrs containers _rx_streamers.resize(_rx_dsps.size()); - _tx_streamers.resize(1/*known to be 1 dsp*/); + _tx_streamers.resize(1 /*known to be 1 dsp*/); //////////////////////////////////////////////////////////////////// // do some post-init tasks //////////////////////////////////////////////////////////////////// this->update_rates(); - _tree->access<double>(mb_path / "tick_rate") //now add_coerced_subscriber the clock rate setter - .add_coerced_subscriber(std::bind(&b100_clock_ctrl::set_fpga_clock_rate, _clock_ctrl, std::placeholders::_1)); + _tree + ->access<double>( + mb_path / "tick_rate") // now add_coerced_subscriber the clock rate setter + .add_coerced_subscriber(std::bind( + &b100_clock_ctrl::set_fpga_clock_rate, _clock_ctrl, std::placeholders::_1)); - //reset cordic rates and their properties to zero - for(const std::string &name: _tree->list(mb_path / "rx_dsps")){ + // reset cordic rates and their properties to zero + for (const std::string& name : _tree->list(mb_path / "rx_dsps")) { _tree->access<double>(mb_path / "rx_dsps" / name / "freq" / "value").set(0.0); } - for(const std::string &name: _tree->list(mb_path / "tx_dsps")){ + for (const std::string& name : _tree->list(mb_path / "tx_dsps")) { _tree->access<double>(mb_path / "tx_dsps" / name / "freq" / "value").set(0.0); } - _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/rx_frontends").at(0))); - _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/tx_frontends").at(0))); + _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec") + .set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/rx_frontends").at(0))); + _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec") + .set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/tx_frontends").at(0))); _tree->access<std::string>(mb_path / "clock_source/value").set("internal"); _tree->access<std::string>(mb_path / "time_source/value").set("none"); _tree->create<double>(mb_path / "link_max_rate").set(B100_MAX_RATE_USB2); } -b100_impl::~b100_impl(void){ - //NOP +b100_impl::~b100_impl(void) +{ + // NOP } -void b100_impl::check_fw_compat(void){ - unsigned char data[4]; //useless data buffer - const uint16_t fw_compat_num = _fx2_ctrl->usrp_control_read( - VRQ_FW_COMPAT, 0, 0, data, sizeof(data) - ); - if (fw_compat_num != B100_FW_COMPAT_NUM){ - throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number %d, but got %d:\n" - "The firmware build is not compatible with the host code build.\n" - "%s" - ) % int(B100_FW_COMPAT_NUM) % fw_compat_num % print_utility_error("uhd_images_downloader.py"))); +void b100_impl::check_fw_compat(void) +{ + unsigned char data[4]; // useless data buffer + const uint16_t fw_compat_num = + _fx2_ctrl->usrp_control_read(VRQ_FW_COMPAT, 0, 0, data, sizeof(data)); + if (fw_compat_num != B100_FW_COMPAT_NUM) { + throw uhd::runtime_error( + str(boost::format( + "Expected firmware compatibility number %d, but got %d:\n" + "The firmware build is not compatible with the host code build.\n" + "%s") + % int(B100_FW_COMPAT_NUM) % fw_compat_num + % print_utility_error("uhd_images_downloader.py"))); } - _tree->create<std::string>("/mboards/0/fw_version").set(str(boost::format("%u.0") % fw_compat_num)); + _tree->create<std::string>("/mboards/0/fw_version") + .set(str(boost::format("%u.0") % fw_compat_num)); } -void b100_impl::check_fpga_compat(void){ +void b100_impl::check_fpga_compat(void) +{ const uint32_t fpga_compat_num = _fifo_ctrl->peek32(REG_RB_COMPAT); uint16_t fpga_major = fpga_compat_num >> 16, fpga_minor = fpga_compat_num & 0xffff; - if (fpga_major == 0){ //old version scheme + if (fpga_major == 0) { // old version scheme fpga_major = fpga_minor; fpga_minor = 0; } - if (fpga_major != B100_FPGA_COMPAT_NUM){ - throw uhd::runtime_error(str(boost::format( - "Expected FPGA compatibility number %d, but got %d:\n" - "The FPGA build is not compatible with the host code build." - "%s" - ) % int(B100_FPGA_COMPAT_NUM) % fpga_major % print_utility_error("uhd_images_downloader.py"))); + if (fpga_major != B100_FPGA_COMPAT_NUM) { + throw uhd::runtime_error( + str(boost::format("Expected FPGA compatibility number %d, but got %d:\n" + "The FPGA build is not compatible with the host code build." + "%s") + % int(B100_FPGA_COMPAT_NUM) % fpga_major + % print_utility_error("uhd_images_downloader.py"))); } - _tree->create<std::string>("/mboards/0/fpga_version").set(str(boost::format("%u.%u") % fpga_major % fpga_minor)); + _tree->create<std::string>("/mboards/0/fpga_version") + .set(str(boost::format("%u.%u") % fpga_major % fpga_minor)); } -double b100_impl::update_rx_codec_gain(const double gain){ - //set gain on both I and Q, readback on one - //TODO in the future, gains should have individual control +double b100_impl::update_rx_codec_gain(const double gain) +{ + // set gain on both I and Q, readback on one + // TODO in the future, gains should have individual control _codec_ctrl->set_rx_pga_gain(gain, 'A'); _codec_ctrl->set_rx_pga_gain(gain, 'B'); return _codec_ctrl->get_rx_pga_gain('A'); } -void b100_impl::set_db_eeprom(const std::string &type, const uhd::usrp::dboard_eeprom_t &db_eeprom){ - if (type == "rx") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_RX_A); - if (type == "tx") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A); - if (type == "gdb") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A ^ 5); +void b100_impl::set_db_eeprom( + const std::string& type, const uhd::usrp::dboard_eeprom_t& db_eeprom) +{ + if (type == "rx") + db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_RX_A); + if (type == "tx") + db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A); + if (type == "gdb") + db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_A ^ 5); } -void b100_impl::update_clock_source(const std::string &source){ - - if (source == "pps_sync"){ +void b100_impl::update_clock_source(const std::string& source) +{ + if (source == "pps_sync") { _clock_ctrl->use_external_ref(); - _fifo_ctrl->poke32(TOREG(SR_MISC+2), 1); + _fifo_ctrl->poke32(TOREG(SR_MISC + 2), 1); return; } - if (source == "_pps_sync_"){ + if (source == "_pps_sync_") { _clock_ctrl->use_external_ref(); - _fifo_ctrl->poke32(TOREG(SR_MISC+2), 3); + _fifo_ctrl->poke32(TOREG(SR_MISC + 2), 3); return; } - _fifo_ctrl->poke32(TOREG(SR_MISC+2), 0); + _fifo_ctrl->poke32(TOREG(SR_MISC + 2), 0); - if (source == "auto") _clock_ctrl->use_auto_ref(); - else if (source == "internal") _clock_ctrl->use_internal_ref(); - else if (source == "external") _clock_ctrl->use_external_ref(); - else throw uhd::runtime_error("unhandled clock configuration reference source: " + source); + if (source == "auto") + _clock_ctrl->use_auto_ref(); + else if (source == "internal") + _clock_ctrl->use_internal_ref(); + else if (source == "external") + _clock_ctrl->use_external_ref(); + else + throw uhd::runtime_error( + "unhandled clock configuration reference source: " + source); } ////////////////// some GPIF preparation related stuff ///////////////// -void b100_impl::enable_gpif(const bool en) { +void b100_impl::enable_gpif(const bool en) +{ _fx2_ctrl->usrp_control_write(VRQ_ENABLE_GPIF, en ? 1 : 0, 0, 0, 0); } -void b100_impl::clear_fpga_fifo(void) { +void b100_impl::clear_fpga_fifo(void) +{ _fx2_ctrl->usrp_control_write(VRQ_CLEAR_FPGA_FIFO, 0, 0, 0, 0); } -sensor_value_t b100_impl::get_ref_locked(void){ +sensor_value_t b100_impl::get_ref_locked(void) +{ const bool lock = _clock_ctrl->get_locked(); return sensor_value_t("Ref", lock, "locked", "unlocked"); } -void b100_impl::set_rx_fe_corrections(const double lo_freq){ - if(not _ignore_cal_file){ +void b100_impl::set_rx_fe_corrections(const double lo_freq) +{ + if (not _ignore_cal_file) { apply_rx_fe_corrections(this->get_tree()->subtree("/mboards/0"), "A", lo_freq); } } -void b100_impl::set_tx_fe_corrections(const double lo_freq){ - if(not _ignore_cal_file){ +void b100_impl::set_tx_fe_corrections(const double lo_freq) +{ + if (not _ignore_cal_file) { apply_tx_fe_corrections(this->get_tree()->subtree("/mboards/0"), "A", lo_freq); } } diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index bb72cd63e..0b46c4815 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -13,55 +13,53 @@ #include "fifo_ctrl_excelsior.hpp" #include <uhd/device.hpp> #include <uhd/property_tree.hpp> +#include <uhd/transport/usb_zero_copy.hpp> #include <uhd/types/dict.hpp> #include <uhd/types/sensors.hpp> #include <uhd/types/stream_cmd.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> -#include <uhd/usrp/subdev_spec.hpp> #include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/dboard_manager.hpp> -#include <uhd/transport/usb_zero_copy.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/usrp/subdev_spec.hpp> #include <uhdlib/usrp/common/fx2_ctrl.hpp> #include <uhdlib/usrp/common/recv_packet_demuxer_3000.hpp> #include <uhdlib/usrp/cores/i2c_core_200.hpp> -#include <uhdlib/usrp/cores/rx_frontend_core_200.hpp> -#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> #include <uhdlib/usrp/cores/rx_dsp_core_200.hpp> -#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> +#include <uhdlib/usrp/cores/rx_frontend_core_200.hpp> #include <uhdlib/usrp/cores/time64_core_200.hpp> +#include <uhdlib/usrp/cores/tx_dsp_core_200.hpp> +#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> #include <uhdlib/usrp/cores/user_settings_core_200.hpp> #include <memory> -static const double B100_LINK_RATE_BPS = 256e6/5; //pratical link rate (< 480 Mbps) -static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; -static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; -static const uint16_t B100_FW_COMPAT_NUM = 4; -static const uint16_t B100_FPGA_COMPAT_NUM = 11; -static const uint32_t B100_RX_SID_BASE = 30; -static const uint32_t B100_TX_ASYNC_SID = 10; -static const uint32_t B100_CTRL_MSG_SID = 20; -static const double B100_DEFAULT_TICK_RATE = 64e6; -static const size_t B100_MAX_PKT_BYTE_LIMIT = 2048; -static const size_t B100_MAX_RATE_USB2 = 32000000; // bytes/s - -#define I2C_ADDR_TX_A (I2C_DEV_EEPROM | 0x4) -#define I2C_ADDR_RX_A (I2C_DEV_EEPROM | 0x5) -#define I2C_ADDR_TX_B (I2C_DEV_EEPROM | 0x6) -#define I2C_ADDR_RX_B (I2C_DEV_EEPROM | 0x7) -#define I2C_DEV_EEPROM 0x50 - -#define VRQ_FW_COMPAT 0x83 -#define VRQ_ENABLE_GPIF 0x0d +static const double B100_LINK_RATE_BPS = 256e6 / 5; // pratical link rate (< 480 Mbps) +static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx"; +static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin"; +static const uint16_t B100_FW_COMPAT_NUM = 4; +static const uint16_t B100_FPGA_COMPAT_NUM = 11; +static const uint32_t B100_RX_SID_BASE = 30; +static const uint32_t B100_TX_ASYNC_SID = 10; +static const uint32_t B100_CTRL_MSG_SID = 20; +static const double B100_DEFAULT_TICK_RATE = 64e6; +static const size_t B100_MAX_PKT_BYTE_LIMIT = 2048; +static const size_t B100_MAX_RATE_USB2 = 32000000; // bytes/s + +#define I2C_ADDR_TX_A (I2C_DEV_EEPROM | 0x4) +#define I2C_ADDR_RX_A (I2C_DEV_EEPROM | 0x5) +#define I2C_ADDR_TX_B (I2C_DEV_EEPROM | 0x6) +#define I2C_ADDR_RX_B (I2C_DEV_EEPROM | 0x7) +#define I2C_DEV_EEPROM 0x50 + +#define VRQ_FW_COMPAT 0x83 +#define VRQ_ENABLE_GPIF 0x0d #define VRQ_CLEAR_FPGA_FIFO 0x0e //! Make a b100 dboard interface -uhd::usrp::dboard_iface::sptr make_b100_dboard_iface( - uhd::timed_wb_iface::sptr wb_iface, +uhd::usrp::dboard_iface::sptr make_b100_dboard_iface(uhd::timed_wb_iface::sptr wb_iface, uhd::i2c_iface::sptr i2c_iface, uhd::spi_iface::sptr spi_iface, b100_clock_ctrl::sptr clock, - b100_codec_ctrl::sptr codec -); + b100_codec_ctrl::sptr codec); /*! * Make a wrapper around a zero copy implementation. @@ -78,25 +76,25 @@ uhd::usrp::dboard_iface::sptr make_b100_dboard_iface( * \return a new zero copy wrapper object */ uhd::transport::zero_copy_if::sptr usb_zero_copy_make_wrapper( - uhd::transport::zero_copy_if::sptr usb_zc, size_t usb_frame_boundary = 512 -); + uhd::transport::zero_copy_if::sptr usb_zc, size_t usb_frame_boundary = 512); //! Implementation guts -class b100_impl : public uhd::device { +class b100_impl : public uhd::device +{ public: - //structors - b100_impl(const uhd::device_addr_t &); + // structors + b100_impl(const uhd::device_addr_t&); ~b100_impl(void); - //the io interface - uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args); - uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args); - bool recv_async_msg(uhd::async_metadata_t &, double); + // the io interface + uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t& args); + uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t& args); + bool recv_async_msg(uhd::async_metadata_t&, double); static uhd::usrp::mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr); private: - //controllers + // controllers fifo_ctrl_excelsior::sptr _fifo_ctrl; i2c_core_200::sptr _fpga_i2c_ctrl; rx_frontend_core_200::sptr _rx_fe; @@ -109,30 +107,30 @@ private: b100_codec_ctrl::sptr _codec_ctrl; uhd::usrp::fx2_ctrl::sptr _fx2_ctrl; - //transports + // transports uhd::transport::zero_copy_if::sptr _ctrl_transport; uhd::transport::zero_copy_if::sptr _data_transport; std::shared_ptr<uhd::usrp::recv_packet_demuxer_3000> _recv_demuxer; - //dboard stuff + // dboard stuff uhd::usrp::dboard_manager::sptr _dboard_manager; bool _ignore_cal_file; - std::vector<std::weak_ptr<uhd::rx_streamer> > _rx_streamers; - std::vector<std::weak_ptr<uhd::tx_streamer> > _tx_streamers; + std::vector<std::weak_ptr<uhd::rx_streamer>> _rx_streamers; + std::vector<std::weak_ptr<uhd::tx_streamer>> _tx_streamers; void check_fw_compat(void); void check_fpga_compat(void); - double update_rx_codec_gain(const double); //sets A and B at once - void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &); - void set_db_eeprom(const std::string &, const uhd::usrp::dboard_eeprom_t &); + double update_rx_codec_gain(const double); // sets A and B at once + void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t&); + void set_db_eeprom(const std::string&, const uhd::usrp::dboard_eeprom_t&); void update_tick_rate(const double rate); void update_rx_samp_rate(const size_t, const double rate); void update_tx_samp_rate(const size_t, const double rate); void update_rates(void); - void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &); - void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &); - void update_clock_source(const std::string &); + void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t&); + void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t&); + void update_clock_source(const std::string&); void enable_gpif(const bool); void clear_fpga_fifo(void); uhd::sensor_value_t get_ref_locked(void); diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index 8cb231488..541a14849 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -14,40 +14,39 @@ #define localparam static const int -localparam SR_MISC = 0; // 5 -localparam SR_USER_REGS = 5; // 2 -localparam SR_PADDER = 10; // 2 +localparam SR_MISC = 0; // 5 +localparam SR_USER_REGS = 5; // 2 +localparam SR_PADDER = 10; // 2 -localparam SR_TX_CTRL = 32; // 6 -localparam SR_TX_DSP = 40; // 5 -localparam SR_TX_FE = 48; // 5 +localparam SR_TX_CTRL = 32; // 6 +localparam SR_TX_DSP = 40; // 5 +localparam SR_TX_FE = 48; // 5 -localparam SR_RX_CTRL0 = 96; // 9 -localparam SR_RX_DSP0 = 106; // 7 -localparam SR_RX_FE = 114; // 5 +localparam SR_RX_CTRL0 = 96; // 9 +localparam SR_RX_DSP0 = 106; // 7 +localparam SR_RX_FE = 114; // 5 -localparam SR_RX_CTRL1 = 128; // 9 -localparam SR_RX_DSP1 = 138; // 7 +localparam SR_RX_CTRL1 = 128; // 9 +localparam SR_RX_DSP1 = 138; // 7 -localparam SR_TIME64 = 192; // 6 -localparam SR_SPI = 208; // 3 -localparam SR_I2C = 216; // 1 -localparam SR_GPIO = 224; // 5 +localparam SR_TIME64 = 192; // 6 +localparam SR_SPI = 208; // 3 +localparam SR_I2C = 216; // 1 +localparam SR_GPIO = 224; // 5 #define REG_RB_TIME_NOW_HI TOREG(10) #define REG_RB_TIME_NOW_LO TOREG(11) #define REG_RB_TIME_PPS_HI TOREG(14) #define REG_RB_TIME_PPS_LO TOREG(15) -#define REG_RB_SPI TOREG(0) -#define REG_RB_COMPAT TOREG(1) -#define REG_RB_GPIO TOREG(3) -#define REG_RB_I2C TOREG(2) -#define REG_RB_NUM_RX_DSP TOREG(6) +#define REG_RB_SPI TOREG(0) +#define REG_RB_COMPAT TOREG(1) +#define REG_RB_GPIO TOREG(3) +#define REG_RB_I2C TOREG(2) +#define REG_RB_NUM_RX_DSP TOREG(6) -//spi slave constants -#define B100_SPI_SS_AD9862 (1 << 2) -#define B100_SPI_SS_TX_DB (1 << 1) -#define B100_SPI_SS_RX_DB (1 << 0) +// spi slave constants +#define B100_SPI_SS_AD9862 (1 << 2) +#define B100_SPI_SS_TX_DB (1 << 1) +#define B100_SPI_SS_RX_DB (1 << 0) #endif /*INCLUDED_B100_REGS_HPP*/ - diff --git a/host/lib/usrp/b100/clock_ctrl.cpp b/host/lib/usrp/b100/clock_ctrl.cpp index 676ebd981..12ef2052f 100644 --- a/host/lib/usrp/b100/clock_ctrl.cpp +++ b/host/lib/usrp/b100/clock_ctrl.cpp @@ -87,7 +87,8 @@ struct clock_settings_type }; //! gives the greatest divisor of num between 1 and max inclusive -template <typename T> static inline T greatest_divisor(T num, T max) +template <typename T> +static inline T greatest_divisor(T num, T max) { for (T i = max; i > 1; i--) { if (num % i == 0) { @@ -98,7 +99,8 @@ template <typename T> static inline T greatest_divisor(T num, T max) } //! gives the least divisor of num between min and num exclusive -template <typename T> static inline T least_divisor(T num, T min) +template <typename T> +static inline T least_divisor(T num, T min) { for (T i = min; i < num; i++) { if (num % i == 0) { diff --git a/host/lib/usrp/b100/clock_ctrl.hpp b/host/lib/usrp/b100/clock_ctrl.hpp index b208e8a0c..318d1b248 100644 --- a/host/lib/usrp/b100/clock_ctrl.hpp +++ b/host/lib/usrp/b100/clock_ctrl.hpp @@ -17,7 +17,8 @@ * The B100 clock control: * - Disable/enable clock lines. */ -class b100_clock_ctrl : uhd::noncopyable{ +class b100_clock_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<b100_clock_ctrl> sptr; @@ -81,12 +82,12 @@ public: * \return the clock rate in Hz */ virtual double get_tx_clock_rate(void) = 0; - + /*! * Enable/disable the FPGA clock. * \param enb true to enable */ - + virtual void enable_fpga_clock(bool enb) = 0; /*! @@ -100,17 +101,17 @@ public: * \param enb true to enable */ virtual void enable_tx_dboard_clock(bool enb) = 0; - + /*! * Use the internal TCXO reference */ virtual void use_internal_ref(void) = 0; - + /*! * Use the external SMA reference */ virtual void use_external_ref(void) = 0; - + /*! * Use external if available, internal otherwise */ @@ -118,7 +119,6 @@ public: //! Is the reference locked? virtual bool get_locked(void) = 0; - }; #endif /* INCLUDED_B100_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/b100/codec_ctrl.cpp b/host/lib/usrp/b100/codec_ctrl.cpp index 10cfa686a..f6e2d8b93 100644 --- a/host/lib/usrp/b100/codec_ctrl.cpp +++ b/host/lib/usrp/b100/codec_ctrl.cpp @@ -7,15 +7,15 @@ #include "codec_ctrl.hpp" #include "ad9862_regs.hpp" -#include <uhd/types/dict.hpp> +#include "b100_regs.hpp" //spi slave constants #include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> #include <stdint.h> -#include <boost/math/special_functions/round.hpp> -#include "b100_regs.hpp" //spi slave constants #include <boost/assign/list_of.hpp> +#include <boost/math/special_functions/round.hpp> #include <tuple> using namespace uhd; @@ -23,24 +23,26 @@ using namespace uhd; const gain_range_t b100_codec_ctrl::tx_pga_gain_range(-20, 0, double(0.1)); const gain_range_t b100_codec_ctrl::rx_pga_gain_range(0, 20, 1); -b100_codec_ctrl::~b100_codec_ctrl(void){ +b100_codec_ctrl::~b100_codec_ctrl(void) +{ /* NOP */ } /*********************************************************************** * Codec Control Implementation **********************************************************************/ -class b100_codec_ctrl_impl : public b100_codec_ctrl{ +class b100_codec_ctrl_impl : public b100_codec_ctrl +{ public: - //structors + // structors b100_codec_ctrl_impl(spi_iface::sptr iface); ~b100_codec_ctrl_impl(void); - //aux adc and dac control + // aux adc and dac control double read_aux_adc(aux_adc_t which); void write_aux_dac(aux_dac_t which, double volts); - //pga gain control + // pga gain control void set_tx_pga_gain(double); double get_tx_pga_gain(void); void set_rx_pga_gain(double, char); @@ -56,157 +58,178 @@ private: /*********************************************************************** * Codec Control Structors **********************************************************************/ -b100_codec_ctrl_impl::b100_codec_ctrl_impl(spi_iface::sptr iface){ +b100_codec_ctrl_impl::b100_codec_ctrl_impl(spi_iface::sptr iface) +{ _iface = iface; - //soft reset + // soft reset _ad9862_regs.soft_reset = 1; this->send_reg(0); - //initialize the codec register settings + // initialize the codec register settings _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO; - _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; + _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; _ad9862_regs.soft_reset = 0; - //setup rx side of codec + // setup rx side of codec _ad9862_regs.byp_buffer_a = 1; _ad9862_regs.byp_buffer_b = 1; - _ad9862_regs.buffer_a_pd = 1; - _ad9862_regs.buffer_b_pd = 1; - _ad9862_regs.mux_out = ad9862_regs_t::MUX_OUT_RX_MUX_MODE; //B100 uses interleaved RX->FPGA - _ad9862_regs.rx_pga_a = 0;//0x1f; //TODO bring under api control - _ad9862_regs.rx_pga_b = 0;//0x1f; //TODO bring under api control + _ad9862_regs.buffer_a_pd = 1; + _ad9862_regs.buffer_b_pd = 1; + _ad9862_regs.mux_out = + ad9862_regs_t::MUX_OUT_RX_MUX_MODE; // B100 uses interleaved RX->FPGA + _ad9862_regs.rx_pga_a = 0; // 0x1f; //TODO bring under api control + _ad9862_regs.rx_pga_b = 0; // 0x1f; //TODO bring under api control _ad9862_regs.rx_twos_comp = 1; - _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; + _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; - //setup tx side of codec + // setup tx side of codec _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; - _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; - _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2; - _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control - _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; - _ad9862_regs.interp = ad9862_regs_t::INTERP_2; - _ad9862_regs.tx_twos_comp = 1; - _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; + _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; + _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2; + _ad9862_regs.tx_pga_gain = 199; // TODO bring under api control + _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; + _ad9862_regs.interp = ad9862_regs_t::INTERP_2; + _ad9862_regs.tx_twos_comp = 1; + _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; _ad9862_regs.dac_a_coarse_gain = 0x3; _ad9862_regs.dac_b_coarse_gain = 0x3; - _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL; + _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL; - //setup the dll + // setup the dll _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; - _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; - _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; + _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; + _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; - //write the register settings to the codec - for (uint8_t addr = 0; addr <= 25; addr++){ + // write the register settings to the codec + for (uint8_t addr = 0; addr <= 25; addr++) { this->send_reg(addr); } - //always start conversions for aux ADC + // always start conversions for aux ADC _ad9862_regs.start_a = 1; _ad9862_regs.start_b = 1; - //aux adc clock + // aux adc clock _ad9862_regs.clk_4 = ad9862_regs_t::CLK_4_1_4; this->send_reg(34); } -b100_codec_ctrl_impl::~b100_codec_ctrl_impl(void){ +b100_codec_ctrl_impl::~b100_codec_ctrl_impl(void) +{ UHD_SAFE_CALL( - //set aux dacs to zero - this->write_aux_dac(AUX_DAC_A, 0); - this->write_aux_dac(AUX_DAC_B, 0); + // set aux dacs to zero + this->write_aux_dac(AUX_DAC_A, 0); this->write_aux_dac(AUX_DAC_B, 0); this->write_aux_dac(AUX_DAC_C, 0); this->write_aux_dac(AUX_DAC_D, 0); - //power down + // power down _ad9862_regs.all_rx_pd = 1; this->send_reg(1); _ad9862_regs.tx_digital_pd = 1; - _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; - this->send_reg(8); - ) + _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; + this->send_reg(8);) } /*********************************************************************** * Codec Control Gain Control Methods **********************************************************************/ -static const int mtpgw = 255; //maximum tx pga gain word +static const int mtpgw = 255; // maximum tx pga gain word -void b100_codec_ctrl_impl::set_tx_pga_gain(double gain){ - int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); +void b100_codec_ctrl_impl::set_tx_pga_gain(double gain) +{ + int gain_word = int(mtpgw * (gain - tx_pga_gain_range.start()) + / (tx_pga_gain_range.stop() - tx_pga_gain_range.start())); _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw); this->send_reg(16); } -double b100_codec_ctrl_impl::get_tx_pga_gain(void){ - return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.stop() - tx_pga_gain_range.start())/mtpgw) + tx_pga_gain_range.start(); +double b100_codec_ctrl_impl::get_tx_pga_gain(void) +{ + return (_ad9862_regs.tx_pga_gain + * (tx_pga_gain_range.stop() - tx_pga_gain_range.start()) / mtpgw) + + tx_pga_gain_range.start(); } -static const int mrpgw = 0x14; //maximum rx pga gain word - -void b100_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){ - int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); - gain_word = uhd::clip(gain_word, 0, mrpgw); - switch(which){ - case 'A': - _ad9862_regs.rx_pga_a = gain_word; - this->send_reg(2); - return; - case 'B': - _ad9862_regs.rx_pga_b = gain_word; - this->send_reg(3); - return; - default: UHD_THROW_INVALID_CODE_PATH(); +static const int mrpgw = 0x14; // maximum rx pga gain word + +void b100_codec_ctrl_impl::set_rx_pga_gain(double gain, char which) +{ + int gain_word = int(mrpgw * (gain - rx_pga_gain_range.start()) + / (rx_pga_gain_range.stop() - rx_pga_gain_range.start())); + gain_word = uhd::clip(gain_word, 0, mrpgw); + switch (which) { + case 'A': + _ad9862_regs.rx_pga_a = gain_word; + this->send_reg(2); + return; + case 'B': + _ad9862_regs.rx_pga_b = gain_word; + this->send_reg(3); + return; + default: + UHD_THROW_INVALID_CODE_PATH(); } } -double b100_codec_ctrl_impl::get_rx_pga_gain(char which){ +double b100_codec_ctrl_impl::get_rx_pga_gain(char which) +{ int gain_word; - switch(which){ - case 'A': gain_word = _ad9862_regs.rx_pga_a; break; - case 'B': gain_word = _ad9862_regs.rx_pga_b; break; - default: UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case 'A': + gain_word = _ad9862_regs.rx_pga_a; + break; + case 'B': + gain_word = _ad9862_regs.rx_pga_b; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } - return (gain_word*(rx_pga_gain_range.stop() - rx_pga_gain_range.start())/mrpgw) + rx_pga_gain_range.start(); + return (gain_word * (rx_pga_gain_range.stop() - rx_pga_gain_range.start()) / mrpgw) + + rx_pga_gain_range.start(); } /*********************************************************************** * Codec Control AUX ADC Methods **********************************************************************/ -static double aux_adc_to_volts(uint8_t high, uint8_t low){ - return double((uint16_t(high) << 2) | low)*3.3/0x3ff; +static double aux_adc_to_volts(uint8_t high, uint8_t low) +{ + return double((uint16_t(high) << 2) | low) * 3.3 / 0x3ff; } -double b100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ - switch(which){ - - case AUX_ADC_A1: - _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; - this->send_reg(34); //start conversion and select mux - this->recv_reg(28); //read the value (2 bytes, 2 reads) - this->recv_reg(29); - return aux_adc_to_volts(_ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); - case AUX_ADC_A2: - _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC2; - this->send_reg(34); //start conversion and select mux - this->recv_reg(26); //read the value (2 bytes, 2 reads) - this->recv_reg(27); - return aux_adc_to_volts(_ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); - - case AUX_ADC_B1: - _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC1; - this->send_reg(34); //start conversion and select mux - this->recv_reg(32); //read the value (2 bytes, 2 reads) - this->recv_reg(33); - return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); - case AUX_ADC_B2: - _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC2; - this->send_reg(34); //start conversion and select mux - this->recv_reg(30); //read the value (2 bytes, 2 reads) - this->recv_reg(31); - return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); +double b100_codec_ctrl_impl::read_aux_adc(aux_adc_t which) +{ + switch (which) { + case AUX_ADC_A1: + _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; + this->send_reg(34); // start conversion and select mux + this->recv_reg(28); // read the value (2 bytes, 2 reads) + this->recv_reg(29); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); + case AUX_ADC_A2: + _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC2; + this->send_reg(34); // start conversion and select mux + this->recv_reg(26); // read the value (2 bytes, 2 reads) + this->recv_reg(27); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); + + case AUX_ADC_B1: + _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC1; + this->send_reg(34); // start conversion and select mux + this->recv_reg(32); // read the value (2 bytes, 2 reads) + this->recv_reg(33); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); + case AUX_ADC_B2: + _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC2; + this->send_reg(34); // start conversion and select mux + this->recv_reg(30); // read the value (2 bytes, 2 reads) + this->recv_reg(31); + return aux_adc_to_volts( + _ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); } UHD_THROW_INVALID_CODE_PATH(); } @@ -214,64 +237,64 @@ double b100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ /*********************************************************************** * Codec Control AUX DAC Methods **********************************************************************/ -void b100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){ - //special case for aux dac d (aka sigma delta word) - if (which == AUX_DAC_D){ - uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); +void b100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts) +{ + // special case for aux dac d (aka sigma delta word) + if (which == AUX_DAC_D) { + uint16_t dac_word = uhd::clip(boost::math::iround(volts * 0xfff / 3.3), 0, 0xfff); _ad9862_regs.sig_delt_11_4 = uint8_t(dac_word >> 4); - _ad9862_regs.sig_delt_3_0 = uint8_t(dac_word & 0xf); + _ad9862_regs.sig_delt_3_0 = uint8_t(dac_word & 0xf); this->send_reg(42); this->send_reg(43); return; } - //calculate the dac word for aux dac a, b, c - uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); + // calculate the dac word for aux dac a, b, c + uint8_t dac_word = uhd::clip(boost::math::iround(volts * 0xff / 3.3), 0, 0xff); - //setup a lookup table for the aux dac params (reg ref, reg addr) + // setup a lookup table for the aux dac params (reg ref, reg addr) typedef std::tuple<uint8_t*, uint8_t> dac_params_t; - uhd::dict<aux_dac_t, dac_params_t> aux_dac_to_params = boost::assign::map_list_of - (AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36)) - (AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37)) - (AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)) - ; + uhd::dict<aux_dac_t, dac_params_t> aux_dac_to_params = + boost::assign::map_list_of(AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36))( + AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37))( + AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)); - //set the aux dac register + // set the aux dac register UHD_ASSERT_THROW(aux_dac_to_params.has_key(which)); uint8_t *reg_ref, reg_addr; std::tie(reg_ref, reg_addr) = aux_dac_to_params[which]; - *reg_ref = dac_word; + *reg_ref = dac_word; this->send_reg(reg_addr); } /*********************************************************************** * Codec Control SPI Methods **********************************************************************/ -void b100_codec_ctrl_impl::send_reg(uint8_t addr){ +void b100_codec_ctrl_impl::send_reg(uint8_t addr) +{ uint32_t reg = _ad9862_regs.get_write_reg(addr); - UHD_LOGGER_TRACE("B100") << "codec control write reg: " << std::hex << reg ; + UHD_LOGGER_TRACE("B100") << "codec control write reg: " << std::hex << reg; _iface->transact_spi( - B100_SPI_SS_AD9862, - spi_config_t::EDGE_RISE, - reg, 16, false /*no rb*/ + B100_SPI_SS_AD9862, spi_config_t::EDGE_RISE, reg, 16, false /*no rb*/ ); } -void b100_codec_ctrl_impl::recv_reg(uint8_t addr){ +void b100_codec_ctrl_impl::recv_reg(uint8_t addr) +{ uint32_t reg = _ad9862_regs.get_read_reg(addr); - UHD_LOGGER_TRACE("B100") << "codec control read reg: " << std::hex << reg ; + UHD_LOGGER_TRACE("B100") << "codec control read reg: " << std::hex << reg; uint32_t ret = _iface->transact_spi( - B100_SPI_SS_AD9862, - spi_config_t::EDGE_RISE, - reg, 16, true /*rb*/ + B100_SPI_SS_AD9862, spi_config_t::EDGE_RISE, reg, 16, true /*rb*/ ); - UHD_LOGGER_TRACE("B100") << "codec control read ret: " << std::hex << uint16_t(ret & 0xFF) ; - _ad9862_regs.set_reg(addr, uint8_t(ret&0xff)); + UHD_LOGGER_TRACE("B100") << "codec control read ret: " << std::hex + << uint16_t(ret & 0xFF); + _ad9862_regs.set_reg(addr, uint8_t(ret & 0xff)); } /*********************************************************************** * Codec Control Make **********************************************************************/ -b100_codec_ctrl::sptr b100_codec_ctrl::make(spi_iface::sptr iface){ +b100_codec_ctrl::sptr b100_codec_ctrl::make(spi_iface::sptr iface) +{ return sptr(new b100_codec_ctrl_impl(iface)); } diff --git a/host/lib/usrp/b100/codec_ctrl.hpp b/host/lib/usrp/b100/codec_ctrl.hpp index 5f77d00f9..36714fc60 100644 --- a/host/lib/usrp/b100/codec_ctrl.hpp +++ b/host/lib/usrp/b100/codec_ctrl.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_B100_CODEC_CTRL_HPP #define INCLUDED_B100_CODEC_CTRL_HPP -#include <uhd/types/serial.hpp> #include <uhd/types/ranges.hpp> +#include <uhd/types/serial.hpp> #include <uhd/utils/noncopyable.hpp> #include <memory> @@ -18,7 +18,8 @@ * - Init/power down codec. * - Read aux adc, write aux dac. */ -class b100_codec_ctrl : uhd::noncopyable{ +class b100_codec_ctrl : uhd::noncopyable +{ public: typedef std::shared_ptr<b100_codec_ctrl> sptr; @@ -35,7 +36,7 @@ public: static sptr make(uhd::spi_iface::sptr iface); //! aux adc identifier constants - enum aux_adc_t{ + enum aux_adc_t { AUX_ADC_A2 = 0xA2, AUX_ADC_A1 = 0xA1, AUX_ADC_B2 = 0xB2, @@ -52,11 +53,11 @@ public: virtual double read_aux_adc(aux_adc_t which) = 0; //! aux dac identifier constants - enum aux_dac_t{ + enum aux_dac_t { AUX_DAC_A = 0xA, AUX_DAC_B = 0xB, AUX_DAC_C = 0xC, - AUX_DAC_D = 0xD //really the sigma delta output + AUX_DAC_D = 0xD // really the sigma delta output }; /*! diff --git a/host/lib/usrp/b100/dboard_iface.cpp b/host/lib/usrp/b100/dboard_iface.cpp index 2ea467fe4..627e7a876 100644 --- a/host/lib/usrp/b100/dboard_iface.cpp +++ b/host/lib/usrp/b100/dboard_iface.cpp @@ -8,10 +8,10 @@ #include "b100_regs.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include <uhd/exception.hpp> +#include <uhd/types/dict.hpp> #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_iface.hpp> -#include <uhd/types/dict.hpp> -#include <uhd/exception.hpp> #include <uhdlib/usrp/cores/gpio_core_200.hpp> #include <boost/assign/list_of.hpp> @@ -19,36 +19,37 @@ using namespace uhd; using namespace uhd::usrp; using namespace boost::assign; -class b100_dboard_iface : public dboard_iface{ +class b100_dboard_iface : public dboard_iface +{ public: - - b100_dboard_iface( - timed_wb_iface::sptr wb_iface, + b100_dboard_iface(timed_wb_iface::sptr wb_iface, i2c_iface::sptr i2c_iface, spi_iface::sptr spi_iface, b100_clock_ctrl::sptr clock, - b100_codec_ctrl::sptr codec - ){ - _wb_iface = wb_iface; + b100_codec_ctrl::sptr codec) + { + _wb_iface = wb_iface; _i2c_iface = i2c_iface; _spi_iface = spi_iface; - _clock = clock; - _codec = codec; - _gpio = gpio_core_200::make(_wb_iface, TOREG(SR_GPIO), REG_RB_GPIO); + _clock = clock; + _codec = codec; + _gpio = gpio_core_200::make(_wb_iface, TOREG(SR_GPIO), REG_RB_GPIO); - //init the clock rate shadows + // init the clock rate shadows this->set_clock_rate(UNIT_RX, _clock->get_fpga_clock_rate()); this->set_clock_rate(UNIT_TX, _clock->get_fpga_clock_rate()); } - ~b100_dboard_iface(void){ + ~b100_dboard_iface(void) + { /* NOP */ } - special_props_t get_special_props(void){ + special_props_t get_special_props(void) + { special_props_t props; props.soft_clock_divider = false; - props.mangle_i2c_addrs = false; + props.mangle_i2c_addrs = false; return props; } @@ -57,7 +58,8 @@ public: void set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_pin_ctrl(unit_t unit); - void set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); + void set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_atr_reg(unit_t unit, atr_reg_t reg); void set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_gpio_ddr(unit_t unit); @@ -68,29 +70,22 @@ public: void set_command_time(const uhd::time_spec_t& t); uhd::time_spec_t get_command_time(void); - void write_i2c(uint16_t, const byte_vector_t &); + void write_i2c(uint16_t, const byte_vector_t&); byte_vector_t read_i2c(uint16_t, size_t); void write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); uint32_t read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits); void set_clock_rate(unit_t, double); std::vector<double> get_clock_rates(unit_t); double get_clock_rate(unit_t); void set_clock_enabled(unit_t, bool); double get_codec_rate(unit_t); - void set_fe_connection(unit_t unit, const std::string&, const fe_connection_t& fe_conn); + void set_fe_connection( + unit_t unit, const std::string&, const fe_connection_t& fe_conn); private: timed_wb_iface::sptr _wb_iface; @@ -104,91 +99,123 @@ private: /*********************************************************************** * Make Function **********************************************************************/ -dboard_iface::sptr make_b100_dboard_iface( - timed_wb_iface::sptr wb_iface, +dboard_iface::sptr make_b100_dboard_iface(timed_wb_iface::sptr wb_iface, i2c_iface::sptr i2c_iface, spi_iface::sptr spi_iface, b100_clock_ctrl::sptr clock, - b100_codec_ctrl::sptr codec -){ - return dboard_iface::sptr(new b100_dboard_iface(wb_iface, i2c_iface, spi_iface, clock, codec)); + b100_codec_ctrl::sptr codec) +{ + return dboard_iface::sptr( + new b100_dboard_iface(wb_iface, i2c_iface, spi_iface, clock, codec)); } /*********************************************************************** * Clock Rates **********************************************************************/ -void b100_dboard_iface::set_clock_rate(unit_t unit, double rate){ - switch(unit){ - case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate); - case UNIT_TX: return _clock->set_tx_dboard_clock_rate(rate); - case UNIT_BOTH: set_clock_rate(UNIT_RX, rate); set_clock_rate(UNIT_TX, rate); return; +void b100_dboard_iface::set_clock_rate(unit_t unit, double rate) +{ + switch (unit) { + case UNIT_RX: + return _clock->set_rx_dboard_clock_rate(rate); + case UNIT_TX: + return _clock->set_tx_dboard_clock_rate(rate); + case UNIT_BOTH: + set_clock_rate(UNIT_RX, rate); + set_clock_rate(UNIT_TX, rate); + return; } } -std::vector<double> b100_dboard_iface::get_clock_rates(unit_t unit){ - switch(unit){ - case UNIT_RX: return _clock->get_rx_dboard_clock_rates(); - case UNIT_TX: return _clock->get_tx_dboard_clock_rates(); - default: UHD_THROW_INVALID_CODE_PATH(); +std::vector<double> b100_dboard_iface::get_clock_rates(unit_t unit) +{ + switch (unit) { + case UNIT_RX: + return _clock->get_rx_dboard_clock_rates(); + case UNIT_TX: + return _clock->get_tx_dboard_clock_rates(); + default: + UHD_THROW_INVALID_CODE_PATH(); } } -double b100_dboard_iface::get_clock_rate(unit_t unit){ - switch(unit){ - case UNIT_RX: return _clock->get_rx_clock_rate(); - case UNIT_TX: return _clock->get_tx_clock_rate(); - default: UHD_THROW_INVALID_CODE_PATH(); +double b100_dboard_iface::get_clock_rate(unit_t unit) +{ + switch (unit) { + case UNIT_RX: + return _clock->get_rx_clock_rate(); + case UNIT_TX: + return _clock->get_tx_clock_rate(); + default: + UHD_THROW_INVALID_CODE_PATH(); } } -void b100_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ - switch(unit){ - case UNIT_RX: return _clock->enable_rx_dboard_clock(enb); - case UNIT_TX: return _clock->enable_tx_dboard_clock(enb); - case UNIT_BOTH: set_clock_enabled(UNIT_RX, enb); set_clock_enabled(UNIT_TX, enb); return; +void b100_dboard_iface::set_clock_enabled(unit_t unit, bool enb) +{ + switch (unit) { + case UNIT_RX: + return _clock->enable_rx_dboard_clock(enb); + case UNIT_TX: + return _clock->enable_tx_dboard_clock(enb); + case UNIT_BOTH: + set_clock_enabled(UNIT_RX, enb); + set_clock_enabled(UNIT_TX, enb); + return; } } -double b100_dboard_iface::get_codec_rate(unit_t){ +double b100_dboard_iface::get_codec_rate(unit_t) +{ return _clock->get_fpga_clock_rate(); } /*********************************************************************** * GPIO **********************************************************************/ -void b100_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask){ +void b100_dboard_iface::set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_pin_ctrl(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_pin_ctrl(unit_t unit){ +uint32_t b100_dboard_iface::get_pin_ctrl(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_pin_ctrl(unit)); } -void b100_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask){ - _gpio->set_atr_reg(unit, reg, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); +void b100_dboard_iface::set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask) +{ + _gpio->set_atr_reg( + unit, reg, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg){ +uint32_t b100_dboard_iface::get_atr_reg(unit_t unit, atr_reg_t reg) +{ return static_cast<uint32_t>(_gpio->get_atr_reg(unit, reg)); } -void b100_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask){ +void b100_dboard_iface::set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_gpio_ddr(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_gpio_ddr(unit_t unit){ +uint32_t b100_dboard_iface::get_gpio_ddr(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_gpio_ddr(unit)); } -void b100_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask){ +void b100_dboard_iface::set_gpio_out(unit_t unit, uint32_t value, uint32_t mask) +{ _gpio->set_gpio_out(unit, static_cast<uint16_t>(value), static_cast<uint16_t>(mask)); } -uint32_t b100_dboard_iface::get_gpio_out(unit_t unit){ +uint32_t b100_dboard_iface::get_gpio_out(unit_t unit) +{ return static_cast<uint32_t>(_gpio->get_gpio_out(unit)); } -uint32_t b100_dboard_iface::read_gpio(unit_t unit){ +uint32_t b100_dboard_iface::read_gpio(unit_t unit) +{ return _gpio->read_gpio(unit); } @@ -200,70 +227,64 @@ uint32_t b100_dboard_iface::read_gpio(unit_t unit){ * \param unit the dboard interface unit type enum * \return the slave device number */ -static uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ - switch(unit){ - case dboard_iface::UNIT_TX: return B100_SPI_SS_TX_DB; - case dboard_iface::UNIT_RX: return B100_SPI_SS_RX_DB; - default: UHD_THROW_INVALID_CODE_PATH(); +static uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit) +{ + switch (unit) { + case dboard_iface::UNIT_TX: + return B100_SPI_SS_TX_DB; + case dboard_iface::UNIT_RX: + return B100_SPI_SS_RX_DB; + default: + UHD_THROW_INVALID_CODE_PATH(); } } void b100_dboard_iface::write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ _spi_iface->write_spi(unit_to_otw_spi_dev(unit), config, data, num_bits); } uint32_t b100_dboard_iface::read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ return _spi_iface->read_spi(unit_to_otw_spi_dev(unit), config, data, num_bits); } /*********************************************************************** * I2C **********************************************************************/ -void b100_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t &bytes){ +void b100_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t& bytes) +{ return _i2c_iface->write_i2c(addr, bytes); } -byte_vector_t b100_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes){ +byte_vector_t b100_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes) +{ return _i2c_iface->read_i2c(addr, num_bytes); } /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void b100_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, double value){ - //same aux dacs for each unit - static const uhd::dict<aux_dac_t, b100_codec_ctrl::aux_dac_t> which_to_aux_dac = map_list_of - (AUX_DAC_A, b100_codec_ctrl::AUX_DAC_A) - (AUX_DAC_B, b100_codec_ctrl::AUX_DAC_B) - (AUX_DAC_C, b100_codec_ctrl::AUX_DAC_C) - (AUX_DAC_D, b100_codec_ctrl::AUX_DAC_D) - ; +void b100_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, double value) +{ + // same aux dacs for each unit + static const uhd::dict<aux_dac_t, b100_codec_ctrl::aux_dac_t> which_to_aux_dac = + map_list_of(AUX_DAC_A, b100_codec_ctrl::AUX_DAC_A)( + AUX_DAC_B, b100_codec_ctrl::AUX_DAC_B)(AUX_DAC_C, b100_codec_ctrl::AUX_DAC_C)( + AUX_DAC_D, b100_codec_ctrl::AUX_DAC_D); _codec->write_aux_dac(which_to_aux_dac[which], value); } -double b100_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ - static const uhd::dict< - unit_t, uhd::dict<aux_adc_t, b100_codec_ctrl::aux_adc_t> - > unit_to_which_to_aux_adc = map_list_of - (UNIT_RX, map_list_of - (AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A1) - (AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B1) - ) - (UNIT_TX, map_list_of - (AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A2) - (AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B2) - ) - ; +double b100_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which) +{ + static const uhd::dict<unit_t, uhd::dict<aux_adc_t, b100_codec_ctrl::aux_adc_t>> + unit_to_which_to_aux_adc = map_list_of(UNIT_RX, + map_list_of(AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A1)( + AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B1))(UNIT_TX, + map_list_of(AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A2)( + AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B2)); return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); } @@ -277,7 +298,9 @@ uhd::time_spec_t b100_dboard_iface::get_command_time(void) return _wb_iface->get_time(); } -void b100_dboard_iface::set_fe_connection(unit_t, const std::string&, const fe_connection_t&) +void b100_dboard_iface::set_fe_connection( + unit_t, const std::string&, const fe_connection_t&) { - throw uhd::not_implemented_error("fe connection configuration support not implemented"); + throw uhd::not_implemented_error( + "fe connection configuration support not implemented"); } diff --git a/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp b/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp index 6eed5c813..4a21770b8 100644 --- a/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp +++ b/host/lib/usrp/b100/fifo_ctrl_excelsior.cpp @@ -6,25 +6,25 @@ // #include "fifo_ctrl_excelsior.hpp" -#include <uhdlib/usrp/common/async_packet_handler.hpp> #include <uhd/exception.hpp> -#include <uhd/utils/log.hpp> +#include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/vrt_if_packet.hpp> #include <uhd/utils/byteswap.hpp> -#include <uhd/utils/tasks.hpp> +#include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> +#include <uhd/utils/tasks.hpp> #include <uhd/utils/thread.hpp> -#include <uhd/transport/vrt_if_packet.hpp> -#include <uhd/transport/bounded_buffer.hpp> +#include <uhdlib/usrp/common/async_packet_handler.hpp> #include <mutex> using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -static const size_t POKE32_CMD = (1 << 8); -static const size_t PEEK32_CMD = 0; +static const size_t POKE32_CMD = (1 << 8); +static const size_t PEEK32_CMD = 0; static const double ACK_TIMEOUT = 0.5; -static const double MASSIVE_TIMEOUT = 10.0; //for when we wait on a timed command +static const double MASSIVE_TIMEOUT = 10.0; // for when we wait on a timed command static const uint32_t MAX_SEQS_OUT = 15; #define SPI_DIV _config.spi_base + 0 @@ -32,81 +32,94 @@ static const uint32_t MAX_SEQS_OUT = 15; #define SPI_DATA _config.spi_base + 8 #define SPI_DIVIDER 4 -struct ctrl_result_t{ +struct ctrl_result_t +{ uint32_t msg[2]; }; -class fifo_ctrl_excelsior_impl : public fifo_ctrl_excelsior{ +class fifo_ctrl_excelsior_impl : public fifo_ctrl_excelsior +{ public: - - fifo_ctrl_excelsior_impl(zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config &config): - _xport(xport), - _config(config), - _seq_out(0), - _seq_ack(0), - _timeout(ACK_TIMEOUT), - _async_fifo(1000), - _ctrl_fifo(MAX_SEQS_OUT+1) + fifo_ctrl_excelsior_impl( + zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config& config) + : _xport(xport) + , _config(config) + , _seq_out(0) + , _seq_ack(0) + , _timeout(ACK_TIMEOUT) + , _async_fifo(1000) + , _ctrl_fifo(MAX_SEQS_OUT + 1) { - while (_xport->get_recv_buff(0.0)){} //flush + while (_xport->get_recv_buff(0.0)) { + } // flush this->set_time(uhd::time_spec_t(0.0)); - this->set_tick_rate(1.0); //something possible but bogus - _msg_task = task::make([this](){ this->handle_msg(); }); + this->set_tick_rate(1.0); // something possible but bogus + _msg_task = task::make([this]() { this->handle_msg(); }); this->init_spi(); } - ~fifo_ctrl_excelsior_impl(void){ - _timeout = ACK_TIMEOUT; //reset timeout to something small + ~fifo_ctrl_excelsior_impl(void) + { + _timeout = ACK_TIMEOUT; // reset timeout to something small UHD_SAFE_CALL( - this->peek32(0); //dummy peek with the purpose of ack'ing all packets + this->peek32(0); // dummy peek with the purpose of ack'ing all packets ) } - bool pop_async_msg(async_metadata_t &async_metadata, double timeout){ + bool pop_async_msg(async_metadata_t& async_metadata, double timeout) + { return _async_fifo.pop_with_timed_wait(async_metadata, timeout); } - void handle_msg(void){ + void handle_msg(void) + { managed_recv_buffer::sptr buff = _xport->get_recv_buff(); - if (not buff) return; - const uint32_t *pkt = buff->cast<const uint32_t *>(); + if (not buff) + return; + const uint32_t* pkt = buff->cast<const uint32_t*>(); vrt::if_packet_info_t packet_info; - packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); - try{ + packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); + try { vrt::if_hdr_unpack_le(pkt, packet_info); - } - catch(const std::exception &ex){ + } catch (const std::exception& ex) { UHD_LOGGER_ERROR("UHD") << "FIFO ctrl bad VITA packet: " << ex.what(); } - if (packet_info.has_sid and packet_info.sid == _config.ctrl_sid_base){ + if (packet_info.has_sid and packet_info.sid == _config.ctrl_sid_base) { ctrl_result_t res = ctrl_result_t(); - res.msg[0] = uhd::wtohx(pkt[packet_info.num_header_words32+0]); - res.msg[1] = uhd::wtohx(pkt[packet_info.num_header_words32+1]); + res.msg[0] = uhd::wtohx(pkt[packet_info.num_header_words32 + 0]); + res.msg[1] = uhd::wtohx(pkt[packet_info.num_header_words32 + 1]); _ctrl_fifo.push_with_haste(res); - } - else if (packet_info.has_sid and packet_info.sid >= _config.async_sid_base and packet_info.sid <= _config.async_sid_base + _config.num_async_chan){ + } else if (packet_info.has_sid and packet_info.sid >= _config.async_sid_base + and packet_info.sid + <= _config.async_sid_base + _config.num_async_chan) { async_metadata_t metadata; - load_metadata_from_buff(uhd::wtohx<uint32_t>, metadata, packet_info, pkt, _tick_rate, packet_info.sid - _config.async_sid_base); + load_metadata_from_buff(uhd::wtohx<uint32_t>, + metadata, + packet_info, + pkt, + _tick_rate, + packet_info.sid - _config.async_sid_base); _async_fifo.push_with_pop_on_full(metadata); standard_async_msg_prints(metadata); - } - else{ - UHD_LOGGER_ERROR("UHD") << "FIFO ctrl got unknown SID: " << packet_info.sid ; + } else { + UHD_LOGGER_ERROR("UHD") << "FIFO ctrl got unknown SID: " << packet_info.sid; } } /******************************************************************* * Peek and poke 32 bit implementation ******************************************************************/ - void poke32(const wb_addr_type addr, const uint32_t data){ + void poke32(const wb_addr_type addr, const uint32_t data) + { std::lock_guard<std::mutex> lock(_mutex); this->send_pkt(addr, data, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); } - uint32_t peek32(const wb_addr_type addr){ + uint32_t peek32(const wb_addr_type addr) + { std::lock_guard<std::mutex> lock(_mutex); this->send_pkt(addr, 0, PEEK32_CMD); @@ -117,58 +130,62 @@ public: /******************************************************************* * Peek and poke 16 bit not implemented ******************************************************************/ - void poke16(const wb_addr_type, const uint16_t){ + void poke16(const wb_addr_type, const uint16_t) + { throw uhd::not_implemented_error("poke16 not implemented in fifo ctrl module"); } - uint16_t peek16(const wb_addr_type){ + uint16_t peek16(const wb_addr_type) + { throw uhd::not_implemented_error("peek16 not implemented in fifo ctrl module"); } /******************************************************************* * FIFO controlled SPI implementation ******************************************************************/ - void init_spi(void){ + void init_spi(void) + { std::lock_guard<std::mutex> lock(_mutex); this->send_pkt(SPI_DIV, SPI_DIVIDER, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); _ctrl_word_cache = 0; // force update first time around } - uint32_t transact_spi( - int which_slave, - const spi_config_t &config, + uint32_t transact_spi(int which_slave, + const spi_config_t& config, uint32_t data, size_t num_bits, - bool readback - ){ + bool readback) + { std::lock_guard<std::mutex> lock(_mutex); - //load control word + // load control word uint32_t ctrl_word = 0; ctrl_word |= ((which_slave & 0xffffff) << 0); ctrl_word |= ((num_bits & 0x3ff) << 24); - if (config.mosi_edge == spi_config_t::EDGE_FALL) ctrl_word |= (1 << 31); - if (config.miso_edge == spi_config_t::EDGE_RISE) ctrl_word |= (1 << 30); + if (config.mosi_edge == spi_config_t::EDGE_FALL) + ctrl_word |= (1 << 31); + if (config.miso_edge == spi_config_t::EDGE_RISE) + ctrl_word |= (1 << 30); - //load data word (must be in upper bits) + // load data word (must be in upper bits) const uint32_t data_out = data << (32 - num_bits); - //conditionally send control word - if (_ctrl_word_cache != ctrl_word){ + // conditionally send control word + if (_ctrl_word_cache != ctrl_word) { this->send_pkt(SPI_CTRL, ctrl_word, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); _ctrl_word_cache = ctrl_word; } - //send data word + // send data word this->send_pkt(SPI_DATA, data_out, POKE32_CMD); - this->wait_for_ack(_seq_out-MAX_SEQS_OUT); + this->wait_for_ack(_seq_out - MAX_SEQS_OUT); - //conditional readback - if (readback){ + // conditional readback + if (readback) { this->send_pkt(_config.spi_rb, 0, PEEK32_CMD); return this->wait_for_ack(_seq_out); } @@ -179,11 +196,13 @@ public: /******************************************************************* * Update methods for time ******************************************************************/ - void set_time(const uhd::time_spec_t &time){ + void set_time(const uhd::time_spec_t& time) + { std::lock_guard<std::mutex> lock(_mutex); - _time = time; + _time = time; _use_time = _time != uhd::time_spec_t(0.0); - if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout + if (_use_time) + _timeout = MASSIVE_TIMEOUT; // permanently sets larger timeout } uhd::time_spec_t get_time(void) @@ -192,65 +211,69 @@ public: return _time; } - void set_tick_rate(const double rate){ + void set_tick_rate(const double rate) + { std::lock_guard<std::mutex> lock(_mutex); _tick_rate = rate; } private: - /******************************************************************* * Primary control and interaction private methods ******************************************************************/ - UHD_INLINE void send_pkt(wb_addr_type addr, uint32_t data, int cmd){ + UHD_INLINE void send_pkt(wb_addr_type addr, uint32_t data, int cmd) + { managed_send_buffer::sptr buff = _xport->get_send_buff(); - if (not buff){ + if (not buff) { throw uhd::runtime_error("fifo ctrl timed out getting a send buffer"); } - uint32_t *pkt = buff->cast<uint32_t *>(); + uint32_t* pkt = buff->cast<uint32_t*>(); - //load packet info + // load packet info vrt::if_packet_info_t packet_info; - packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; + packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; packet_info.num_payload_words32 = 2; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); + packet_info.num_payload_bytes = + packet_info.num_payload_words32 * sizeof(uint32_t); packet_info.packet_count = ++_seq_out; - packet_info.tsf = _time.to_ticks(_tick_rate); - packet_info.sob = false; - packet_info.eob = false; - packet_info.has_sid = false; - packet_info.has_cid = false; - packet_info.has_tsi = false; - packet_info.has_tsf = _use_time; - packet_info.has_tlr = false; - - //load header + packet_info.tsf = _time.to_ticks(_tick_rate); + packet_info.sob = false; + packet_info.eob = false; + packet_info.has_sid = false; + packet_info.has_cid = false; + packet_info.has_tsi = false; + packet_info.has_tsf = _use_time; + packet_info.has_tlr = false; + + // load header vrt::if_hdr_pack_le(pkt, packet_info); - //load payload - const uint32_t ctrl_word = (addr/4 & 0xff) | cmd | (_seq_out << 16); - pkt[packet_info.num_header_words32+0] = uhd::htowx(ctrl_word); - pkt[packet_info.num_header_words32+1] = uhd::htowx(data); + // load payload + const uint32_t ctrl_word = (addr / 4 & 0xff) | cmd | (_seq_out << 16); + pkt[packet_info.num_header_words32 + 0] = uhd::htowx(ctrl_word); + pkt[packet_info.num_header_words32 + 1] = uhd::htowx(data); - //send the buffer over the interface - buff->commit(sizeof(uint32_t)*(packet_info.num_packet_words32)); + // send the buffer over the interface + buff->commit(sizeof(uint32_t) * (packet_info.num_packet_words32)); } - UHD_INLINE bool wraparound_lt16(const int16_t i0, const int16_t i1){ - if (((i0 ^ i1) & 0x8000) == 0) //same sign bits + UHD_INLINE bool wraparound_lt16(const int16_t i0, const int16_t i1) + { + if (((i0 ^ i1) & 0x8000) == 0) // same sign bits return uint16_t(i0) < uint16_t(i1); return int16_t(i1 - i0) > 0; } - UHD_INLINE uint32_t wait_for_ack(const uint16_t seq_to_ack){ - - while (wraparound_lt16(_seq_ack, seq_to_ack)){ + UHD_INLINE uint32_t wait_for_ack(const uint16_t seq_to_ack) + { + while (wraparound_lt16(_seq_ack, seq_to_ack)) { ctrl_result_t res = ctrl_result_t(); - if (not _ctrl_fifo.pop_with_timed_wait(res, _timeout)){ + if (not _ctrl_fifo.pop_with_timed_wait(res, _timeout)) { throw uhd::runtime_error("fifo ctrl timed out looking for acks"); } _seq_ack = res.msg[0] >> 16; - if (_seq_ack == seq_to_ack) return res.msg[1]; + if (_seq_ack == seq_to_ack) + return res.msg[1]; } return 0; @@ -272,7 +295,8 @@ private: }; -fifo_ctrl_excelsior::sptr fifo_ctrl_excelsior::make(zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config &config) +fifo_ctrl_excelsior::sptr fifo_ctrl_excelsior::make( + zero_copy_if::sptr xport, const fifo_ctrl_excelsior_config& config) { return sptr(new fifo_ctrl_excelsior_impl(xport, config)); } diff --git a/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp b/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp index 27da0026c..69b2dd4fc 100644 --- a/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp +++ b/host/lib/usrp/b100/fifo_ctrl_excelsior.hpp @@ -8,13 +8,13 @@ #ifndef INCLUDED_B200_CTRL_HPP #define INCLUDED_B200_CTRL_HPP -#include <uhd/types/time_spec.hpp> +#include <uhd/transport/zero_copy.hpp> #include <uhd/types/metadata.hpp> #include <uhd/types/serial.hpp> -#include <uhd/transport/zero_copy.hpp> -#include <memory> -#include <boost/utility.hpp> +#include <uhd/types/time_spec.hpp> #include <uhd/types/wb_iface.hpp> +#include <boost/utility.hpp> +#include <memory> #include <string> @@ -36,16 +36,14 @@ public: typedef std::shared_ptr<fifo_ctrl_excelsior> sptr; //! Make a new control object - static sptr make( - uhd::transport::zero_copy_if::sptr xport, - const fifo_ctrl_excelsior_config &config - ); + static sptr make(uhd::transport::zero_copy_if::sptr xport, + const fifo_ctrl_excelsior_config& config); //! Set the tick rate (converting time into ticks) virtual void set_tick_rate(const double rate) = 0; //! Pop an async message from the queue or timeout - virtual bool pop_async_msg(uhd::async_metadata_t &async_metadata, double timeout) = 0; + virtual bool pop_async_msg(uhd::async_metadata_t& async_metadata, double timeout) = 0; }; #endif /* INCLUDED_B200_CTRL_HPP */ diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index c50327271..8aad480e7 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -19,146 +19,169 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -void b100_impl::update_rates(void){ +void b100_impl::update_rates(void) +{ const fs_path mb_path = "/mboards/0"; _tree->access<double>(mb_path / "tick_rate").update(); - //and now that the tick rate is set, init the host rates to something - for(const std::string &name: _tree->list(mb_path / "rx_dsps")){ + // and now that the tick rate is set, init the host rates to something + for (const std::string& name : _tree->list(mb_path / "rx_dsps")) { _tree->access<double>(mb_path / "rx_dsps" / name / "rate" / "value").update(); } - for(const std::string &name: _tree->list(mb_path / "tx_dsps")){ + for (const std::string& name : _tree->list(mb_path / "tx_dsps")) { _tree->access<double>(mb_path / "tx_dsps" / name / "rate" / "value").update(); } } -void b100_impl::update_tick_rate(const double rate){ - - //update the tick rate on all existing streamers -> thread safe - for (size_t i = 0; i < _rx_streamers.size(); i++){ +void b100_impl::update_tick_rate(const double rate) +{ + // update the tick rate on all existing streamers -> thread safe + for (size_t i = 0; i < _rx_streamers.size(); i++) { std::shared_ptr<sph::recv_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::recv_packet_streamer>(_rx_streamers[i].lock()); - if (my_streamer.get() == NULL) continue; + if (my_streamer.get() == NULL) + continue; my_streamer->set_tick_rate(rate); } - for (size_t i = 0; i < _tx_streamers.size(); i++){ + for (size_t i = 0; i < _tx_streamers.size(); i++) { std::shared_ptr<sph::send_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::send_packet_streamer>(_tx_streamers[i].lock()); - if (my_streamer.get() == NULL) continue; + if (my_streamer.get() == NULL) + continue; my_streamer->set_tick_rate(rate); } } -void b100_impl::update_rx_samp_rate(const size_t dspno, const double rate){ +void b100_impl::update_rx_samp_rate(const size_t dspno, const double rate) +{ std::shared_ptr<sph::recv_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::recv_packet_streamer>(_rx_streamers[dspno].lock()); - if (my_streamer.get() == NULL) return; + if (my_streamer.get() == NULL) + return; my_streamer->set_samp_rate(rate); const double adj = _rx_dsps[dspno]->get_scaling_adjustment(); my_streamer->set_scale_factor(adj); } -void b100_impl::update_tx_samp_rate(const size_t dspno, const double rate){ +void b100_impl::update_tx_samp_rate(const size_t dspno, const double rate) +{ std::shared_ptr<sph::send_packet_streamer> my_streamer = std::dynamic_pointer_cast<sph::send_packet_streamer>(_tx_streamers[dspno].lock()); - if (my_streamer.get() == NULL) return; + if (my_streamer.get() == NULL) + return; my_streamer->set_samp_rate(rate); const double adj = _tx_dsp->get_scaling_adjustment(); my_streamer->set_scale_factor(adj); } -void b100_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ +void b100_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t& spec) +{ fs_path root = "/mboards/0/dboards"; - //sanity checking + // sanity checking validate_subdev_spec(_tree, spec, "rx"); - //setup mux for this spec + // setup mux for this spec bool fe_swapped = false; - for (size_t i = 0; i < spec.size(); i++){ - const std::string conn = _tree->access<std::string>(root / spec[i].db_name / "rx_frontends" / spec[i].sd_name / "connection").get(); - if (i == 0 and (conn == "QI" or conn == "Q")) fe_swapped = true; + for (size_t i = 0; i < spec.size(); i++) { + const std::string conn = + _tree + ->access<std::string>(root / spec[i].db_name / "rx_frontends" + / spec[i].sd_name / "connection") + .get(); + if (i == 0 and (conn == "QI" or conn == "Q")) + fe_swapped = true; _rx_dsps[i]->set_mux(conn, fe_swapped); } _rx_fe->set_mux(fe_swapped); } -void b100_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){ +void b100_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t& spec) +{ fs_path root = "/mboards/0/dboards"; - //sanity checking + // sanity checking validate_subdev_spec(_tree, spec, "tx"); - //set the mux for this spec - const std::string conn = _tree->access<std::string>(root / spec[0].db_name / "tx_frontends" / spec[0].sd_name / "connection").get(); + // set the mux for this spec + const std::string conn = + _tree + ->access<std::string>( + root / spec[0].db_name / "tx_frontends" / spec[0].sd_name / "connection") + .get(); _tx_fe->set_mux(conn); } /*********************************************************************** * Async Data **********************************************************************/ -bool b100_impl::recv_async_msg( - async_metadata_t &async_metadata, double timeout -){ +bool b100_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout) +{ return _fifo_ctrl->pop_async_msg(async_metadata, timeout); } /*********************************************************************** * Receive streamer **********************************************************************/ -rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ +rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; - - //calculate packet size - static const size_t hdr_size = 0 - + vrt::max_if_hdr_words32*sizeof(uint32_t) - + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used - ; + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels; + + // calculate packet size + static const size_t hdr_size = + 0 + vrt::max_if_hdr_words32 * sizeof(uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer + - sizeof(vrt::if_packet_info_t().cid) // no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used + ; const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size; const size_t bpi = convert::get_bytes_per_item(args.otw_format); - const size_t spp = unsigned(args.args.cast<double>("spp", bpp/bpi)); + const size_t spp = unsigned(args.args.cast<double>("spp", bpp / bpi)); - //make the new streamer given the samples per packet - std::shared_ptr<sph::recv_packet_streamer> my_streamer = std::make_shared<sph::recv_packet_streamer>(spp); + // make the new streamer given the samples per packet + std::shared_ptr<sph::recv_packet_streamer> my_streamer = + std::make_shared<sph::recv_packet_streamer>(spp); - //init some streamer stuff + // init some streamer stuff my_streamer->resize(args.channels.size()); my_streamer->set_vrt_unpacker(&vrt::if_hdr_unpack_le); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.otw_format + "_item32_le"; - id.num_inputs = 1; + id.input_format = args.otw_format + "_item32_le"; + id.num_inputs = 1; id.output_format = args.cpu_format; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); - //bind callbacks for the handler - for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ + // bind callbacks for the handler + for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) { const size_t dsp = args.channels[chan_i]; - _rx_dsps[dsp]->set_nsamps_per_packet(spp); //seems to be a good place to set this + _rx_dsps[dsp]->set_nsamps_per_packet(spp); // seems to be a good place to set this _rx_dsps[dsp]->setup(args); _recv_demuxer->realloc_sid(B100_RX_SID_BASE + dsp); - my_streamer->set_xport_chan_get_buff(chan_i, std::bind( - &recv_packet_demuxer_3000::get_recv_buff, _recv_demuxer, B100_RX_SID_BASE + dsp, std::placeholders::_1 - ), true /*flush*/); - my_streamer->set_overflow_handler(chan_i, std::bind( - &rx_dsp_core_200::handle_overflow, _rx_dsps[dsp] - )); - my_streamer->set_issue_stream_cmd(chan_i, std::bind( - &rx_dsp_core_200::issue_stream_command, _rx_dsps[dsp], std::placeholders::_1)); - _rx_streamers[dsp] = my_streamer; //store weak pointer + my_streamer->set_xport_chan_get_buff(chan_i, + std::bind(&recv_packet_demuxer_3000::get_recv_buff, + _recv_demuxer, + B100_RX_SID_BASE + dsp, + std::placeholders::_1), + true /*flush*/); + my_streamer->set_overflow_handler( + chan_i, std::bind(&rx_dsp_core_200::handle_overflow, _rx_dsps[dsp])); + my_streamer->set_issue_stream_cmd(chan_i, + std::bind(&rx_dsp_core_200::issue_stream_command, + _rx_dsps[dsp], + std::placeholders::_1)); + _rx_streamers[dsp] = my_streamer; // store weak pointer } - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; @@ -167,52 +190,57 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){ /*********************************************************************** * Transmit streamer **********************************************************************/ -tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){ +tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t& args_) +{ stream_args_t args = args_; - //setup defaults for unspecified values - args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format; - args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; - - //calculate packet size - static const size_t hdr_size = 0 - + vrt::max_if_hdr_words32*sizeof(uint32_t) - + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used - ; + // setup defaults for unspecified values + args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format; + args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels; + + // calculate packet size + static const size_t hdr_size = + 0 + vrt::max_if_hdr_words32 * sizeof(uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer + - sizeof(vrt::if_packet_info_t().sid) // no stream id ever used + - sizeof(vrt::if_packet_info_t().cid) // no class id ever used + - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used + ; static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; - const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); + const size_t spp = bpp / convert::get_bytes_per_item(args.otw_format); - //make the new streamer given the samples per packet - std::shared_ptr<sph::send_packet_streamer> my_streamer = std::make_shared<sph::send_packet_streamer>(spp); + // make the new streamer given the samples per packet + std::shared_ptr<sph::send_packet_streamer> my_streamer = + std::make_shared<sph::send_packet_streamer>(spp); - //init some streamer stuff + // init some streamer stuff my_streamer->resize(args.channels.size()); my_streamer->set_vrt_packer(&vrt::if_hdr_pack_le); - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.cpu_format; - id.num_inputs = 1; + id.input_format = args.cpu_format; + id.num_inputs = 1; id.output_format = args.otw_format + "_item32_le"; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); - //bind callbacks for the handler - for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){ + // bind callbacks for the handler + for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) { const size_t dsp = args.channels[chan_i]; - UHD_ASSERT_THROW(dsp == 0); //always 0 + UHD_ASSERT_THROW(dsp == 0); // always 0 _tx_dsp->setup(args); - my_streamer->set_xport_chan_get_buff(chan_i, std::bind( - &zero_copy_if::get_send_buff, _data_transport, std::placeholders::_1 - )); - my_streamer->set_async_receiver(std::bind(&fifo_ctrl_excelsior::pop_async_msg, _fifo_ctrl, std::placeholders::_1, std::placeholders::_2)); - _tx_streamers[dsp] = my_streamer; //store weak pointer + my_streamer->set_xport_chan_get_buff(chan_i, + std::bind( + &zero_copy_if::get_send_buff, _data_transport, std::placeholders::_1)); + my_streamer->set_async_receiver(std::bind(&fifo_ctrl_excelsior::pop_async_msg, + _fifo_ctrl, + std::placeholders::_1, + std::placeholders::_2)); + _tx_streamers[dsp] = my_streamer; // store weak pointer } - //sets all tick and samp rates on this streamer + // sets all tick and samp rates on this streamer this->update_rates(); return my_streamer; diff --git a/host/lib/usrp/b100/mb_eeprom.cpp b/host/lib/usrp/b100/mb_eeprom.cpp index 3e46d7d1f..2be09891f 100644 --- a/host/lib/usrp/b100/mb_eeprom.cpp +++ b/host/lib/usrp/b100/mb_eeprom.cpp @@ -5,21 +5,22 @@ // #include "b100_impl.hpp" -#include <uhdlib/utils/eeprom_utils.hpp> #include <uhd/usrp/mboard_eeprom.hpp> +#include <uhdlib/utils/eeprom_utils.hpp> namespace { - const uint8_t B100_EEPROM_ADDR = 0x50; +const uint8_t B100_EEPROM_ADDR = 0x50; - //use char array so we dont need to attribute packed - struct b100_eeprom_map{ - unsigned char _r[220]; - unsigned char revision[2]; - unsigned char product[2]; - unsigned char name[NAME_MAX_LEN]; - unsigned char serial[SERIAL_LEN]; - }; -} +// use char array so we dont need to attribute packed +struct b100_eeprom_map +{ + unsigned char _r[220]; + unsigned char revision[2]; + unsigned char product[2]; + unsigned char name[NAME_MAX_LEN]; + unsigned char serial[SERIAL_LEN]; +}; +} // namespace using namespace uhd; using uhd::usrp::mboard_eeprom_t; @@ -28,64 +29,50 @@ mboard_eeprom_t b100_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) { mboard_eeprom_t mb_eeprom; - //extract the revision number + // extract the revision number mb_eeprom["revision"] = uint16_bytes_to_string( - iface->read_eeprom( - B100_EEPROM_ADDR, - offsetof(b100_eeprom_map, revision), - 2 - ) - ); + iface->read_eeprom(B100_EEPROM_ADDR, offsetof(b100_eeprom_map, revision), 2)); - //extract the product code + // extract the product code mb_eeprom["product"] = uint16_bytes_to_string( - iface->read_eeprom( - B100_EEPROM_ADDR, - offsetof(b100_eeprom_map, product), - 2 - ) - ); + iface->read_eeprom(B100_EEPROM_ADDR, offsetof(b100_eeprom_map, product), 2)); - //extract the serial + // extract the serial mb_eeprom["serial"] = bytes_to_string(iface->read_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, serial), SERIAL_LEN - )); + B100_EEPROM_ADDR, offsetof(b100_eeprom_map, serial), SERIAL_LEN)); - //extract the name + // extract the name mb_eeprom["name"] = bytes_to_string(iface->read_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, name), NAME_MAX_LEN - )); + B100_EEPROM_ADDR, offsetof(b100_eeprom_map, name), NAME_MAX_LEN)); return mb_eeprom; } -void b100_impl::set_mb_eeprom( - const uhd::usrp::mboard_eeprom_t &mb_eeprom -) { - auto &iface = _fx2_ctrl; - - //parse the revision number - if (mb_eeprom.has_key("revision")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, revision), - string_to_uint16_bytes(mb_eeprom["revision"]) - ); - - //parse the product code - if (mb_eeprom.has_key("product")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, product), - string_to_uint16_bytes(mb_eeprom["product"]) - ); +void b100_impl::set_mb_eeprom(const uhd::usrp::mboard_eeprom_t& mb_eeprom) +{ + auto& iface = _fx2_ctrl; - //store the serial - if (mb_eeprom.has_key("serial")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, serial), - string_to_bytes(mb_eeprom["serial"], SERIAL_LEN) - ); + // parse the revision number + if (mb_eeprom.has_key("revision")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, revision), + string_to_uint16_bytes(mb_eeprom["revision"])); - //store the name - if (mb_eeprom.has_key("name")) iface->write_eeprom( - B100_EEPROM_ADDR, offsetof(b100_eeprom_map, name), - string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN) - ); + // parse the product code + if (mb_eeprom.has_key("product")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, product), + string_to_uint16_bytes(mb_eeprom["product"])); + + // store the serial + if (mb_eeprom.has_key("serial")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, serial), + string_to_bytes(mb_eeprom["serial"], SERIAL_LEN)); + + // store the name + if (mb_eeprom.has_key("name")) + iface->write_eeprom(B100_EEPROM_ADDR, + offsetof(b100_eeprom_map, name), + string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)); } - diff --git a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp index 8059c2a0d..908841462 100644 --- a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp +++ b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp @@ -21,42 +21,52 @@ using namespace uhd; using namespace uhd::transport; -static const boost::posix_time::time_duration AUTOFLUSH_TIMEOUT(boost::posix_time::milliseconds(1)); +static const boost::posix_time::time_duration AUTOFLUSH_TIMEOUT( + boost::posix_time::milliseconds(1)); /*********************************************************************** * USB zero copy wrapper - managed receive buffer **********************************************************************/ -class usb_zero_copy_wrapper_mrb : public managed_recv_buffer{ +class usb_zero_copy_wrapper_mrb : public managed_recv_buffer +{ public: - usb_zero_copy_wrapper_mrb(void){/*NOP*/} + usb_zero_copy_wrapper_mrb(void) + { /*NOP*/ + } - void release(void){ - _mrb.reset(); //decrement ref count, other MRB's may hold a ref + void release(void) + { + _mrb.reset(); // decrement ref count, other MRB's may hold a ref _claimer.release(); } - UHD_INLINE sptr get_new( - managed_recv_buffer::sptr &mrb, size_t &offset_bytes, - const double timeout, size_t &index - ){ - if (not mrb or not _claimer.claim_with_wait(timeout)) return sptr(); + UHD_INLINE sptr get_new(managed_recv_buffer::sptr& mrb, + size_t& offset_bytes, + const double timeout, + size_t& index) + { + if (not mrb or not _claimer.claim_with_wait(timeout)) + return sptr(); - index++; //advances the caller's buffer + index++; // advances the caller's buffer - //hold a copy of the buffer shared pointer + // hold a copy of the buffer shared pointer UHD_ASSERT_THROW(not _mrb); _mrb = mrb; - //extract this packet's memory address and length in bytes - char *mem = mrb->cast<char *>() + offset_bytes; - const uint32_t *mem32 = reinterpret_cast<const uint32_t *>(mem); - const size_t words32 = (uhd::wtohx(mem32[0]) & 0xffff); //length in words32 (from VRT header) - const size_t len = words32*sizeof(uint32_t); //length in bytes + // extract this packet's memory address and length in bytes + char* mem = mrb->cast<char*>() + offset_bytes; + const uint32_t* mem32 = reinterpret_cast<const uint32_t*>(mem); + const size_t words32 = + (uhd::wtohx(mem32[0]) & 0xffff); // length in words32 (from VRT header) + const size_t len = words32 * sizeof(uint32_t); // length in bytes - //check if this receive buffer has been exhausted + // check if this receive buffer has been exhausted offset_bytes += len; - if (offset_bytes >= mrb->size()) mrb.reset(); //drop caller's ref - else if (uhd::wtohx(mem32[words32]) == 0) mrb.reset(); + if (offset_bytes >= mrb->size()) + mrb.reset(); // drop caller's ref + else if (uhd::wtohx(mem32[words32]) == 0) + mrb.reset(); return make(this, mem, len); } @@ -69,10 +79,12 @@ private: /*********************************************************************** * USB zero copy wrapper - managed send buffer **********************************************************************/ -class usb_zero_copy_wrapper_msb : public managed_send_buffer{ +class usb_zero_copy_wrapper_msb : public managed_send_buffer +{ public: - usb_zero_copy_wrapper_msb(const zero_copy_if::sptr internal, const size_t fragmentation_size): - _internal(internal), _fragmentation_size(fragmentation_size) + usb_zero_copy_wrapper_msb( + const zero_copy_if::sptr internal, const size_t fragmentation_size) + : _internal(internal), _fragmentation_size(fragmentation_size) { _ok_to_auto_flush = false; _task = uhd::task::make(std::bind(&usb_zero_copy_wrapper_msb::auto_flush, this)); @@ -80,40 +92,46 @@ public: ~usb_zero_copy_wrapper_msb(void) { - //ensure the task has exited before anything auto deconstructs + // ensure the task has exited before anything auto deconstructs _task.reset(); } - void release(void){ + void release(void) + { boost::mutex::scoped_lock lock(_mutex); _ok_to_auto_flush = true; - //get a reference to the VITA header before incrementing - const uint32_t vita_header = reinterpret_cast<const uint32_t *>(_mem_buffer_tip)[0]; + // get a reference to the VITA header before incrementing + const uint32_t vita_header = + reinterpret_cast<const uint32_t*>(_mem_buffer_tip)[0]; _bytes_in_buffer += size(); _mem_buffer_tip += size(); - //extract VITA end of packet flag, we must force flush under eof conditions - const bool eop = (uhd::wtohx(vita_header) & (0x1 << 24)) != 0; - const bool full = _bytes_in_buffer >= (_last_send_buff->size() - _fragmentation_size); - if (eop or full){ + // extract VITA end of packet flag, we must force flush under eof conditions + const bool eop = (uhd::wtohx(vita_header) & (0x1 << 24)) != 0; + const bool full = _bytes_in_buffer + >= (_last_send_buff->size() - _fragmentation_size); + if (eop or full) { _last_send_buff->commit(_bytes_in_buffer); _last_send_buff.reset(); - //notify the auto-flusher to restart its timed_wait - lock.unlock(); _cond.notify_one(); + // notify the auto-flusher to restart its timed_wait + lock.unlock(); + _cond.notify_one(); } } - UHD_INLINE sptr get_new(const double timeout){ + UHD_INLINE sptr get_new(const double timeout) + { boost::mutex::scoped_lock lock(_mutex); _ok_to_auto_flush = false; - if (not _last_send_buff){ + if (not _last_send_buff) { _last_send_buff = _internal->get_send_buff(timeout); - if (not _last_send_buff) return sptr(); - _mem_buffer_tip = _last_send_buff->cast<char *>(); + if (not _last_send_buff) + return sptr(); + _mem_buffer_tip = _last_send_buff->cast<char*>(); _bytes_in_buffer = 0; } @@ -125,9 +143,9 @@ private: const size_t _fragmentation_size; managed_send_buffer::sptr _last_send_buff; size_t _bytes_in_buffer; - char *_mem_buffer_tip; + char* _mem_buffer_tip; - //private variables for auto flusher + // private variables for auto flusher boost::mutex _mutex; boost::condition_variable _cond; uhd::task::sptr _task; @@ -141,8 +159,7 @@ private: { boost::mutex::scoped_lock lock(_mutex); const bool timeout = not _cond.timed_wait(lock, AUTOFLUSH_TIMEOUT); - if (timeout and _ok_to_auto_flush and _last_send_buff and _bytes_in_buffer != 0) - { + if (timeout and _ok_to_auto_flush and _last_send_buff and _bytes_in_buffer != 0) { _last_send_buff->commit(_bytes_in_buffer); _last_send_buff.reset(); } @@ -152,69 +169,78 @@ private: /*********************************************************************** * USB zero copy wrapper implementation **********************************************************************/ -class usb_zero_copy_wrapper : public usb_zero_copy{ +class usb_zero_copy_wrapper : public usb_zero_copy +{ public: - usb_zero_copy_wrapper(zero_copy_if::sptr usb_zc, const size_t frame_boundary): - _internal_zc(usb_zc), - _frame_boundary(frame_boundary), - _last_recv_offset(0), - _next_recv_buff_index(0) + usb_zero_copy_wrapper(zero_copy_if::sptr usb_zc, const size_t frame_boundary) + : _internal_zc(usb_zc) + , _frame_boundary(frame_boundary) + , _last_recv_offset(0) + , _next_recv_buff_index(0) { - for (size_t i = 0; i < this->get_num_recv_frames(); i++){ + for (size_t i = 0; i < this->get_num_recv_frames(); i++) { _mrb_pool.push_back(std::make_shared<usb_zero_copy_wrapper_mrb>()); } - _the_only_msb = std::make_shared<usb_zero_copy_wrapper_msb>(usb_zc, frame_boundary); + _the_only_msb = + std::make_shared<usb_zero_copy_wrapper_msb>(usb_zc, frame_boundary); } - managed_recv_buffer::sptr get_recv_buff(double timeout){ - //lazy flush mechanism - negative timeout - if (timeout < 0.0) - { + managed_recv_buffer::sptr get_recv_buff(double timeout) + { + // lazy flush mechanism - negative timeout + if (timeout < 0.0) { _last_recv_buff.reset(); - while (_internal_zc->get_recv_buff()){} + while (_internal_zc->get_recv_buff()) { + } return managed_recv_buffer::sptr(); } - //attempt to get a managed recv buffer - if (not _last_recv_buff){ - _last_recv_buff = _internal_zc->get_recv_buff(timeout); - _last_recv_offset = 0; //reset offset into buffer + // attempt to get a managed recv buffer + if (not _last_recv_buff) { + _last_recv_buff = _internal_zc->get_recv_buff(timeout); + _last_recv_offset = 0; // reset offset into buffer } - //get the buffer to be returned to the user - if (_next_recv_buff_index == _mrb_pool.size()) _next_recv_buff_index = 0; + // get the buffer to be returned to the user + if (_next_recv_buff_index == _mrb_pool.size()) + _next_recv_buff_index = 0; return _mrb_pool[_next_recv_buff_index]->get_new( - _last_recv_buff, _last_recv_offset, timeout, _next_recv_buff_index - ); + _last_recv_buff, _last_recv_offset, timeout, _next_recv_buff_index); } - size_t get_num_recv_frames(void) const{ - return (_internal_zc->get_num_recv_frames()*_internal_zc->get_recv_frame_size())/this->get_recv_frame_size(); + size_t get_num_recv_frames(void) const + { + return (_internal_zc->get_num_recv_frames() * _internal_zc->get_recv_frame_size()) + / this->get_recv_frame_size(); } - size_t get_recv_frame_size(void) const{ + size_t get_recv_frame_size(void) const + { return std::min(_frame_boundary, _internal_zc->get_recv_frame_size()); } - managed_send_buffer::sptr get_send_buff(double timeout){ + managed_send_buffer::sptr get_send_buff(double timeout) + { return _the_only_msb->get_new(timeout); } - size_t get_num_send_frames(void) const{ + size_t get_num_send_frames(void) const + { return _internal_zc->get_num_send_frames(); } - size_t get_send_frame_size(void) const{ + size_t get_send_frame_size(void) const + { return std::min(_frame_boundary, _internal_zc->get_send_frame_size()); } private: zero_copy_if::sptr _internal_zc; size_t _frame_boundary; - std::vector<std::shared_ptr<usb_zero_copy_wrapper_mrb> > _mrb_pool; + std::vector<std::shared_ptr<usb_zero_copy_wrapper_mrb>> _mrb_pool; std::shared_ptr<usb_zero_copy_wrapper_msb> _the_only_msb; - //state for last recv buffer to create multiple managed buffers + // state for last recv buffer to create multiple managed buffers managed_recv_buffer::sptr _last_recv_buff; size_t _last_recv_offset; size_t _next_recv_buff_index; @@ -224,7 +250,7 @@ private: * USB zero copy wrapper factory function **********************************************************************/ zero_copy_if::sptr usb_zero_copy_make_wrapper( - zero_copy_if::sptr usb_zc, size_t usb_frame_boundary -){ + zero_copy_if::sptr usb_zc, size_t usb_frame_boundary) +{ return zero_copy_if::sptr(new usb_zero_copy_wrapper(usb_zc, usb_frame_boundary)); } |