3 * Copyright 2003,2004 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
31 #include <usb.h> /* needed for usb functions */
35 #include "time_stuff.h"
36 #include "usrp_standard.h"
37 #include "usrp_bytesex.h"
45 static bool test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
46 bool dc_p, bool counting_p);
49 set_progname (char *path)
51 char *p = strrchr (path, '/');
62 "usage: %s [-f] [-v] [-d] [-c] [-a <ampl>][-I <interp>] [-F freq] [-D]\n", prog_name);
63 fprintf (stderr, " [-f] loop forever\n");
64 fprintf (stderr, " [-M] how many Megabytes to transfer (default 128)\n");
65 fprintf (stderr, " [-v] verbose\n");
66 fprintf (stderr, " [-d] dump registers\n");
67 // fprintf (stderr, " [-l] digital loopback in FPGA\n");
68 fprintf (stderr, " [-c] Tx counting sequence\n");
69 fprintf (stderr, " [-D] DC output\n");
71 fprintf (stderr, " [-B <fusb_block_size>] set fast usb block_size\n");
72 fprintf (stderr, " [-N <fusb_nblocks>] set fast usb nblocks\n");
73 fprintf (stderr, " [-R] set real time scheduling: SCHED_FIFO; pri = midpoint\n");
81 fprintf (stderr, "die: %s: %s\n", prog_name, msg);
86 dump_codec_regs (usrp_basic *u, int which_codec, FILE *fp)
88 for (int i = 0; i < 64; i++){
90 u->_read_9862 (which_codec, i, &v);
91 fprintf (fp, "%2d: 0x%02x\n", i, v);
97 do_dump_codec_regs (usrp_basic *u)
100 strcpy (name, "regsXXXXXX");
101 int fd = mkstemp (name);
106 FILE *fp = fdopen (fd, "w");
107 dump_codec_regs (u, 0, fp);
113 main (int argc, char **argv)
115 bool verbose_p = false;
116 bool dump_regs_p = false;
118 // bool loopback_p = false;
119 bool counting_p = false;
120 int max_bytes = 128 * (1L << 20);
123 int interp = 16; // 32.0 MB/sec
124 double center_freq = 0;
126 int fusb_block_size = 0;
127 int fusb_nblocks = 0;
128 bool realtime_p = false;
131 set_progname (argv[0]);
133 while ((ch = getopt (argc, argv, "vfdcI:F:a:DM:B:N:R")) != EOF){
162 interp = strtol (optarg, 0, 0);
166 center_freq = strtod (optarg, 0);
170 ampl = strtod (optarg, 0);
174 max_bytes = strtol (optarg, 0, 0) * (1L << 20);
175 if (max_bytes < 0) max_bytes = 0;
179 fusb_block_size = strtol (optarg, 0, 0);
183 fusb_nblocks = strtol (optarg, 0, 0);
195 #ifdef HAVE_SCHED_SETSCHEDULER
197 int policy = SCHED_FIFO;
198 int pri = (sched_get_priority_max (policy) - sched_get_priority_min (policy)) / 2;
199 int pid = 0; // this process
201 struct sched_param param;
202 memset(¶m, 0, sizeof(param));
203 param.sched_priority = pri;
204 int result = sched_setscheduler(pid, policy, ¶m);
206 perror ("sched_setscheduler: failed to set real time priority");
209 printf("SCHED_FIFO enabled with priority = %d\n", pri);
213 usrp_standard_tx *utx;
215 utx = usrp_standard_tx::make (which_board,
223 die ("usrp_standard_tx::make");
225 if (!utx->set_tx_freq (0, center_freq))
226 die ("utx->set_tx_freq");
229 do_dump_codec_regs (utx);
235 utx->start(); // start data xfers
237 test_output (utx, max_bytes, ampl, dc_p, counting_p);
246 test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
247 bool dc_p, bool counting_p)
249 static const int BUFSIZE = utx->block_size();
250 static const int N = BUFSIZE/sizeof (short);
256 static const int PERIOD = 65; // any value is valid
257 static const int PATLEN = 2 * PERIOD;
258 short pattern[PATLEN];
260 for (int i = 0; i < PERIOD; i++){
262 pattern[2*i+0] = host_to_usrp_short ((short) ampl);
263 pattern[2*i+1] = host_to_usrp_short ((short) 0);
266 pattern[2*i+0] = host_to_usrp_short ((short) (ampl * cos (2*M_PI * i / PERIOD)));
267 pattern[2*i+1] = host_to_usrp_short ((short) (ampl * sin (2*M_PI * i / PERIOD)));
271 double start_wall_time = get_elapsed_time ();
272 double start_cpu_time = get_cpu_usage ();
278 for (nbytes = 0; max_bytes == 0 || nbytes < max_bytes; nbytes += BUFSIZE){
281 for (int i = 0; i < N; i++)
282 buf[i] = host_to_usrp_short (counter++ & 0xffff);
285 for (int i = 0; i < N; i++){
286 buf[i] = pattern[pi];
293 int ret = utx->write (buf, sizeof (buf), &underrun);
294 if ((unsigned) ret != sizeof (buf)){
295 fprintf (stderr, "test_output: error, ret = %d\n", ret);
300 printf ("tx_underrun\n");
301 //printf ("tx_underrun %9d %6d\n", nbytes, nbytes/BUFSIZE);
305 utx->wait_for_completion ();
307 double stop_wall_time = get_elapsed_time ();
308 double stop_cpu_time = get_cpu_usage ();
310 double delta_wall = stop_wall_time - start_wall_time;
311 double delta_cpu = stop_cpu_time - start_cpu_time;
313 printf ("xfered %.3g bytes in %.3g seconds. %.4g bytes/sec. cpu time = %.3g\n",
314 (double) max_bytes, delta_wall, max_bytes / delta_wall, delta_cpu);
316 printf ("%d underruns\n", nunderruns);