summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-02-17 16:23:12 -0800
committerJosh Blum <josh@joshknows.com>2010-02-17 16:23:12 -0800
commit4fb4572e1a16f54439f57655f90e0fc937c57c1e (patch)
tree5dc731d266c8f5f783c5b28996a1583dac18ab57 /host/lib/usrp
parenteb7e709b7aff162cc7c8f9b8004089846839ffbe (diff)
downloaduhd-4fb4572e1a16f54439f57655f90e0fc937c57c1e.tar.gz
uhd-4fb4572e1a16f54439f57655f90e0fc937c57c1e.tar.bz2
uhd-4fb4572e1a16f54439f57655f90e0fc937c57c1e.zip
Worked out spi api for the dboard interface.
Created usrp2 spi transaction control on host and fw
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/dboard/interface.cpp26
-rw-r--r--host/lib/usrp/dboard/manager.cpp12
-rw-r--r--host/lib/usrp/mboard/test.cpp188
-rw-r--r--host/lib/usrp/mboard/usrp2/dboard_interface.cpp88
-rw-r--r--host/lib/usrp/mboard/usrp2/dboard_interface.hpp16
-rw-r--r--host/lib/usrp/mboard/usrp2/fw_common.h22
-rw-r--r--host/lib/usrp/usrp.cpp4
7 files changed, 152 insertions, 204 deletions
diff --git a/host/lib/usrp/dboard/interface.cpp b/host/lib/usrp/dboard/interface.cpp
index 837c76d0a..b8f6724ba 100644
--- a/host/lib/usrp/dboard/interface.cpp
+++ b/host/lib/usrp/dboard/interface.cpp
@@ -26,3 +26,29 @@ interface::interface(void){
interface::~interface(void){
/* NOP */
}
+
+void interface::write_spi(
+ spi_dev_t dev,
+ spi_push_t push,
+ const byte_vector_t &buf
+){
+ transact_spi(dev, SPI_LATCH_RISE, push, buf, false); //dont readback
+}
+
+interface::byte_vector_t interface::read_spi(
+ spi_dev_t dev,
+ spi_latch_t latch,
+ size_t num_bytes
+){
+ byte_vector_t buf(num_bytes, 0x00); //dummy data
+ return transact_spi(dev, latch, SPI_PUSH_RISE, buf, true); //readback
+}
+
+interface::byte_vector_t interface::read_write_spi(
+ spi_dev_t dev,
+ spi_latch_t latch,
+ spi_push_t push,
+ const byte_vector_t &buf
+){
+ return transact_spi(dev, latch, push, buf, true); //readback
+}
diff --git a/host/lib/usrp/dboard/manager.cpp b/host/lib/usrp/dboard/manager.cpp
index 4a675fd0b..3540cd1bc 100644
--- a/host/lib/usrp/dboard/manager.cpp
+++ b/host/lib/usrp/dboard/manager.cpp
@@ -135,6 +135,17 @@ manager::manager(
register_internal_dboards(); //always call first
const dboard_ctor_t rx_dboard_ctor = get_dboard_ctor(rx_dboard_id, "rx");
const dboard_ctor_t tx_dboard_ctor = get_dboard_ctor(tx_dboard_id, "tx");
+
+ //initialize the gpio pins before creating subdevs
+ dboard_interface->set_gpio_ddr(interface::GPIO_RX_BANK, 0x0000, 0xffff); //all inputs
+ dboard_interface->set_gpio_ddr(interface::GPIO_TX_BANK, 0x0000, 0xffff);
+
+ dboard_interface->write_gpio(interface::GPIO_RX_BANK, 0x0000, 0xffff); //all zeros
+ dboard_interface->write_gpio(interface::GPIO_TX_BANK, 0x0000, 0xffff);
+
+ dboard_interface->set_atr_reg(interface::GPIO_RX_BANK, 0x0000, 0x0000, 0x0000); //software controlled
+ dboard_interface->set_atr_reg(interface::GPIO_TX_BANK, 0x0000, 0x0000, 0x0000);
+
//make xcvr subdevs (make one subdev for both rx and tx dboards)
if (rx_dboard_ctor == tx_dboard_ctor){
BOOST_FOREACH(std::string name, ctor_to_names_map[rx_dboard_ctor]){
@@ -151,6 +162,7 @@ manager::manager(
);
}
}
+
//make tx and rx subdevs (separate subdevs for rx and tx dboards)
else{
//make the rx subdevs
diff --git a/host/lib/usrp/mboard/test.cpp b/host/lib/usrp/mboard/test.cpp
deleted file mode 100644
index 67d3c70fa..000000000
--- a/host/lib/usrp/mboard/test.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-//
-// Copyright 2010 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
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-
-#include <uhd/usrp/mboard/test.hpp>
-#include <uhd/props.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/format.hpp>
-#include <stdexcept>
-
-using namespace uhd;
-using namespace uhd::usrp;
-using namespace uhd::usrp::mboard;
-
-/***********************************************************************
- * dummy interface for dboards
- **********************************************************************/
-class dummy_interface : public uhd::usrp::dboard::interface{
-public:
- dummy_interface(void){}
- ~dummy_interface(void){}
- void write_aux_dac(int, int){}
- int read_aux_adc(int){return 0;}
- void set_atr_reg(gpio_bank_t, uint16_t, uint16_t, uint16_t){}
- void set_gpio_ddr(gpio_bank_t, uint16_t, uint16_t){}
- void write_gpio(gpio_bank_t, uint16_t, uint16_t){}
- uint16_t read_gpio(gpio_bank_t){return 0;}
- void write_i2c (int, const std::string &){}
- std::string read_i2c (int, size_t){return "";}
- void write_spi (spi_dev_t, spi_push_t, const std::string &){}
- std::string read_spi (spi_dev_t, spi_latch_t, size_t){return "";}
- double get_rx_clock_rate(void){return 0.0;}
- double get_tx_clock_rate(void){return 0.0;}
-};
-
-/***********************************************************************
- * shell class to act as a dboard
- **********************************************************************/
-class shell_dboard : public wax::obj{
-public:
- enum type_t {TYPE_RX, TYPE_TX};
- shell_dboard(dboard::manager::sptr mgr, type_t type){
- _mgr = mgr;
- _type = type;
- }
- ~shell_dboard(void){}
-private:
- void get(const wax::obj &key_, wax::obj &val){
- wax::obj key; std::string name;
- boost::tie(key, name) = extract_named_prop(key_);
-
- //handle the get request conditioned on the key
- switch(wax::cast<dboard_prop_t>(key)){
- case DBOARD_PROP_NAME:
- val = std::string("dboard test mboard");
- return;
-
- case DBOARD_PROP_SUBDEV:
- switch(_type){
- case TYPE_RX:
- val = _mgr->get_rx_subdev(name);
- return;
-
- case TYPE_TX:
- val = _mgr->get_tx_subdev(name);
- return;
- }
-
- case DBOARD_PROP_SUBDEV_NAMES:
- switch(_type){
- case TYPE_RX:
- val = _mgr->get_rx_subdev_names();
- return;
-
- case TYPE_TX:
- val = _mgr->get_tx_subdev_names();
- return;
- }
-
- case DBOARD_PROP_CODEC:
- return;
- }
- }
-
- void set(const wax::obj &, const wax::obj &){
- throw std::runtime_error("Cannot set on usrp test dboard");
- }
-
- type_t _type;
- dboard::manager::sptr _mgr;
-};
-
-/***********************************************************************
- * test usrp mboard class
- **********************************************************************/
-test::test(const device_addr_t &device_addr){
- //extract the number of dboards
- size_t num_dboards = boost::lexical_cast<size_t>(device_addr["num_dboards"]);
- //create a manager for each dboard
- for (size_t i = 0; i < num_dboards; i++){
- dboard::interface::sptr ifc(new dummy_interface());
- _dboard_managers[boost::lexical_cast<std::string>(i)] = dboard::manager::sptr(
- new dboard::manager(dboard::ID_BASIC_RX, dboard::ID_BASIC_TX, ifc)
- );
- }
-}
-
-test::~test(void){
- /* NOP */
-}
-
-void test::get(const wax::obj &key_, wax::obj &val){
- wax::obj key; std::string name;
- boost::tie(key, name) = extract_named_prop(key_);
-
- //handle the get request conditioned on the key
- switch(wax::cast<mboard_prop_t>(key)){
- case MBOARD_PROP_NAME:
- val = std::string("usrp test mboard");
- return;
-
- case MBOARD_PROP_OTHERS:
- val = prop_names_t(); //empty other props
- return;
-
- case MBOARD_PROP_RX_DBOARD:
- if (not _dboard_managers.has_key(name)) throw std::invalid_argument(
- str(boost::format("Unknown rx dboard name %s") % name)
- );
- //FIXME store the shell dboard within the class
- //may not fix, plan to remove this test class when real usrps work
- //val = wax::obj::sptr(
- // new shell_dboard(_dboard_managers[name], shell_dboard::TYPE_RX)
- //);
- return;
-
- case MBOARD_PROP_RX_DBOARD_NAMES:
- val = prop_names_t(_dboard_managers.get_keys());
- return;
-
- case MBOARD_PROP_TX_DBOARD:
- if (not _dboard_managers.has_key(name)) throw std::invalid_argument(
- str(boost::format("Unknown tx dboard name %s") % name)
- );
- //FIXME store the shell dboard within the class
- //may not fix, plan to remove this test class when real usrps work
- //val = wax::obj::sptr(
- // new shell_dboard(_dboard_managers[name], shell_dboard::TYPE_TX)
- //);
- return;
-
- case MBOARD_PROP_TX_DBOARD_NAMES:
- val = prop_names_t(_dboard_managers.get_keys());
- return;
-
- case MBOARD_PROP_MTU:
- case MBOARD_PROP_CLOCK_RATE:
- case MBOARD_PROP_RX_DSP:
- case MBOARD_PROP_RX_DSP_NAMES:
- case MBOARD_PROP_TX_DSP:
- case MBOARD_PROP_TX_DSP_NAMES:
- case MBOARD_PROP_PPS_SOURCE:
- case MBOARD_PROP_PPS_SOURCE_NAMES:
- case MBOARD_PROP_PPS_POLARITY:
- case MBOARD_PROP_REF_SOURCE:
- case MBOARD_PROP_REF_SOURCE_NAMES:
- case MBOARD_PROP_TIME_NOW:
- case MBOARD_PROP_TIME_NEXT_PPS:
- throw std::runtime_error("unhandled prop is usrp test mboard");
- }
-}
-
-void test::set(const wax::obj &, const wax::obj &){
- throw std::runtime_error("Cannot set on usrp test mboard");
-}
diff --git a/host/lib/usrp/mboard/usrp2/dboard_interface.cpp b/host/lib/usrp/mboard/usrp2/dboard_interface.cpp
index 05d29daef..d244e0bee 100644
--- a/host/lib/usrp/mboard/usrp2/dboard_interface.cpp
+++ b/host/lib/usrp/mboard/usrp2/dboard_interface.cpp
@@ -52,10 +52,10 @@ double dboard_interface::get_tx_clock_rate(void){
*/
static uint8_t gpio_bank_to_otw(uhd::usrp::dboard::interface::gpio_bank_t bank){
switch(bank){
- case uhd::usrp::dboard::interface::GPIO_TX_BANK: return USRP2_GPIO_BANK_TX;
- case uhd::usrp::dboard::interface::GPIO_RX_BANK: return USRP2_GPIO_BANK_RX;
+ case uhd::usrp::dboard::interface::GPIO_TX_BANK: return USRP2_DIR_TX;
+ case uhd::usrp::dboard::interface::GPIO_RX_BANK: return USRP2_DIR_RX;
}
- throw std::runtime_error("unknown gpio bank");
+ throw std::invalid_argument("unknown gpio bank type");
}
void dboard_interface::set_gpio_ddr(gpio_bank_t bank, uint16_t value, uint16_t mask){
@@ -109,3 +109,85 @@ void dboard_interface::set_atr_reg(gpio_bank_t bank, uint16_t tx_value, uint16_t
usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data);
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THE_ATR_SETTINGS_DUDE);
}
+
+/***********************************************************************
+ * SPI
+ **********************************************************************/
+/*!
+ * Static function to convert a spi dev enum
+ * to an over-the-wire value for the usrp2 control.
+ * \param dev the dboard interface spi dev enum
+ * \return an over the wire representation
+ */
+static uint8_t spi_dev_to_otw(uhd::usrp::dboard::interface::spi_dev_t dev){
+ switch(dev){
+ case uhd::usrp::dboard::interface::SPI_TX_DEV: return USRP2_DIR_TX;
+ case uhd::usrp::dboard::interface::SPI_RX_DEV: return USRP2_DIR_RX;
+ }
+ throw std::invalid_argument("unknown spi device type");
+}
+
+/*!
+ * Static function to convert a spi latch enum
+ * to an over-the-wire value for the usrp2 control.
+ * \param latch the dboard interface spi latch enum
+ * \return an over the wire representation
+ */
+static uint8_t spi_latch_to_otw(uhd::usrp::dboard::interface::spi_latch_t latch){
+ switch(latch){
+ case uhd::usrp::dboard::interface::SPI_LATCH_RISE: return USRP2_CLK_EDGE_RISE;
+ case uhd::usrp::dboard::interface::SPI_LATCH_FALL: return USRP2_CLK_EDGE_FALL;
+ }
+ throw std::invalid_argument("unknown spi latch type");
+}
+
+/*!
+ * Static function to convert a spi push enum
+ * to an over-the-wire value for the usrp2 control.
+ * \param push the dboard interface spi push enum
+ * \return an over the wire representation
+ */
+static uint8_t spi_push_to_otw(uhd::usrp::dboard::interface::spi_push_t push){
+ switch(push){
+ case uhd::usrp::dboard::interface::SPI_PUSH_RISE: return USRP2_CLK_EDGE_RISE;
+ case uhd::usrp::dboard::interface::SPI_PUSH_FALL: return USRP2_CLK_EDGE_FALL;
+ }
+ throw std::invalid_argument("unknown spi push type");
+}
+
+uhd::usrp::dboard::interface::byte_vector_t dboard_interface::transact_spi(
+ spi_dev_t dev,
+ spi_latch_t latch,
+ spi_push_t push,
+ const byte_vector_t &buf,
+ bool readback
+){
+ //setup the out data
+ usrp2_ctrl_data_t out_data;
+ out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO);
+ out_data.data.spi_args.dev = spi_dev_to_otw(dev);
+ out_data.data.spi_args.latch = spi_latch_to_otw(latch);
+ out_data.data.spi_args.push = spi_push_to_otw(push);
+ out_data.data.spi_args.readback = (readback)? 1 : 0;
+ out_data.data.spi_args.bytes = buf.size();
+
+ //limitation of spi transaction size
+ ASSERT_THROW(buf.size() <= sizeof(out_data.data.spi_args.data));
+
+ //copy in the data
+ for (size_t i = 0; i < buf.size(); i++){
+ out_data.data.spi_args.data[i] = buf[i];
+ }
+
+ //send and recv
+ usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data);
+ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE);
+ ASSERT_THROW(in_data.data.spi_args.bytes == buf.size());
+
+ //copy out the data
+ byte_vector_t result;
+ for (size_t i = 0; i < buf.size(); i++){
+ result.push_back(in_data.data.spi_args.data[i]);
+ }
+ return result;
+}
diff --git a/host/lib/usrp/mboard/usrp2/dboard_interface.hpp b/host/lib/usrp/mboard/usrp2/dboard_interface.hpp
index 645681f43..8880eaf97 100644
--- a/host/lib/usrp/mboard/usrp2/dboard_interface.hpp
+++ b/host/lib/usrp/mboard/usrp2/dboard_interface.hpp
@@ -39,19 +39,23 @@ public:
uint16_t read_gpio(gpio_bank_t);
- void write_i2c (int, const std::string &){}
+ void write_i2c(int, const byte_vector_t &){}
- std::string read_i2c (int, size_t){return "";}
-
- void write_spi (spi_dev_t, spi_push_t, const std::string &){}
-
- std::string read_spi (spi_dev_t, spi_latch_t, size_t){return "";}
+ byte_vector_t read_i2c(int, size_t){return byte_vector_t();}
double get_rx_clock_rate(void);
double get_tx_clock_rate(void);
private:
+ byte_vector_t transact_spi(
+ spi_dev_t dev,
+ spi_latch_t latch,
+ spi_push_t push,
+ const byte_vector_t &buf,
+ bool readback
+ );
+
impl_base *_impl;
};
diff --git a/host/lib/usrp/mboard/usrp2/fw_common.h b/host/lib/usrp/mboard/usrp2/fw_common.h
index 8cd15c7c3..8e5810a14 100644
--- a/host/lib/usrp/mboard/usrp2/fw_common.h
+++ b/host/lib/usrp/mboard/usrp2/fw_common.h
@@ -63,6 +63,9 @@ typedef enum{
USRP2_CTRL_ID_USE_THESE_ATR_SETTINGS_BRO,
USRP2_CTRL_ID_GOT_THE_ATR_SETTINGS_DUDE,
+ USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO,
+ USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE,
+
USRP2_CTRL_ID_PEACE_OUT
} usrp2_ctrl_id_t;
@@ -84,9 +87,14 @@ typedef enum{
} usrp2_ref_source_t;
typedef enum{
- USRP2_GPIO_BANK_RX,
- USRP2_GPIO_BANK_TX
-} usrp2_gpio_bank_t;
+ USRP2_DIR_RX,
+ USRP2_DIR_TX
+} usrp2_dir_which_t;
+
+typedef enum{
+ USRP2_CLK_EDGE_RISE,
+ USRP2_CLK_EDGE_FALL
+} usrp2_clk_edge_t;
typedef struct{
uint32_t id;
@@ -117,6 +125,14 @@ typedef struct{
uint16_t rx_value;
uint16_t mask;
} atr_config;
+ struct {
+ uint8_t dev;
+ uint8_t latch;
+ uint8_t push;
+ uint8_t readback;
+ uint8_t bytes;
+ uint8_t data[sizeof(uint32_t)];
+ } spi_args;
} data;
} usrp2_ctrl_data_t;
diff --git a/host/lib/usrp/usrp.cpp b/host/lib/usrp/usrp.cpp
index 86a40ebd8..9b1603a4a 100644
--- a/host/lib/usrp/usrp.cpp
+++ b/host/lib/usrp/usrp.cpp
@@ -17,7 +17,6 @@
#include <uhd/usrp/usrp.hpp>
#include <uhd/usrp/mboard/usrp2.hpp>
-#include <uhd/usrp/mboard/test.hpp>
#include <boost/format.hpp>
#include <boost/bind.hpp>
#include <stdexcept>
@@ -48,9 +47,6 @@ usrp::usrp(const device_addr_t &device_addr){
if (not device_addr.has_key("type")){
//TODO nothing
}
- else if (device_addr["type"] == "test"){
- _mboards[""] = mboard::base::sptr(new mboard::test(device_addr));
- }
else if (device_addr["type"] == "udp"){
_mboards[""] = mboard::base::sptr(new mboard::usrp2(device_addr));
}