aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2012-03-01 15:59:40 -0800
committerJosh Blum <josh@joshknows.com>2012-03-23 14:36:56 -0700
commitf59ef44a43d0d16655cb67a3d0334e8cacd76f09 (patch)
tree0f7fb004ca2f3c304ce0a9361ba52f2ae09e49a1 /host/lib/usrp
parentcda81f584ca36dffeb8d2184f5769f9c8b9ab4eb (diff)
downloaduhd-f59ef44a43d0d16655cb67a3d0334e8cacd76f09.tar.gz
uhd-f59ef44a43d0d16655cb67a3d0334e8cacd76f09.tar.bz2
uhd-f59ef44a43d0d16655cb67a3d0334e8cacd76f09.zip
usrp2: integrated fifo ctrl into usrp2 modules, implemented window'd acking
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp48
-rw-r--r--host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp48
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp33
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp12
4 files changed, 76 insertions, 65 deletions
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index bc510c8a1..edd9ef242 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
//
#include "gpio_core_200.hpp"
-#include "usrp2_iface.hpp"
+#include <uhd/types/serial.hpp>
#include "clock_ctrl.hpp"
#include "usrp2_regs.hpp" //wishbone address constants
#include <uhd/usrp/dboard_iface.hpp>
@@ -35,7 +35,12 @@ using namespace boost::assign;
class usrp2_dboard_iface : public dboard_iface{
public:
- usrp2_dboard_iface(usrp2_iface::sptr iface, usrp2_clock_ctrl::sptr clock_ctrl);
+ usrp2_dboard_iface(
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
+ usrp2_clock_ctrl::sptr clock_ctrl
+ );
~usrp2_dboard_iface(void);
special_props_t get_special_props(void){
@@ -79,7 +84,8 @@ public:
);
private:
- usrp2_iface::sptr _iface;
+ uhd::i2c_iface::sptr _i2c_iface;
+ uhd::spi_iface::sptr _spi_iface;
usrp2_clock_ctrl::sptr _clock_ctrl;
gpio_core_200::sptr _gpio;
@@ -92,22 +98,28 @@ private:
* Make Function
**********************************************************************/
dboard_iface::sptr make_usrp2_dboard_iface(
- usrp2_iface::sptr iface,
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
usrp2_clock_ctrl::sptr clock_ctrl
){
- return dboard_iface::sptr(new usrp2_dboard_iface(iface, clock_ctrl));
+ return dboard_iface::sptr(new usrp2_dboard_iface(wb_iface, i2c_iface, spi_iface, clock_ctrl));
}
/***********************************************************************
* Structors
**********************************************************************/
usrp2_dboard_iface::usrp2_dboard_iface(
- usrp2_iface::sptr iface,
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
usrp2_clock_ctrl::sptr clock_ctrl
-){
- _iface = iface;
- _clock_ctrl = clock_ctrl;
- _gpio = gpio_core_200::make(_iface, U2_REG_SR_ADDR(SR_GPIO), U2_REG_GPIO_RB);
+):
+ _i2c_iface(i2c_iface),
+ _spi_iface(spi_iface),
+ _clock_ctrl(clock_ctrl)
+{
+ _gpio = gpio_core_200::make(wb_iface, U2_REG_SR_ADDR(SR_GPIO), U2_REG_GPIO_RB);
//reset the aux dacs
_dac_regs[UNIT_RX] = ad5623_regs_t();
@@ -202,7 +214,7 @@ void usrp2_dboard_iface::write_spi(
boost::uint32_t data,
size_t num_bits
){
- _iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits);
+ _spi_iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits);
}
boost::uint32_t usrp2_dboard_iface::read_write_spi(
@@ -211,18 +223,18 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(
boost::uint32_t data,
size_t num_bits
){
- return _iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits);
+ return _spi_iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits);
}
/***********************************************************************
* I2C
**********************************************************************/
void usrp2_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){
- return _iface->write_i2c(addr, bytes);
+ return _i2c_iface->write_i2c(addr, bytes);
}
byte_vector_t usrp2_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){
- return _iface->read_i2c(addr, num_bytes);
+ return _i2c_iface->read_i2c(addr, num_bytes);
}
/***********************************************************************
@@ -233,7 +245,7 @@ void usrp2_dboard_iface::_write_aux_dac(unit_t unit){
(UNIT_RX, SPI_SS_RX_DAC)
(UNIT_TX, SPI_SS_TX_DAC)
;
- _iface->write_spi(
+ _spi_iface->write_spi(
unit_to_spi_dac[unit], spi_config_t::EDGE_FALL,
_dac_regs[unit].get_reg(), 24
);
@@ -281,11 +293,11 @@ double usrp2_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which){
} ad7922_regs.chn = ad7922_regs.mod; //normal mode: mod == chn
//write and read spi
- _iface->write_spi(
+ _spi_iface->write_spi(
unit_to_spi_adc[unit], config,
ad7922_regs.get_reg(), 16
);
- ad7922_regs.set_reg(boost::uint16_t(_iface->read_spi(
+ ad7922_regs.set_reg(boost::uint16_t(_spi_iface->read_spi(
unit_to_spi_adc[unit], config,
ad7922_regs.get_reg(), 16
)));
diff --git a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp
index 4691fa887..e19e7d5e7 100644
--- a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include "usrp2_regs.hpp"
#include <uhd/exception.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/transport/vrt_if_packet.hpp>
@@ -27,24 +28,25 @@ using namespace uhd::transport;
static const size_t POKE32_CMD = (1 << 8);
static const size_t PEEK32_CMD = 0;
static const double ACK_TIMEOUT = 0.5;
+static const boost::uint32_t MAX_SEQS_OUT = 16;
class usrp2_fifo_ctrl_impl : public usrp2_fifo_ctrl{
public:
usrp2_fifo_ctrl_impl(zero_copy_if::sptr xport):
_xport(xport),
- _seq(0)
+ _seq(0), _last_seq_ack(0)
{
- //NOP
+ while (_xport->get_recv_buff(0.0)){} //flush
}
UHD_INLINE void send_pkt(wb_addr_type addr, boost::uint32_t data, int cmd){
managed_send_buffer::sptr buff = _xport->get_send_buff(0.0);
if (not buff){
- throw uhd::runtime_error("peek32/poke32 in fifo ctrl timed out getting a send buffer");
+ throw uhd::runtime_error("fifo ctrl timed out getting a send buffer");
}
boost::uint32_t *trans = buff->cast<boost::uint32_t *>();
- trans[0] = htonl(_seq++);
+ trans[0] = htonl(++_seq);
boost::uint32_t *pkt = trans + 1;
//load packet info
@@ -61,10 +63,10 @@ public:
packet_info.has_tsf = false;
packet_info.has_tlr = false;
- //load header with offset 1
+ //load header
vrt::if_hdr_pack_be(pkt, packet_info);
- //load payload with offset 1
+ //load payload
const boost::uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq << 16);
pkt[packet_info.num_header_words32+0] = htonl(ctrl_word);
pkt[packet_info.num_header_words32+1] = htonl(data);
@@ -76,40 +78,37 @@ public:
void poke32(wb_addr_type addr, boost::uint32_t data){
boost::mutex::scoped_lock lock(_mutex);
- while (_xport->get_recv_buff(0.0)){} //flush
-
- this->send_pkt(addr, data, POKE32_CMD);
+ this->send_pkt((addr - SETTING_REGS_BASE)/4, data, POKE32_CMD);
- {
- managed_recv_buffer::sptr buff = _xport->get_recv_buff(ACK_TIMEOUT);
- if (not buff){
- throw uhd::runtime_error("poke32 in fifo ctrl timed out getting a recv buffer");
- }
- const boost::uint32_t *pkt = buff->cast<const boost::uint32_t *>();
- vrt::if_packet_info_t packet_info;
- packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
- vrt::if_hdr_unpack_be(pkt, packet_info);
- }
+ this->wait_for_ack(boost::int16_t(_seq-MAX_SEQS_OUT));
}
boost::uint32_t peek32(wb_addr_type addr){
boost::mutex::scoped_lock lock(_mutex);
- while (_xport->get_recv_buff(0.0)){} //flush
+ this->send_pkt((addr - READBACK_BASE)/4, 0, PEEK32_CMD);
- this->send_pkt(addr >> 2, 0, PEEK32_CMD);
+ return this->wait_for_ack(boost::int16_t(_seq));
+ }
+
+ boost::uint32_t wait_for_ack(const boost::int16_t seq_to_ack){
- {
+ while (_last_seq_ack < seq_to_ack){
managed_recv_buffer::sptr buff = _xport->get_recv_buff(ACK_TIMEOUT);
if (not buff){
- throw uhd::runtime_error("peek32 in fifo ctrl timed out getting a recv buffer");
+ throw uhd::runtime_error("fifo ctrl timed out looking for acks");
}
const boost::uint32_t *pkt = buff->cast<const boost::uint32_t *>();
vrt::if_packet_info_t packet_info;
packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
vrt::if_hdr_unpack_be(pkt, packet_info);
- return ntohl(pkt[packet_info.num_header_words32+1]);
+ _last_seq_ack = ntohl(pkt[packet_info.num_header_words32+0]) >> 16;
+ if (_last_seq_ack == seq_to_ack){
+ return ntohl(pkt[packet_info.num_header_words32+1]);
+ }
}
+
+ return 0;
}
void poke16(wb_addr_type, boost::uint16_t){
@@ -124,6 +123,7 @@ private:
zero_copy_if::sptr _xport;
boost::mutex _mutex;
boost::uint32_t _seq;
+ boost::uint16_t _last_seq_ack;
};
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 5e873f741..59cf65828 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -462,10 +462,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
// create frontend control objects
////////////////////////////////////////////////////////////////
_mbc[mb].rx_fe = rx_frontend_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_FRONT)
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_FRONT)
);
_mbc[mb].tx_fe = tx_frontend_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_TX_FRONT)
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TX_FRONT)
);
_tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec")
@@ -496,10 +496,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
// create rx dsp control objects
////////////////////////////////////////////////////////////////
_mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), USRP2_RX_SID_BASE + 0, true
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), USRP2_RX_SID_BASE + 0, true
));
_mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), USRP2_RX_SID_BASE + 1, true
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), USRP2_RX_SID_BASE + 1, true
));
for (size_t dspno = 0; dspno < _mbc[mb].rx_dsps.size(); dspno++){
_mbc[mb].rx_dsps[dspno]->set_link_rate(USRP2_LINK_RATE_BPS);
@@ -524,7 +524,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
// create tx dsp control objects
////////////////////////////////////////////////////////////////
_mbc[mb].tx_dsp = tx_dsp_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), USRP2_TX_ASYNC_SID
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), USRP2_TX_ASYNC_SID
);
_mbc[mb].tx_dsp->set_link_rate(USRP2_LINK_RATE_BPS);
_tree->access<double>(mb_path / "tick_rate")
@@ -558,8 +558,9 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
time64_rb_bases.rb_hi_pps = U2_REG_TIME64_HI_RB_PPS;
time64_rb_bases.rb_lo_pps = U2_REG_TIME64_LO_RB_PPS;
_mbc[mb].time64 = time64_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles
);
+ //_mbc[mb].fifo_ctrl->poke32(0x7, 0x1234);
_tree->access<double>(mb_path / "tick_rate")
.subscribe(boost::bind(&time64_core_200::set_tick_rate, _mbc[mb].time64, _1));
_tree->create<time_spec_t>(mb_path / "time/now")
@@ -582,7 +583,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
////////////////////////////////////////////////////////////////////
// create user-defined control objects
////////////////////////////////////////////////////////////////////
- _mbc[mb].user = user_settings_core_200::make(_mbc[mb].iface, U2_REG_SR_ADDR(SR_USER_REGS));
+ _mbc[mb].user = user_settings_core_200::make(_mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_USER_REGS));
_tree->create<user_settings_core_200::user_reg_t>(mb_path / "user/regs")
.subscribe(boost::bind(&user_settings_core_200::set_reg, _mbc[mb].user, _1));
@@ -608,7 +609,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
.subscribe(boost::bind(&usrp2_impl::set_db_eeprom, this, mb, "gdb", _1));
//create a new dboard interface and manager
- _mbc[mb].dboard_iface = make_usrp2_dboard_iface(_mbc[mb].iface, _mbc[mb].clock);
+ _mbc[mb].dboard_iface = make_usrp2_dboard_iface(_mbc[mb].fifo_ctrl, _mbc[mb].iface, _mbc[mb].iface, _mbc[mb].clock);
_tree->create<dboard_iface::sptr>(mb_path / "dboards/A/iface").set(_mbc[mb].dboard_iface);
_mbc[mb].dboard_manager = dboard_manager::make(
rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id,
@@ -678,12 +679,12 @@ void usrp2_impl::set_db_eeprom(const std::string &mb, const std::string &type, c
}
sensor_value_t usrp2_impl::get_mimo_locked(const std::string &mb){
- const bool lock = (_mbc[mb].iface->peek32(U2_REG_IRQ_RB) & (1<<10)) != 0;
+ const bool lock = (_mbc[mb].fifo_ctrl->peek32(U2_REG_IRQ_RB) & (1<<10)) != 0;
return sensor_value_t("MIMO", lock, "locked", "unlocked");
}
sensor_value_t usrp2_impl::get_ref_locked(const std::string &mb){
- const bool lock = (_mbc[mb].iface->peek32(U2_REG_IRQ_RB) & (1<<11)) != 0;
+ const bool lock = (_mbc[mb].fifo_ctrl->peek32(U2_REG_IRQ_RB) & (1<<11)) != 0;
return sensor_value_t("Ref", lock, "locked", "unlocked");
}
@@ -728,18 +729,18 @@ void usrp2_impl::update_clock_source(const std::string &mb, const std::string &s
case usrp2_iface::USRP_N210:
case usrp2_iface::USRP_N200_R4:
case usrp2_iface::USRP_N210_R4:
- if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12);
- else if (source == "external") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C);
- else if (source == "mimo") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);
+ if (source == "internal") _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12);
+ else if (source == "external") _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C);
+ else if (source == "mimo") _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);
else throw uhd::value_error("unhandled clock configuration reference source: " + source);
_mbc[mb].clock->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO
break;
case usrp2_iface::USRP2_REV3:
case usrp2_iface::USRP2_REV4:
- if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10);
- else if (source == "external") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C);
- else if (source == "mimo") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);
+ if (source == "internal") _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10);
+ else if (source == "external") _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C);
+ else if (source == "mimo") _mbc[mb].fifo_ctrl->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);
else throw uhd::value_error("unhandled clock configuration reference source: " + source);
_mbc[mb].clock->enable_external_ref(source != "internal");
break;
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 291208eff..3d2fbf14f 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -18,6 +18,7 @@
#ifndef INCLUDED_USRP2_IMPL_HPP
#define INCLUDED_USRP2_IMPL_HPP
+#include "gpio_core_200.hpp"
#include "usrp2_iface.hpp"
#include "usrp2_fifo_ctrl.hpp"
#include "clock_ctrl.hpp"
@@ -53,14 +54,11 @@ static const size_t USRP2_SRAM_BYTES = size_t(1 << 20);
static const boost::uint32_t USRP2_TX_ASYNC_SID = 2;
static const boost::uint32_t USRP2_RX_SID_BASE = 3;
-/*!
- * Make a usrp2 dboard interface.
- * \param iface the usrp2 interface object
- * \param clk_ctrl the clock control object
- * \return a sptr to a new dboard interface
- */
+//! Make a usrp2 dboard interface.
uhd::usrp::dboard_iface::sptr make_usrp2_dboard_iface(
- usrp2_iface::sptr iface,
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
usrp2_clock_ctrl::sptr clk_ctrl
);