[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r7367 - in usrp2/trunk: firmware/apps firmware/include
From: |
eb |
Subject: |
[Commit-gnuradio] r7367 - in usrp2/trunk: firmware/apps firmware/include host/apps host/lib |
Date: |
Sun, 6 Jan 2008 13:00:42 -0700 (MST) |
Author: eb
Date: 2008-01-06 13:00:40 -0700 (Sun, 06 Jan 2008)
New Revision: 7367
Added:
usrp2/trunk/host/lib/strtod_si.c
usrp2/trunk/host/lib/strtod_si.h
Modified:
usrp2/trunk/firmware/apps/app_common.c
usrp2/trunk/firmware/apps/app_common.h
usrp2/trunk/firmware/apps/rx_only.c
usrp2/trunk/firmware/apps/tx_only.c
usrp2/trunk/firmware/include/usrp2_eth_packet.h
usrp2/trunk/host/apps/rx_samples.cc
usrp2/trunk/host/lib/Makefile.am
usrp2/trunk/host/lib/usrp2_basic.cc
usrp2/trunk/host/lib/usrp2_basic.h
Log:
rx_samples now controls rx parameters
Modified: usrp2/trunk/firmware/apps/app_common.c
===================================================================
--- usrp2/trunk/firmware/apps/app_common.c 2008-01-06 03:13:48 UTC (rev
7366)
+++ usrp2/trunk/firmware/apps/app_common.c 2008-01-06 20:00:40 UTC (rev
7367)
@@ -90,13 +90,17 @@
break;
case OP_START_RX:
- start_rx_cmd(&pkt->ehdr.src);
+ start_rx_cmd(&pkt->ehdr.src, (op_start_rx_t *) p);
break;
case OP_STOP_RX:
stop_rx_cmd();
break;
+ case OP_CONFIG_TX:
+ config_tx_cmd((op_config_tx_t *) p);
+ break;
+
case OP_BURN_MAC_ADDR:
burn_mac_addr((op_burn_mac_addr_t *) p);
break;
@@ -181,3 +185,12 @@
printf("\neth link changed: speed = %d\n", speed);
}
+
+void
+config_tx_cmd(op_config_tx_t *p)
+{
+ 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/app_common.h
===================================================================
--- usrp2/trunk/firmware/apps/app_common.h 2008-01-06 03:13:48 UTC (rev
7366)
+++ usrp2/trunk/firmware/apps/app_common.h 2008-01-06 20:00:40 UTC (rev
7367)
@@ -33,7 +33,6 @@
extern volatile bool link_is_up; // eth handler sets this
void set_reply_hdr(u2_eth_packet_t *reply_pkt, u2_eth_packet_t const *cmd_pkt);
-//void handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len);
/*
* Called when an ethernet packet is received.
@@ -46,8 +45,8 @@
// FIXME move these somewhere else?
-void start_rx_cmd(const u2_mac_addr_t *host);
+void start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p);
void stop_rx_cmd(void);
+void config_tx_cmd(op_config_tx_t *p);
-
#endif /* INCLUDED_APP_COMMON_H */
Modified: usrp2/trunk/firmware/apps/rx_only.c
===================================================================
--- usrp2/trunk/firmware/apps/rx_only.c 2008-01-06 03:13:48 UTC (rev 7366)
+++ usrp2/trunk/firmware/apps/rx_only.c 2008-01-06 20:00:40 UTC (rev 7367)
@@ -131,11 +131,8 @@
}
void
-start_rx_cmd(const u2_mac_addr_t *host)
+start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
{
- // printf("start_rx_cmd\n");
- // hal_toggle_leds(0x2);
-
host_mac_addr = *host; // remember who we're sending to
/*
@@ -153,22 +150,17 @@
// setup RX DSP regs
- dsp_rx_regs->clear_state = 1; // reset
- dsp_rx_regs->freq = 0;
- dsp_rx_regs->scale_iq = (256 << 16) | 256;
- dsp_rx_regs->decim_rate = 63; // register gets N - 1
+ dsp_rx_regs->clear_state = 1; // reset
- uint32_t cmd = MK_RX_CMD(10000 * DSP_RX_SAMPLES_PER_FRAME,
DSP_RX_SAMPLES_PER_FRAME);
- // printf("rx_command = "); puthex32_nl(cmd);
- dsp_rx_regs->rx_command = cmd;
+ dsp_rx_regs->freq = p->phase_inc;
+ dsp_rx_regs->scale_iq = p->scale_iq;
+ dsp_rx_regs->decim_rate = p->decim - 1; // register gets N-1
+ dsp_rx_regs->rx_command = MK_RX_CMD(p->total_samples, p->samples_per_frame);
// kick off the state machine
dbsm_start(&dsp_rx_sm);
- // dsp_rx_regs->rx_time = 1; // timer_regs->time + 10000;
dsp_rx_regs->rx_time = T_NOW; // start NOW!
-
- // FIXME need to arrange to add additional stuff to cmd queue
}
@@ -242,8 +234,20 @@
if (hwconfig_simulation_p()){
// If we're simulating, pretend that we got a start command from the host
+
+ int rx_scale = 256;
+ int decim = 64;
+
u2_mac_addr_t host = {{ 0x00, 0x0A, 0xE4, 0x3E, 0xD2, 0xD5 }};
- start_rx_cmd(&host);
+ op_start_rx_t def_config;
+ memset(&def_config, 0, sizeof(def_config));
+ def_config.phase_inc = 0;
+ def_config.scale_iq = (rx_scale << 16) | rx_scale;
+ def_config.decim = decim;
+ def_config.samples_per_frame = DSP_RX_SAMPLES_PER_FRAME;
+ def_config.total_samples = 10000 * DSP_RX_SAMPLES_PER_FRAME;
+
+ start_rx_cmd(&host, &def_config);
}
while(1){
Modified: usrp2/trunk/firmware/apps/tx_only.c
===================================================================
--- usrp2/trunk/firmware/apps/tx_only.c 2008-01-06 03:13:48 UTC (rev 7366)
+++ usrp2/trunk/firmware/apps/tx_only.c 2008-01-06 20:00:40 UTC (rev 7367)
@@ -158,7 +158,7 @@
void
-start_rx_cmd(const u2_mac_addr_t *host)
+start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
{
}
@@ -175,12 +175,17 @@
bp_clear_buf(DSP_TX_BUF_1);
int tx_scale = 256;
+ int interp = 32;
+ op_config_tx_t def_config;
+ memset(&def_config, 0, sizeof(def_config));
+ def_config.phase_inc = 408021893; // 9.5 MHz [2**32 *
fc/fsample]
+ def_config.scale_iq = (tx_scale << 16) | tx_scale;
+ def_config.interp = interp;
+
// setup Tx DSP regs
dsp_tx_regs->clear_state = 1; // reset
- dsp_tx_regs->freq = 408021893; // 9.5 MHz [2**32 * fc/fsample]
- dsp_tx_regs->scale_iq = (tx_scale << 16) | tx_scale;
- dsp_tx_regs->interp_rate = 31; // register gets N - 1
+ config_tx_cmd(&def_config);
}
#if 0
Modified: usrp2/trunk/firmware/include/usrp2_eth_packet.h
===================================================================
--- usrp2/trunk/firmware/include/usrp2_eth_packet.h 2008-01-06 03:13:48 UTC
(rev 7366)
+++ usrp2/trunk/firmware/include/usrp2_eth_packet.h 2008-01-06 20:00:40 UTC
(rev 7367)
@@ -161,6 +161,7 @@
#define OP_READ_REG 7
#define OP_READ_REG_REPLY 8
#define OP_BURN_MAC_ADDR 9
+#define OP_CONFIG_TX 10
typedef struct {
uint8_t opcode;
@@ -189,25 +190,27 @@
uint8_t opcode;
uint8_t len;
uint16_t mbz;
+ int32_t phase_inc; // 2**32 * desired_freq/100e6
+ uint32_t scale_iq; // (scale_i << 16) | scale_q [16.0 format]
+ uint32_t decim; // desired decimation factor (NOT -1)
+ uint32_t samples_per_frame; // MTU=1500: [9,372]; MTU=2034: [9,506]
+ uint32_t total_samples; // [9, 2^23-1] == [9, 8,388,607]
} op_start_rx_t;
-// FIXME move this into op_start_rx_t
typedef struct {
uint8_t opcode;
uint8_t len;
uint16_t mbz;
+} op_stop_rx_t;
- int32_t freq;
- uint32_t scale_iq;
- uint32_t decim;
- uint32_t cmd;
-} op_config_rx_t;
-
typedef struct {
uint8_t opcode;
uint8_t len;
uint16_t mbz;
-} op_stop_rx_t;
+ int32_t phase_inc; // 2**32 * desired_freq/100e6
+ uint32_t scale_iq; // (scale_i << 16) | scale_q [16.0 format]
+ uint32_t interp; // desired interpolation factor (NOT -1)
+} op_config_tx_t;
typedef struct {
uint8_t opcode;
@@ -223,6 +226,7 @@
op_id_reply_t op_id_reply;
op_start_rx_t op_start_rx;
op_stop_rx_t op_stop_rx;
+ op_config_tx_t op_config_tx;
op_burn_mac_addr_t op_burn_mac_addr;
} u2_subpkt_t;
Modified: usrp2/trunk/host/apps/rx_samples.cc
===================================================================
--- usrp2/trunk/host/apps/rx_samples.cc 2008-01-06 03:13:48 UTC (rev 7366)
+++ usrp2/trunk/host/apps/rx_samples.cc 2008-01-06 20:00:40 UTC (rev 7367)
@@ -23,7 +23,10 @@
#include <iostream>
#include <complex>
#include <getopt.h>
+#include <string.h>
+#include "strtod_si.h"
+
typedef std::complex<float> fcomplex;
@@ -47,31 +50,97 @@
static void
usage(const char *progname)
{
- fprintf(stderr, "usage: %s [-o <output_file> ] [-N nsamples] [-h] [-e
ethN]\n",
- progname);
+ const char *p = strrchr(progname, '/'); // drop leading directory path
+ if (p)
+ p++;
+
+ if (strncmp(p, "lt-", 3) == 0) // drop lt- libtool prefix
+ p += 3;
+
+ fprintf(stderr, "Usage: %s [options]\n\n", p);
+ 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, " -o OUTPUT_FILE set output filename
[default=samples.dat]\n");
+ fprintf(stderr, " -f FREQ set frequency to FREQ
[default=0]\n");
+ fprintf(stderr, " -d DECIM set decimation rate to DECIM
[default=32]\n");
+ fprintf(stderr, " -N NSAMPLES total number of samples to receive
[default=2.5e6]\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;
+
+ // options and their defaults
+ const char *interface = "eth0";
+ const char *mac_addr_str = 0;
const char *output_filename = "samples.dat";
- const char *interface = "eth0";
- ssize_t nsamples = -1; // inf
+ double freq = 0;
+ int32_t decim = 32;
+ int32_t nsamples = static_cast<int32_t>(2.5e6);
+ int32_t samples_per_frame = 372;
+ int32_t scale = 256;
- while ((ch = getopt(argc, argv, "o:N:he:")) != EOF){
+ int ch;
+ double tmp;
+ u2_mac_addr_t mac_addr;
+
+ while ((ch = getopt(argc, argv, "he:m:o:f:d:N: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]);
+ exit(1);
+ }
+ break;
+
case 'o':
output_filename = optarg;
break;
+ case 'f':
+ if (!strtod_si(optarg, &freq)){
+ std::cerr << "invalid number: " << optarg << std::endl;
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+
case 'N':
- nsamples = strtol(optarg, 0, 0);
+ if (!strtod_si(optarg, &tmp)){
+ std::cerr << "invalid number: " << optarg << std::endl;
+ usage(argv[0]);
+ exit(1);
+ }
+ nsamples = static_cast<int32_t>(tmp);
break;
- case 'e':
- interface = optarg;
+ case 'F':
+ samples_per_frame = strtol(optarg, 0, 0);
break;
+
+ case 'd':
+ decim = strtol(optarg, 0, 0);
+ break;
+
+ case 'S':
+ if (!strtod_si(optarg, &tmp)){
+ std::cerr << "invalid number: " << optarg << std::endl;
+ usage(argv[0]);
+ exit(1);
+ }
+ scale = static_cast<int32_t>(tmp);
+ break;
case 'h':
default:
@@ -107,14 +176,14 @@
u2_mac_addr_t which = r[0].addr; // pick the first one
- if (!u2->start_rx(which)){
+ if (!u2->start_rx(which, freq, decim, nsamples, samples_per_frame, scale,
scale)){
std::cerr << "start_rx failed\n";
return 1;
}
while (1){
u2_eth_samples_t pkt;
- fcomplex c_samples[U2_MAX_SAMPLES];
+ // fcomplex c_samples[U2_MAX_SAMPLES];
// read samples
int n = u2->read_samples(which, &pkt);
@@ -123,8 +192,9 @@
printf("%3d %8d\n", n, u2p_timestamp(&pkt.fixed));
- convert_samples_to_complex(n, pkt.samples, c_samples);
+ // convert_samples_to_complex(n, pkt.samples, c_samples);
// size_t r = fwrite(c_samples, sizeof(fcomplex), n, of);
+
size_t r = fwrite(pkt.samples, sizeof(uint32_t), n, of);
fflush(of);
}
Modified: usrp2/trunk/host/lib/Makefile.am
===================================================================
--- usrp2/trunk/host/lib/Makefile.am 2008-01-06 03:13:48 UTC (rev 7366)
+++ usrp2/trunk/host/lib/Makefile.am 2008-01-06 20:00:40 UTC (rev 7367)
@@ -24,11 +24,13 @@
libusrp2_la_SOURCES = \
gri_ethernet.cc \
gri_pktfilter.cc \
+ strtod_si.c \
usrp2_basic.cc
include_HEADERS = \
gri_ethernet.h \
gri_pktfilter.h \
+ strtod_si.h \
usrp2_basic.h
Added: usrp2/trunk/host/lib/strtod_si.c
===================================================================
--- usrp2/trunk/host/lib/strtod_si.c (rev 0)
+++ usrp2/trunk/host/lib/strtod_si.c 2008-01-06 20:00:40 UTC (rev 7367)
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "strtod_si.h"
+#include <stdlib.h>
+
+#define true 1
+#define false 0
+
+int
+strtod_si(const char *s, double *result)
+{
+ *result = 0;
+
+ char *endptr;
+ double r = strtod(s, &endptr);
+ if (s == endptr)
+ return false;
+
+ switch (*endptr){
+ case 'p': r *= 1e-12; break;
+ case 'n': r *= 1e-9; break;
+ case 'u': r *= 1e-6; break;
+ case 'm': r *= 1e-3; break;
+ case 'k': r *= 1e3; break;
+ case 'M': r *= 1e6; break;
+ case 'G': r *= 1e9; break;
+ case 'T': r *= 1e12; break;
+ default:
+ // ignore. FIXME could be more robust
+ break;
+ }
+
+ *result = r;
+ return true;
+}
+
+
Property changes on: usrp2/trunk/host/lib/strtod_si.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: usrp2/trunk/host/lib/strtod_si.h
===================================================================
--- usrp2/trunk/host/lib/strtod_si.h (rev 0)
+++ usrp2/trunk/host/lib/strtod_si.h 2008-01-06 20:00:40 UTC (rev 7367)
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDED_STRTOD_SI_H
+#define INCLUDED_STRTOD_SI_H
+
+#include "usrp2_cdefs.h"
+__U2_BEGIN_DECLS
+
+
+/*!
+ * \brief convert string at s to double honoring any trailing SI suffixes
+ *
+ * \param[in] s is the string to convert
+ * \param[out] result is the converted value
+ * \returns non-zero iff conversion was successful.
+ */
+int strtod_si(const char *s, double *result);
+
+__U2_END_DECLS
+
+
+#endif /* INCLUDED_STRTOD_SI_H */
+
Property changes on: usrp2/trunk/host/lib/strtod_si.h
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: usrp2/trunk/host/lib/usrp2_basic.cc
===================================================================
--- usrp2/trunk/host/lib/usrp2_basic.cc 2008-01-06 03:13:48 UTC (rev 7366)
+++ usrp2/trunk/host/lib/usrp2_basic.cc 2008-01-06 20:00:40 UTC (rev 7367)
@@ -22,6 +22,8 @@
#include "usrp2_basic.h"
#include "gri_ethernet.h"
#include "gri_pktfilter.h"
+#include <iostream>
+#include <math.h>
#include <time.h> // debug
#ifdef HAVE_SYS_SELECT_H
@@ -163,17 +165,43 @@
// ------------------------------------------------------------------------
+static int32_t
+compute_freq_control_word_fpga(double master_freq, double target_freq,
+ double *actual_freq)
+{
+ int v = (int) rint (target_freq / master_freq * pow (2.0, 32.0));
+ *actual_freq = v * master_freq / pow (2.0, 32.0);
+ return v;
+}
+
bool
-usrp2_basic::start_rx(const u2_mac_addr_t &which)
+usrp2_basic::start_rx(const u2_mac_addr_t &which,
+ double freq,
+ unsigned int decim,
+ unsigned int total_samples, // [9, 2**23 - 1]
+ unsigned int samples_per_frame, // [9, 372] or [9, 506]
if MTU==2034
+ 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_id_t op_start_rx;
+ op_start_rx_t op;
};
+ if (total_samples < 9 || total_samples >= (1L << 23)){
+ std::cerr << "usrp2_basic::start_rx: total_samples is out of range\n";
+ return false;
+ }
+
+ if (samples_per_frame < 9 || samples_per_frame > 506){
+ std::cerr << "usrp2_basic::start_rx: samples_per_frame is out of range\n";
+ return false;
+ }
+
command *c = (command *) pktbuf;
c->h.ehdr.ethertype = htons(U2_ETHERTYPE);
c->h.ehdr._pad = 0;
@@ -182,8 +210,17 @@
u2p_set_word0(&c->h.fixed, 0, CONTROL_CHAN);
u2p_set_timestamp(&c->h.fixed, -1);
- c->op_start_rx.opcode = OP_START_RX;
- c->op_start_rx.len = sizeof(op_start_rx_t);
+ c->op.opcode = OP_START_RX;
+ c->op.len = sizeof(op_start_rx_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.decim = htonl(decim);
+ c->op.samples_per_frame = htonl(samples_per_frame);
+ c->op.total_samples = htonl(total_samples);
+
+
int len = std::max((size_t) MIN_PKTLEN, sizeof(command));
if (d_ethernet->write_packet(c, len) != len)
return false;
Modified: usrp2/trunk/host/lib/usrp2_basic.h
===================================================================
--- usrp2/trunk/host/lib/usrp2_basic.h 2008-01-06 03:13:48 UTC (rev 7366)
+++ usrp2/trunk/host/lib/usrp2_basic.h 2008-01-06 20:00:40 UTC (rev 7367)
@@ -49,11 +49,17 @@
/*!
* \brief Find usrp by mac address
+ *
+ * \param[in] addr is the mac address of the USRP to look for
+ * \param[out] u if not 0, is filled in with USRP info if found
+ *
+ * \returns true iff the specified usrp was found
*/
bool find_usrp_by_mac(const u2_mac_addr_t &addr, op_id_reply_t *u);
/*!
* \brief Parse short or long format mac address.
+ *
* \param[in] s must be either HH:HH or HH:HH:HH:HH:HH:HH.
* \param[out] p receives the parsed address
*
@@ -62,7 +68,15 @@
static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
- bool start_rx(const u2_mac_addr_t &which);
+ bool start_rx(const u2_mac_addr_t &which,
+ double freq,
+ unsigned int decim,
+ unsigned int total_samples, // [9, 2**23 - 1]
+ unsigned int samples_per_frame, // [9, 372] or [9, 506] if
MTU==2034
+ int scale_i, // 16.0 fixed point format
+ int scale_q // 16.0 fixed point format
+ );
+
bool stop_rx(const u2_mac_addr_t &which);
/*!
@@ -115,6 +129,16 @@
bool burn_mac_addr(const u2_mac_addr_t &which,
const u2_mac_addr_t &new_addr);
+
+ //! Return frequency of master oscillator on USRP2.
+ long fpga_master_clock_freq () const { return 100000000; } // 100e6
+
+ //! Return A/D sample rate
+ 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
+
};
std::ostream& operator<<(std::ostream &os, const op_id_reply_t &x);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7367 - in usrp2/trunk: firmware/apps firmware/include host/apps host/lib,
eb <=