From 069a7ce0570001ea3d9512a11d238ea4d6773f1d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 21 Jan 2010 19:05:30 -0800 Subject: Added more to the mboard test and the usrp device. --- include/usrp_uhd/device.hpp | 20 ++-- include/usrp_uhd/usrp/dboard/interface.hpp | 28 +++--- include/usrp_uhd/usrp/mboard/test.hpp | 4 + include/usrp_uhd/usrp/usrp.hpp | 2 + lib/device.cpp | 6 +- lib/usrp/mboard/test.cpp | 148 +++++++++++++++++++++++++++-- lib/usrp/usrp.cpp | 29 +++++- test/device_test.cpp | 15 +++ 8 files changed, 211 insertions(+), 41 deletions(-) diff --git a/include/usrp_uhd/device.hpp b/include/usrp_uhd/device.hpp index ad2d3b368..32d58b21f 100644 --- a/include/usrp_uhd/device.hpp +++ b/include/usrp_uhd/device.hpp @@ -26,9 +26,15 @@ public: typedef boost::shared_ptr sptr; //argument types for send and recv raw methods - typedef std::vector send_args_t; + //the send args is an array of buffers + //the recv args is a callback that takes a buffer + typedef std::vector send_args_t; typedef boost::function recv_args_t; + //structors + device(void); + virtual ~device(void); + /*! * \brief Discover usrp devices attached to the host. * @@ -53,16 +59,6 @@ public: */ static sptr make(const device_addr_t & hint, size_t which = 0); - /*! - * Constructor: Called in derived classes. - */ - device(void); - - /*! - * Deconstructor: called automatically by the shared pointer. - */ - virtual ~device(void); - /*! * Get the device address for this board. */ @@ -74,8 +70,6 @@ public: //connect dsps and subdevs void connect(const wax::type &src, const wax::type &sink); - -private: }; } //namespace usrp_uhd diff --git a/include/usrp_uhd/usrp/dboard/interface.hpp b/include/usrp_uhd/usrp/dboard/interface.hpp index acbfc6d70..7af45f7a2 100644 --- a/include/usrp_uhd/usrp/dboard/interface.hpp +++ b/include/usrp_uhd/usrp/dboard/interface.hpp @@ -96,50 +96,44 @@ public: /*! * Read daughterboard GPIO pin values * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK + * \param bank GPIO_TX_BANK or GPIO_RX_BANK * \return the value of the gpio bank */ virtual uint16_t read_gpio(gpio_bank_t bank) = 0; /*! * \brief Write to I2C peripheral - * \param i2c_addr I2C bus address (7-bits) - * \param buf the data to write - * Writes are limited to a maximum of of 64 bytes. + * \param i2c_addr I2C bus address (7-bits) + * \param buf the data to write */ - virtual void write_i2c (int i2c_addr, const std::string &buf) = 0; + virtual void write_i2c(int i2c_addr, const std::string &buf) = 0; /*! * \brief Read from I2C peripheral - * \param i2c_addr I2C bus address (7-bits) - * \param len number of bytes to read + * \param i2c_addr I2C bus address (7-bits) + * \param len number of bytes to read * \return the data read if successful, else a zero length string. - * Reads are limited to a maximum of 64 bytes. */ - virtual std::string read_i2c (int i2c_addr, size_t len) = 0; + virtual std::string read_i2c(int i2c_addr, size_t len) = 0; /*! * \brief Write data to SPI bus peripheral. * * \param dev which spi device * \param push args for writing - * \param buf the data to write - * - * Writes are limited to a maximum of 64 bytes. + * \param buf the data to write */ - virtual void write_spi (spi_dev_t dev, spi_push_t push, const std::string &buf) = 0; + virtual void write_spi(spi_dev_t dev, spi_push_t push, const std::string &buf) = 0; /*! * \brief Read data from SPI bus peripheral. * * \param dev which spi device * \param push args for reading - * \param len number of bytes to read. Must be in [0,64]. + * \param len number of bytes to read * \return the data read if sucessful, else a zero length string. - * - * Reads are limited to a maximum of 64 bytes. */ - virtual std::string read_spi (spi_dev_t dev, spi_latch_t latch, size_t len) = 0; + virtual std::string read_spi(spi_dev_t dev, spi_latch_t latch, size_t len) = 0; }; }}} //namespace diff --git a/include/usrp_uhd/usrp/mboard/test.hpp b/include/usrp_uhd/usrp/mboard/test.hpp index f3c2899cf..10b46c7fc 100644 --- a/include/usrp_uhd/usrp/mboard/test.hpp +++ b/include/usrp_uhd/usrp/mboard/test.hpp @@ -7,6 +7,8 @@ #include #include +#include +#include namespace usrp_uhd{ namespace usrp{ namespace mboard{ @@ -22,6 +24,8 @@ public: private: void get(const wax::type &, wax::type &); void set(const wax::type &, const wax::type &); + + std::vector _dboard_managers; }; }}} //namespace diff --git a/include/usrp_uhd/usrp/usrp.hpp b/include/usrp_uhd/usrp/usrp.hpp index b280b0d40..7506f798f 100644 --- a/include/usrp_uhd/usrp/usrp.hpp +++ b/include/usrp_uhd/usrp/usrp.hpp @@ -30,6 +30,8 @@ private: void set(const wax::type &, const wax::type &); std::vector _mboards; + boost::function _send_raw_cb; + boost::function _recv_raw_cb; }; }} //namespace diff --git a/lib/device.cpp b/lib/device.cpp index 4f942ebaf..cd1055d76 100644 --- a/lib/device.cpp +++ b/lib/device.cpp @@ -21,12 +21,14 @@ std::vector device::discover(const device_addr_t & hint = device_ device::sptr device::make(const device_addr_t & hint, size_t which){ std::vector device_addrs = discover(hint); + //check that we found any devices if (device_addrs.size() == 0){ throw std::runtime_error(str( boost::format("No devices found for %s") % hint.to_string() )); } + //check that the which index is valid if (device_addrs.size() <= which){ throw std::runtime_error(str( @@ -34,8 +36,10 @@ device::sptr device::make(const device_addr_t & hint, size_t which){ % which % hint.to_string() )); } + //create the new device with the discovered address - if (hint.type == DEVICE_ADDR_TYPE_VIRTUAL){ + //TODO only a usrp device will be made (until others are supported) + if (true){ return sptr(new usrp_uhd::usrp::usrp(device_addrs.at(which))); } throw std::runtime_error("cant make a device"); diff --git a/lib/usrp/mboard/test.cpp b/lib/usrp/mboard/test.cpp index 564f19efc..6bcbea94f 100644 --- a/lib/usrp/mboard/test.cpp +++ b/lib/usrp/mboard/test.cpp @@ -3,22 +3,158 @@ // #include +#include #include +using namespace usrp_uhd; +using namespace usrp_uhd::usrp; using namespace usrp_uhd::usrp::mboard; -test::test(const device_addr_t &){ - // +/*********************************************************************** + * dummy interface for dboards + **********************************************************************/ +class dummy_interface : public usrp_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 "";} +}; + +/*********************************************************************** + * 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::type &key_, wax::type &val){ + //extract the index if key is an indexed prop + wax::type key = key_; size_t index = 0; + if (key.type() == typeid(indexed_prop_t)){ + boost::tie(key, index) = wax::cast(key); + } + + //handle the get request conditioned on the key + switch(wax::cast(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(index); + return; + + case TYPE_TX: + val = _mgr->get_tx_subdev(index); + return; + } + + case DBOARD_PROP_NUM_SUBDEVS: + switch(_type){ + case TYPE_RX: + val = _mgr->get_num_rx_subdevs(); + return; + + case TYPE_TX: + val = _mgr->get_num_tx_subdevs(); + return; + } + + case DBOARD_PROP_CODEC: + val = NULL; //TODO + return; + } + } + + void set(const wax::type &, const wax::type &){ + 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){ + //create a manager for each dboard + for (size_t i = 0; i < device_addr.virtual_args.num_dboards; i++){ + dboard::interface::sptr ifc(new dummy_interface()); + _dboard_managers.push_back(dboard::manager::sptr( + new dboard::manager(0x0001, 0x0000, ifc) + )); + } } test::~test(void){ - // + /* NOP */ } -void test::get(const wax::type &, wax::type &){ - // +void test::get(const wax::type &key_, wax::type &val){ + //extract the index if key is an indexed prop + wax::type key = key_; size_t index = 0; + if (key.type() == typeid(indexed_prop_t)){ + boost::tie(key, index) = wax::cast(key); + } + + //handle the get request conditioned on the key + switch(wax::cast(key)){ + case MBOARD_PROP_NAME: + val = std::string("usrp test mboard"); + return; + + case MBOARD_PROP_RX_DBOARD: + val = wax::obj::sptr( + new shell_dboard(_dboard_managers.at(index), shell_dboard::TYPE_RX) + ); + return; + + case MBOARD_PROP_NUM_RX_DBOARDS: + val = size_t(_dboard_managers.size()); + return; + + case MBOARD_PROP_TX_DBOARD: + val = wax::obj::sptr( + new shell_dboard(_dboard_managers.at(index), shell_dboard::TYPE_TX) + ); + return; + + case MBOARD_PROP_NUM_TX_DBOARDS: + val = size_t(_dboard_managers.size()); + return; + + case MBOARD_PROP_MTU: + case MBOARD_PROP_CLOCK_RATE: + case MBOARD_PROP_RX_DSP: + case MBOARD_PROP_NUM_RX_DSPS: + case MBOARD_PROP_TX_DSP: + case MBOARD_PROP_NUM_TX_DSPS: + case MBOARD_PROP_PPS_SOURCE: + case MBOARD_PROP_PPS_POLARITY: + case MBOARD_PROP_REF_SOURCE: + 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::type &, const wax::type &){ - // + throw std::runtime_error("Cannot set on usrp test mboard"); } diff --git a/lib/usrp/usrp.cpp b/lib/usrp/usrp.cpp index af0e66e9f..5838ab90a 100644 --- a/lib/usrp/usrp.cpp +++ b/lib/usrp/usrp.cpp @@ -4,11 +4,32 @@ #include #include +#include #include using namespace usrp_uhd::usrp; +/*********************************************************************** + * default callbacks for the send and recv + * these should be replaced with callbacks from the mboard object + **********************************************************************/ +static void send_raw_default(const usrp_uhd::device::send_args_t &){ + throw std::runtime_error("No callback registered for send raw"); +} + +static void recv_raw_default(const usrp_uhd::device::recv_args_t &){ + throw std::runtime_error("No callback registered for recv raw"); +} + +/*********************************************************************** + * the usrp device wrapper + **********************************************************************/ usrp::usrp(const device_addr_t & device_addr){ + //set the default callbacks, the code below should replace them + _send_raw_cb = boost::bind(&send_raw_default, _1); + _recv_raw_cb = boost::bind(&recv_raw_default, _1); + + //create mboard based on the device addr if (device_addr.type == DEVICE_ADDR_TYPE_VIRTUAL){ _mboards.push_back( mboard::base::sptr(new mboard::test(device_addr)) @@ -49,10 +70,10 @@ void usrp::set(const wax::type &, const wax::type &){ throw std::runtime_error("Cannot set in usrp device"); } -void usrp::send_raw(const send_args_t &){ - //TODO make the call on the mboard +void usrp::send_raw(const send_args_t &args){ + return _send_raw_cb(args); } -void usrp::recv_raw(const recv_args_t &){ - //TODO make the call on the mboard +void usrp::recv_raw(const recv_args_t &args){ + return _recv_raw_cb(args); } diff --git a/test/device_test.cpp b/test/device_test.cpp index bbcada3ab..66256ba88 100644 --- a/test/device_test.cpp +++ b/test/device_test.cpp @@ -27,5 +27,20 @@ void device_test::test(void){ device_addr.virtual_args.num_rx_dsps = 3; device_addr.virtual_args.num_tx_dsps = 4; device::sptr dev = device::make(device_addr); + + std::cout << "Access the device" << std::endl; std::cout << wax::cast((*dev)[DEVICE_PROP_NAME]) << std::endl; + + std::cout << "Access the mboard" << std::endl; + wax::proxy mb0 = (*dev)[DEVICE_PROP_MBOARD]; + std::cout << wax::cast(mb0[MBOARD_PROP_NAME]) << std::endl; + CPPUNIT_ASSERT_EQUAL( + device_addr.virtual_args.num_dboards, + wax::cast(mb0[MBOARD_PROP_NUM_RX_DBOARDS]) + ); + CPPUNIT_ASSERT_EQUAL( + device_addr.virtual_args.num_dboards, + wax::cast(mb0[MBOARD_PROP_NUM_TX_DBOARDS]) + ); + } -- cgit v1.2.3