From 9b388ac1184c71449c49fb44551c5c38f8098d8e Mon Sep 17 00:00:00 2001 From: jcorgan Date: Wed, 4 Feb 2009 23:06:02 +0000 Subject: [PATCH] Merged r10383:10390 from jcorgan/u2-wip into trunk. * Implements daughterboard independent LO offset tuning * Removes RFX specific LO offset code * Adds 'set_lo_offset' to libusrp2 and Python API * Adds --lo-offset to usrp2_fft.py and usrp2_rx_cfile.py * Ensures daughterboards are reset to default values at startup. Trunk passes distcheck. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10392 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-usrp2/src/usrp2.i | 2 + gr-usrp2/src/usrp2_sink_base.cc | 6 ++ gr-usrp2/src/usrp2_sink_base.h | 5 ++ gr-usrp2/src/usrp2_source_base.cc | 6 ++ gr-usrp2/src/usrp2_source_base.h | 7 +- gr-utils/src/python/usrp2_rx_cfile.py | 8 ++- gr-utils/src/python/usrp2_siggen.py | 6 ++ usrp2/firmware/apps/app_common_v2.c | 37 +++++++--- usrp2/firmware/include/usrp2_eth_packet.h | 22 +++++- usrp2/firmware/lib/db.h | 12 +++- usrp2/firmware/lib/db_base.h | 5 +- usrp2/firmware/lib/db_basic.c | 10 +-- usrp2/firmware/lib/db_dbsrx.c | 2 +- usrp2/firmware/lib/db_init.c | 14 +++- usrp2/firmware/lib/db_rfx.c | 55 ++++++-------- usrp2/firmware/lib/db_tvrx.c | 8 +-- usrp2/firmware/lib/db_xcvr2450.c | 2 + usrp2/host/include/usrp2/usrp2.h | 12 +++- usrp2/host/lib/control.h | 8 ++- usrp2/host/lib/usrp2.cc | 14 +++- usrp2/host/lib/usrp2_impl.cc | 88 ++++++++++++++++++++++- usrp2/host/lib/usrp2_impl.h | 5 +- 22 files changed, 268 insertions(+), 66 deletions(-) mode change 100755 => 100644 usrp2/firmware/lib/db_dbsrx.c diff --git a/gr-usrp2/src/usrp2.i b/gr-usrp2/src/usrp2.i index c979750a..c9a4af59 100644 --- a/gr-usrp2/src/usrp2.i +++ b/gr-usrp2/src/usrp2.i @@ -67,6 +67,7 @@ public: bool set_gain(double gain); %rename(_real_set_center_freq) set_center_freq; + bool set_lo_offset(double frequency); bool set_center_freq(double frequency, usrp2::tune_result *r); bool set_decim(int decimation_factor); bool set_scale_iq(int scale_i, int scale_q); @@ -132,6 +133,7 @@ public: bool set_gain(double gain); %rename(_real_set_center_freq) set_center_freq; + bool set_lo_offset(double frequency); bool set_center_freq(double frequency, usrp2::tune_result *r); bool set_interp(int interp_factor); bool set_scale_iq(int scale_i, int scale_q); diff --git a/gr-usrp2/src/usrp2_sink_base.cc b/gr-usrp2/src/usrp2_sink_base.cc index 579aaaa4..8118407c 100644 --- a/gr-usrp2/src/usrp2_sink_base.cc +++ b/gr-usrp2/src/usrp2_sink_base.cc @@ -52,6 +52,12 @@ usrp2_sink_base::set_gain(double gain) return d_u2->set_tx_gain(gain); } +bool +usrp2_sink_base::set_lo_offset(double frequency) +{ + return d_u2->set_tx_lo_offset(frequency); +} + bool usrp2_sink_base::set_center_freq(double frequency, usrp2::tune_result *tr) { diff --git a/gr-usrp2/src/usrp2_sink_base.h b/gr-usrp2/src/usrp2_sink_base.h index fad96562..37905f4e 100644 --- a/gr-usrp2/src/usrp2_sink_base.h +++ b/gr-usrp2/src/usrp2_sink_base.h @@ -45,6 +45,11 @@ public: */ bool set_gain(double gain); + /*! + * \brief Set transmitter LO offset frequency + */ + bool set_lo_offset(double frequency); + /*! * \brief Set transmitter center frequency */ diff --git a/gr-usrp2/src/usrp2_source_base.cc b/gr-usrp2/src/usrp2_source_base.cc index 1ed4d55d..8bcac5d6 100644 --- a/gr-usrp2/src/usrp2_source_base.cc +++ b/gr-usrp2/src/usrp2_source_base.cc @@ -52,6 +52,12 @@ usrp2_source_base::set_gain(double gain) return d_u2->set_rx_gain(gain); } +bool +usrp2_source_base::set_lo_offset(double frequency) +{ + return d_u2->set_rx_lo_offset(frequency); +} + bool usrp2_source_base::set_center_freq(double frequency, usrp2::tune_result *tr) { diff --git a/gr-usrp2/src/usrp2_source_base.h b/gr-usrp2/src/usrp2_source_base.h index 998a022d..f98d329f 100644 --- a/gr-usrp2/src/usrp2_source_base.h +++ b/gr-usrp2/src/usrp2_source_base.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -45,6 +45,11 @@ public: */ bool set_gain(double gain); + /*! + * \brief Set receive LO offset frequency + */ + bool set_lo_offset(double frequency); + /*! * \brief Set receiver center frequency */ diff --git a/gr-utils/src/python/usrp2_rx_cfile.py b/gr-utils/src/python/usrp2_rx_cfile.py index f8f1de69..1f23eee4 100755 --- a/gr-utils/src/python/usrp2_rx_cfile.py +++ b/gr-utils/src/python/usrp2_rx_cfile.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc. +# Copyright 2004,2005,2007,2008,2009 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -58,6 +58,9 @@ class rx_cfile_block(gr.top_block): self._u.set_gain(options.gain) # Set receive frequency + if options.lo_offset is not None: + self._u.set_lo_offset(options.lo_offset) + tr = self._u.set_center_freq(options.freq) if tr == None: sys.stderr.write('Failed to set center frequency\n') @@ -115,6 +118,9 @@ def get_options(): help="number of samples to collect [default=+inf]") parser.add_option("-v", "--verbose", action="store_true", default=False, help="verbose output") + parser.add_option("", "--lo-offset", type="eng_float", default=None, + help="set daughterboard LO offset to OFFSET [default=hw default]") + (options, args) = parser.parse_args () if len(args) != 1: parser.print_help() diff --git a/gr-utils/src/python/usrp2_siggen.py b/gr-utils/src/python/usrp2_siggen.py index 9929112e..9cea2eff 100755 --- a/gr-utils/src/python/usrp2_siggen.py +++ b/gr-utils/src/python/usrp2_siggen.py @@ -44,6 +44,10 @@ class siggen_top_block(gr.top_block): self._u.set_gain(options.gain) # Tune the USRP2 FPGA and daughterboard to the requested center frequency + # and LO offset + if options.lo_offset is not None: + self._u.set_lo_offset(options.lo_offset) + tr = self._u.set_center_freq(options.tx_freq) if tr == None: sys.stderr.write('Failed to set center frequency\n') @@ -143,6 +147,8 @@ def get_options(): help="set waveform amplitude to AMPLITUDE (0-1.0) [default=%default]", metavar="AMPL") parser.add_option("--offset", type="eng_float", default=0, help="set waveform offset to OFFSET [default=%default]") + parser.add_option("--lo-offset", type="eng_float", default=None, + help="set daughterboard LO offset to OFFSET [default=hw default]") parser.add_option("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE, help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE) parser.add_option("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, diff --git a/usrp2/firmware/apps/app_common_v2.c b/usrp2/firmware/apps/app_common_v2.c index 9f5fd94f..c277d12f 100644 --- a/usrp2/firmware/apps/app_common_v2.c +++ b/usrp2/firmware/apps/app_common_v2.c @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2008 Free Software Foundation, Inc. + * Copyright 2007,2008,2009 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 @@ -369,6 +369,16 @@ poke_cmd(const op_poke_t *p) return true; } +static bool +set_lo_offset_cmd(const op_freq_t *p) +{ + u2_fxpt_freq_t f = u2_fxpt_freq_from_hilo(p->freq_hi, p->freq_lo); + if (p->opcode == OP_SET_TX_LO_OFFSET) + return db_set_lo_offset(tx_dboard, f); + else + return db_set_lo_offset(rx_dboard, f); +} + static size_t generic_reply(const op_generic_t *p, void *reply_payload, size_t reply_payload_space, @@ -377,12 +387,12 @@ generic_reply(const op_generic_t *p, op_generic_t *r = (op_generic_t *) reply_payload; if (reply_payload_space < sizeof(*r)) return 0; // no room - + r->opcode = p->opcode | OP_REPLY_BIT; r->len = sizeof(*r); r->rid = p->rid; r->ok = ok; - + return r->len; } @@ -392,12 +402,12 @@ add_eop(void *reply_payload, size_t reply_payload_space) op_generic_t *r = (op_generic_t *) reply_payload; if (reply_payload_space < sizeof(*r)) return 0; // no room - + r->opcode = OP_EOP; r->len = sizeof(*r); r->rid = 0; r->ok = 0; - + return r->len; } @@ -407,15 +417,15 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len) unsigned char reply[sizeof(u2_eth_packet_t) + 4 * sizeof(u2_subpkt_t)] _AL4; unsigned char *reply_payload = &reply[sizeof(u2_eth_packet_t)]; int reply_payload_space = sizeof(reply) - sizeof(u2_eth_packet_t); - + // initialize reply memset(reply, 0, sizeof(reply)); set_reply_hdr((u2_eth_packet_t *) reply, pkt); - + // point to beginning of payload (subpackets) unsigned char *payload = ((unsigned char *) pkt) + sizeof(u2_eth_packet_t); int payload_len = len - sizeof(u2_eth_packet_t); - + size_t subpktlen = 0; while (payload_len >= sizeof(op_generic_t)){ @@ -484,6 +494,17 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len) poke_cmd((op_poke_t *)payload)); break; + case OP_SET_TX_LO_OFFSET: + case OP_SET_RX_LO_OFFSET: + subpktlen = generic_reply(gp, reply_payload, reply_payload_space, + set_lo_offset_cmd((op_freq_t *)payload)); + break; + + case OP_RESET_DB: + db_init(); + subpktlen = generic_reply(gp, reply_payload, reply_payload_space, true); + break; + default: printf("app_common_v2: unhandled opcode = %d\n", gp->opcode); break; diff --git a/usrp2/firmware/include/usrp2_eth_packet.h b/usrp2/firmware/include/usrp2_eth_packet.h index e212fab8..77de02db 100644 --- a/usrp2/firmware/include/usrp2_eth_packet.h +++ b/usrp2/firmware/include/usrp2_eth_packet.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2008 Free Software Foundation, Inc. + * Copyright 2007,2008,2009 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 @@ -189,6 +189,12 @@ typedef struct { #define OP_PEEK_REPLY (OP_PEEK | OP_REPLY_BIT) #define OP_POKE 12 #define OP_POKE_REPLY (OP_POKE | OP_REPLY_BIT) +#define OP_SET_TX_LO_OFFSET 13 +#define OP_SET_TX_LO_OFFSET_REPLY (OP_SET_TX_LO_OFFSET | OP_REPLY_BIT) +#define OP_SET_RX_LO_OFFSET 14 +#define OP_SET_RX_LO_OFFSET_REPLY (OP_SET_RX_LO_OFFSET | OP_REPLY_BIT) +#define OP_RESET_DB 15 +#define OP_RESET_DB_REPLY (OP_RESET_DB | OP_REPLY_BIT) /* * All subpackets are a multiple of 4 bytes long. @@ -402,6 +408,19 @@ typedef struct { // Words follow here } _AL4 op_poke_t; +/* + * Common structure for commands with a single frequency param + * (e.g., set_*_lo_offset, set_*_bw) + */ +typedef struct { + uint8_t opcode; + uint8_t len; + uint8_t rid; + uint8_t mbz; + uint32_t freq_hi; //< high 32-bits of 64-bit fxpt_freq (Q44.20) + uint32_t freq_lo; //< low 32-bits of 64-bit fxpt_freq (Q44.20) +} _AL4 op_freq_t; + /* * ================================================================ * union of all of subpacket types @@ -421,6 +440,7 @@ typedef union { op_config_mimo_t op_config_mimo; op_peek_t op_peek; op_poke_t op_poke; + op_freq_t op_freq; } u2_subpkt_t; diff --git a/usrp2/firmware/lib/db.h b/usrp2/firmware/lib/db.h index 5828fb00..cec96026 100644 --- a/usrp2/firmware/lib/db.h +++ b/usrp2/firmware/lib/db.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -59,6 +59,16 @@ struct tune_result void db_init(void); +/*! + * \brief Set daughterboard LO offset frequency. + * + * \param[in] db is the daughterboard instance + * \param[in] offset is the amount to add to tuning requests + * \param[out] success or failure + */ +bool +db_set_lo_offset(struct db_base *db, u2_fxpt_freq_t offset); + /*! * \brief Two stage tuning. Given target_freq, tune LO and DDC/DUC * diff --git a/usrp2/firmware/lib/db_base.h b/usrp2/firmware/lib/db_base.h index 9b5ce051..2ccfbf50 100644 --- a/usrp2/firmware/lib/db_base.h +++ b/usrp2/firmware/lib/db_base.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -43,7 +43,8 @@ struct db_base { u2_fxpt_gain_t gain_max; //< max gain that can be set (dB) u2_fxpt_gain_t gain_step_size; //< (dB) - // u2_fxpt_freq_t lo_offset; + u2_fxpt_freq_t default_lo_offset; //< offset to add to tune frequency, reset value + u2_fxpt_freq_t current_lo_offset; //< current value of lo_offset /* * Auto T/R control values diff --git a/usrp2/firmware/lib/db_basic.c b/usrp2/firmware/lib/db_basic.c index 0f1ad650..2bd4ebfb 100644 --- a/usrp2/firmware/lib/db_basic.c +++ b/usrp2/firmware/lib/db_basic.c @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -42,7 +42,7 @@ struct db_basic db_basic_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.atr_mask = 0, .base.atr_txval = 0, .base.atr_rxval = 0, @@ -68,7 +68,7 @@ struct db_basic db_basic_rx = { .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.atr_mask = 0, .base.atr_txval = 0, .base.atr_rxval = 0, @@ -94,7 +94,7 @@ struct db_basic db_lf_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.atr_mask = 0, .base.atr_txval = 0, .base.atr_rxval = 0, @@ -120,7 +120,7 @@ struct db_basic db_lf_rx = { .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.atr_mask = 0, .base.atr_txval = 0, .base.atr_rxval = 0, diff --git a/usrp2/firmware/lib/db_dbsrx.c b/usrp2/firmware/lib/db_dbsrx.c old mode 100755 new mode 100644 index 31b02722..6e261cc3 --- a/usrp2/firmware/lib/db_dbsrx.c +++ b/usrp2/firmware/lib/db_dbsrx.c @@ -80,7 +80,7 @@ struct db_dbsrx db_dbsrx = { .base.is_quadrature = true, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = db_dbsrx_init, .base.set_freq = db_dbsrx_set_freq, .base.set_gain = db_dbsrx_set_gain, diff --git a/usrp2/firmware/lib/db_init.c b/usrp2/firmware/lib/db_init.c index 121bfbd9..0aef75e5 100644 --- a/usrp2/firmware/lib/db_init.c +++ b/usrp2/firmware/lib/db_init.c @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -270,6 +270,7 @@ db_init(void) //m = determine_tx_mux_value(tx_dboard); //dsp_tx_regs->tx_mux = m; //printf("tx_mux = 0x%x\n", m); + tx_dboard->current_lo_offset = tx_dboard->default_lo_offset; rx_dboard = lookup_dboard(I2C_ADDR_RX_A, &db_basic_rx, "Rx"); //printf("db_init: rx dbid = 0x%x\n", rx_dboard->dbid); @@ -278,6 +279,7 @@ db_init(void) m = determine_rx_mux_value(rx_dboard); dsp_rx_regs->rx_mux = m; //printf("rx_mux = 0x%x\n", m); + rx_dboard->current_lo_offset = rx_dboard->default_lo_offset; } /*! @@ -330,6 +332,12 @@ calc_dxc_freq(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t baseband_freq, } } +bool +db_set_lo_offset(struct db_base *db, u2_fxpt_freq_t offset) +{ + db->current_lo_offset = offset; + return true; +} bool db_tune(struct db_base *db, u2_fxpt_freq_t target_freq, struct tune_result *result) @@ -339,8 +347,8 @@ db_tune(struct db_base *db, u2_fxpt_freq_t target_freq, struct tune_result *resu u2_fxpt_freq_t dxc_freq; u2_fxpt_freq_t actual_dxc_freq; - // Ask the d'board to tune as closely as it can to target_freq - bool ok = db->set_freq(db, target_freq, &result->baseband_freq); + // Ask the d'board to tune as closely as it can to target_freq+lo_offset + bool ok = db->set_freq(db, target_freq+db->current_lo_offset, &result->baseband_freq); // Calculate the DDC setting that will downconvert the baseband from the // daughterboard to our target frequency. diff --git a/usrp2/firmware/lib/db_rfx.c b/usrp2/firmware/lib/db_rfx.c index 0d5c89a8..3efb9f66 100644 --- a/usrp2/firmware/lib/db_rfx.c +++ b/usrp2/firmware/lib/db_rfx.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -73,7 +73,6 @@ struct db_rfx_common { unsigned char CP2; int freq_mult; int spi_mask; - u2_fxpt_freq_t freq_offset; }; struct db_rfx_dummy { @@ -149,7 +148,7 @@ struct db_rfx_400_rx db_rfx_400_rx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = rfx_init_rx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_rx, @@ -163,8 +162,7 @@ struct db_rfx_400_rx db_rfx_400_rx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_RX_DB, - .common.freq_mult = 2, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(0) + .common.freq_mult = 2 }; @@ -181,7 +179,7 @@ struct db_rfx_400_tx db_rfx_400_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6), .base.init = rfx_init_tx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_tx, @@ -195,8 +193,7 @@ struct db_rfx_400_tx db_rfx_400_tx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_TX_DB, - .common.freq_mult = 2, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6) + .common.freq_mult = 2 }; struct db_rfx_900_rx db_rfx_900_rx = { @@ -212,7 +209,7 @@ struct db_rfx_900_rx db_rfx_900_rx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = rfx_init_rx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_rx, @@ -226,8 +223,7 @@ struct db_rfx_900_rx db_rfx_900_rx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_RX_DB, - .common.freq_mult = 2, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(0) + .common.freq_mult = 2 }; @@ -244,7 +240,7 @@ struct db_rfx_900_tx db_rfx_900_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6), .base.init = rfx_init_tx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_tx, @@ -258,8 +254,7 @@ struct db_rfx_900_tx db_rfx_900_tx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_TX_DB, - .common.freq_mult = 2, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6) + .common.freq_mult = 2 }; struct db_rfx_1200_rx db_rfx_1200_rx = { @@ -275,7 +270,7 @@ struct db_rfx_1200_rx db_rfx_1200_rx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = rfx_init_rx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_rx, @@ -289,8 +284,7 @@ struct db_rfx_1200_rx db_rfx_1200_rx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_RX_DB, - .common.freq_mult = 2, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(0) + .common.freq_mult = 2 }; @@ -307,7 +301,7 @@ struct db_rfx_1200_tx db_rfx_1200_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6), .base.init = rfx_init_tx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_tx, @@ -321,8 +315,7 @@ struct db_rfx_1200_tx db_rfx_1200_tx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_TX_DB, - .common.freq_mult = 2, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6) + .common.freq_mult = 2 }; struct db_rfx_1800_rx db_rfx_1800_rx = { @@ -338,7 +331,7 @@ struct db_rfx_1800_rx db_rfx_1800_rx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = rfx_init_rx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_rx, @@ -352,8 +345,7 @@ struct db_rfx_1800_rx db_rfx_1800_rx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_RX_DB, - .common.freq_mult = 1, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(0) + .common.freq_mult = 1 }; @@ -370,7 +362,7 @@ struct db_rfx_1800_tx db_rfx_1800_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6), .base.init = rfx_init_tx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_tx, @@ -384,8 +376,7 @@ struct db_rfx_1800_tx db_rfx_1800_tx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_TX_DB, - .common.freq_mult = 1, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6) + .common.freq_mult = 1 }; @@ -402,7 +393,7 @@ struct db_rfx_2400_rx db_rfx_2400_rx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = rfx_init_rx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_rx, @@ -416,8 +407,7 @@ struct db_rfx_2400_rx db_rfx_2400_rx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_RX_DB, - .common.freq_mult = 1, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(0) + .common.freq_mult = 1 }; @@ -434,7 +424,7 @@ struct db_rfx_2400_tx db_rfx_2400_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6), .base.init = rfx_init_tx, .base.set_freq = rfx_set_freq, .base.set_gain = rfx_set_gain_tx, @@ -448,8 +438,7 @@ struct db_rfx_2400_tx db_rfx_2400_tx = { .common.CP1 = 7, .common.CP2 = 7, .common.spi_mask = SPI_SS_TX_DB, - .common.freq_mult = 1, - .common.freq_offset = U2_DOUBLE_TO_FXPT_FREQ(12.5e6) + .common.freq_mult = 1 }; @@ -488,7 +477,7 @@ rfx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc) *dc = 0; struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb; - u2_fxpt_freq_t desired_n = (U2_DOUBLE_TO_FXPT_FREQ(1.0)*db->common.freq_mult*(freq+db->common.freq_offset))/phdet_freq; + u2_fxpt_freq_t desired_n = (U2_DOUBLE_TO_FXPT_FREQ(1.0)*db->common.freq_mult*freq)/phdet_freq; int N_DIV = u2_fxpt_freq_round_to_int(desired_n); int B = N_DIV/PRESCALER; int A = N_DIV - PRESCALER*B; diff --git a/usrp2/firmware/lib/db_tvrx.c b/usrp2/firmware/lib/db_tvrx.c index 9e600bf8..435fe7da 100644 --- a/usrp2/firmware/lib/db_tvrx.c +++ b/usrp2/firmware/lib/db_tvrx.c @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -88,7 +88,7 @@ struct db_tvrx1 db_tvrx1 = { .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = tvrx_init, .base.set_freq = tvrx_set_freq, .base.set_gain = tvrx_set_gain, @@ -115,7 +115,7 @@ struct db_tvrx2 db_tvrx2 = { .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = true, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = tvrx_init, .base.set_freq = tvrx_set_freq, .base.set_gain = tvrx_set_gain, @@ -142,7 +142,7 @@ struct db_tvrx3 db_tvrx3 = { .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = true, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6), + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = tvrx_init, .base.set_freq = tvrx_set_freq, .base.set_gain = tvrx_set_gain, diff --git a/usrp2/firmware/lib/db_xcvr2450.c b/usrp2/firmware/lib/db_xcvr2450.c index 6c165bc9..8132d69a 100644 --- a/usrp2/firmware/lib/db_xcvr2450.c +++ b/usrp2/firmware/lib/db_xcvr2450.c @@ -147,6 +147,7 @@ struct db_xcvr2450_rx db_xcvr2450_rx = { .base.is_quadrature = true, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = xcvr2450_init, .base.set_freq = xcvr2450_set_freq, .base.set_gain = xcvr2450_set_gain_rx, @@ -169,6 +170,7 @@ struct db_xcvr2450_tx db_xcvr2450_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = xcvr2450_init, .base.set_freq = xcvr2450_set_freq, .base.set_gain = xcvr2450_set_gain_tx, diff --git a/usrp2/host/include/usrp2/usrp2.h b/usrp2/host/include/usrp2/usrp2.h index 39da63aa..2186ce90 100644 --- a/usrp2/host/include/usrp2/usrp2.h +++ b/usrp2/host/include/usrp2/usrp2.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -115,6 +115,11 @@ namespace usrp2 { //! return Rx gain db_per_step double rx_gain_db_per_step(); + /*! + * \brief Set receive daughterboard LO offset frequency + */ + bool set_rx_lo_offset(double frequency); + /*! * Set receiver center frequency */ @@ -200,6 +205,11 @@ namespace usrp2 { //! return Tx gain db_per_step double tx_gain_db_per_step(); + /* + * \brief Set transmit daughterboard LO offset frequency + */ + bool set_tx_lo_offset(double frequency); + /*! * Set transmitter center frequency */ diff --git a/usrp2/host/lib/control.h b/usrp2/host/lib/control.h index 2c042f0c..33f73fa9 100644 --- a/usrp2/host/lib/control.h +++ b/usrp2/host/lib/control.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -93,6 +93,12 @@ namespace usrp2 { // eop must be dynamically written here }; + struct op_freq_cmd { + u2_eth_packet_t h; + op_freq_t op; + op_generic_t eop; + }; + /*! * Control mechanism to allow API calls to block waiting for reply packets */ diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc index 90a31b22..6a54c6da 100644 --- a/usrp2/host/lib/usrp2.cc +++ b/usrp2/host/lib/usrp2.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -186,6 +186,12 @@ namespace usrp2 { return d_impl->rx_gain_db_per_step(); } + bool + usrp2::set_rx_lo_offset(double frequency) + { + return d_impl->set_rx_lo_offset(frequency); + } + bool usrp2::set_rx_center_freq(double frequency, tune_result *result) { @@ -278,6 +284,12 @@ namespace usrp2 { return d_impl->tx_gain_db_per_step(); } + bool + usrp2::set_tx_lo_offset(double frequency) + { + return d_impl->set_tx_lo_offset(frequency); + } + bool usrp2::set_tx_center_freq(double frequency, tune_result *result) { diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc index 2aa43013..4b4de024 100644 --- a/usrp2/host/lib/usrp2_impl.cc +++ b/usrp2/host/lib/usrp2_impl.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -73,6 +73,10 @@ namespace usrp2 { case OP_SYNC_TO_PPS: return "OP_SYNC_TO_PPS"; case OP_PEEK: return "OP_PEEK"; case OP_PEEK_REPLY: return "OP_PEEK_REPLY"; + case OP_SET_TX_LO_OFFSET: return "OP_SET_TX_LO_OFFSET"; + case OP_SET_TX_LO_OFFSET_REPLY: return "OP_SET_TX_LO_OFFSET_REPLY"; + case OP_SET_RX_LO_OFFSET: return "OP_SET_RX_LO_OFFSET"; + case OP_SET_RX_LO_OFFSET_REPLY: return "OP_SET_RX_LO_OFFSET_REPLY"; default: char buf[64]; @@ -169,6 +173,10 @@ namespace usrp2 { fprintf(stderr, " gain_db_per_step = %g\n", rx_gain_db_per_step()); } + // Ensure any custom values in hardware are cleared + if (!reset_db()) + std::cerr << "usrp2::ctor reset_db failed\n"; + // default gains to mid point if (!set_tx_gain((tx_gain_min() + tx_gain_max()) / 2)) std::cerr << "usrp2::ctor set_tx_gain failed\n"; @@ -471,6 +479,33 @@ namespace usrp2 { return success; } + bool + usrp2::impl::set_rx_lo_offset(double frequency) + { + op_freq_cmd cmd; + op_generic_t reply; + + memset(&cmd, 0, sizeof(cmd)); + init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); + cmd.op.opcode = OP_SET_RX_LO_OFFSET; + cmd.op.len = sizeof(cmd.op); + cmd.op.rid = d_next_rid++; + + u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency); + cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt)); + cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt)); + + cmd.eop.opcode = OP_EOP; + cmd.eop.len = sizeof(cmd.eop); + + pending_reply p(cmd.op.rid, &reply, sizeof(reply)); + if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) + return false; + + bool success = (ntohx(reply.ok) == 1); + return success; + } + bool usrp2::impl::set_rx_center_freq(double frequency, tune_result *result) { @@ -710,6 +745,33 @@ namespace usrp2 { return success; } + bool + usrp2::impl::set_tx_lo_offset(double frequency) + { + op_freq_cmd cmd; + op_generic_t reply; + + memset(&cmd, 0, sizeof(cmd)); + init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); + cmd.op.opcode = OP_SET_TX_LO_OFFSET; + cmd.op.len = sizeof(cmd.op); + cmd.op.rid = d_next_rid++; + + u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency); + cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt)); + cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt)); + + cmd.eop.opcode = OP_EOP; + cmd.eop.len = sizeof(cmd.eop); + + pending_reply p(cmd.op.rid, &reply, sizeof(reply)); + if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) + return false; + + bool success = (ntohx(reply.ok) == 1); + return success; + } + bool usrp2::impl::set_tx_center_freq(double frequency, tune_result *result) { @@ -1152,7 +1214,7 @@ namespace usrp2 { // Copy data from vector into packet space uint32_t *dest = (uint32_t *)((uint8_t *)cmd+plen); - for (unsigned int i = 0; i < words; i++) { + for (int i = 0; i < words; i++) { //fprintf(stderr, "%03i@%p\n", i, dest); *dest++ = htonl(data[i]); } @@ -1174,4 +1236,26 @@ namespace usrp2 { return ok; } + bool + usrp2::impl::reset_db() + { + op_generic_cmd cmd; + op_generic_t reply; + + memset(&cmd, 0, sizeof(cmd)); + init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); + cmd.op.opcode = OP_RESET_DB; + cmd.op.len = sizeof(cmd.op); + cmd.op.rid = d_next_rid++; + cmd.eop.opcode = OP_EOP; + cmd.eop.len = sizeof(cmd.eop); + + pending_reply p(cmd.op.rid, &reply, sizeof(reply)); + if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) + return false; + + bool success = (ntohx(reply.ok) == 1); + return success; + } + } // namespace usrp2 diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h index b332d65d..dfd054c0 100644 --- a/usrp2/host/lib/usrp2_impl.h +++ b/usrp2/host/lib/usrp2_impl.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 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 @@ -108,6 +108,7 @@ namespace usrp2 { data_handler::result handle_control_packet(const void *base, size_t len); data_handler::result handle_data_packet(const void *base, size_t len); bool dboard_info(); + bool reset_db(); public: impl(const std::string &ifc, props *p); @@ -123,6 +124,7 @@ namespace usrp2 { double rx_gain_min() { return d_rx_db_info.gain_min; } double rx_gain_max() { return d_rx_db_info.gain_max; } double rx_gain_db_per_step() { return d_rx_db_info.gain_step_size; } + bool set_rx_lo_offset(double frequency); bool set_rx_center_freq(double frequency, tune_result *result); double rx_freq_min() { return d_rx_db_info.freq_min; } double rx_freq_max() { return d_rx_db_info.freq_max; } @@ -141,6 +143,7 @@ namespace usrp2 { double tx_gain_min() { return d_tx_db_info.gain_min; } double tx_gain_max() { return d_tx_db_info.gain_max; } double tx_gain_db_per_step() { return d_tx_db_info.gain_step_size; } + bool set_tx_lo_offset(double frequency); bool set_tx_center_freq(double frequency, tune_result *result); double tx_freq_min() { return d_tx_db_info.freq_min; } double tx_freq_max() { return d_tx_db_info.freq_max; } -- 2.30.2