[Top][All Lists]
[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(); }
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7404 - in usrp2/trunk: firmware/apps host/apps host/lib,
eb <=