From cbf2109e7ea123870988aae852b0b1af1b2ab222 Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Mon, 12 Apr 2010 19:37:38 -0700
Subject: controlling dboard clock enables from host

---
 host/lib/ic_reg_maps/gen_ad9510_regs.py  | 19 ++++++++++++++-----
 host/lib/usrp/dboard_manager.cpp         | 28 +++++++++++++++++-----------
 host/lib/usrp/usrp2/dboard_interface.cpp | 30 ++++++++++++++++++++++++++----
 3 files changed, 57 insertions(+), 20 deletions(-)

(limited to 'host')

diff --git a/host/lib/ic_reg_maps/gen_ad9510_regs.py b/host/lib/ic_reg_maps/gen_ad9510_regs.py
index 624249563..90230b8f9 100755
--- a/host/lib/ic_reg_maps/gen_ad9510_regs.py
+++ b/host/lib/ic_reg_maps/gen_ad9510_regs.py
@@ -60,7 +60,7 @@ prescaler_value                A[2:4]        0      div1, div2, 2_3, 4_5, 8_9, 1
 b_counter_bypass               A[6]          0
 ref_counter_msb                B[0:5]        0
 ref_counter_lsb                C[0:7]        0
-antibacklash_pw                D[0:1]        0      1_3ns, 2_9ns, 6_0ns, 1_3ns
+antibacklash_pw                D[0:1]        0      1_3ns, 2_9ns, 6_0ns
 dld_window                     D[5]          0      9_5ns, 3_5ns
 lock_detect_disable            D[6]          0      enb, dis
 ########################################################################
@@ -69,7 +69,7 @@ lock_detect_disable            D[6]          0      enb, dis
 #for $i, $o in ((5, 0), (6, 4))
 delay_control_out$i            $hex(0x34+$o)[0]    0
 ramp_current_out$i             $hex(0x35+$o)[0:2]  0   200ua, 400ua, 600ua, 800ua, 1000ua, 1200ua, 1400ua, 1600ua
-ramp_capacitor_out$i           $hex(0x35+$o)[3:5]  0   4caps=0, 3caps=1, 2caps=3, 3caps=4, 1cap=7
+ramp_capacitor_out$i           $hex(0x35+$o)[3:5]  0   4caps=0, 3caps=1, 2caps=3, 1cap=7
 delay_fine_adjust_out$i        $hex(0x36+$o)[1:5]  0
 #end for
 ########################################################################
@@ -130,7 +130,7 @@ HEADER_TEXT="""
 
 \#include <boost/cstdint.hpp>
 
-struct adf4360_regs_t{
+struct ad9510_regs_t{
 #for $reg in $regs
     #if $reg.get_enums()
     enum $(reg.get_name())_t{
@@ -144,13 +144,13 @@ struct adf4360_regs_t{
     #end if
 #end for
 
-    adf4360_regs_t(void){
+    ad9510_regs_t(void){
 #for $reg in $regs
         $reg.get_name() = $reg.get_default();
 #end for
     }
 
-    boost::uint8_t get_reg(boost::uint8_t addr){
+    boost::uint8_t get_reg(boost::uint16_t addr){
         boost::uint8_t reg = 0;
         switch(addr){
         #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs)))
@@ -163,6 +163,15 @@ struct adf4360_regs_t{
         }
         return reg;
     }
+
+    boost::uint32_t get_write_reg(boost::uint16_t addr){
+        return (boost::uint32_t(addr) << 8) | get_reg(addr);
+    }
+
+    boost::uint32_t get_read_reg(boost::uint16_t addr){
+        return (boost::uint32_t(addr) << 8) | (1 << 15);
+    }
+
 };
 
 \#endif /* INCLUDED_AD9510_REGS_HPP */
diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp
index f8ff38c39..5e62b5564 100644
--- a/host/lib/usrp/dboard_manager.cpp
+++ b/host/lib/usrp/dboard_manager.cpp
@@ -25,6 +25,7 @@
 #include <boost/format.hpp>
 #include <boost/bind.hpp>
 #include <boost/foreach.hpp>
+#include <boost/assign/list_of.hpp>
 
 using namespace uhd;
 using namespace uhd::usrp;
@@ -141,7 +142,7 @@ private:
     uhd::dict<std::string, subdev_proxy::sptr> _rx_dboards;
     uhd::dict<std::string, subdev_proxy::sptr> _tx_dboards;
     dboard_interface::sptr _interface;
-    void set_nice_gpio_pins(void);
+    void set_nice_dboard_if(void);
 };
 
 /***********************************************************************
@@ -200,7 +201,7 @@ dboard_manager_impl::dboard_manager_impl(
     boost::tie(tx_dboard_ctor, tx_name, tx_subdevs) = get_dboard_args(tx_dboard_id, "tx");
 
     //initialize the gpio pins before creating subdevs
-    set_nice_gpio_pins();
+    set_nice_dboard_if();
 
     //make xcvr subdevs (make one subdev for both rx and tx dboards)
     if (rx_dboard_ctor == tx_dboard_ctor){
@@ -246,7 +247,7 @@ dboard_manager_impl::dboard_manager_impl(
 }
 
 dboard_manager_impl::~dboard_manager_impl(void){
-    set_nice_gpio_pins();
+    set_nice_dboard_if();
 }
 
 prop_names_t dboard_manager_impl::get_rx_subdev_names(void){
@@ -273,12 +274,17 @@ wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){
     return _tx_dboards[subdev_name]->get_link();
 }
 
-void dboard_manager_impl::set_nice_gpio_pins(void){
-    //std::cout << "Set nice GPIO pins" << std::endl;
-
-    _interface->set_gpio_ddr(dboard_interface::UNIT_RX, 0x0000); //all inputs
-    _interface->set_atr_reg(dboard_interface::UNIT_RX, dboard_interface::ATR_REG_IDLE, 0x0000); //all low
-
-    _interface->set_gpio_ddr(dboard_interface::UNIT_TX, 0x0000); //all inputs
-    _interface->set_atr_reg(dboard_interface::UNIT_TX, dboard_interface::ATR_REG_IDLE, 0x0000); //all low
+void dboard_manager_impl::set_nice_dboard_if(void){
+    //make a list of possible unit types
+    std::vector<dboard_interface::unit_t> units = boost::assign::list_of
+        (dboard_interface::UNIT_RX)
+        (dboard_interface::UNIT_TX)
+    ;
+
+    //set nice settings on each unit
+    BOOST_FOREACH(dboard_interface::unit_t unit, units){
+        _interface->set_gpio_ddr(unit, 0x0000); //all inputs
+        _interface->set_atr_reg(unit, dboard_interface::ATR_REG_IDLE, 0x0000); //all low
+        _interface->set_clock_enabled(unit, false); //clock off
+    }
 }
diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp
index db8679b9b..8a3df08cb 100644
--- a/host/lib/usrp/usrp2/dboard_interface.cpp
+++ b/host/lib/usrp/usrp2/dboard_interface.cpp
@@ -17,6 +17,7 @@
 
 #include "usrp2_impl.hpp"
 #include "usrp2_regs.hpp"
+#include "ad9510_regs.hpp"
 #include <uhd/types/dict.hpp>
 #include <uhd/utils/assert.hpp>
 #include <boost/assign/list_of.hpp>
@@ -60,6 +61,8 @@ public:
 private:
     usrp2_impl *_impl;
     boost::uint32_t _ddr_shadow;
+    ad9510_regs_t _ad9510_regs;
+    uhd::dict<unit_t, bool> _clock_enb_shadow;
 };
 
 /***********************************************************************
@@ -96,12 +99,31 @@ double usrp2_dboard_interface::get_clock_rate(unit_t){
     return _impl->get_master_clock_freq();
 }
 
-void usrp2_dboard_interface::set_clock_enabled(unit_t, bool){
-    //TODO
+void usrp2_dboard_interface::set_clock_enabled(unit_t unit, bool enb){
+    uint16_t data = 0;
+    switch(unit){
+    case UNIT_RX:
+        _ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1;
+        _ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS;
+        _ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA;
+        data = _ad9510_regs.get_write_reg(0x43);
+        break;
+    case UNIT_TX:
+        _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1;
+        _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS;
+        _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA;
+        data = _ad9510_regs.get_write_reg(0x42);
+        break;
+    }
+    _impl->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24, false /*no rb*/);
+
+    _ad9510_regs.update_registers = 1;
+    _impl->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, _ad9510_regs.get_write_reg(0x5a), 24, false /*no rb*/);
+    _clock_enb_shadow[unit] = unit;
 }
 
-bool usrp2_dboard_interface::get_clock_enabled(unit_t){
-    return false; //TODO
+bool usrp2_dboard_interface::get_clock_enabled(unit_t unit){
+    return _clock_enb_shadow[unit];
 }
 
 /***********************************************************************
-- 
cgit v1.2.3