commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r9330 - gnuradio/branches/developers/trondeau/dbs/usrp


From: trondeau
Subject: [Commit-gnuradio] r9330 - gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy
Date: Tue, 19 Aug 2008 07:03:27 -0600 (MDT)

Author: trondeau
Date: 2008-08-19 07:03:20 -0600 (Tue, 19 Aug 2008)
New Revision: 9330

Added:
   gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.cc
   gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.h
Modified:
   gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/Makefile.am
Log:
wip: adding DBSRX daughterboard class.

Modified: 
gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/Makefile.am
===================================================================
--- gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/Makefile.am  
2008-08-19 05:02:44 UTC (rev 9329)
+++ gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/Makefile.am  
2008-08-19 13:03:20 UTC (rev 9330)
@@ -110,7 +110,8 @@
        db_basic.cc                     \
        db_tv_rx.cc                     \
        db_flexrf.cc                    \
-       db_flexrf_mimo.cc
+       db_flexrf_mimo.cc               \
+       db_dbs_rx.cc
 
 
 if FUSB_TECH_generic
@@ -146,7 +147,8 @@
        db_basic.h                      \
        db_tv_rx.h                      \
        db_flexrf.h                     \
-       db_flexrf_mimo.h
+       db_flexrf_mimo.h                \
+       db_dbs_rx.h
 
 noinst_HEADERS =                       \
        ad9862.h                        \

Added: 
gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.cc
===================================================================
--- gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.cc 
                        (rev 0)
+++ gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.cc 
2008-08-19 13:03:20 UTC (rev 9330)
@@ -0,0 +1,489 @@
+//
+// Copyright 2008 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio 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 asversion 3, or (at your option)
+// any later version.
+// 
+// GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#include <db_dbs_rx.h>
+#include <db_tv_rx.h>
+#include <sstream>
+#include <assert.h>
+#include <stdexcept>
+#include <cmath>
+
+
+/*****************************************************************************/
+
+
+db_dbs_rx::db_dbs_rx(usrp_basic *usrp, int which)
+  : db_base(usrp, which, false)
+{
+  // Control DBS receiver based USRP daughterboard.
+  // 
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+  d_usrp = (usrp_basic_rx*)usrp;
+  d_tx = false; // FIXME: this should be redundant
+
+  d_usrp->_write_oe(d_which, 0x0001, 0x0001);
+  if(which == 0) {
+    d_i2c_addr = 0x67;
+  }
+  else {
+    d_i2c_addr = 0x65;
+  }
+
+  d_n = 950;
+  d_div2 = 0;
+  d_osc = 5;
+  d_cp = 3;
+  d_r = 4;
+  d_r_int = 1;
+  d_fdac = 127;
+  d_m = 2;
+  d_dl = 0;
+  d_ade = 0;
+  d_adl = 0;
+  d_gc1 = 0;
+  d_gc2 = 31;
+  d_diag = 0;
+  
+  d_refclk_divisor = 16;
+  _enable_refclk(true);
+  
+  set_gain((gain_min() + gain_max()) / 2.0);       // initialize gain
+
+  bypass_adc_buffers(true);
+}
+
+db_dbs_rx::~db_dbs_rx()
+{
+  if(d_usrp) {
+    _enable_refclk(false);
+  }
+}
+
+void
+db_dbs_rx::_write_reg (int regno, int v)
+{
+  //regno is in [0,5], v is value to write to register"""
+  assert (0 <= regno && regno <= 5);
+  std::vector<int> args(2);
+  args[0] = regno;
+  args[1] = v;
+  d_usrp->write_i2c (d_i2c_addr, int_seq_to_str (args));
+}
+
+void
+db_dbs_rx::_write_regs (int starting_regno, const std::vector<int> &vals)
+{
+  // starting_regno is in [0,5],
+  // vals is a seq of integers to write to consecutive registers"""
+
+  //FIXME
+  std::vector<int> args;
+  args.push_back(starting_regno);
+  args.insert(args.end(), vals.begin(), vals.end());
+  d_usrp->write_i2c (d_i2c_addr, int_seq_to_str (args));
+}
+        
+std::vector<int>
+db_dbs_rx::_read_status ()
+{
+  //If successful, return list of two ints: [status_info, filter_DAC]"""
+  std::string s = d_usrp->read_i2c (d_i2c_addr, 2);
+  if(s.size() != 2) {
+    std::vector<int> ret(0);
+    return ret;
+  }
+  return str_to_int_seq (s);
+}
+
+void
+db_dbs_rx::_send_reg(int regno)
+{
+  assert(0 <= regno && regno <= 5);
+  if(regno == 0)
+    _write_reg(0,(d_div2<<7) + (d_n>>8));
+  if(regno == 1)
+    _write_reg(1,d_n & 255);
+  if(regno == 2)
+    _write_reg(2,d_osc + (d_cp<<3) + (d_r_int<<5));
+  if(regno == 3)
+    _write_reg(3,d_fdac);
+  if(regno == 4)
+    _write_reg(4,d_m + (d_dl<<5) + (d_ade<<6) + (d_adl<<7));
+  if(regno == 5)
+    _write_reg(5,d_gc2 + (d_diag<<5));
+}
+
+// BW setting
+void
+db_dbs_rx::_set_m(int m)
+{
+  assert(m>0 && m<32);
+  d_m = m;
+  _send_reg(4);
+}
+  
+void
+db_dbs_rx::_set_fdac(int fdac)
+{
+  assert(fdac>=0 && fdac<128);
+  d_fdac = fdac;
+  _send_reg(3);
+}
+
+struct bw_t
+db_dbs_rx::set_bw (float bw)
+{
+  assert(bw>=1e6 && bw<=33e6);
+
+  struct bw_t ret = {0, 0, 0};
+  int m_max, m_min, m_test, fdac_test;
+  if(bw >= 4e6)
+    m_max = int(std::min(31, (int)floor(_refclk_freq()/1e6)));
+  else if(bw >= 2e6)      // Outside of Specs!
+    m_max = int(std::min(31, (int)floor(_refclk_freq()/.5e6)));
+  else      // Way outside of Specs!
+    m_max = int(std::min(31, (int)floor(_refclk_freq()/.25e6)));
+  
+  m_min = int(ceil(_refclk_freq()/2.5e6));
+  m_test = m_max;
+  while(m_test >= m_min) {
+    fdac_test = int(round(((bw * m_test / _refclk_freq())-4)/.145));
+    if(fdac_test > 127)
+      m_test = m_test - 1;
+    else
+      break;
+  }
+
+  if(m_test>=m_min && fdac_test>=0) {
+    _set_m(m_test);
+    _set_fdac(fdac_test);
+
+    ret.m = d_m;
+    ret.fdac = d_fdac;
+    ret.div = _refclk_freq()/d_m*(4+0.145*d_fdac);
+    return ret;
+  }
+  else {
+    fprintf(stderr, "Failed to set bw\n");
+  }
+}
+
+// Gain setting
+void
+db_dbs_rx::_set_dl(int dl)
+{
+  assert(dl == 0 || dl == 1);
+  d_dl = dl;
+  _send_reg(4);
+}
+
+void
+db_dbs_rx::_set_gc2(int gc2)
+{
+  assert(gc2<32 && gc2>=0);
+  d_gc2 = gc2;
+  _send_reg(5);
+}
+
+void
+db_dbs_rx::_set_gc1(int gc1)
+{
+  assert(gc1>=0 && gc1<4096);
+  d_gc1 = gc1;
+  d_usrp->write_aux_dac(d_which, 0, gc1);
+}
+
+void
+db_dbs_rx::_set_pga(int pga_gain)
+{
+  assert(pga_gain>=0 && pga_gain<=20);
+  if(d_which == 0) {
+    d_usrp->set_pga (0, pga_gain);
+    d_usrp->set_pga (1, pga_gain);
+  }
+  else {
+    d_usrp->set_pga (2, pga_gain);
+    d_usrp->set_pga (3, pga_gain);
+  }
+}
+
+float
+db_dbs_rx::gain_min()
+{
+  return 0;
+}
+
+float
+db_dbs_rx::gain_max()
+{
+  return 104;
+}
+
+float
+db_dbs_rx::gain_db_per_step()
+{
+  return 1;
+}
+
+bool 
+db_dbs_rx::set_gain(float gain)
+{
+  // Set the gain.
+  // 
+  // @param gain:  gain in decibels
+  // @returns True/False
+
+  if(!(gain>=0 && gain<105)) {
+    throw std::runtime_error("gain out of range\n");
+  }
+
+  int gc1=0, gc2=0, dl=0, pga=0;
+
+  if(gain < 56) {
+    gc1 = int((-gain*1.85/56.0 + 2.6)*4096.0/3.3);
+    gain = 0;
+  }
+  else {
+    gc1 = 0;
+    gain -= 56;
+  }
+   
+  if(gain < 24) {
+    gc2 = int(round(31.0 * (1-gain/24.0)));
+    gain = 0;
+  }
+  else {
+    gc2 = 0;
+    gain -=24;
+  }
+  
+  if(gain >= 4.58) {
+    dl = 1;
+    gain -= 4.58;
+  }
+
+  pga = gain;
+  _set_gc1(gc1);
+  _set_gc2(gc2);
+  _set_pga(pga);
+
+  return true;
+}
+
+// Frequency setting
+void
+db_dbs_rx::_set_osc(int osc)
+{
+  assert(osc>=0 && osc<8);
+  d_osc = osc;
+  _send_reg(2);
+}
+
+void
+db_dbs_rx::_set_cp(int cp)
+{
+  assert(cp>=0 && cp<4);
+  d_cp = cp;
+  _send_reg(2);
+}
+
+void
+db_dbs_rx::_set_n(int n)
+{
+  assert(n>256 && n<32768);
+  d_n = n;
+  _send_reg(0);
+  _send_reg(1);
+}
+
+void
+db_dbs_rx::_set_div2(int div2)
+{
+  assert(div2 == 0 || div2 == 1);
+  d_div2 = div2;
+  _send_reg(0);
+}
+
+void
+db_dbs_rx::_set_r(int r)
+{
+  assert(r>=0 && r<128);
+  d_r = r;
+  d_r_int = int(round(log10(r)/log10(2)) - 1);
+  _send_reg(2);
+}
+
+// FIXME  How do we handle ADE and ADL properly?
+void
+db_dbs_rx::_set_ade(int ade)
+{
+  assert(ade == 0 || ade == 1);
+  d_ade = ade;
+  _send_reg(4);
+}
+
+float
+db_dbs_rx::freq_min()
+{
+  return 500e6;
+}
+
+float
+db_dbs_rx::freq_max()
+{
+  return 2.6e9;
+}
+
+struct freq_result_t
+db_dbs_rx::set_freq(float freq)
+{
+  // Set the frequency.
+  // 
+  // @param freq:  target RF frequency in Hz
+  // @type freq:   float
+  // 
+  // @returns (ok, actual_baseband_freq) where:
+  //   ok is True or False and indicates success or failure,
+  //   actual_baseband_freq is RF frequency that corresponds to DC in the IF.
+  
+  freq_result_t args = {false, 0};
+  
+  if(!(freq>=500e6 && freq<=2.6e9)) {
+    return args;
+  }
+
+  float vcofreq;
+  if(freq<1150e6) {
+    _set_div2(0);
+    vcofreq = 4 * freq;
+  }
+  else {
+    _set_div2(1);
+    vcofreq = 2 * freq;
+  }
+  
+  _set_ade(1);
+  int rmin = std::max(2, (int)(_refclk_freq()/2e6));
+  int rmax = std::min(128, (int)(_refclk_freq()/500e3));
+  int r = 2;
+  int n=0;
+  int best_r = 2;
+  int best_n =0;
+  int best_delta = 10e6;
+  float delta;
+  
+  while(r <= rmax) {
+    n = round(freq/(_refclk_freq()/r));
+    if(r<rmin || n<256) {
+      r = r * 2;
+      continue;
+    }
+    delta = abs(n*_refclk_freq()/r - freq);
+    if(delta < 75e3) {
+      best_r = r;
+      best_n = n;
+      break;
+    }
+    if(delta < best_delta*0.9) {
+      best_r = r;
+      best_n = n;
+      best_delta = delta;
+    }
+    r = r * 2;
+  }
+  _set_r(int(best_r));
+
+  _set_n(int(round(best_n)));
+ 
+  int vco;
+  if(vcofreq < 2433e6)
+    vco = 0;
+  else if(vcofreq < 2711e6)
+    vco=1;
+  else if(vcofreq < 3025e6)
+    vco=2;
+  else if(vcofreq < 3341e6)
+    vco=3;
+  else if(vcofreq < 3727e6)
+    vco=4;
+  else if(vcofreq < 4143e6)
+    vco=5;
+  else if(vcofreq < 4493e6)
+    vco=6;
+  else
+    vco=7;
+  
+  _set_osc(vco);
+  
+  // Set CP current
+  int adc_val = 0;
+  std::vector<int> bytes(2);
+  while(adc_val == 0 || adc_val == 7) {
+    bytes = _read_status();
+    adc_val = bytes[0] >> 2;
+    if(adc_val == 0) {
+      if(vco <= 0) {
+       return args;
+      }
+      else {
+       vco = vco - 1;
+      }
+    }
+    else if(adc_val == 7) {
+      if(vco >= 7) {
+       return args;
+      }
+      else {
+       vco = vco + 1;
+      }
+    }
+    _set_osc(vco);
+  }
+  
+  if(adc_val == 1 || adc_val == 2) {
+    _set_cp(1);
+  }
+  else if(adc_val == 3 || adc_val == 4) {
+    _set_cp(2);
+  }
+  else {
+    _set_cp(3);
+  }
+  
+  args.ok = true;
+  args.baseband_freq = d_n * _refclk_freq() / d_r;
+  return args;
+}
+
+int
+db_dbs_rx::_refclk_divisor()
+{
+  //Return value to stick in REFCLK_DIVISOR register
+  return 16;
+}
+
+bool 
+db_dbs_rx::is_quadrature()
+{
+  // Return True if this board requires both I & Q analog channels.  
+  return true;
+}

Added: 
gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.h
===================================================================
--- gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.h  
                        (rev 0)
+++ gnuradio/branches/developers/trondeau/dbs/usrp/host/lib/legacy/db_dbs_rx.h  
2008-08-19 13:03:20 UTC (rev 9330)
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio 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 asversion 3, or (at your option)
+// any later version.
+// 
+// GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_DBS_RX_H
+#define DB_DBS_RX_H
+
+#include <db_base.h>
+
+struct bw_t {
+  int m;
+  int fdac;
+  float div;
+};
+
+class db_dbs_rx : public db_base
+{
+private:
+  usrp_basic_rx *d_usrp;
+  int d_osc, d_cp, d_n, d_div2, d_r, d_r_int;
+  int d_fdac, d_m, d_dl, d_ade, d_adl, d_gc1, d_gc2, d_diag;
+  int d_refclk_divisor;
+  int d_i2c_addr;
+  
+  // Internal gain functions
+  void _write_reg(int regno, int v);
+  void _write_regs(int starting_regno, const std::vector<int> &vals);
+  std::vector<int> _read_status();
+  void _send_reg(int regno);
+  void _set_m(int m);
+  void _set_fdac(int fdac);
+  bw_t set_bw(float bw);
+  void _set_dl(int dl);
+  void _set_gc2(int gc2);
+  void _set_gc1(int gc1);
+  void _set_pga(int pga_gain);
+
+  // Internal frequency function
+  void _set_osc(int osc);
+  void _set_cp(int cp);
+  void _set_n(int n);
+  void _set_div2(int div2);
+  void _set_r(int r);
+  void _set_ade(int ade);
+
+  int _refclk_divisor();
+
+
+public:
+  db_dbs_rx(usrp_basic *usrp, int which);
+  ~db_dbs_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  float freq_min();
+  float freq_max();
+  struct freq_result_t set_freq(float freq);
+  bool  set_gain(float gain);
+  bool  is_quadrature();
+};
+
+#endif





reply via email to

[Prev in Thread] Current Thread [Next in Thread]