[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r7347 - gnuradio/branches/developers/jcorgan/xcvr2450/
From: |
jcorgan |
Subject: |
[Commit-gnuradio] r7347 - gnuradio/branches/developers/jcorgan/xcvr2450/gr-usrp/src |
Date: |
Fri, 4 Jan 2008 19:44:02 -0700 (MST) |
Author: jcorgan
Date: 2008-01-04 19:44:01 -0700 (Fri, 04 Jan 2008)
New Revision: 7347
Modified:
gnuradio/branches/developers/jcorgan/xcvr2450/gr-usrp/src/db_xcvr2450.py
Log:
Work in progress. Implemented set_gain. Not debugged.
Modified:
gnuradio/branches/developers/jcorgan/xcvr2450/gr-usrp/src/db_xcvr2450.py
===================================================================
--- gnuradio/branches/developers/jcorgan/xcvr2450/gr-usrp/src/db_xcvr2450.py
2008-01-05 00:26:00 UTC (rev 7346)
+++ gnuradio/branches/developers/jcorgan/xcvr2450/gr-usrp/src/db_xcvr2450.py
2008-01-05 02:44:01 UTC (rev 7347)
@@ -40,7 +40,6 @@
TX_EN = (1 << 11) # 1 = TX on, 0 = TX off
TX_OE_MASK = HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN
TX_SAFE_IO = HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2
-TX_TEST_IO = LB_PA_OFF|ANTSEL_TX1_RX2|TX_EN
# RX IO Pins
LOCKDET = (1 << 15) # This is an INPUT!!!
@@ -89,14 +88,14 @@
class xcvr2450(object):
def __init__(self, usrp, which):
print "xcvr2450: __init__ with %s: %d" % (usrp.serial_number(), which)
- self._u = usrp
- self._which = which
+ self.u = usrp
+ self.which = which
# Use MSB with no header
self.spi_format = usrp1.SPI_FMT_MSB | usrp1.SPI_FMT_HDR_0
self.spi_enable = (usrp1.SPI_ENABLE_RX_A, usrp1.SPI_ENABLE_RX_B)[which]
- # MAX2829 chipset configuration
+ # Sane defaults
self.mimo = 1 # 0 = OFF, 1 = ON
self.int_div = 192 # 128 = min, 255 = max
self.frac_div = 0 # 0 = min, 65535 = max
@@ -112,29 +111,32 @@
self.rssi_range = 1 # 0 = low range (datasheet typo), 1 = high
range (0.5V - 2.0V)
self.rssi_mode = 1 # 0 = enable follows RXHP, 1 = enabled
self.rssi_mux = 0 # 0 = RSSI, 1 = TEMP
+ self.rx_hp_pin = 0 # 0 = Fc set by rx_hpf, 1 = 600 KHz
self.rx_hpf = 0 # 0 = 100Hz, 1 = 30KHz
+ self.rx_ant = 0 # 0 = Ant. #1, 1 = Ant. #2
+ self.tx_ant = 0 # 0 = Ant. #1, 1 = Ant. #2
self.txvga_ser = 1 # 0 = TXVGA controlled by B6:1, 1 =
controlled serially
self.tx_driver_lin = 2 # 0 = 50% (worst linearity), 1 = 63%, 2 =
78%, 3 = 100% (best lin)
self.tx_vga_lin = 2 # 0 = 50% (worst linearity), 1 = 63%, 2 =
78%, 3 = 100% (best lin)
self.tx_upconv_lin = 2 # 0 = 50% (worst linearity), 1 = 63%, 2 =
78%, 3 = 100% (best lin)
- self.tx_bb_gain = 0 # 0 = maxgain-5dB, 1 = max-3dB, 2 =
max-1.5dB, 3 = max
+ self.tx_bb_gain = 3 # 0 = maxgain-5dB, 1 = max-3dB, 2 =
max-1.5dB, 3 = max
self.pabias_delay = 15 # 0 = 0, 15 = 7uS
self.pabias = 0 # 0 = 0 uA, 63 = 315uA
self.rxgain = 64 # 0 = min, 127 = max
- self.txgain = 63 # 0 = min, 63 = max
+ self.txgain = 32 # 0 = min, 63 = max
# Initialize GPIO and ATR
- self._tx_write_io(TX_SAFE_IO, TX_OE_MASK)
- self._tx_write_oe(TX_OE_MASK, ~0)
- self._tx_set_atr_txval(TX_SAFE_IO)
- self._tx_set_atr_rxval(TX_SAFE_IO)
- self._tx_set_atr_mask(TX_OE_MASK)
- self._rx_write_io(RX_SAFE_IO, RX_OE_MASK)
- self._rx_write_oe(RX_OE_MASK, ~0)
- self._rx_set_atr_rxval(RX_SAFE_IO)
- self._rx_set_atr_txval(RX_SAFE_IO)
- self._rx_set_atr_mask(RX_OE_MASK)
-
+ self.tx_write_io(TX_SAFE_IO, TX_OE_MASK)
+ self.tx_write_oe(TX_OE_MASK, ~0)
+ self.tx_set_atr_txval(TX_SAFE_IO)
+ self.tx_set_atr_rxval(TX_SAFE_IO)
+ self.tx_set_atr_mask(TX_OE_MASK)
+ self.rx_write_io(RX_SAFE_IO, RX_OE_MASK)
+ self.rx_write_oe(RX_OE_MASK, ~0)
+ self.rx_set_atr_rxval(RX_SAFE_IO)
+ self.rx_set_atr_txval(RX_SAFE_IO)
+ self.rx_set_atr_mask(RX_OE_MASK)
+
# Initialize chipset
# TODO: perform reset sequence to ensure power up defaults
self.set_reg_standby()
@@ -146,8 +148,16 @@
self.set_reg_pabias()
self.set_reg_rxgain()
self.set_reg_txgain()
- #self.set_freq(2.45e9)
+ self.set_freq(2.45e9)
+ def __del__(self):
+ print "xcvr2450: __del__"
+ self.tx_set_atr_txval(TX_SAFE_IO)
+ self.tx_set_atr_rxval(TX_SAFE_IO)
+ self.rx_set_atr_rxval(RX_SAFE_IO)
+ self.rx_set_atr_txval(RX_SAFE_IO)
+
+
# --------------------------------------------------------------------
# These methods set the MAX2829 onboard registers over the SPI bus.
# The SPI format is 18 bits, with the four LSBs holding the register no.
@@ -162,19 +172,19 @@
(1<<6) |
(1<<5) |
(1<<4) | 2)
- self._send_reg(self.reg_standby)
+ self.send_reg(self.reg_standby)
# Integer-Divider Ratio (3)
def set_reg_int_divider(self):
self.reg_int_divider = (
((self.frac_div & 0x03)<<16) |
(self.int_div<<4) | 3)
- self._send_reg(self.reg_int_divider)
+ self.send_reg(self.reg_int_divider)
# Fractional-Divider Ratio (4)
def set_reg_frac_divider(self):
self.reg_frac_divider = ((self.frac_div & 0xfffc)<<2) | 4
- self._send_reg(self.reg_frac_divider)
+ self.send_reg(self.reg_frac_divider)
# Band Select and PLL (5)
def set_reg_bandselpll(self):
@@ -187,14 +197,14 @@
(self.cp_current<<9) |
(self.ref_div<<5) |
(self.five_gig<<4) | 5)
- self._send_reg(self.reg_bandselpll)
+ self.send_reg(self.reg_bandselpll)
# Calibration (6)
def set_reg_cal(self):
# FIXME do calibration
self.reg_cal = (1<<14)|6
- self._send_reg(self.reg_cal)
+ self.send_reg(self.reg_cal)
# Lowpass Filter (7)
@@ -204,7 +214,7 @@
(self.txlpf_bw<<10) |
(self.rxlpf_bw<<9) |
(self.rxlpf_fine<<4) | 7)
- self._send_reg(self.reg_lpf)
+ self.send_reg(self.reg_lpf)
# Rx Control/RSSI (8)
@@ -217,7 +227,7 @@
(1<<9) |
(self.rx_hpf<<6) |
(1<<4) | 8)
- self._send_reg(self.reg_rxrssi_ctrl)
+ self.send_reg(self.reg_rxrssi_ctrl)
# Tx Linearity/Baseband Gain (9)
@@ -228,7 +238,7 @@
(self.tx_vga_lin<<10) |
(self.tx_upconv_lin<<6) |
(self.tx_bb_gain<<4) | 9)
- self._send_reg(self.reg_txlin_gain)
+ self.send_reg(self.reg_txlin_gain)
# PA Bias DAC (10)
@@ -236,28 +246,28 @@
self.reg_pabias = (
(self.pabias_delay<<10) |
(self.pabias<<4) | 10)
- self._send_reg(self.reg_pabias)
+ self.send_reg(self.reg_pabias)
# Rx Gain (11)
def set_reg_rxgain(self):
self.reg_rxgain = (self.rxgain<<4) | 11
- self._send_reg(self.reg_rxgain)
+ self.send_reg(self.reg_rxgain)
# Tx Gain (12)
def set_reg_txgain(self):
self.reg_txgain = (self.txgain<<4) | 12
- self._send_reg(self.reg_txgain)
+ self.send_reg(self.reg_txgain)
# Send register write to SPI
- def _send_reg(self, v):
+ def send_reg(self, v):
# Send 24 bits, it keeps last 18 clocked in
s = ''.join((chr((v >> 16) & 0xff),
chr((v >> 8) & 0xff),
chr(v & 0xff)))
- self._u._write_spi(0, self.spi_enable, self.spi_format, s)
+ self.u._write_spi(0, self.spi_enable, self.spi_format, s)
print "xcvr2450: Setting reg %d to %06X" % ((v&15), v)
# --------------------------------------------------------------------
@@ -268,62 +278,81 @@
# The board operates in ATR mode, always. Thus, when the board is first
# initialized, it is in receive mode, until bits show up in the TX FIFO.
#
- # We calculate and maintain four values:
- #
- # io_rx_while_rx: what to drive onto io_rx_* when receiving
- # io_rx_while_tx: what to drive onto io_rx_* when transmitting
- # io_tx_while_rx: what to drive onto io_tx_* when receiving
- # io_tx_while_tx: what to drive onto io_tx_* when transmitting
-
- def _tx_write_oe(self, value, mask):
- return self._u._write_fpga_reg((FR_OE_0, FR_OE_2)[self._which],
+ def tx_write_oe(self, value, mask):
+ return self.u._write_fpga_reg((FR_OE_0, FR_OE_2)[self.which],
gru.hexint((mask << 16) | value))
- def _tx_write_io(self, value, mask):
- return self._u._write_fpga_reg((FR_IO_0, FR_IO_2)[self._which],
+ def tx_write_io(self, value, mask):
+ return self.u._write_fpga_reg((FR_IO_0, FR_IO_2)[self.which],
gru.hexint((mask << 16) | value))
- def _tx_read_io(self):
- t = self._u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A,
FR_RB_IO_RX_B_IO_TX_B)[self._which])
+ def tx_read_io(self):
+ t = self.u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A,
FR_RB_IO_RX_B_IO_TX_B)[self.which])
return t & 0xffff
- def _rx_write_oe(self, value, mask):
- return self._u._write_fpga_reg((FR_OE_1, FR_OE_3)[self._which],
+ def rx_write_oe(self, value, mask):
+ return self.u._write_fpga_reg((FR_OE_1, FR_OE_3)[self.which],
gru.hexint((mask << 16) | value))
- def _rx_write_io(self, value, mask):
- return self._u._write_fpga_reg((FR_IO_1, FR_IO_3)[self._which],
+ def rx_write_io(self, value, mask):
+ return self.u._write_fpga_reg((FR_IO_1, FR_IO_3)[self.which],
gru.hexint((mask << 16) | value))
- def _rx_read_io(self):
- t = self._u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A,
FR_RB_IO_RX_B_IO_TX_B)[self._which])
+ def rx_read_io(self):
+ t = self.u._read_fpga_reg((FR_RB_IO_RX_A_IO_TX_A,
FR_RB_IO_RX_B_IO_TX_B)[self.which])
return (t >> 16) & 0xffff
- def _tx_set_atr_mask(self, v):
- return
self._u._write_fpga_reg((FR_ATR_MASK_0,FR_ATR_MASK_2)[self._which],
+ def tx_set_atr_mask(self, v):
+ return
self.u._write_fpga_reg((FR_ATR_MASK_0,FR_ATR_MASK_2)[self.which],
gru.hexint(v))
- def _tx_set_atr_txval(self, v):
- return
self._u._write_fpga_reg((FR_ATR_TXVAL_0,FR_ATR_TXVAL_2)[self._which],
+ def tx_set_atr_txval(self, v):
+ return
self.u._write_fpga_reg((FR_ATR_TXVAL_0,FR_ATR_TXVAL_2)[self.which],
gru.hexint(v))
- def _tx_set_atr_rxval(self, v):
- return
self._u._write_fpga_reg((FR_ATR_RXVAL_0,FR_ATR_RXVAL_2)[self._which],
+ def tx_set_atr_rxval(self, v):
+ return
self.u._write_fpga_reg((FR_ATR_RXVAL_0,FR_ATR_RXVAL_2)[self.which],
gru.hexint(v))
- def _rx_set_atr_mask(self, v):
- return
self._u._write_fpga_reg((FR_ATR_MASK_1,FR_ATR_MASK_3)[self._which],
+ def rx_set_atr_mask(self, v):
+ return
self.u._write_fpga_reg((FR_ATR_MASK_1,FR_ATR_MASK_3)[self.which],
gru.hexint(v))
- def _rx_set_atr_txval(self, v):
- return
self._u._write_fpga_reg((FR_ATR_TXVAL_1,FR_ATR_TXVAL_3)[self._which],
+ def rx_set_atr_txval(self, v):
+ return
self.u._write_fpga_reg((FR_ATR_TXVAL_1,FR_ATR_TXVAL_3)[self.which],
gru.hexint(v))
- def _rx_set_atr_rxval(self, v):
- return
self._u._write_fpga_reg((FR_ATR_RXVAL_1,FR_ATR_RXVAL_3)[self._which],
+ def rx_set_atr_rxval(self, v):
+ return
self.u._write_fpga_reg((FR_ATR_RXVAL_1,FR_ATR_RXVAL_3)[self.which],
gru.hexint(v))
+ def set_gpio(self):
+ # We calculate four values:
+ #
+ # io_rx_while_rx: what to drive onto io_rx_* when receiving
+ # io_rx_while_tx: what to drive onto io_rx_* when transmitting
+ # io_tx_while_rx: what to drive onto io_tx_* when receiving
+ # io_tx_while_tx: what to drive onto io_tx_* when transmitting
+ #
+ # B1-B7 is ignored as gain is set serially for now.
+
+ rx_hp = (0, RX_HP)[self.rx_hp_pin]
+ tx_antsel = (ANTSEL_TX1_RX2, ANTSEL_TX2_RX1)[self.tx_ant]
+ rx_antsel = (ANTSEL_TX1_RX2, ANTSEL_TX2_RX1)[self.rx_ant]
+ tx_pa_sel = (HB_PA_OFF, LB_PA_OFF)[self.five_gig]
+ io_rx_while_rx = EN|rx_hp|RX_EN
+ io_rx_while_tx = EN|rx_hp
+ io_tx_while_rx = HB_PA_OFF|LB_PA_OFF|rx_antsel
+ io_tx_while_tx = tx_pa_sel|tx_antsel|TX_EN
+ self.rx_set_atr_rxval(io_rx_while_rx)
+ self.rx_set_atr_txval(io_rx_while_tx)
+ self.tx_set_atr_rxval(io_tx_while_rx)
+ self.tx_set_atr_txval(io_tx_while_tx)
+
+ print "GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X" % (
+ io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx)
+
# --------------------------------------------------------------------
# These methods set control the high-level operating parameters.
@@ -343,41 +372,47 @@
self.highband = 0
vco_freq = target_freq*scaler;
- ref_clk = self._u.fpga_master_clock_freq() # Assumes AD9515 is
bypassed
+ ref_clk = self.u.fpga_master_clock_freq() # Assumes AD9515 is bypassed
phdet_freq = ref_clk/self.ref_div
div = vco_freq/phdet_freq
self.int_div = int(math.floor(div))
self.frac_div = int((div-self.int_div)*65536.0)
actual_freq = phdet_freq*(self.int_div+(self.frac_div/65536.0))/scaler
-
- print "For target =", n2s(target_freq)
- print " VCO freq =", n2s(vco_freq)
- print " ref_div =", self.ref_div
- print " div =", div
- print " int_div =", self.int_div
- print " frac_div =", self.frac_div
- print " actual =", n2s(actual_freq)
+ print "RF=%s VCO=%s R=%d PHD=%s DIV=%3.5f I=%3d F=%5d ACT=%s" % (
+ n2s(target_freq), n2s(vco_freq), self.ref_div, n2s(phdet_freq),
+ div, self.int_div, self.frac_div, n2s(actual_freq))
+
+ self.set_gpio()
self.set_reg_int_divider()
self.set_reg_frac_divider()
self.set_reg_bandselpll()
- return (self._lock_detect(), actual_freq)
+ ok = self.lock_detect()
+ print "lock detect:", ok
+ return (ok, actual_freq)
- def _lock_detect(self):
+ def lock_detect(self):
"""
@returns: the value of the VCO/PLL lock detect bit.
@rtype: 0 or 1
"""
- if self._rx_read_io() & LOCKDET:
+ if self.rx_read_io() & LOCKDET:
return True
else: # Give it a second chance
- if self._rx_read_io() & LOCKDET:
+ if self.rx_read_io() & LOCKDET:
return True
else:
return False
+ def set_rx_gain(self, gain):
+ self.rxgain = int(gain)
+ self.set_reg_rxgain()
+ def set_tx_gain(self, gain):
+ self.txgain = int(gain)
+ self.set_reg_txgain()
+
class db_xcvr2450_base(db_base.db_base):
"""
Abstract base class for all xcvr2450 boards.
@@ -392,18 +427,16 @@
"""
# sets _u _which _tx and _slot
db_base.db_base.__init__(self, usrp, which)
- self._xcvr = _get_or_make_xcvr2450(usrp, which)
+ self.xcvr = _get_or_make_xcvr2450(usrp, which)
-
def set_freq(self, target_freq):
"""
@returns (ok, actual_baseband_freq) where:
ok is True or False and indicates success or failure,
actual_baseband_freq is the RF frequency that corresponds to DC in
the IF.
"""
- return self._xcvr.set_freq(target_freq)
+ return self.xcvr.set_freq(target_freq)
-
def is_quadrature(self):
"""
Return True if this board requires both I & Q analog channels.
@@ -412,18 +445,12 @@
"""
return True
-
def freq_range(self):
return (2.4e9, 6e9, 1e6)
-
def set_freq(self, target_freq):
- return self._xcvr.set_freq(target_freq)
+ return self.xcvr.set_freq(target_freq)
- #FIXME: temporary for debugging
- def set_gain(self, gain):
- return True
-
# ----------------------------------------------------------------
class db_xcvr2450_tx(db_xcvr2450_base):
@@ -435,10 +462,13 @@
print "db_xcvr2450_tx: __init__"
db_xcvr2450_base.__init__(self, usrp, which)
- #FIXME: temporary for debugging
+ # FIXME: this is not in dB
def gain_range(self):
return (0, 63, 1)
+ def set_gain(self, gain):
+ return self.xcvr.set_tx_gain(gain)
+
class db_xcvr2450_rx(db_xcvr2450_base):
def __init__(self, usrp, which):
@@ -449,10 +479,12 @@
print "db_xcvr2450_rx: __init__"
db_xcvr2450_base.__init__(self, usrp, which)
- #FIXME: temporary for debugging
+ # FIXME: this is not in dB
def gain_range(self):
return (0, 127, 1)
+ def set_gain(self, gain):
+ return self.xcvr.set_rx_gain(gain)
#------------------------------------------------------------
# hook these daughterboard classes into the auto-instantiation framework
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7347 - gnuradio/branches/developers/jcorgan/xcvr2450/gr-usrp/src,
jcorgan <=