commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r7404 - in usrp2/trunk: firmware/apps host/apps host/l


From: eb
Subject: [Commit-gnuradio] r7404 - in usrp2/trunk: firmware/apps host/apps host/lib
Date: Fri, 11 Jan 2008 15:04:58 -0700 (MST)

Author: eb
Date: 2008-01-11 15:04:50 -0700 (Fri, 11 Jan 2008)
New Revision: 7404

Modified:
   usrp2/trunk/firmware/apps/app_common.c
   usrp2/trunk/firmware/apps/rx_only.c
   usrp2/trunk/firmware/apps/tx_only.c
   usrp2/trunk/host/apps/tx_samples.cc
   usrp2/trunk/host/lib/usrp2_basic.cc
   usrp2/trunk/host/lib/usrp2_basic.h
Log:
work-in-progress.  tx_samples can now control various tx parameters.
tx_only.c hangs periodically, particularly with large frame sizes 
(> 250 samples) or interp <= 16.  Seems to be related to flow control
implementation.  Host stops sending frames (verified by looking at LED
on host RJ45 connector), I'm guessing that it's been flow controlled by a
PAUSE from the USRP.   On the opteron with forcedeth nic driver,
wireshark does not appear to show received PAUSED frames, but the host
does stop sending.



Modified: usrp2/trunk/firmware/apps/app_common.c
===================================================================
--- usrp2/trunk/firmware/apps/app_common.c      2008-01-11 21:59:46 UTC (rev 
7403)
+++ usrp2/trunk/firmware/apps/app_common.c      2008-01-11 22:04:50 UTC (rev 
7404)
@@ -189,6 +189,8 @@
 void
 config_tx_cmd(op_config_tx_t *p)
 {
+  printf("config_tx_cmd: interp = %d\n", p->interp);
+
   dsp_tx_regs->freq = p->phase_inc;
   dsp_tx_regs->scale_iq = p->scale_iq;
   dsp_tx_regs->interp_rate = p->interp - 1;    // register gets N-1

Modified: usrp2/trunk/firmware/apps/rx_only.c
===================================================================
--- usrp2/trunk/firmware/apps/rx_only.c 2008-01-11 21:59:46 UTC (rev 7403)
+++ usrp2/trunk/firmware/apps/rx_only.c 2008-01-11 22:04:50 UTC (rev 7404)
@@ -99,31 +99,15 @@
   hal_set_timeout(timer_delta);        // schedule next timeout
 }
 
-// Tx DSP underrun
-void
-underrun_irq_handler(unsigned irq)
-{
-  dsp_tx_regs->clear_state = 1;
-  //bp_clear_buf(DSP_TX_BUF_0);
-  //bp_clear_buf(DSP_TX_BUF_1);
-  //dbsm_stop(&dsp_tx_sm);
 
-  // FIXME anything else?
-
-  putstr("\nirq: underrun\n");
-}
-
 // Rx DSP overrun
 void
 overrun_irq_handler(unsigned irq)
 {
   dsp_rx_regs->clear_state = 1;
-  bp_clear_buf(DSP_RX_BUF_0);
-  bp_clear_buf(DSP_RX_BUF_1);
   dbsm_stop(&dsp_rx_sm);
+  // dbsm_start(&dsp_rx_sm);  // restart in start_rx_cmd
 
-  // FIXME anything else?
-
   putstr("\nirq: overrun\n");
 }
 
@@ -164,7 +148,7 @@
 void
 stop_rx_cmd(void)
 {
-  dsp_rx_regs->clear_state = 1;        // FIXME need to flush cmd queue
+  dsp_rx_regs->clear_state = 1;        // flush cmd queue
   bp_clear_buf(DSP_RX_BUF_0);
   bp_clear_buf(DSP_RX_BUF_1);
 }
@@ -208,7 +192,7 @@
   hal_set_leds(0x0, 0x3);
 
   pic_register_handler(IRQ_OVERRUN,  overrun_irq_handler);
-  pic_register_handler(IRQ_UNDERRUN, underrun_irq_handler);
+  // pic_register_handler(IRQ_UNDERRUN, underrun_irq_handler);
 
   //pic_register_handler(IRQ_TIMER, timer_irq_handler);
   //hal_set_timeout(timer_delta);

Modified: usrp2/trunk/firmware/apps/tx_only.c
===================================================================
--- usrp2/trunk/firmware/apps/tx_only.c 2008-01-11 21:59:46 UTC (rev 7403)
+++ usrp2/trunk/firmware/apps/tx_only.c 2008-01-11 22:04:50 UTC (rev 7404)
@@ -130,31 +130,16 @@
 void
 underrun_irq_handler(unsigned irq)
 {
-  dsp_tx_regs->clear_state = 1;
+  putchar('U');
 
+  dsp_tx_regs->clear_state = 1;
   dbsm_stop(&dsp_tx_sm);
   dbsm_start(&dsp_tx_sm);  // restart sm so we're listening to ethernet again
 
-  // FIXME anything else?
-
-  putstr("\nirq: underrun\n");
+  // putstr("\nirq: underrun\n");
 }
 
-// Rx DSP overrun
-void
-overrun_irq_handler(unsigned irq)
-{
-  dsp_rx_regs->clear_state = 1;
-  bp_clear_buf(DSP_RX_BUF_0);
-  bp_clear_buf(DSP_RX_BUF_1);
-  dbsm_stop(&dsp_rx_sm);
 
-  // FIXME anything else?
-
-  putstr("\nirq: overrun\n");
-}
-
-
 void
 start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
 {
@@ -172,6 +157,7 @@
   bp_clear_buf(DSP_TX_BUF_0);
   bp_clear_buf(DSP_TX_BUF_1);
 
+#if 1
   int tx_scale = 256;
   int interp = 32;
 
@@ -182,21 +168,11 @@
   def_config.interp = interp;
 
   // setup Tx DSP regs
-  dsp_tx_regs->clear_state = 1;                        // reset
   config_tx_cmd(&def_config);
+#endif
 }
 
-#if 0
-static void
-stop_tx_cmd(void)
-{
-  dsp_tx_regs->clear_state = 1;
-  bp_clear_buf(DSP_TX_BUF_0);
-  bp_clear_buf(DSP_TX_BUF_1);
-}
-#endif
 
-
 inline static void
 buffer_irq_handler(unsigned irq)
 {
@@ -229,7 +205,7 @@
   // Control LEDs
   hal_set_leds(0x0, 0x3);
 
-  pic_register_handler(IRQ_OVERRUN,  overrun_irq_handler);
+  // pic_register_handler(IRQ_OVERRUN,  overrun_irq_handler);
   pic_register_handler(IRQ_UNDERRUN, underrun_irq_handler);
 
   //pic_register_handler(IRQ_TIMER, timer_irq_handler);

Modified: usrp2/trunk/host/apps/tx_samples.cc
===================================================================
--- usrp2/trunk/host/apps/tx_samples.cc 2008-01-11 21:59:46 UTC (rev 7403)
+++ usrp2/trunk/host/apps/tx_samples.cc 2008-01-11 22:04:50 UTC (rev 7404)
@@ -23,53 +23,118 @@
 #include <iostream>
 #include <complex>
 #include <getopt.h>
+#include "strtod_si.h"
 
 #define        T_NOW (-1)
 
 typedef std::complex<float> fcomplex;
 
 
+static const char *
+prettify_progname(const char *progname)                // that's probably 
almost a word ;)
+{
+  const char *p = strrchr(progname, '/');      // drop leading directory path
+  if (p)
+    p++;
+
+  if (strncmp(p, "lt-", 3) == 0)               // drop lt- libtool prefix
+    p += 3;
+
+  return p;
+}
+
 static void
 usage(const char *progname)
 {
-  fprintf(stderr, "usage: %s [-h] [-r] [-i <input_file>] [-e ethN]\n",
-         progname);
+  fprintf(stderr, "Usage: %s [options]\n\n", prettify_progname(progname));
+  fprintf(stderr, "Options:\n");
+  fprintf(stderr, "  -h                   show this message and exit\n");
+  fprintf(stderr, "  -e ETH_INTERFACE     specify ethernet interface 
[default=eth0]\n");
+  fprintf(stderr, "  -m MAC_ADDR          mac address of USRP2 HH:HH 
[default=first one found]\n");
+  fprintf(stderr, "  -I INPUT_FILE        set input filename 
[default=stdin]\n");
+  fprintf(stderr, "  -r                   repeat.  When EOF of input file is 
reached, seek to beginning\n");
+  fprintf(stderr, "  -f FREQ              set frequency to FREQ 
[default=0]\n");
+  fprintf(stderr, "  -i INTERP            set interpolation rate to INTERP 
[default=32]\n");
+  fprintf(stderr, "  -F SAMPLES_PER_FRAME number of samples in each frame 
[default=372]\n");
+  fprintf(stderr, "  -S SCALE             fpga scaling factor for I & Q 
[default=256]\n");
 }
 
 int
 main(int argc, char **argv)
 {
-  int ch;
+  const char *interface = "eth0";
   const char *input_filename = 0;
-  const char *interface = "eth0";
-  size_t nsamples_per_pkt = 250;
   bool repeat = false;
+  const char *mac_addr_str = 0;
+  double freq = 0;
+  int32_t interp = 32;
+  int32_t samples_per_frame = 372;
+  int32_t scale = 256;
   
+  int    ch;
+  double tmp;
+  u2_mac_addr_t mac_addr;
 
-  while ((ch = getopt(argc, argv, "i:hre:")) != EOF){
+  while ((ch = getopt(argc, argv, "he:m:I:rf:i:F:S")) != EOF){
     switch (ch){
+
+    case 'e':
+      interface = optarg;
+      break;
+      
+    case 'm':
+      mac_addr_str = optarg;
+      if (!usrp2_basic::parse_mac_addr(optarg, &mac_addr)){
+       std::cerr << "invalid mac addr: " << optarg << std::endl;
+       usage(argv[0]);
+       return 1;
+      }
+      break;
+
+    case 'I':
+      input_filename = optarg;
+      break;
+      
     case 'r':
       repeat = true;
       break;
       
+    case 'f':
+      if (!strtod_si(optarg, &freq)){
+       std::cerr << "invalid number: " << optarg << std::endl;
+       usage(argv[0]);
+       return 1;
+      }
+      break;
+
+    case 'F':
+      samples_per_frame = strtol(optarg, 0, 0);
+      break;
+
     case 'i':
-      input_filename = optarg;
+      interp = strtol(optarg, 0, 0);
       break;
-      
-    case 'e':
-      interface = optarg;
+
+    case 'S':
+      if (!strtod_si(optarg, &tmp)){
+       std::cerr << "invalid number: " << optarg << std::endl;
+       usage(argv[0]);
+       return 1;
+      }
+      scale = static_cast<int32_t>(tmp);
       break;
       
     case 'h':
     default:
       usage(argv[0]);
-      exit(1);
+      return 1;
     }
   }
+
   
   if (argc - optind != 0){
     usage(argv[0]);
-    exit(1);
+    return 1;
   }
   
   FILE *fp = 0;
@@ -83,11 +148,18 @@
     }
   }
 
+  if (samples_per_frame < 9 || samples_per_frame > 506){
+    std::cerr << prettify_progname(argv[0])
+             << ": samples_per_frame is out of range.  Must be in [9, 506].\n";
+    usage(argv[0]);
+    return 1;
+  }
+
   usrp2_basic *u2 = new usrp2_basic();
 
   if (!u2->open(interface)){
     std::cerr << "couldn't open " << interface << std::endl;
-    return 0;
+    return 1;
   }
 
   std::vector<op_id_reply_t> r = u2->find_usrps();
@@ -104,22 +176,32 @@
   u2_mac_addr_t which = r[0].addr;     // pick the first one
 
 
+  if (1){
+    if (!u2->config_tx(which, freq, interp, scale, scale)){
+      std::cerr << "tx_samples: config_tx failed\n";
+      return 1;
+    }
+  }
+
   u2_eth_samples_t     pkt;
   u2p_set_word0(&pkt.fixed, U2P_TX_IMMEDIATE | U2P_TX_START_OF_BURST, 0);
   u2p_set_timestamp(&pkt.fixed, T_NOW);
 
   while (1){
 
-    int r = fread(&pkt.samples, sizeof(uint32_t), nsamples_per_pkt, fp);
+    int r = fread(&pkt.samples, sizeof(uint32_t), samples_per_frame, fp);
 
     // fprintf(stderr, "fread -> %d\n", r);
     
     if (r == 0){
       if (!repeat)
        break;
-      fseek(fp, 0, SEEK_SET);
+      if (fseek(fp, 0, SEEK_SET) == -1)
+       break;
     }
 
+    // FIXME if r < 9, pad to 9 for minimum packet size constraint
+
     if (!u2->write_samples(which, &pkt, r))
       break;
   }

Modified: usrp2/trunk/host/lib/usrp2_basic.cc
===================================================================
--- usrp2/trunk/host/lib/usrp2_basic.cc 2008-01-11 21:59:46 UTC (rev 7403)
+++ usrp2/trunk/host/lib/usrp2_basic.cc 2008-01-11 22:04:50 UTC (rev 7404)
@@ -256,6 +256,46 @@
   return true;
 }
 
+bool
+usrp2_basic::config_tx(const u2_mac_addr_t &which,
+                      double freq,
+                      unsigned int interp,
+                      int scale_i,                     // 16.0 fixed point 
format
+                      int scale_q                      // 16.0 fixed point 
format
+                      )
+{
+  uint8_t      pktbuf[MAX_PKTLEN];
+  memset(pktbuf, 0, sizeof(pktbuf));
+
+  struct command {
+    u2_eth_packet_t    h;
+    op_config_tx_t     op;
+  };
+    
+  command      *c = (command *) pktbuf;
+  c->h.ehdr.ethertype = htons(U2_ETHERTYPE);
+  c->h.ehdr._pad = 0;
+  c->h.ehdr.dst = which;
+  memcpy(&c->h.ehdr.src, d_ethernet->mac(), 6);
+  u2p_set_word0(&c->h.fixed, 0, CONTROL_CHAN);
+  u2p_set_timestamp(&c->h.fixed, -1);
+
+  c->op.opcode = OP_CONFIG_TX;
+  c->op.len = sizeof(op_config_tx_t);
+
+  double actual_freq;
+  c->op.phase_inc = htonl(compute_freq_control_word_fpga(adc_rate(), freq, 
&actual_freq));
+  c->op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
+  c->op.interp = htonl(interp);
+
+  int len = std::max((size_t) MIN_PKTLEN, sizeof(command));
+  if (d_ethernet->write_packet(c, len) != len)
+    return false;
+
+  return true;
+}
+
+
 // ------------------------------------------------------------------------
 
 void
@@ -376,7 +416,7 @@
 bool
 usrp2_basic::parse_mac_addr(const std::string &s, u2_mac_addr_t *p)
 {
-  p->addr[0] = 0x00;
+  p->addr[0] = 0x00;           // Matt's IAB
   p->addr[1] = 0x50;
   p->addr[2] = 0xC2;
   p->addr[3] = 0x85;

Modified: usrp2/trunk/host/lib/usrp2_basic.h
===================================================================
--- usrp2/trunk/host/lib/usrp2_basic.h  2008-01-11 21:59:46 UTC (rev 7403)
+++ usrp2/trunk/host/lib/usrp2_basic.h  2008-01-11 22:04:50 UTC (rev 7404)
@@ -79,6 +79,14 @@
 
   bool stop_rx(const u2_mac_addr_t &which);
 
+
+  bool config_tx(const u2_mac_addr_t &which,
+                double freq,
+                unsigned int interp,
+                int scale_i,                   // 16.0 fixed point format
+                int scale_q                    // 16.0 fixed point format
+                );
+
   /*!
    * \brief Read raw samples from USRP2.
    *
@@ -137,7 +145,7 @@
   long adc_rate() const { return fpga_master_clock_freq(); }
 
   //! Return D/A sample rate
-  long dac_rate() const { return fpga_master_clock_freq(); }   // FIXME? * 4
+  long dac_rate() const { return fpga_master_clock_freq(); }
 
 };
 





reply via email to

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