switch source package format to 3.0 quilt
[debian/gnuradio] / usrp2 / firmware / lib / db_init.c
index d47beb11d85d30dd556cdad46eb2c368247a085c..d58badc9e5d9907c12c5899c2010e617838115f4 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  *
  * 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
@@ -37,9 +37,21 @@ extern struct db_base db_lf_tx;
 extern struct db_base db_lf_rx;
 extern struct db_base db_rfx_400_tx;
 extern struct db_base db_rfx_400_rx;
+extern struct db_base db_rfx_900_tx;
+extern struct db_base db_rfx_900_rx;
+extern struct db_base db_rfx_1200_tx;
+extern struct db_base db_rfx_1200_rx;
+extern struct db_base db_rfx_1800_tx;
+extern struct db_base db_rfx_1800_rx;
+extern struct db_base db_rfx_2400_tx;
+extern struct db_base db_rfx_2400_rx;
+extern struct db_base db_wbxng_rx;
+extern struct db_base db_wbxng_tx;
 extern struct db_base db_tvrx1;
 extern struct db_base db_tvrx2;
 extern struct db_base db_tvrx3;
+extern struct db_base db_dbsrx;
+extern struct db_base db_bitshark_rx;
 
 struct db_base *all_dboards[] = {
   &db_basic_tx,
@@ -48,9 +60,21 @@ struct db_base *all_dboards[] = {
   &db_lf_rx,
   &db_rfx_400_tx,
   &db_rfx_400_rx,
+  &db_rfx_900_tx,
+  &db_rfx_900_rx,
+  &db_rfx_1200_tx,
+  &db_rfx_1200_rx,
+  &db_rfx_1800_tx,
+  &db_rfx_1800_rx,
+  &db_rfx_2400_tx,
+  &db_rfx_2400_rx,
   &db_tvrx1,
+#if 0
   &db_tvrx2,
+#endif
   &db_tvrx3,
+  &db_dbsrx,
+  &db_bitshark_rx,
   0
 };
 
@@ -81,7 +105,7 @@ read_raw_dboard_eeprom (unsigned char *buf, int i2c_addr)
 /*
  * Return DBID, -1 <none> or -2 <invalid eeprom contents>
  */
-static int
+int
 read_dboard_eeprom(int i2c_addr)
 {
   unsigned char buf[DB_EEPROM_CLEN];
@@ -123,19 +147,23 @@ lookup_dboard(int i2c_addr, struct db_base *default_db, char *msg)
 {
   struct db_base *db;
   int dbid = read_dboard_eeprom(i2c_addr);
+
+  // FIXME removing this printf has the system hang if there are two d'boards
+  // installed.  (I think the problem is in i2c_read/write or the way
+  // I kludge the zero-byte write to set the read address in eeprom_read.)
   printf("%s dbid: 0x%x\n", msg, dbid);
 
   if (dbid < 0){       // there was some kind of problem.  Treat as Basic Tx
     return default_db;
   }
   else if ((db = lookup_dbid(dbid)) == 0){
-    return default_db;
     printf("No daugherboard code for dbid = 0x%x\n", dbid);
+    return default_db;
   }
   return db;
 }
 
-static void
+void
 set_atr_regs(int bank, struct db_base *db)
 {
   uint32_t     val[4];
@@ -180,19 +208,79 @@ set_gpio_mode(int bank, struct db_base *db)
   }
 }
 
+static int __attribute__((unused))
+determine_tx_mux_value(struct db_base *db) 
+{
+  if (db->i_and_q_swapped)
+    return 0x01;
+  else
+    return 0x10;
+}
+
+static int
+determine_rx_mux_value(struct db_base *db)
+{
+#define        ADC0 0x0
+#define        ADC1 0x1
+#define ZERO 0x2
+  
+  static int truth_table[8] = {
+    /* swap_iq, uses */
+    /* 0, 0x0 */    (ZERO << 2) | ZERO,                // N/A
+    /* 0, 0x1 */    (ZERO << 2) | ADC0,
+    /* 0, 0x2 */    (ZERO << 2) | ADC1,
+    /* 0, 0x3 */    (ADC1 << 2) | ADC0,
+    /* 1, 0x0 */    (ZERO << 2) | ZERO,                // N/A
+    /* 1, 0x1 */    (ZERO << 2) | ADC0,
+    /* 1, 0x2 */    (ZERO << 2) | ADC1,
+    /* 1, 0x3 */    (ADC0 << 2) | ADC1,
+  };
+
+  int  subdev0_uses;
+  int  subdev1_uses;
+  int  uses;
+
+  if (db->is_quadrature)
+    subdev0_uses = 0x3;                // uses A/D 0 and 1
+  else
+    subdev0_uses = 0x1;                // uses A/D 0 only
+
+  // FIXME second subdev on Basic Rx, LF RX
+  // if subdev2 exists
+  // subdev1_uses = 0x2;
+  subdev1_uses = 0;
+
+  uses = subdev0_uses;
+
+  int swap_iq = db->i_and_q_swapped & 0x1;
+  int index = (swap_iq << 2) | uses;
+
+  return truth_table[index];
+}
+
+
 void
 db_init(void)
 {
+  int  m;
 
   tx_dboard = lookup_dboard(I2C_ADDR_TX_A, &db_basic_tx, "Tx");
   //printf("db_init: tx dbid = 0x%x\n", tx_dboard->dbid);
   set_gpio_mode(GPIO_TX_BANK, tx_dboard);
   tx_dboard->init(tx_dboard);
+  m = determine_tx_mux_value(tx_dboard);
+  dsp_tx_regs->tx_mux = m;
+  //printf("tx_mux = 0x%x\n", m);
+  tx_dboard->current_lo_offset = tx_dboard->default_lo_offset;
 
   rx_dboard = lookup_dboard(I2C_ADDR_RX_A, &db_basic_rx, "Rx");
   //printf("db_init: rx dbid = 0x%x\n", rx_dboard->dbid);
   set_gpio_mode(GPIO_RX_BANK, rx_dboard);
   rx_dboard->init(rx_dboard);
+  m = determine_rx_mux_value(rx_dboard);
+  dsp_rx_regs->rx_mux = m;
+  //printf("rx_mux = 0x%x\n", m);
+  rx_dboard->current_lo_offset = rx_dboard->default_lo_offset;
 }
 
 /*!
@@ -211,19 +299,13 @@ calc_dxc_freq(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t baseband_freq,
   u2_fxpt_freq_t fs = U2_DOUBLE_TO_FXPT_FREQ(100e6);   // converter sample rate
   u2_fxpt_freq_t delta = target_freq - baseband_freq;
 
+#if 0
   printf("calc_dxc_freq\n");
   printf("  fs       = "); print_fxpt_freq(fs); newline();
   printf("  target   = "); print_fxpt_freq(target_freq); newline();
   printf("  baseband = "); print_fxpt_freq(baseband_freq); newline();
   printf("  delta    = "); print_fxpt_freq(delta); newline();
-  
-#if 0
-  printf("--- printed as uint64_t ---\n");
-  printf("  fs       = "); print_uint64(fs); newline();
-  printf("  target   = "); print_uint64(target_freq); newline();
-  printf("  baseband = "); print_uint64(baseband_freq); newline();
-  printf("  delta    = "); print_uint64(delta); newline();
-#endif
+#endif  
 
   if (delta >= 0){
     while (delta > fs)
@@ -238,20 +320,25 @@ calc_dxc_freq(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t baseband_freq,
     }
   }
   else {
-    while (delta < -fs){
+    while (delta < -fs)
       delta += fs;
-      if (delta >= -fs/2){     // non-inverted region
-       *dxc_freq = -delta;
-       *inverted = false;
-      }
-      else {                   // inverted region
-       *dxc_freq = delta + fs;
-       *inverted = true;
-      }
+    if (delta >= -fs/2){       // non-inverted region
+      *dxc_freq = -delta;
+      *inverted = false;
+    }
+    else {                     // inverted region
+      *dxc_freq = delta + fs;
+      *inverted = true;
     }
   }
 }
 
+bool
+db_set_lo_offset(struct db_base *db, u2_fxpt_freq_t offset)
+{
+  db->current_lo_offset = offset;
+  return true;
+}
 
 bool
 db_tune(struct db_base *db, u2_fxpt_freq_t target_freq, struct tune_result *result)
@@ -261,8 +348,8 @@ db_tune(struct db_base *db, u2_fxpt_freq_t target_freq, struct tune_result *resu
   u2_fxpt_freq_t dxc_freq;
   u2_fxpt_freq_t actual_dxc_freq;
 
-  // Ask the d'board to tune as closely as it can to target_freq
-  bool ok = db->set_freq(db, target_freq, &result->baseband_freq);
+  // Ask the d'board to tune as closely as it can to target_freq+lo_offset
+  bool ok = db->set_freq(db, target_freq+db->current_lo_offset, &result->baseband_freq);
 
   // Calculate the DDC setting that will downconvert the baseband from the
   // daughterboard to our target frequency.
@@ -301,17 +388,17 @@ compute_freq_control_word(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t *actual_fre
   //   master = 100e6;
   //   v = (int) rint(target_freq / master_freq) * pow(2.0, 32.0);
 
-  printf("compute_freq_control_word\n");
-  printf("  target_freq = "); print_fxpt_freq(target_freq); newline();
+  //printf("compute_freq_control_word\n");
+  //printf("  target_freq = "); print_fxpt_freq(target_freq); newline();
 
   int32_t master_freq = 100000000;     // 100M
 
   int32_t v = ((target_freq << 12)) / master_freq;
-  printf("  fcw = %d\n", v);
+  //printf("  fcw = %d\n", v);
 
   *actual_freq = (v * (int64_t) master_freq) >> 12;
 
-  printf("  actual = "); print_fxpt_freq(*actual_freq); newline();
+  //printf("  actual = "); print_fxpt_freq(*actual_freq); newline();
 
   return v;
 }
@@ -338,3 +425,10 @@ db_set_gain(struct db_base *db, u2_fxpt_gain_t gain)
 {
   return db->set_gain(db, gain);
 }
+
+bool
+db_set_antenna(struct db_base *db, int ant)
+{
+  if (db->set_antenna == 0) return false;
+  return db->set_antenna(db, ant);
+}