From 03be4d0673c5e0f597db7d27f535956a591bbeb7 Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Tue, 30 Mar 2010 17:52:27 +0000
Subject: filled in some gpio handling code, some mboard impl, added
 usrp_e_regs (like memory map)

---
 host/lib/usrp/usrp_e/dboard_impl.cpp      |  1 -
 host/lib/usrp/usrp_e/dboard_interface.cpp | 89 +++++++++++++++++++++++++++----
 host/lib/usrp/usrp_e/mboard_impl.cpp      | 77 ++++++++++++++++++++++++--
 host/lib/usrp/usrp_e/usrp_e_impl.hpp      |  3 ++
 host/lib/usrp/usrp_e/usrp_e_regs.hpp      | 49 +++++++++++++++++
 5 files changed, 205 insertions(+), 14 deletions(-)
 create mode 100644 host/lib/usrp/usrp_e/usrp_e_regs.hpp

(limited to 'host/lib')

diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp
index 88d04ce7a..7c87361e0 100644
--- a/host/lib/usrp/usrp_e/dboard_impl.cpp
+++ b/host/lib/usrp/usrp_e/dboard_impl.cpp
@@ -16,7 +16,6 @@
 //
 
 #include <boost/bind.hpp>
-#include <uhd/utils.hpp>
 #include "usrp_e_impl.hpp"
 
 using namespace uhd::usrp;
diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp
index c7c7d8c1f..a343d93b8 100644
--- a/host/lib/usrp/usrp_e/dboard_interface.cpp
+++ b/host/lib/usrp/usrp_e/dboard_interface.cpp
@@ -15,10 +15,14 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
+#include "usrp_e_impl.hpp"
+#include "usrp_e_regs.hpp"
+#include <uhd/types/dict.hpp>
 #include <uhd/utils/assert.hpp>
+#include <boost/assign/list_of.hpp>
 #include <algorithm> //std::copy
-#include "usrp_e_impl.hpp"
-#include <linux/usrp1_e.h>
+#include <linux/usrp_e.h>
+#include <cstddef>
 
 using namespace uhd::usrp;
 
@@ -31,8 +35,8 @@ public:
     int read_aux_adc(unit_type_t, int);
 
     void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t);
-    void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t);
-    void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t);
+    void set_gpio_ddr(gpio_bank_t, boost::uint16_t);
+    void write_gpio(gpio_bank_t, boost::uint16_t);
     boost::uint16_t read_gpio(gpio_bank_t);
 
     void write_i2c(int, const byte_vector_t &);
@@ -85,20 +89,85 @@ double usrp_e_dboard_interface::get_tx_clock_rate(void){
 /***********************************************************************
  * GPIO
  **********************************************************************/
-void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){
-    throw std::runtime_error("not implemented");
+void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){
+    //define mapping of gpio bank to register address
+    static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of
+        (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_ddr))
+        (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_ddr))
+    ;
+
+    //load the data struct
+    usrp_e_ctl16 data;
+    data.offset = bank_to_addr[bank];
+    data.count = 1;
+    data.buf[0] = value;
+
+    //call the ioctl
+    _impl->ioctl(USRP_E_WRITE_CTL16, &data);
 }
 
-void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){
-    throw std::runtime_error("not implemented");
+void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value){
+    //define mapping of gpio bank to register address
+    static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of
+        (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io))
+        (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io))
+    ;
+
+    //load the data struct
+    usrp_e_ctl16 data;
+    data.offset = bank_to_addr[bank];
+    data.count = 1;
+    data.buf[0] = value;
+
+    //call the ioctl
+    _impl->ioctl(USRP_E_WRITE_CTL16, &data);
 }
 
 boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){
-    throw std::runtime_error("not implemented");
+    //define mapping of gpio bank to register address
+    static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of
+        (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io))
+        (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io))
+    ;
+
+    //load the data struct
+    usrp_e_ctl16 data;
+    data.offset = bank_to_addr[bank];
+    data.count = 1;
+
+    //call the ioctl
+    _impl->ioctl(USRP_E_READ_CTL16, &data);
+
+    return data.buf[0];
 }
 
 void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){
-    throw std::runtime_error("not implemented");
+    //define mapping of gpio bank to register address
+    static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of
+        (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_sel_low))
+        (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_sel_low))
+    ;
+
+    //set the gpio selection mux to atr or software controlled
+    boost::uint16_t low_sel = 0, high_sel = 0;
+    for(size_t i = 0; i < 16; i++){
+        boost::uint16_t code = (mask & (1 << i))? GPIO_SEL_ATR : GPIO_SEL_SW;
+        if(i < 8) low_sel  |= code << (2*i-0);
+        else      high_sel |= code << (2*i-8);
+    }
+
+    //load the data struct
+    usrp_e_ctl16 data;
+    data.offset = bank_to_addr[bank];
+    data.count = 2;
+    data.buf[0] = low_sel;
+    data.buf[1] = high_sel;
+
+    //call the ioctl
+    _impl->ioctl(USRP_E_READ_CTL16, &data);
+
+    //----------------------------------------> TODO
+    //TODO set the atr regs
 }
 
 /***********************************************************************
diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp
index 333fb2e51..1d3f9f466 100644
--- a/host/lib/usrp/usrp_e/mboard_impl.cpp
+++ b/host/lib/usrp/usrp_e/mboard_impl.cpp
@@ -15,9 +15,12 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-#include <boost/bind.hpp>
 #include "usrp_e_impl.hpp"
+#include <uhd/utils/assert.hpp>
+#include <uhd/props.hpp>
+#include <boost/bind.hpp>
 
+using namespace uhd;
 using namespace uhd::usrp;
 
 /***********************************************************************
@@ -28,13 +31,81 @@ void usrp_e_impl::mboard_init(void){
         boost::bind(&usrp_e_impl::mboard_get, this, _1, _2),
         boost::bind(&usrp_e_impl::mboard_set, this, _1, _2)
     );
+
+    //init the clock config
+    _clock_config.ref_source = clock_config_t::REF_AUTO;
+    _clock_config.pps_source = clock_config_t::PPS_SMA;
+
+    //TODO poke the clock config regs
 }
 
 /***********************************************************************
  * Mboard Get
  **********************************************************************/
-void usrp_e_impl::mboard_get(const wax::obj &, wax::obj &){
-    
+void usrp_e_impl::mboard_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(key.as<mboard_prop_t>()){
+    case MBOARD_PROP_NAME:
+        val = std::string("usrp-e mboard");
+        return;
+
+    case MBOARD_PROP_OTHERS:
+        val = prop_names_t();
+        return;
+
+    case MBOARD_PROP_RX_DBOARD:
+        ASSERT_THROW(name == "");
+        val = _rx_dboard_proxy->get_link();
+        return;
+
+    case MBOARD_PROP_RX_DBOARD_NAMES:
+        val = prop_names_t(1, ""); //vector of size 1 with empty string
+        return;
+
+    case MBOARD_PROP_TX_DBOARD:
+        ASSERT_THROW(name == "");
+        val = _tx_dboard_proxy->get_link();
+        return;
+
+    case MBOARD_PROP_TX_DBOARD_NAMES:
+        val = prop_names_t(1, ""); //vector of size 1 with empty string
+        return;
+
+    case MBOARD_PROP_CLOCK_RATE:
+        //val = TODO probably remove this property
+        return;
+
+    case MBOARD_PROP_RX_DSP:
+        ASSERT_THROW(name == "ddc0");
+        val = _rx_ddc_proxy->get_link();
+        return;
+
+    case MBOARD_PROP_RX_DSP_NAMES:
+        val = prop_names_t(1, "ddc0");
+        return;
+
+    case MBOARD_PROP_TX_DSP:
+        ASSERT_THROW(name == "duc0");
+        val = _tx_duc_proxy->get_link();
+        return;
+
+    case MBOARD_PROP_TX_DSP_NAMES:
+        val = prop_names_t(1, "duc0");
+        return;
+
+    case MBOARD_PROP_CLOCK_CONFIG:
+        val = _clock_config;
+        return;
+
+    case MBOARD_PROP_TIME_NOW:
+    case MBOARD_PROP_TIME_NEXT_PPS:
+        throw std::runtime_error("Error: trying to get write-only property on usrp-e mboard");
+
+    }
 }
 
 /***********************************************************************
diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp
index e593b13ad..643589754 100644
--- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp
+++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp
@@ -15,6 +15,7 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
+#include <uhd/types/clock_config.hpp>
 #include <uhd/usrp/usrp_e.hpp>
 #include <uhd/usrp/dboard_manager.hpp>
 
@@ -95,6 +96,8 @@ private:
     static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t);
     int _node_fd;
 
+    uhd::clock_config_t _clock_config;
+
     //device functions and settings
     void get(const wax::obj &, wax::obj &);
     void set(const wax::obj &, const wax::obj &);
diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp
new file mode 100644
index 000000000..219f459a5
--- /dev/null
+++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp
@@ -0,0 +1,49 @@
+//
+// 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/>.
+//
+
+#ifndef INCLUDED_USRP_E_REGS_HPP
+#define INCLUDED_USRP_E_REGS_HPP
+
+#include <boost/cstdint.hpp>
+
+////////////////////////////////////////////////
+// GPIO, Slave 4
+//
+// These go to the daughterboard i/o pins
+
+#define GPIO_BASE 0x40
+
+struct gpio_regs_t{
+    boost::uint16_t rx_io;      // tx data in high 16, rx in low 16
+    boost::uint16_t tx_io;
+    boost::uint16_t rx_ddr;     // 32 bits, 1 means output. tx in high 16, rx in low 16
+    boost::uint16_t tx_ddr;
+    boost::uint16_t tx_sel_low; // 16 2-bit fields select which source goes to TX DB
+    boost::uint16_t tx_sel_high;
+    boost::uint16_t rx_sel_low; // 16 2-bit fields select which source goes to RX DB
+    boost::uint16_t rx_sel_high;
+};
+
+// each 2-bit sel field is layed out this way
+#define GPIO_SEL_SW        0 // if pin is an output, set by software in the io reg
+#define GPIO_SEL_ATR       1 // if pin is an output, set by ATR logic
+#define GPIO_SEL_DEBUG_0   2 // if pin is an output, debug lines from FPGA fabric
+#define GPIO_SEL_DEBUG_1   3 // if pin is an output, debug lines from FPGA fabric
+
+//#define gpio_base ((gpio_regs_t *) GPIO_BASE)
+
+#endif /* INCLUDED_USRP_E_REGS_HPP */
-- 
cgit v1.2.3