summaryrefslogtreecommitdiff
path: root/usrp/host/apps/test_usrp_standard_tx.cc
diff options
context:
space:
mode:
authorjcorgan2006-08-03 04:51:51 +0000
committerjcorgan2006-08-03 04:51:51 +0000
commit5d69a524f81f234b3fbc41d49ba18d6f6886baba (patch)
treeb71312bf7f1e8d10fef0f3ac6f28784065e73e72 /usrp/host/apps/test_usrp_standard_tx.cc
downloadgnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.tar.gz
gnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.tar.bz2
gnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.zip
Houston, we have a trunk.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3122 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'usrp/host/apps/test_usrp_standard_tx.cc')
-rw-r--r--usrp/host/apps/test_usrp_standard_tx.cc319
1 files changed, 319 insertions, 0 deletions
diff --git a/usrp/host/apps/test_usrp_standard_tx.cc b/usrp/host/apps/test_usrp_standard_tx.cc
new file mode 100644
index 000000000..8aebaeb8f
--- /dev/null
+++ b/usrp/host/apps/test_usrp_standard_tx.cc
@@ -0,0 +1,319 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 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 version 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <usb.h> /* needed for usb functions */
+#include <getopt.h>
+#include <assert.h>
+#include <math.h>
+#include "time_stuff.h"
+#include "usrp_standard.h"
+#include "usrp_bytesex.h"
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+char *prog_name;
+
+static bool test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
+ bool dc_p, bool counting_p);
+
+static void
+set_progname (char *path)
+{
+ char *p = strrchr (path, '/');
+ if (p != 0)
+ prog_name = p+1;
+ else
+ prog_name = path;
+}
+
+static void
+usage ()
+{
+ fprintf (stderr,
+ "usage: %s [-f] [-v] [-d] [-c] [-a <ampl>][-I <interp>] [-F freq] [-D]\n", prog_name);
+ fprintf (stderr, " [-f] loop forever\n");
+ fprintf (stderr, " [-M] how many Megabytes to transfer (default 128)\n");
+ fprintf (stderr, " [-v] verbose\n");
+ fprintf (stderr, " [-d] dump registers\n");
+ // fprintf (stderr, " [-l] digital loopback in FPGA\n");
+ fprintf (stderr, " [-c] Tx counting sequence\n");
+ fprintf (stderr, " [-D] DC output\n");
+
+ fprintf (stderr, " [-B <fusb_block_size>] set fast usb block_size\n");
+ fprintf (stderr, " [-N <fusb_nblocks>] set fast usb nblocks\n");
+ fprintf (stderr, " [-R] set real time scheduling: SCHED_FIFO; pri = midpoint\n");
+
+ exit (1);
+}
+
+static void
+die (const char *msg)
+{
+ fprintf (stderr, "die: %s: %s\n", prog_name, msg);
+ exit (1);
+}
+
+static void
+dump_codec_regs (usrp_basic *u, int which_codec, FILE *fp)
+{
+ for (int i = 0; i < 64; i++){
+ unsigned char v;
+ u->_read_9862 (which_codec, i, &v);
+ fprintf (fp, "%2d: 0x%02x\n", i, v);
+ }
+ fflush (fp);
+}
+
+static void
+do_dump_codec_regs (usrp_basic *u)
+{
+ char name[100];
+ strcpy (name, "regsXXXXXX");
+ int fd = mkstemp (name);
+ if (fd == -1){
+ perror (name);
+ }
+ else {
+ FILE *fp = fdopen (fd, "w");
+ dump_codec_regs (u, 0, fp);
+ fclose (fp);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ bool verbose_p = false;
+ bool dump_regs_p = false;
+ bool dc_p = false;
+ // bool loopback_p = false;
+ bool counting_p = false;
+ int max_bytes = 128 * (1L << 20);
+ int ch;
+ int which_board = 0;
+ int interp = 16; // 32.0 MB/sec
+ double center_freq = 0;
+ double ampl = 10000;
+ int fusb_block_size = 0;
+ int fusb_nblocks = 0;
+ bool realtime_p = false;
+
+
+ set_progname (argv[0]);
+
+ while ((ch = getopt (argc, argv, "vfdcI:F:a:DM:B:N:R")) != EOF){
+ switch (ch){
+ case 'f':
+ max_bytes = 0;
+ break;
+
+ case 'v':
+ verbose_p = true;
+ break;
+
+ case 'd':
+ dump_regs_p = true;
+ break;
+
+ case 'D':
+ dc_p = true;
+ break;
+
+#if 0
+ case 'l':
+ loopback_p = true;
+ break;
+#endif
+
+ case 'c':
+ counting_p = true;
+ break;
+
+ case 'I':
+ interp = strtol (optarg, 0, 0);
+ break;
+
+ case 'F':
+ center_freq = strtod (optarg, 0);
+ break;
+
+ case 'a':
+ ampl = strtod (optarg, 0);
+ break;
+
+ case 'M':
+ max_bytes = strtol (optarg, 0, 0) * (1L << 20);
+ if (max_bytes < 0) max_bytes = 0;
+ break;
+
+ case 'B':
+ fusb_block_size = strtol (optarg, 0, 0);
+ break;
+
+ case 'N':
+ fusb_nblocks = strtol (optarg, 0, 0);
+ break;
+
+ case 'R':
+ realtime_p = true;
+ break;
+
+ default:
+ usage ();
+ }
+ }
+
+#ifdef HAVE_SCHED_SETSCHEDULER
+ if (realtime_p){
+ int policy = SCHED_FIFO;
+ int pri = (sched_get_priority_max (policy) - sched_get_priority_min (policy)) / 2;
+ int pid = 0; // this process
+
+ struct sched_param param;
+ memset(&param, 0, sizeof(param));
+ param.sched_priority = pri;
+ int result = sched_setscheduler(pid, policy, &param);
+ if (result != 0){
+ perror ("sched_setscheduler: failed to set real time priority");
+ }
+ else
+ printf("SCHED_FIFO enabled with priority = %d\n", pri);
+ }
+#endif
+
+ usrp_standard_tx *utx;
+
+ utx = usrp_standard_tx::make (which_board,
+ interp,
+ 1, // nchan
+ -1, // mux
+ fusb_block_size,
+ fusb_nblocks);
+
+ if (utx == 0)
+ die ("usrp_standard_tx::make");
+
+ if (!utx->set_tx_freq (0, center_freq))
+ die ("utx->set_tx_freq");
+
+ if (dump_regs_p)
+ do_dump_codec_regs (utx);
+
+
+ fflush (stdout);
+ fflush (stderr);
+
+ utx->start(); // start data xfers
+
+ test_output (utx, max_bytes, ampl, dc_p, counting_p);
+
+ delete utx;
+
+ return 0;
+}
+
+
+static bool
+test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
+ bool dc_p, bool counting_p)
+{
+ static const int BUFSIZE = utx->block_size();
+ static const int N = BUFSIZE/sizeof (short);
+
+ short buf[N];
+ int nbytes = 0;
+ int counter = 0;
+
+ static const int PERIOD = 65; // any value is valid
+ static const int PATLEN = 2 * PERIOD;
+ short pattern[PATLEN];
+
+ for (int i = 0; i < PERIOD; i++){
+ if (dc_p){
+ pattern[2*i+0] = host_to_usrp_short ((short) ampl);
+ pattern[2*i+1] = host_to_usrp_short ((short) 0);
+ }
+ else {
+ pattern[2*i+0] = host_to_usrp_short ((short) (ampl * cos (2*M_PI * i / PERIOD)));
+ pattern[2*i+1] = host_to_usrp_short ((short) (ampl * sin (2*M_PI * i / PERIOD)));
+ }
+ }
+
+ double start_wall_time = get_elapsed_time ();
+ double start_cpu_time = get_cpu_usage ();
+
+ bool underrun;
+ int nunderruns = 0;
+ int pi = 0;
+
+ for (nbytes = 0; max_bytes == 0 || nbytes < max_bytes; nbytes += BUFSIZE){
+
+ if (counting_p){
+ for (int i = 0; i < N; i++)
+ buf[i] = host_to_usrp_short (counter++ & 0xffff);
+ }
+ else {
+ for (int i = 0; i < N; i++){
+ buf[i] = pattern[pi];
+ pi++;
+ if (pi >= PATLEN)
+ pi = 0;
+ }
+ }
+
+ int ret = utx->write (buf, sizeof (buf), &underrun);
+ if ((unsigned) ret != sizeof (buf)){
+ fprintf (stderr, "test_output: error, ret = %d\n", ret);
+ }
+
+ if (underrun){
+ nunderruns++;
+ printf ("tx_underrun\n");
+ //printf ("tx_underrun %9d %6d\n", nbytes, nbytes/BUFSIZE);
+ }
+ }
+
+ utx->wait_for_completion ();
+
+ double stop_wall_time = get_elapsed_time ();
+ double stop_cpu_time = get_cpu_usage ();
+
+ double delta_wall = stop_wall_time - start_wall_time;
+ double delta_cpu = stop_cpu_time - start_cpu_time;
+
+ printf ("xfered %.3g bytes in %.3g seconds. %.4g bytes/sec. cpu time = %.3g\n",
+ (double) max_bytes, delta_wall, max_bytes / delta_wall, delta_cpu);
+
+ printf ("%d underruns\n", nunderruns);
+
+ return true;
+}