diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java b/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java
index d5ae5674c..df4b8062a 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java
@@ -55,9 +55,11 @@
import io.github.dsheirer.source.tuner.rtl.e4k.E4KEmbeddedTuner;
import io.github.dsheirer.source.tuner.rtl.e4k.E4KTunerConfiguration;
import io.github.dsheirer.source.tuner.rtl.e4k.E4KTunerEditor;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TEmbeddedTuner;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TTunerConfiguration;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TTunerEditor;
+import io.github.dsheirer.source.tuner.rtl.r8x.R8xTunerEditor;
+import io.github.dsheirer.source.tuner.rtl.r8x.r820t.R820TEmbeddedTuner;
+import io.github.dsheirer.source.tuner.rtl.r8x.r820t.R820TTunerConfiguration;
+import io.github.dsheirer.source.tuner.rtl.r8x.r828d.R828DEmbeddedTuner;
+import io.github.dsheirer.source.tuner.rtl.r8x.r828d.R828DTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
import io.github.dsheirer.source.tuner.sdrplay.api.DeviceSelectionMode;
@@ -367,7 +369,8 @@ public static EmbeddedTuner getRtlEmbeddedTuner(TunerType tunerType,
{
case ELONICS_E4000 -> new E4KEmbeddedTuner(adapter);
case RAFAELMICRO_R820T -> new R820TEmbeddedTuner(adapter);
- default -> throw new SourceException("Unsupported/Unrecognized Tuner Type");
+ case RAFAELMICRO_R828D -> new R828DEmbeddedTuner(adapter);
+ default -> throw new SourceException("Unsupported/Unrecognized Tuner Type: " + tunerType);
};
}
@@ -394,6 +397,8 @@ public static TunerConfiguration getTunerConfiguration(TunerType type, String un
return new HackRFTunerConfiguration(uniqueID);
case RAFAELMICRO_R820T:
return new R820TTunerConfiguration(uniqueID);
+ case RAFAELMICRO_R828D:
+ return new R828DTunerConfiguration(uniqueID);
case RECORDING:
return RecordingTunerConfiguration.create();
case RSP_1:
@@ -475,7 +480,8 @@ else if(discoveredRspTuner instanceof DiscoveredRspDuoTuner2 duoTuner2)
case ELONICS_E4000:
return new E4KTunerEditor(userPreferences, tunerManager, discoveredTuner);
case RAFAELMICRO_R820T:
- return new R820TTunerEditor(userPreferences, tunerManager, discoveredTuner);
+ case RAFAELMICRO_R828D:
+ return new R8xTunerEditor(userPreferences, tunerManager, discoveredTuner);
}
}
return new RTL2832UnknownTunerEditor(userPreferences, tunerManager, discoveredTuner);
diff --git a/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java
index d45c2ddf9..6de3ee44e 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * Copyright (C) 2014-2023 Dennis Sheirer
*
* 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
@@ -31,7 +31,8 @@
import io.github.dsheirer.source.tuner.hackrf.HackRFTunerConfiguration;
import io.github.dsheirer.source.tuner.recording.RecordingTunerConfiguration;
import io.github.dsheirer.source.tuner.rtl.e4k.E4KTunerConfiguration;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TTunerConfiguration;
+import io.github.dsheirer.source.tuner.rtl.r8x.r820t.R820TTunerConfiguration;
+import io.github.dsheirer.source.tuner.rtl.r8x.r828d.R828DTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration;
/**
@@ -47,6 +48,7 @@
@JsonSubTypes.Type(value = HackRFTunerConfiguration.class, name = "hackRFTunerConfiguration"),
@JsonSubTypes.Type(value = RecordingTunerConfiguration.class, name = "recordingTunerConfiguration"),
@JsonSubTypes.Type(value = R820TTunerConfiguration.class, name = "r820TTunerConfiguration"),
+ @JsonSubTypes.Type(value = R828DTunerConfiguration.class, name = "r828DTunerConfiguration"),
@JsonSubTypes.Type(value = RspTunerConfiguration.class, name = "rspTunerConfiguration"),
})
@JacksonXmlRootElement(localName = "tuner_configuration")
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerConfiguration.java
index d5025ff11..a22150546 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerConfiguration.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerConfiguration.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * Copyright (C) 2014-2023 Dennis Sheirer
*
* 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
@@ -24,7 +24,8 @@
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
import io.github.dsheirer.source.tuner.rtl.e4k.E4KTunerConfiguration;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TTunerConfiguration;
+import io.github.dsheirer.source.tuner.rtl.r8x.r820t.R820TTunerConfiguration;
+import io.github.dsheirer.source.tuner.rtl.r8x.r828d.R828DTunerConfiguration;
/**
* RTL2832 tuner configuration
@@ -33,6 +34,7 @@
@JsonSubTypes({
@JsonSubTypes.Type(value = E4KTunerConfiguration.class, name = "e4KTunerConfiguration"),
@JsonSubTypes.Type(value = R820TTunerConfiguration.class, name = "r820TTunerConfiguration"),
+ @JsonSubTypes.Type(value = R828DTunerConfiguration.class, name = "r828DTunerConfiguration"),
})
@JacksonXmlRootElement(localName = "tuner_configuration")
public abstract class RTL2832TunerConfiguration extends TunerConfiguration
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java
index 876ae8a3b..98aa86f38 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/RTL2832TunerController.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * Copyright (C) 2014-2023 Dennis Sheirer
*
* 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
@@ -238,7 +238,7 @@ protected void deviceStart() throws SourceException
if(tunerType == TunerType.UNKNOWN)
{
- throw new SourceException("Unrecognized embedded tuner type for RTL-2832");
+ throw new SourceException("Unrecognized RTL-2832 embedded tuner type: " + tunerType);
}
mEmbeddedTuner = TunerFactory.getRtlEmbeddedTuner(tunerType, new ControllerAdapter(this));
@@ -869,11 +869,11 @@ private boolean isTuner(TunerTypeCheck type, boolean controlI2CRepeater)
if(type == TunerTypeCheck.FC2580)
{
- return ((value & 0x7F) == type.getCheckValue());
+ return ((value & 0x7F) == (type.getCheckValue() & 0xFF));
}
else
{
- return (value == type.getCheckValue());
+ return (value == (type.getCheckValue() & 0xFF));
}
}
catch(LibUsbException e)
@@ -973,7 +973,7 @@ private int getUSBTransferBufferSize(double sampleRate)
public void setSampleRateFrequencyCorrection(int ppm) throws SourceException
{
- int offset = -ppm * TWO_TO_22_POWER / 1000000;
+ int offset = -ppm * TWO_TO_22_POWER / 1_000_000;
writeDemodRegister(Page.ONE, (short) 0x3F, (offset & 0xFF), 1);
writeDemodRegister(Page.ONE, (short) 0x3E, (Integer.rotateRight(offset, 8) & 0xFF), 1);
/* Test to retune controller to apply frequency correction */
@@ -983,7 +983,7 @@ public void setSampleRateFrequencyCorrection(int ppm) throws SourceException
}
catch(Exception e)
{
- throw new SourceException("couldn't set sample rate frequency correction", e);
+ throw new SourceException("Couldn't set sample rate frequency correction", e);
}
}
@@ -1314,6 +1314,14 @@ public Descriptor(byte[] data)
getLabels();
}
+ /**
+ * Indicates if this is a rtl-sdr.com V4 R828D dongle with notch filtering.
+ */
+ public boolean isRtlSdrV4()
+ {
+ return "RTLSDRBlog".equals(getVendorLabel()) && "Blog V4".equals(getProductLabel());
+ }
+
public boolean isValid()
{
return mData[0] != (byte)0x0 && mData[1] != (byte)0x0;
@@ -1479,6 +1487,15 @@ public boolean isRunning()
return mController.isRunning();
}
+ /**
+ * Indicates if this is a rtl-sdr.com V4 dongle with support for notch filtering.
+ * @return true if this is a V4 R828D tuner.
+ */
+ public boolean isV4Dongle()
+ {
+ return mController.getDescriptor().isRtlSdrV4();
+ }
+
/**
* Device handle for the tuner controller.
* @return
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TEmbeddedTuner.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xEmbeddedTuner.java
similarity index 67%
rename from src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TEmbeddedTuner.java
rename to src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xEmbeddedTuner.java
index f43b86c13..3711d12eb 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TEmbeddedTuner.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xEmbeddedTuner.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * Copyright (C) 2014-2023 Dennis Sheirer
*
* 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
@@ -16,88 +16,64 @@
* along with this program. If not, see
* ****************************************************************************
*/
-package io.github.dsheirer.source.tuner.rtl.r820t;
+
+package io.github.dsheirer.source.tuner.rtl.r8x;
import io.github.dsheirer.source.SourceException;
-import io.github.dsheirer.source.tuner.TunerType;
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
import io.github.dsheirer.source.tuner.rtl.EmbeddedTuner;
import io.github.dsheirer.source.tuner.rtl.RTL2832TunerController;
+import java.nio.ByteBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.usb4java.LibUsbException;
import javax.usb.UsbException;
-import java.nio.ByteBuffer;
-public class R820TEmbeddedTuner extends EmbeddedTuner
+/**
+ * Abstract Rafael Micro R8XXX Embedded Tuner base class implementation
+ */
+public abstract class R8xEmbeddedTuner extends EmbeddedTuner
{
- private final static Logger mLog = LoggerFactory.getLogger(R820TEmbeddedTuner.class);
+ public static final byte[] BIT_REV_LOOKUP_TABLE = {(byte) 0x0, (byte) 0x8, (byte) 0x4, (byte) 0xC, (byte) 0x2,
+ (byte) 0xA, (byte) 0x6, (byte) 0xE, (byte) 0x1, (byte) 0x9, (byte) 0x5, (byte) 0xD, (byte) 0x3, (byte) 0xB,
+ (byte) 0x7, (byte) 0xF};
private static final long MINIMUM_SUPPORTED_FREQUENCY = 3180000;
private static final long MAXIMUM_SUPPORTED_FREQUENCY = 1782030000;
private static final double USABLE_BANDWIDTH_PERCENT = 0.98;
private static final int DC_SPIKE_AVOID_BUFFER = 5000;
- private static final int R820T_IF_FREQUENCY = 3570000;
private static final byte VERSION = (byte) 49;
- private static final byte I2C_ADDRESS = (byte) 0x34;
- public static final byte[] BIT_REV_LOOKUP_TABLE = {(byte) 0x0, (byte) 0x8, (byte) 0x4, (byte) 0xC, (byte) 0x2,
- (byte) 0xA, (byte) 0x6, (byte) 0xE, (byte) 0x1, (byte) 0x9, (byte) 0x5, (byte) 0xD, (byte) 0x3, (byte) 0xB,
- (byte) 0x7, (byte) 0xF};
+ protected static final int IF_FREQUENCY = 3570000;
+ private static final Logger mLog = LoggerFactory.getLogger(R8xEmbeddedTuner.class);
+ private static int mVcoPowerRef = 1;
/**
* Shadow register is used to keep a cached (in-memory) copy of all registers, so that we don't have to read a
* full byte from a register in order to apply a masked value and then re-write the full byte. With the shadow
* register, we can apply the masked value to the cached value, and then just write the masked byte, skipping the
- * need to read the byte first.
+ * need to read the byte first and avoid writing the byte value if the value is unchanged.
*/
- private int[] mShadowRegister = {0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x32, 0x75, 0xC0, 0x40, 0xD6, 0x6C, 0xF5, 0x63,
- 0x75, 0x68, 0x6C, 0x83, 0x80, 0x00, 0x0F, 0x00, 0xC0, 0x30, 0x48, 0xCC, 0x60, 0x00, 0x54, 0xAE, 0x4A, 0xC0};
-
+ private byte[] mShadowRegister = {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x83,
+ (byte) 0x32, (byte) 0x75, (byte) 0xC0, (byte) 0x40, (byte) 0xD6, (byte) 0x6C, (byte) 0xF5, (byte) 0x63,
+ (byte) 0x75, (byte) 0x68, (byte) 0x6C, (byte) 0x83, (byte) 0x80, (byte) 0x00, (byte) 0x0F, (byte) 0x00,
+ (byte) 0xC0, (byte) 0x30, (byte) 0x48, (byte) 0xCC, (byte) 0x60, (byte) 0x00, (byte) 0x54, (byte) 0xAE,
+ (byte) 0x4A, (byte) 0xC0};
/**
* Constructs an instance
- * @param adapter for accessing RTL2832USBController interfaces
+ * @param adapter to control the RTL2832 interface.
+ * @param vcoPowerRef power reference.
*/
- public R820TEmbeddedTuner(RTL2832TunerController.ControllerAdapter adapter)
+ public R8xEmbeddedTuner(RTL2832TunerController.ControllerAdapter adapter, int vcoPowerRef)
{
super(adapter);
+ mVcoPowerRef = vcoPowerRef;
}
- @Override
- public TunerType getTunerType()
- {
- return TunerType.RAFAELMICRO_R820T;
- }
-
- @Override
- public long getMinimumFrequencySupported()
- {
- return MINIMUM_SUPPORTED_FREQUENCY;
- }
-
- @Override
- public long getMaximumFrequencySupported()
- {
- return MAXIMUM_SUPPORTED_FREQUENCY;
- }
-
- @Override
- public int getDcSpikeHalfBandwidth()
- {
- return DC_SPIKE_AVOID_BUFFER;
- }
-
- @Override
- public double getUsableBandwidthPercent()
- {
- return USABLE_BANDWIDTH_PERCENT;
- }
-
- @Override
- public void setSampleRateFilters(int sampleRate) throws SourceException
- {
- //No-op
- }
+ /**
+ * I2C Address for the embedded tuner
+ */
+ public abstract byte getI2CAddress();
/**
* Applies the tuner configuration values to this embedded tuner
@@ -109,14 +85,14 @@ public void apply(TunerConfiguration tunerConfig) throws SourceException
{
//Invoke super for frequency, frequency correction and autoPPM
- if(tunerConfig instanceof R820TTunerConfiguration config)
+ if(tunerConfig instanceof R8xTunerConfiguration config)
{
try
{
- R820TGain masterGain = config.getMasterGain();
+ MasterGain masterGain = config.getMasterGain();
setGain(masterGain, true);
- if(masterGain == R820TGain.MANUAL)
+ if(masterGain == MasterGain.MANUAL)
{
setLNAGain(config.getLNAGain(), true);
setMixerGain(config.getMixerGain(), true);
@@ -125,83 +101,92 @@ public void apply(TunerConfiguration tunerConfig) throws SourceException
}
catch(UsbException e)
{
- throw new SourceException("R820TTunerController - usb error while applying tuner config", e);
+ throw new SourceException("R8xxxTunerController - usb error while applying tuner config", e);
}
}
}
/**
- * Sets the center frequency. Setting the frequency is a two-part process
- * of setting the multiplexer and then setting the Oscillator (PLL).
+ * Writes the byte value to the specified register, optionally controlling the I2C repeater as needed.
*/
- @Override
- public synchronized void setTunedFrequency(long frequency) throws SourceException
+ public synchronized void writeRegister(Register register, byte value, boolean controlI2C) throws UsbException
{
- getAdapter().getLock().lock();
+ byte current = mShadowRegister[register.getRegister()];
- try
- {
- getAdapter().enableI2CRepeater();
- boolean controlI2C = false;
- long offsetFrequency = frequency + R820T_IF_FREQUENCY;
- setMux(offsetFrequency, controlI2C);
- setPLL(offsetFrequency, controlI2C);
- getAdapter().disableI2CRepeater();
- }
- catch(UsbException e)
+ if(register.isMasked())
{
- throw new SourceException("R820TTunerController - exception while setting frequency [" + frequency + "] - " +
- e.getLocalizedMessage());
+ value = (byte) ((current & ~register.getMask()) | (value & register.getMask()));
}
- finally
+
+ if(value != current)
{
- getAdapter().getLock().unlock();
+ getAdapter().writeI2CRegister(getI2CAddress(), (byte) register.getRegister(), value, controlI2C);
+ mShadowRegister[register.getRegister()] = value;
}
}
/**
- * Overrides the same method from the RTL2832 tuner controller to apply
- * settings specific to the R820T tuner.
+ * Reads the specified register, optionally controlling the I2C repeater
*/
- public void setSamplingMode(RTL2832TunerController.SampleMode mode) throws LibUsbException
+ public int readRegister(Register register, boolean controlI2C) throws UsbException
{
- if(mode == RTL2832TunerController.SampleMode.QUADRATURE)
- {
- /* Set intermediate frequency to R820T IF frequency */
- getAdapter().setIFFrequency(R820T_IF_FREQUENCY);
-
- /* Enable spectrum inversion */
- getAdapter().writeDemodRegister(RTL2832TunerController.Page.ONE, (short) 0x15, (short) 0x01, 1);
-
- /* Set default i/q path */
- getAdapter().writeDemodRegister(RTL2832TunerController.Page.ZERO, (short) 0x06, (short) 0x80, 1);
- }
+ return getAdapter().readI2CRegister(getI2CAddress(), (byte) register.getRegister(), controlI2C);
}
/**
- * Sets the multiplexer for the desired center frequency.
+ * Assumes value is a byte value and reverses the bits in the byte.
*/
- private void setMux(long frequency, boolean controlI2C) throws UsbException
+ private static int bitReverse(int value)
{
- FrequencyRange range = FrequencyRange.getRangeForFrequency(frequency);
+ return BIT_REV_LOOKUP_TABLE[value & 0x0F] << 4 | BIT_REV_LOOKUP_TABLE[(value & 0xF0) >> 4];
+ }
- /* Set open drain */
- writeR820TRegister(Register.DRAIN, range.getOpenDrain(), controlI2C);
+ @Override
+ public long getMinimumFrequencySupported()
+ {
+ return MINIMUM_SUPPORTED_FREQUENCY;
+ }
- /* RF_MUX, Polymux */
- writeR820TRegister(Register.RF_POLY_MUX, range.getRFMuxPolyMux(), controlI2C);
+ @Override
+ public long getMaximumFrequencySupported()
+ {
+ return MAXIMUM_SUPPORTED_FREQUENCY;
+ }
- /* TF Band */
- writeR820TRegister(Register.TF_BAND, range.getTFC(), controlI2C);
+ @Override
+ public int getDcSpikeHalfBandwidth()
+ {
+ return DC_SPIKE_AVOID_BUFFER;
+ }
- /* XTAL CAP & Drive */
- writeR820TRegister(Register.PLL_XTAL_CAPACITOR_AND_DRIVE, range.getXTALHighCap0P(), controlI2C);
+ @Override
+ public double getUsableBandwidthPercent()
+ {
+ return USABLE_BANDWIDTH_PERCENT;
+ }
- /* Register 8 - what is it? */
- writeR820TRegister(Register.UNKNOWN_REGISTER_8, (byte) 0x00, controlI2C);
+ @Override
+ public void setSampleRateFilters(int sampleRate) throws SourceException
+ {
+ //No-op
+ }
- /* Register 9 - what is it? */
- writeR820TRegister(Register.UNKNOWN_REGISTER_9, (byte) 0x00, controlI2C);
+ /**
+ * Overrides the same method from the RTL2832 tuner controller to apply settings specific to the R8xxx tuner.
+ */
+ public void setSamplingMode(RTL2832TunerController.SampleMode mode) throws LibUsbException
+ {
+ if(mode == RTL2832TunerController.SampleMode.QUADRATURE)
+ {
+ /* Set intermediate frequency to R820T IF frequency */
+ getAdapter().setIFFrequency(IF_FREQUENCY);
+
+ /* Enable spectrum inversion */
+ getAdapter().writeDemodRegister(RTL2832TunerController.Page.ONE, (short) 0x15, (short) 0x01, 1);
+
+ /* Set default i/q path */
+ getAdapter().writeDemodRegister(RTL2832TunerController.Page.ZERO, (short) 0x06, (short) 0x80, 1);
+ }
}
/**
@@ -215,8 +200,8 @@ protected void initTuner() throws UsbException
/* Only enable in-phase ADC input */
getAdapter().writeDemodRegister(RTL2832TunerController.Page.ZERO, (short) 0x08, (short) 0x4D, 1);
- /* Set intermediate frequency to R820T IF frequency (3.57 MHz) */
- getAdapter().setIFFrequency(R820T_IF_FREQUENCY);
+ /* Set intermediate frequency to IF frequency (3.57 MHz) */
+ getAdapter().setIFFrequency(IF_FREQUENCY);
/* Enable spectrum inversion */
getAdapter().writeDemodRegister(RTL2832TunerController.Page.ONE, (short) 0x15, (short) 0x01, 1);
@@ -225,44 +210,146 @@ protected void initTuner() throws UsbException
systemFrequencySelect(0, false);
}
+ /**
+ * Sets the tuner's Phase-Locked-Loop (PLL) oscillator used for frequency (tuning) control
+ *
+ * @param frequency - desired center frequency
+ * @param controlI2C - control the I2C repeater locally
+ * @throws UsbException - if unable to set any of the R8xxx registers
+ */
+ protected void setPLL(long frequency, boolean controlI2C) throws UsbException
+ {
+ /* Set reference divider to 0 */
+ writeRegister(Register.REFERENCE_DIVIDER_2, (byte) 0x00, controlI2C);
+ /* Set PLL autotune to 128kHz */
+ writeRegister(Register.PLL_AUTOTUNE, (byte) 0x00, controlI2C);
+ /* Set VCO current to 100 */
+ writeRegister(Register.VCO_CURRENT, (byte) 0x80, controlI2C);
+ /* Set the frequency divider - adjust for vco_fine_tune status */
+ FrequencyDivider divider = FrequencyDivider.fromFrequency(frequency);
+ int statusRegister4 = getStatusRegister(4, controlI2C);
+ int vco_fine_tune = (statusRegister4 & 0x30) >> 4;
+ int div_num = divider.getDividerNumber(vco_fine_tune);
+ writeRegister(Register.DIVIDER, (byte) (div_num << 5), controlI2C);
+ /* Get the integral number for this divider and frequency */
+ Integral integral = divider.getIntegral(frequency);
+ writeRegister(Register.PLL, integral.getRegisterValue(), controlI2C);
+ /* Calculate the sigma-delta modulator fractional setting. If it's non-zero, power up the sdm and apply the
+ fractional setting, otherwise turn it off */
+ int sdm = divider.getSDM(integral, frequency);
+ if(sdm != 0)
+ {
+ writeRegister(Register.SIGMA_DELTA_MODULATOR_POWER, (byte) 0x00, controlI2C);
+ writeRegister(Register.SIGMA_DELTA_MODULATOR_MSB, (byte) ((sdm >> 8) & 0xFF), controlI2C);
+ writeRegister(Register.SIGMA_DELTA_MODULATOR_LSB, (byte) (sdm & 0xFF), controlI2C);
+ }
+ else
+ {
+ writeRegister(Register.SIGMA_DELTA_MODULATOR_POWER, (byte) 0x08, controlI2C);
+ }
+
+ /* Check to see if the PLL locked with these divider, integral and sdm
+ * settings */
+ if(!isPLLLocked(controlI2C))
+ {
+ mLog.info("PLL is not locked. Increasing VCO current");
+ /* Increase VCO current */
+ writeRegister(Register.VCO_CURRENT, (byte) 0x60, controlI2C);
+
+ if(!isPLLLocked(controlI2C))
+ {
+ throw new UsbException("R8xxx Tuner Controller - couldn't achieve PLL lock on frequency [" + frequency + "]");
+ }
+ }
+ /* set pll autotune to 8kHz */
+ writeRegister(Register.PLL_AUTOTUNE_VARIANT, (byte) 0x08, controlI2C);
+ }
+
+ /**
+ * Sets the system IF frequency
+ */
+ private void systemFrequencySelect(long frequency, boolean controlI2C) throws UsbException
+ {
+ /* LNA top? */
+ writeRegister(Register.LNA_TOP2, (byte) 0xE5, controlI2C);
+
+ byte mixer_top;
+ byte cp_cur;
+ byte div_buf_cur;
+
+ if(frequency == 506000000 || frequency == 666000000 || frequency == 818000000)
+ {
+ mixer_top = (byte) 0x14;
+ cp_cur = (byte) 0x28;
+ div_buf_cur = (byte) 0x20;
+ }
+ else
+ {
+ mixer_top = (byte) 0x24;
+ cp_cur = (byte) 0x38;
+ div_buf_cur = (byte) 0x30;
+ }
+
+ writeRegister(Register.MIXER_TOP, mixer_top, controlI2C);
+ writeRegister(Register.LNA_VTH_L, (byte) 0x53, controlI2C);
+ writeRegister(Register.MIXER_VTH_L, (byte) 0x75, controlI2C);
+ /* Air-In only for Astrometa */
+ writeRegister(Register.INPUT_SELECTOR_AIR_AND_CABLE_1, (byte) 0x00, controlI2C);
+ writeRegister(Register.INPUT_SELECTOR_CABLE_2, (byte) 0x00, controlI2C);
+ writeRegister(Register.CP_CUR, cp_cur, controlI2C);
+ writeRegister(Register.DIVIDER_BUFFER_CURRENT, div_buf_cur, controlI2C);
+ writeRegister(Register.FILTER_CURRENT, (byte) 0x40, controlI2C);
+ /* if( type != TUNER_ANALOG_TV ) ... */
+ writeRegister(Register.LNA_TOP, (byte) 0x00, controlI2C);
+ writeRegister(Register.MIXER_TOP2, (byte) 0x00, controlI2C);
+ writeRegister(Register.PRE_DETECT, (byte) 0x00, controlI2C);
+ writeRegister(Register.AGC_CLOCK, (byte) 0x30, controlI2C);
+ writeRegister(Register.LNA_TOP, (byte) 0x18, controlI2C);
+ writeRegister(Register.MIXER_TOP2, mixer_top, controlI2C);
+ /* LNA discharge current */
+ writeRegister(Register.LNA_DISCHARGE_CURRENT, (byte) 0x14, controlI2C);
+ /* AGC clock 1 khz, external det1 cap 1u */
+ writeRegister(Register.AGC_CLOCK, (byte) 0x20, controlI2C);
+ }
+
/**
* Partially implements the r82xx_set_tv_standard() method from librtlsdr.
* Sets standard to digital tv to support sdr operations only.
*/
- private void setTVStandard(boolean controlI2C) throws UsbException
+ protected void setTVStandard(boolean controlI2C) throws UsbException
{
/* Init Flag & Xtal check Result */
- writeR820TRegister(Register.XTAL_CHECK, (byte) 0x00, controlI2C);
+ writeRegister(Register.XTAL_CHECK, (byte) 0x00, controlI2C);
/* Set version */
- writeR820TRegister(Register.VERSION, VERSION, controlI2C);
+ writeRegister(Register.VERSION, VERSION, controlI2C);
/* LT Gain Test */
- writeR820TRegister(Register.LNA_TOP, (byte) 0x00, controlI2C);
+ writeRegister(Register.LNA_TOP, (byte) 0x00, controlI2C);
int calibrationCode = 0;
for(int x = 0; x < 2; x++)
{
/* Set filter cap */
- writeR820TRegister(Register.FILTER_CAPACITOR, (byte) 0x6B, controlI2C);
+ writeRegister(Register.FILTER_CAPACITOR, (byte) 0x6B, controlI2C);
/* Set calibration clock on */
- writeR820TRegister(Register.CALIBRATION_CLOCK, (byte) 0x04, controlI2C);
+ writeRegister(Register.CALIBRATION_CLOCK, (byte) 0x04, controlI2C);
/* XTAL capacitor 0pF for PLL */
- writeR820TRegister(Register.PLL_XTAL_CAPACITOR, (byte) 0x00, controlI2C);
+ writeRegister(Register.PLL_XTAL_CAPACITOR, (byte) 0x00, controlI2C);
setPLL(56000 * 1000, controlI2C);
/* Start trigger */
- writeR820TRegister(Register.CALIBRATION_TRIGGER, (byte) 0x10, controlI2C);
+ writeRegister(Register.CALIBRATION_TRIGGER, (byte) 0x10, controlI2C);
/* Stop trigger */
- writeR820TRegister(Register.CALIBRATION_TRIGGER, (byte) 0x00, controlI2C);
+ writeRegister(Register.CALIBRATION_TRIGGER, (byte) 0x00, controlI2C);
/* Set calibration clock off */
- writeR820TRegister(Register.CALIBRATION_CLOCK, (byte) 0x00, controlI2C);
+ writeRegister(Register.CALIBRATION_CLOCK, (byte) 0x00, controlI2C);
calibrationCode = getCalibrationCode(controlI2C);
@@ -280,33 +367,31 @@ private void setTVStandard(boolean controlI2C) throws UsbException
/* Write calibration code */
byte filt_q = 0x10;
- writeR820TRegister(Register.FILTER_CALIBRATION_CODE,
- (byte) (calibrationCode | filt_q), controlI2C);
+ writeRegister(Register.FILTER_CALIBRATION_CODE, (byte) (calibrationCode | filt_q), controlI2C);
/* Set BW, Filter gain & HP Corner */
- writeR820TRegister(Register.BANDWIDTH_FILTER_GAIN_HIGHPASS_FILTER_CORNER,
- (byte) 0x6B, controlI2C);
+ writeRegister(Register.BANDWIDTH_FILTER_GAIN_HIGHPASS_FILTER_CORNER, (byte) 0x6B, controlI2C);
/* Set Image_R */
- writeR820TRegister(Register.IMAGE_REVERSE, (byte) 0x00, controlI2C);
+ writeRegister(Register.IMAGE_REVERSE, (byte) 0x00, controlI2C);
/* Set filter_3db, V6MHz */
- writeR820TRegister(Register.FILTER_GAIN, (byte) 0x10, controlI2C);
+ writeRegister(Register.FILTER_GAIN, (byte) 0x10, controlI2C);
/* Channel filter extension */
- writeR820TRegister(Register.CHANNEL_FILTER_EXTENSION, (byte) 0x60, controlI2C);
+ writeRegister(Register.CHANNEL_FILTER_EXTENSION, (byte) 0x60, controlI2C);
/* Loop through */
- writeR820TRegister(Register.LOOP_THROUGH, (byte) 0x00, controlI2C);
+ writeRegister(Register.LOOP_THROUGH, (byte) 0x00, controlI2C);
/* Loop through attenuation */
- writeR820TRegister(Register.LOOP_THROUGH_ATTENUATION, (byte) 0x00, controlI2C);
+ writeRegister(Register.LOOP_THROUGH_ATTENUATION, (byte) 0x00, controlI2C);
/* Filter extension widest */
- writeR820TRegister(Register.FILTER_EXTENSION_WIDEST, (byte) 0x00, controlI2C);
+ writeRegister(Register.FILTER_EXTENSION_WIDEST, (byte) 0x00, controlI2C);
/* RF poly filter current */
- writeR820TRegister(Register.RF_POLY_FILTER_CURRENT, (byte) 0x60, controlI2C);
+ writeRegister(Register.RF_POLY_FILTER_CURRENT, (byte) 0x60, controlI2C);
}
/**
@@ -326,119 +411,43 @@ private int getCalibrationCode(boolean controlI2C) throws UsbException
}
/**
- * Sets the system IF frequency
+ * Indicates if the Phase Locked Loop (PLL) oscillator is locked following
+ * a change in the tuned center frequency. Checks status register 2 to see
+ * if the PLL locked indicator bit is set.
*/
- private void systemFrequencySelect(long frequency, boolean controlI2C) throws UsbException
+ protected boolean isPLLLocked(boolean controlI2C) throws UsbException
{
- /* LNA top? */
- writeR820TRegister(Register.LNA_TOP2, (byte) 0xE5, controlI2C);
-
- byte mixer_top;
- byte cp_cur;
- byte div_buf_cur;
-
- if(frequency == 506000000 || frequency == 666000000 || frequency == 818000000)
- {
- mixer_top = (byte) 0x14;
- cp_cur = (byte) 0x28;
- div_buf_cur = (byte) 0x20;
- }
- else
- {
- mixer_top = (byte) 0x24;
- cp_cur = (byte) 0x38;
- div_buf_cur = (byte) 0x30;
- }
-
- writeR820TRegister(Register.MIXER_TOP, mixer_top, controlI2C);
- writeR820TRegister(Register.LNA_VTH_L, (byte) 0x53, controlI2C);
- writeR820TRegister(Register.MIXER_VTH_L, (byte) 0x75, controlI2C);
- /* Air-In only for Astrometa */
- writeR820TRegister(Register.AIR_CABLE1_INPUT_SELECTOR, (byte) 0x00, controlI2C);
- writeR820TRegister(Register.CABLE2_INPUT_SELECTOR, (byte) 0x00, controlI2C);
- writeR820TRegister(Register.CP_CUR, cp_cur, controlI2C);
- writeR820TRegister(Register.DIVIDER_BUFFER_CURRENT, div_buf_cur, controlI2C);
- writeR820TRegister(Register.FILTER_CURRENT, (byte) 0x40, controlI2C);
- /* if( type != TUNER_ANALOG_TV ) ... */
- writeR820TRegister(Register.LNA_TOP, (byte) 0x00, controlI2C);
- writeR820TRegister(Register.MIXER_TOP2, (byte) 0x00, controlI2C);
- writeR820TRegister(Register.PRE_DETECT, (byte) 0x00, controlI2C);
- writeR820TRegister(Register.AGC_CLOCK, (byte) 0x30, controlI2C);
- writeR820TRegister(Register.LNA_TOP, (byte) 0x18, controlI2C);
- writeR820TRegister(Register.MIXER_TOP2, mixer_top, controlI2C);
- /* LNA discharge current */
- writeR820TRegister(Register.LNA_DISCHARGE_CURRENT, (byte) 0x14, controlI2C);
- /* AGC clock 1 khz, external det1 cap 1u */
- writeR820TRegister(Register.AGC_CLOCK, (byte) 0x20, controlI2C);
+ int register = getStatusRegister(2, controlI2C);
+ return (register & 0x40) == 0x40;
}
/**
- * Sets the tuner's Phase-Locked-Loop (PLL) oscillator used for frequency (tuning) control
- *
- * @param frequency - desired center frequency
- * @param controlI2C - control the I2C repeater locally
- * @throws UsbException - if unable to set any of the R820T registers
+ * Sets the multiplexer for the desired center frequency.
*/
- private void setPLL(long frequency, boolean controlI2C) throws UsbException
+ protected void setMux(long frequency, boolean controlI2C) throws UsbException
{
- /* Set reference divider to 0 */
- writeR820TRegister(Register.REFERENCE_DIVIDER_2, (byte) 0x00, controlI2C);
- /* Set PLL autotune to 128kHz */
- writeR820TRegister(Register.PLL_AUTOTUNE, (byte) 0x00, controlI2C);
- /* Set VCO current to 100 */
- writeR820TRegister(Register.VCO_CURRENT, (byte) 0x80, controlI2C);
- /* Set the frequency divider - adjust for vco_fine_tune status */
- FrequencyDivider divider = FrequencyDivider.fromFrequency(frequency);
- int statusRegister4 = getStatusRegister(4, controlI2C);
- int vco_fine_tune = (statusRegister4 & 0x30) >> 4;
- int div_num = divider.getDividerNumber(vco_fine_tune);
- writeR820TRegister(Register.DIVIDER, (byte) (div_num << 5), controlI2C);
- /* Get the integral number for this divider and frequency */
- Integral integral = divider.getIntegral(frequency);
- writeR820TRegister(Register.PLL, integral.getRegisterValue(), controlI2C);
- /* Calculate the sigma-delta modulator fractional setting. If it's
- * non-zero, power up the sdm and apply the fractional setting,
- * otherwise turn it off */
- int sdm = divider.getSDM(integral, frequency);
- if(sdm != 0)
- {
- writeR820TRegister(Register.SIGMA_DELTA_MODULATOR_POWER, (byte) 0x00, controlI2C);
- writeR820TRegister(Register.SIGMA_DELTA_MODULATOR_MSB, (byte) ((sdm >> 8) & 0xFF), controlI2C);
- writeR820TRegister(Register.SIGMA_DELTA_MODULATOR_LSB, (byte) (sdm & 0xFF), controlI2C);
- }
- else
- {
- writeR820TRegister(Register.SIGMA_DELTA_MODULATOR_POWER, (byte) 0x08, controlI2C);
- }
+ FrequencyRange range = FrequencyRange.getRangeForFrequency(frequency);
- /* Check to see if the PLL locked with these divider, integral and sdm
- * settings */
- if(!isPLLLocked(controlI2C))
- {
- /* Increase VCO current */
- writeR820TRegister(Register.VCO_CURRENT, (byte) 0x60, controlI2C);
+ /* Set open drain */
+ writeRegister(Register.DRAIN, range.getOpenDrain(), controlI2C);
- if(!isPLLLocked(controlI2C))
- {
- throw new UsbException("R820T Tuner Controller - couldn't achieve PLL lock on frequency [" + frequency + "]");
- }
- }
+ /* RF_MUX, Polymux */
+ writeRegister(Register.RF_POLY_MUX, range.getRFMuxPolyMux(), controlI2C);
- /* set pll autotune to 8kHz */
- writeR820TRegister(Register.PLL_AUTOTUNE_VARIANT, (byte) 0x08, controlI2C);
- }
+ /* TF Band */
+ writeRegister(Register.TF_BAND, range.getTFC(), controlI2C);
- /**
- * Indicates if the Phase Locked Loop (PLL) oscillator is locked following
- * a change in the tuned center frequency. Checks status register 2 to see
- * if the PLL locked indicator bit is set.
- */
- private boolean isPLLLocked(boolean controlI2C) throws UsbException
- {
- int register = getStatusRegister(2, controlI2C);
- return (register & 0x40) == 0x40;
+ /* XTAL CAP & Drive */
+ writeRegister(Register.PLL_XTAL_CAPACITOR_AND_DRIVE, range.getXTALHighCap0P(), controlI2C);
+
+ /* Register 8 - what is it? */
+ writeRegister(Register.UNKNOWN_REGISTER_8, (byte) 0x00, controlI2C);
+
+ /* Register 9 - what is it? */
+ writeRegister(Register.UNKNOWN_REGISTER_9, (byte) 0x00, controlI2C);
}
+
/**
* Writes initial starting value of registers 0x05 through 0x1F using the
* default value initialized in the shadow register array. This method only
@@ -446,77 +455,45 @@ private boolean isPLLLocked(boolean controlI2C) throws UsbException
*
* @throws UsbException
*/
- private void initializeRegisters(boolean controlI2C) throws UsbException
+ protected void initializeRegisters(boolean controlI2C) throws UsbException
{
for(int x = 5; x < mShadowRegister.length; x++)
{
- getAdapter().writeI2CRegister(I2C_ADDRESS, (byte) x, (byte) mShadowRegister[x], controlI2C);
+ getAdapter().writeI2CRegister(getI2CAddress(), (byte) x, mShadowRegister[x], controlI2C);
}
}
/**
* Returns the contents of status registers 0 through 4
*/
- private int getStatusRegister(int register, boolean controlI2C) throws UsbException
+ protected int getStatusRegister(int register, boolean controlI2C) throws UsbException
{
ByteBuffer buffer = ByteBuffer.allocateDirect(5);
- getAdapter().read(I2C_ADDRESS, RTL2832TunerController.Block.I2C, buffer);
+ getAdapter().read(getI2CAddress(), RTL2832TunerController.Block.I2C, buffer);
return bitReverse(buffer.get(register) & 0xFF);
}
- /**
- * Assumes value is a byte value and reverses the bits in the byte.
- */
- private static int bitReverse(int value)
- {
- return BIT_REV_LOOKUP_TABLE[value & 0x0F] << 4 | BIT_REV_LOOKUP_TABLE[(value & 0xF0) >> 4];
- }
-
- /**
- * Writes the byte value to the specified register, optionally controlling
- * the I2C repeater as needed.
- */
- public synchronized void writeR820TRegister(Register register, byte value, boolean controlI2C) throws UsbException
- {
- if(register.isMasked())
- {
- int current = mShadowRegister[register.getRegister()];
- value = (byte) ((current & ~register.getMask()) | (value & register.getMask()));
- }
-
- getAdapter().writeI2CRegister(I2C_ADDRESS, (byte) register.getRegister(), value, controlI2C);
- mShadowRegister[register.getRegister()] = value;
- }
-
- /**
- * Reads the specified register, optionally controlling the I2C repeater
- */
- public int readR820TRegister(Register register, boolean controlI2C) throws UsbException
- {
- return getAdapter().readI2CRegister(I2C_ADDRESS, (byte) register.getRegister(), controlI2C);
- }
-
/**
* Sets master gain by applying gain component values to LNA, Mixer and
* VGA gain registers.
*/
- public void setGain(R820TGain gain, boolean controlI2C) throws UsbException
+ public void setGain(MasterGain masterGain, boolean controlI2C) throws UsbException
{
- setLNAGain(gain.getLNAGain(), controlI2C);
- setMixerGain(gain.getMixerGain(), controlI2C);
- setVGAGain(gain.getVGAGain(), controlI2C);
+ setLNAGain(masterGain.getLNAGain(), controlI2C);
+ setMixerGain(masterGain.getMixerGain(), controlI2C);
+ setVGAGain(masterGain.getVGAGain(), controlI2C);
}
/**
* Sets LNA gain
*/
- public void setLNAGain(R820TLNAGain gain, boolean controlI2C) throws UsbException
+ public void setLNAGain(LNAGain gain, boolean controlI2C) throws UsbException
{
getAdapter().getLock().lock();
try
{
- writeR820TRegister(Register.LNA_GAIN, gain.getSetting(), controlI2C);
+ writeRegister(Register.LNA_GAIN, gain.getSetting(), controlI2C);
}
finally
{
@@ -527,13 +504,13 @@ public void setLNAGain(R820TLNAGain gain, boolean controlI2C) throws UsbExceptio
/**
* Sets Mixer gain
*/
- public void setMixerGain(R820TMixerGain gain, boolean controlI2C) throws UsbException
+ public void setMixerGain(MixerGain gain, boolean controlI2C) throws UsbException
{
getAdapter().getLock().lock();
try
{
- writeR820TRegister(Register.MIXER_GAIN, gain.getSetting(), controlI2C);
+ writeRegister(Register.MIXER_GAIN, gain.getSetting(), controlI2C);
}
finally
{
@@ -544,13 +521,13 @@ public void setMixerGain(R820TMixerGain gain, boolean controlI2C) throws UsbExce
/**
* Sets VGA gain
*/
- public void setVGAGain(R820TVGAGain gain, boolean controlI2C) throws UsbException
+ public void setVGAGain(VGAGain gain, boolean controlI2C) throws UsbException
{
getAdapter().getLock().lock();
try
{
- writeR820TRegister(Register.VGA_GAIN, gain.getSetting(), controlI2C);
+ writeRegister(Register.VGA_GAIN, gain.getSetting(), controlI2C);
}
finally
{
@@ -559,9 +536,9 @@ public void setVGAGain(R820TVGAGain gain, boolean controlI2C) throws UsbExceptio
}
/**
- * R820T VGA gain settings
+ * VGA gain settings
*/
- public enum R820TVGAGain
+ public enum VGAGain
{
GAIN_0("0", 0x00),
GAIN_26("26", 0x01),
@@ -583,7 +560,7 @@ public enum R820TVGAGain
private String mLabel;
private int mSetting;
- R820TVGAGain(String label, int setting)
+ VGAGain(String label, int setting)
{
mLabel = label;
mSetting = setting;
@@ -601,9 +578,9 @@ public byte getSetting()
}
/**
- * R820T Low Noise Amplifier gain settings
+ * Low Noise Amplifier gain settings
*/
- public enum R820TLNAGain
+ public enum LNAGain
{
AUTOMATIC("Automatic", 0x00),
GAIN_0("0", 0x10),
@@ -626,7 +603,7 @@ public enum R820TLNAGain
private String mLabel;
private int mSetting;
- R820TLNAGain(String label, int setting)
+ LNAGain(String label, int setting)
{
mLabel = label;
mSetting = setting;
@@ -644,12 +621,12 @@ public byte getSetting()
}
/**
- * R820T mixer gain settings
- *
+ * Mixer gain settings
+ *
* Note: gain labels were changed from measured dB values to simple 1-16 value labels to conform
* with the ICD listing the values from 0-15 as minimum to maximum.
*/
- public enum R820TMixerGain
+ public enum MixerGain
{
AUTOMATIC("Automatic", 0x10),
GAIN_0("1", 0x00),
@@ -672,7 +649,7 @@ public enum R820TMixerGain
private String mLabel;
private int mSetting;
- R820TMixerGain(String label, int setting)
+ MixerGain(String label, int setting)
{
mLabel = label;
mSetting = setting;
@@ -690,49 +667,49 @@ public byte getSetting()
}
/**
- * R820T Master gain settings
+ * Master gain settings
*/
- public enum R820TGain
+ public enum MasterGain
{
- AUTOMATIC("Automatic", R820TVGAGain.GAIN_312, R820TLNAGain.AUTOMATIC, R820TMixerGain.AUTOMATIC),
- MANUAL("Manual", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_248, R820TMixerGain.GAIN_123),
- GAIN_0("0", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_0, R820TMixerGain.GAIN_0),
- GAIN_9("9", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_9, R820TMixerGain.GAIN_0),
- GAIN_14("14", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_9, R820TMixerGain.GAIN_5),
- GAIN_26("26", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_21, R820TMixerGain.GAIN_5),
- GAIN_36("36", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_21, R820TMixerGain.GAIN_15),
- GAIN_76("76", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_61, R820TMixerGain.GAIN_15),
- GAIN_86("86", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_61, R820TMixerGain.GAIN_25),
- GAIN_124("124", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_99, R820TMixerGain.GAIN_25),
- GAIN_143("143", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_99, R820TMixerGain.GAIN_44),
- GAIN_156("156", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_112, R820TMixerGain.GAIN_44),
- GAIN_165("165", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_112, R820TMixerGain.GAIN_53),
- GAIN_196("196", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_143, R820TMixerGain.GAIN_53),
- GAIN_208("208", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_143, R820TMixerGain.GAIN_63),
- GAIN_228("228", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_165, R820TMixerGain.GAIN_63),
- GAIN_253("253", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_165, R820TMixerGain.GAIN_88),
- GAIN_279("279", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_191, R820TMixerGain.GAIN_88),
- GAIN_296("296", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_191, R820TMixerGain.GAIN_105),
- GAIN_327("327", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_222, R820TMixerGain.GAIN_105),
- GAIN_337("337", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_222, R820TMixerGain.GAIN_115),
- GAIN_363("363", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_248, R820TMixerGain.GAIN_115),
- GAIN_371("371", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_248, R820TMixerGain.GAIN_123),
- GAIN_385("385", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_262, R820TMixerGain.GAIN_123),
- GAIN_401("401", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_262, R820TMixerGain.GAIN_139),
- GAIN_420("420", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_281, R820TMixerGain.GAIN_139),
- GAIN_433("433", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_281, R820TMixerGain.GAIN_152),
- GAIN_438("438", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_286, R820TMixerGain.GAIN_152),
- GAIN_444("444", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_286, R820TMixerGain.GAIN_158),
- GAIN_479("479", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_321, R820TMixerGain.GAIN_158),
- GAIN_482("482", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_321, R820TMixerGain.GAIN_161),
- GAIN_495("495", R820TVGAGain.GAIN_210, R820TLNAGain.GAIN_334, R820TMixerGain.GAIN_161);
+ AUTOMATIC("Automatic", VGAGain.GAIN_312, LNAGain.AUTOMATIC, MixerGain.AUTOMATIC),
+ MANUAL("Manual", VGAGain.GAIN_210, LNAGain.GAIN_248, MixerGain.GAIN_123),
+ GAIN_0("0", VGAGain.GAIN_210, LNAGain.GAIN_0, MixerGain.GAIN_0),
+ GAIN_9("9", VGAGain.GAIN_210, LNAGain.GAIN_9, MixerGain.GAIN_0),
+ GAIN_14("14", VGAGain.GAIN_210, LNAGain.GAIN_9, MixerGain.GAIN_5),
+ GAIN_26("26", VGAGain.GAIN_210, LNAGain.GAIN_21, MixerGain.GAIN_5),
+ GAIN_36("36", VGAGain.GAIN_210, LNAGain.GAIN_21, MixerGain.GAIN_15),
+ GAIN_76("76", VGAGain.GAIN_210, LNAGain.GAIN_61, MixerGain.GAIN_15),
+ GAIN_86("86", VGAGain.GAIN_210, LNAGain.GAIN_61, MixerGain.GAIN_25),
+ GAIN_124("124", VGAGain.GAIN_210, LNAGain.GAIN_99, MixerGain.GAIN_25),
+ GAIN_143("143", VGAGain.GAIN_210, LNAGain.GAIN_99, MixerGain.GAIN_44),
+ GAIN_156("156", VGAGain.GAIN_210, LNAGain.GAIN_112, MixerGain.GAIN_44),
+ GAIN_165("165", VGAGain.GAIN_210, LNAGain.GAIN_112, MixerGain.GAIN_53),
+ GAIN_196("196", VGAGain.GAIN_210, LNAGain.GAIN_143, MixerGain.GAIN_53),
+ GAIN_208("208", VGAGain.GAIN_210, LNAGain.GAIN_143, MixerGain.GAIN_63),
+ GAIN_228("228", VGAGain.GAIN_210, LNAGain.GAIN_165, MixerGain.GAIN_63),
+ GAIN_253("253", VGAGain.GAIN_210, LNAGain.GAIN_165, MixerGain.GAIN_88),
+ GAIN_279("279", VGAGain.GAIN_210, LNAGain.GAIN_191, MixerGain.GAIN_88),
+ GAIN_296("296", VGAGain.GAIN_210, LNAGain.GAIN_191, MixerGain.GAIN_105),
+ GAIN_327("327", VGAGain.GAIN_210, LNAGain.GAIN_222, MixerGain.GAIN_105),
+ GAIN_337("337", VGAGain.GAIN_210, LNAGain.GAIN_222, MixerGain.GAIN_115),
+ GAIN_363("363", VGAGain.GAIN_210, LNAGain.GAIN_248, MixerGain.GAIN_115),
+ GAIN_371("371", VGAGain.GAIN_210, LNAGain.GAIN_248, MixerGain.GAIN_123),
+ GAIN_385("385", VGAGain.GAIN_210, LNAGain.GAIN_262, MixerGain.GAIN_123),
+ GAIN_401("401", VGAGain.GAIN_210, LNAGain.GAIN_262, MixerGain.GAIN_139),
+ GAIN_420("420", VGAGain.GAIN_210, LNAGain.GAIN_281, MixerGain.GAIN_139),
+ GAIN_433("433", VGAGain.GAIN_210, LNAGain.GAIN_281, MixerGain.GAIN_152),
+ GAIN_438("438", VGAGain.GAIN_210, LNAGain.GAIN_286, MixerGain.GAIN_152),
+ GAIN_444("444", VGAGain.GAIN_210, LNAGain.GAIN_286, MixerGain.GAIN_158),
+ GAIN_479("479", VGAGain.GAIN_210, LNAGain.GAIN_321, MixerGain.GAIN_158),
+ GAIN_482("482", VGAGain.GAIN_210, LNAGain.GAIN_321, MixerGain.GAIN_161),
+ GAIN_495("495", VGAGain.GAIN_210, LNAGain.GAIN_334, MixerGain.GAIN_161);
private String mLabel;
- private R820TVGAGain mVGAGain;
- private R820TLNAGain mLNAGain;
- private R820TMixerGain mMixerGain;
+ private VGAGain mVGAGain;
+ private LNAGain mLNAGain;
+ private MixerGain mMixerGain;
- R820TGain(String label, R820TVGAGain vga, R820TLNAGain lna, R820TMixerGain mixer)
+ MasterGain(String label, VGAGain vga, LNAGain lna, MixerGain mixer)
{
mLabel = label;
mVGAGain = vga;
@@ -745,31 +722,33 @@ public String toString()
return mLabel;
}
- public R820TVGAGain getVGAGain()
+ public VGAGain getVGAGain()
{
return mVGAGain;
}
- public R820TLNAGain getLNAGain()
+ public LNAGain getLNAGain()
{
return mLNAGain;
}
- public R820TMixerGain getMixerGain()
+ public MixerGain getMixerGain()
{
return mMixerGain;
}
}
/**
- * R820T tuner registers and register mask values
+ * R8xxx tuner registers and register mask values
*/
public enum Register
{
LNA_GAIN(0x05, 0x1F),
- AIR_CABLE1_INPUT_SELECTOR(0x05, 0x60),
+ INPUT_SELECTOR_AIR(0x05, 0x20),
+ INPUT_SELECTOR_CABLE_1(0x05, 0x40),
+ INPUT_SELECTOR_AIR_AND_CABLE_1(0x05, 0x60),
LOOP_THROUGH(0x05, 0x80),
- CABLE2_INPUT_SELECTOR(0x06, 0x08),
+ INPUT_SELECTOR_CABLE_2(0x06, 0x08),
FILTER_GAIN(0x06, 0x30),
PRE_DETECT(0x06, 0x40),
MIXER_GAIN(0x07, 0x1F),
@@ -896,6 +875,7 @@ public boolean contains(long frequency)
/**
* Finds the correct frequency range that contains the frequency
+ *
* @param frequency to lookup
* @return frequency range
*/
@@ -960,9 +940,9 @@ public byte getXTALHighCap0P()
/**
* Frequency Divider Ranges
- *
+ *
* Actual Tuned Frequency Ranges (after subtracting IF = 3.57 MHz )
- *
+ *
* Divider 0: 860.43 to 1782.03 MHz
* Divider 1: 428.43 to 889.23 MHz
* Divider 2: 212.43 to 457.23 MHz
@@ -989,7 +969,6 @@ public enum FrequencyDivider
private long mMaximumFrequency;
private int mRegisterSetting;
private int mIntegralValue;
- private static final int mVCOPowerReference = 2;
FrequencyDivider(int dividerNumber, int mixerDivider, long minimumFrequency, long maximumFrequency,
int registerSetting, int integralValue)
@@ -1004,15 +983,15 @@ public enum FrequencyDivider
public int getDividerNumber(int vcoFineTune)
{
- if(vcoFineTune == mVCOPowerReference)
+ if(vcoFineTune == mVcoPowerRef)
{
return mDividerNumber;
}
- else if(vcoFineTune < mVCOPowerReference)
+ else if(vcoFineTune < mVcoPowerRef)
{
return mDividerNumber - 1;
}
- else if(vcoFineTune > mVCOPowerReference)
+ else if(vcoFineTune > mVcoPowerRef)
{
return mDividerNumber + 1;
}
@@ -1055,7 +1034,7 @@ public boolean contains(long frequency)
*/
public static FrequencyDivider fromFrequency(long frequency)
{
- for(FrequencyDivider divider : FrequencyDivider.values())
+ for(FrequencyDivider divider : R8xEmbeddedTuner.FrequencyDivider.values())
{
if(divider.contains(frequency))
{
@@ -1063,7 +1042,7 @@ public static FrequencyDivider fromFrequency(long frequency)
}
}
- return FrequencyDivider.DIVIDER_5;
+ return R8xEmbeddedTuner.FrequencyDivider.DIVIDER_5;
}
/**
@@ -1077,7 +1056,7 @@ public Integral getIntegral(long frequency)
int integral = (int) ((double) delta / (double) mIntegralValue);
- return Integral.fromValue(integral);
+ return R8xEmbeddedTuner.Integral.fromValue(integral);
}
throw new IllegalArgumentException("PLL frequency [" + frequency + "] is not valid for this frequency " +
@@ -1105,16 +1084,7 @@ public int getSDM(Integral integral, long frequency)
}
/**
- * PLL Integral values. Each value represents one unit of the divided
- * crystal frequency as follows:
- *
- * Divider Value
- * 64 I * 0.9 MHz
- * 32 I * 1.8 MHz
- * 16 I * 3.6 MHz
- * 8 I * 7.2 MHz
- * 4 I * 14.4 MHz
- * 2 I * 28.8 MHz
+ * PLL Integral values. Each value represents one unit of the divided crystal frequency.
*/
public enum Integral
{
@@ -1174,10 +1144,10 @@ public static Integral fromValue(int value)
{
if(0 <= value && value <= 31)
{
- return Integral.values()[value];
+ return R8xEmbeddedTuner.Integral.values()[value];
}
throw new IllegalArgumentException("PLL integral value [" + value + "] must be in the range 0 - 31");
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TTunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xTunerConfiguration.java
similarity index 53%
rename from src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TTunerConfiguration.java
rename to src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xTunerConfiguration.java
index cdeb67b79..43ab8b7f9 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TTunerConfiguration.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xTunerConfiguration.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * Copyright (C) 2014-2023 Dennis Sheirer
*
* 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
@@ -16,87 +16,78 @@
* along with this program. If not, see
* ****************************************************************************
*/
-package io.github.dsheirer.source.tuner.rtl.r820t;
+package io.github.dsheirer.source.tuner.rtl.r8x;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import io.github.dsheirer.source.tuner.TunerType;
import io.github.dsheirer.source.tuner.rtl.RTL2832TunerConfiguration;
/**
- * RTL-2832 with embedded R820T tuner configuration
+ * RTL-2832 with embedded R8xxx tuner configuration
*/
-public class R820TTunerConfiguration extends RTL2832TunerConfiguration
+public abstract class R8xTunerConfiguration extends RTL2832TunerConfiguration
{
- private R820TEmbeddedTuner.R820TGain mMasterGain = R820TEmbeddedTuner.R820TGain.GAIN_327;
- private R820TEmbeddedTuner.R820TMixerGain mMixerGain = R820TEmbeddedTuner.R820TMixerGain.GAIN_105;
- private R820TEmbeddedTuner.R820TLNAGain mLNAGain = R820TEmbeddedTuner.R820TLNAGain.GAIN_222;
- private R820TEmbeddedTuner.R820TVGAGain mVGAGain = R820TEmbeddedTuner.R820TVGAGain.GAIN_210;
+ private R8xEmbeddedTuner.MasterGain mMasterMasterGain = R8xEmbeddedTuner.MasterGain.GAIN_327;
+ private R8xEmbeddedTuner.MixerGain mMixerGain = R8xEmbeddedTuner.MixerGain.GAIN_105;
+ private R8xEmbeddedTuner.LNAGain mLNAGain = R8xEmbeddedTuner.LNAGain.GAIN_222;
+ private R8xEmbeddedTuner.VGAGain mVGAGain = R8xEmbeddedTuner.VGAGain.GAIN_210;
/**
* Default constructor for JAXB
*/
- public R820TTunerConfiguration()
+ public R8xTunerConfiguration()
{
}
- @JsonIgnore
- @Override
- public TunerType getTunerType()
- {
- return TunerType.RAFAELMICRO_R820T;
- }
-
/**
* Constructs an instance
*
* @param uniqueID for the tuner
*/
- public R820TTunerConfiguration(String uniqueID)
+ public R8xTunerConfiguration(String uniqueID)
{
super(uniqueID);
}
@JacksonXmlProperty(isAttribute = true, localName = "master_gain")
- public R820TEmbeddedTuner.R820TGain getMasterGain()
+ public R8xEmbeddedTuner.MasterGain getMasterGain()
{
- return mMasterGain;
+ return mMasterMasterGain;
}
- public void setMasterGain(R820TEmbeddedTuner.R820TGain gain)
+ public void setMasterGain(R8xEmbeddedTuner.MasterGain masterGain)
{
- mMasterGain = gain;
+ mMasterMasterGain = masterGain;
}
@JacksonXmlProperty(isAttribute = true, localName = "mixer_gain")
- public R820TEmbeddedTuner.R820TMixerGain getMixerGain()
+ public R8xEmbeddedTuner.MixerGain getMixerGain()
{
return mMixerGain;
}
- public void setMixerGain(R820TEmbeddedTuner.R820TMixerGain mixerGain)
+ public void setMixerGain(R8xEmbeddedTuner.MixerGain mixerGain)
{
mMixerGain = mixerGain;
}
@JacksonXmlProperty(isAttribute = true, localName = "lna_gain")
- public R820TEmbeddedTuner.R820TLNAGain getLNAGain()
+ public R8xEmbeddedTuner.LNAGain getLNAGain()
{
return mLNAGain;
}
- public void setLNAGain(R820TEmbeddedTuner.R820TLNAGain lnaGain)
+ public void setLNAGain(R8xEmbeddedTuner.LNAGain lnaGain)
{
mLNAGain = lnaGain;
}
@JacksonXmlProperty(isAttribute = true, localName = "vga_gain")
- public R820TEmbeddedTuner.R820TVGAGain getVGAGain()
+ public R8xEmbeddedTuner.VGAGain getVGAGain()
{
return mVGAGain;
}
- public void setVGAGain(R820TEmbeddedTuner.R820TVGAGain vgaGain)
+ public void setVGAGain(R8xEmbeddedTuner.VGAGain vgaGain)
{
mVGAGain = vgaGain;
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xTunerEditor.java
similarity index 79%
rename from src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TTunerEditor.java
rename to src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xTunerEditor.java
index bc9aa49e3..2343392b9 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/rtl/r820t/R820TTunerEditor.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/R8xTunerEditor.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* ****************************************************************************
*/
-package io.github.dsheirer.source.tuner.rtl.r820t;
+package io.github.dsheirer.source.tuner.rtl.r8x;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.source.SourceException;
@@ -25,10 +25,6 @@
import io.github.dsheirer.source.tuner.rtl.RTL2832Tuner;
import io.github.dsheirer.source.tuner.rtl.RTL2832TunerController;
import io.github.dsheirer.source.tuner.rtl.RTL2832TunerController.SampleRate;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TEmbeddedTuner.R820TGain;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TEmbeddedTuner.R820TLNAGain;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TEmbeddedTuner.R820TMixerGain;
-import io.github.dsheirer.source.tuner.rtl.r820t.R820TEmbeddedTuner.R820TVGAGain;
import io.github.dsheirer.source.tuner.ui.TunerEditor;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
@@ -43,17 +39,20 @@
import javax.swing.SpinnerNumberModel;
import javax.usb.UsbException;
-public class R820TTunerEditor extends TunerEditor
+/**
+ * R8xxx Tuner Editor
+ */
+public class R8xTunerEditor extends TunerEditor
{
- private final static Logger mLog = LoggerFactory.getLogger(R820TTunerEditor.class);
+ private final static Logger mLog = LoggerFactory.getLogger(R8xTunerEditor.class);
private static final long serialVersionUID = 1L;
- private static final R820TGain DEFAULT_GAIN = R820TGain.GAIN_279;
+ private static final R8xEmbeddedTuner.MasterGain DEFAULT_GAIN = R8xEmbeddedTuner.MasterGain.GAIN_279;
private JButton mTunerInfoButton;
private JComboBox mSampleRateCombo;
- private JComboBox mMasterGainCombo;
- private JComboBox mMixerGainCombo;
- private JComboBox mLNAGainCombo;
- private JComboBox mVGAGainCombo;
+ private JComboBox mMasterGainCombo;
+ private JComboBox mMixerGainCombo;
+ private JComboBox mLNAGainCombo;
+ private JComboBox mVGAGainCombo;
/**
* Constructs an instance
@@ -61,7 +60,7 @@ public class R820TTunerEditor extends TunerEditor JOptionPane.showMessageDialog(R820TTunerEditor.this,
+ mTunerInfoButton.addActionListener(e -> JOptionPane.showMessageDialog(R8xTunerEditor.this,
getTunerInfo(), "Tuner Info", JOptionPane.INFORMATION_MESSAGE));
}
@@ -211,13 +215,13 @@ private JComboBox getVGAGainCombo()
{
if(mVGAGainCombo == null)
{
- mVGAGainCombo = new JComboBox<>(R820TVGAGain.values());
+ mVGAGainCombo = new JComboBox<>(R8xEmbeddedTuner.VGAGain.values());
mVGAGainCombo.setEnabled(false);
mVGAGainCombo.addActionListener(arg0 ->
{
try
{
- R820TVGAGain vgaGain = (R820TVGAGain) mVGAGainCombo.getSelectedItem();
+ R8xEmbeddedTuner.VGAGain vgaGain = (R8xEmbeddedTuner.VGAGain) mVGAGainCombo.getSelectedItem();
if(vgaGain == null)
{
@@ -233,9 +237,9 @@ private JComboBox getVGAGainCombo()
}
catch(UsbException e)
{
- JOptionPane.showMessageDialog(R820TTunerEditor.this, "R820T Tuner Controller - " +
+ JOptionPane.showMessageDialog(R8xTunerEditor.this, getLogPrefix() +
"couldn't apply the VGA gain setting - " + e.getLocalizedMessage());
- mLog.error("R820T Tuner Controller - couldn't apply VGA gain setting", e);
+ mLog.error(getLogPrefix() + "couldn't apply VGA gain setting", e);
}
});
mVGAGainCombo.setToolTipText("VGA Gain. Set master gain to MANUAL to enable adjustment");
@@ -248,13 +252,13 @@ private JComboBox getLNAGainCombo()
{
if(mLNAGainCombo == null)
{
- mLNAGainCombo = new JComboBox<>(R820TLNAGain.values());
+ mLNAGainCombo = new JComboBox<>(R8xEmbeddedTuner.LNAGain.values());
mLNAGainCombo.setEnabled(false);
mLNAGainCombo.addActionListener(arg0 ->
{
try
{
- R820TLNAGain lnaGain = (R820TLNAGain) mLNAGainCombo.getSelectedItem();
+ R8xEmbeddedTuner.LNAGain lnaGain = (R8xEmbeddedTuner.LNAGain) mLNAGainCombo.getSelectedItem();
if(lnaGain == null)
{
@@ -270,9 +274,9 @@ private JComboBox getLNAGainCombo()
}
catch(UsbException e)
{
- JOptionPane.showMessageDialog(R820TTunerEditor.this, "R820T Tuner Controller - " +
+ JOptionPane.showMessageDialog(R8xTunerEditor.this, getLogPrefix() +
"couldn't apply the LNA gain setting - " + e.getLocalizedMessage());
- mLog.error("R820T Tuner Controller - couldn't apply LNA " + "gain setting - ", e);
+ mLog.error(getLogPrefix() + "couldn't apply LNA " + "gain setting - ", e);
}
});
mLNAGainCombo.setToolTipText("LNA Gain. Set master gain to MANUAL to enable adjustment");
@@ -300,11 +304,11 @@ private JComboBox getSampleRateCombo()
}
catch(SourceException | LibUsbException eSampleRate)
{
- JOptionPane.showMessageDialog(R820TTunerEditor.this,
- "R820T Tuner Controller - couldn't apply the sample rate setting [" +
+ JOptionPane.showMessageDialog(R8xTunerEditor.this,
+ getLogPrefix() + "couldn't apply the sample rate setting [" +
sampleRate.getLabel() + "] " + eSampleRate.getLocalizedMessage());
- mLog.error("R820T Tuner Controller - couldn't apply sample rate setting [" + sampleRate.getLabel() +
+ mLog.error(getLogPrefix() + "couldn't apply sample rate setting [" + sampleRate.getLabel() +
"]", eSampleRate);
}
}
@@ -318,7 +322,7 @@ private JComboBox getMixerGainCombo()
{
if(mMixerGainCombo == null)
{
- mMixerGainCombo = new JComboBox<>(R820TMixerGain.values());
+ mMixerGainCombo = new JComboBox<>(R8xEmbeddedTuner.MixerGain.values());
mMixerGainCombo.setEnabled(false);
mMixerGainCombo.addActionListener(arg0 ->
{
@@ -326,7 +330,7 @@ private JComboBox getMixerGainCombo()
{
try
{
- R820TMixerGain mixerGain = (R820TMixerGain) mMixerGainCombo.getSelectedItem();
+ R8xEmbeddedTuner.MixerGain mixerGain = (R8xEmbeddedTuner.MixerGain) mMixerGainCombo.getSelectedItem();
if(mixerGain == null)
{
@@ -342,10 +346,10 @@ private JComboBox getMixerGainCombo()
}
catch(UsbException e)
{
- JOptionPane.showMessageDialog(R820TTunerEditor.this, "R820T Tuner Controller - " +
+ JOptionPane.showMessageDialog(R8xTunerEditor.this, getLogPrefix() +
"couldn't apply the mixer gain setting - " + e.getLocalizedMessage());
- mLog.error("R820T Tuner Controller - couldn't apply mixer gain setting - ", e);
+ mLog.error(getLogPrefix() + "couldn't apply mixer gain setting - ", e);
}
}
});
@@ -359,7 +363,7 @@ private JComboBox getMasterGainCombo()
{
if(mMasterGainCombo == null)
{
- mMasterGainCombo = new JComboBox<>(R820TGain.values());
+ mMasterGainCombo = new JComboBox<>(R8xEmbeddedTuner.MasterGain.values());
mMasterGainCombo.setEnabled(false);
mMasterGainCombo.addActionListener(arg0 ->
{
@@ -367,10 +371,10 @@ private JComboBox getMasterGainCombo()
{
try
{
- R820TGain gain = (R820TGain)getMasterGainCombo().getSelectedItem();
- getEmbeddedTuner().setGain((R820TGain)getMasterGainCombo().getSelectedItem(), true);
+ R8xEmbeddedTuner.MasterGain gain = (R8xEmbeddedTuner.MasterGain)getMasterGainCombo().getSelectedItem();
+ getEmbeddedTuner().setGain((R8xEmbeddedTuner.MasterGain)getMasterGainCombo().getSelectedItem(), true);
- if(gain == R820TGain.MANUAL)
+ if(gain == R8xEmbeddedTuner.MasterGain.MANUAL)
{
getMixerGainCombo().setSelectedItem(gain.getMixerGain());
getMixerGainCombo().setEnabled(true);
@@ -397,9 +401,9 @@ private JComboBox getMasterGainCombo()
}
catch(UsbException e)
{
- JOptionPane.showMessageDialog(R820TTunerEditor.this, "R820T Tuner Controller - " +
+ JOptionPane.showMessageDialog(R8xTunerEditor.this, getLogPrefix() +
"couldn't apply the gain setting - " + e.getLocalizedMessage());
- mLog.error("R820T Tuner Controller - couldn't apply gain setting - ", e);
+ mLog.error(getLogPrefix() + "couldn't apply gain setting - ", e);
}
}
});
@@ -442,7 +446,7 @@ private String getTunerInfo()
{
StringBuilder sb = new StringBuilder();
RTL2832TunerController.Descriptor descriptor = getTuner().getController().getDescriptor();
- sb.append("RTL-2832 with R820T Tuner
");
+ sb.append("RTL-2832 with " + getEmbeddedTuner().getTunerType().getLabel() + " Tuner
");
if(descriptor == null)
{
@@ -485,7 +489,7 @@ public void save()
{
if(hasConfiguration() && !isLoading())
{
- R820TTunerConfiguration config = getConfiguration();
+ R8xTunerConfiguration config = getConfiguration();
config.setFrequency(getFrequencyControl().getFrequency());
double value = ((SpinnerNumberModel)getFrequencyCorrectionSpinner().getModel()).getNumber().doubleValue();
@@ -493,13 +497,13 @@ public void save()
config.setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected());
config.setSampleRate((SampleRate)getSampleRateCombo().getSelectedItem());
- R820TGain gain = (R820TGain)getMasterGainCombo().getSelectedItem();
+ R8xEmbeddedTuner.MasterGain gain = (R8xEmbeddedTuner.MasterGain)getMasterGainCombo().getSelectedItem();
config.setMasterGain(gain);
- R820TMixerGain mixerGain = (R820TMixerGain)getMixerGainCombo().getSelectedItem();
+ R8xEmbeddedTuner.MixerGain mixerGain = (R8xEmbeddedTuner.MixerGain)getMixerGainCombo().getSelectedItem();
config.setMixerGain(mixerGain);
- R820TLNAGain lnaGain = (R820TLNAGain)getLNAGainCombo().getSelectedItem();
+ R8xEmbeddedTuner.LNAGain lnaGain = (R8xEmbeddedTuner.LNAGain)getLNAGainCombo().getSelectedItem();
config.setLNAGain(lnaGain);
- R820TVGAGain vgaGain = (R820TVGAGain)getVGAGainCombo().getSelectedItem();
+ R8xEmbeddedTuner.VGAGain vgaGain = (R8xEmbeddedTuner.VGAGain)getVGAGainCombo().getSelectedItem();
config.setVGAGain(vgaGain);
saveConfiguration();
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r820t/R820TEmbeddedTuner.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r820t/R820TEmbeddedTuner.java
new file mode 100644
index 000000000..49444e0b1
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r820t/R820TEmbeddedTuner.java
@@ -0,0 +1,85 @@
+/*
+ * *****************************************************************************
+ * Copyright (C) 2014-2023 Dennis Sheirer
+ *
+ * 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
+ * ****************************************************************************
+ */
+package io.github.dsheirer.source.tuner.rtl.r8x.r820t;
+
+import io.github.dsheirer.source.SourceException;
+import io.github.dsheirer.source.tuner.TunerType;
+import io.github.dsheirer.source.tuner.rtl.RTL2832TunerController;
+import io.github.dsheirer.source.tuner.rtl.r8x.R8xEmbeddedTuner;
+
+import javax.usb.UsbException;
+
+/**
+ * Rafael Micro R820T and R820T2 Embedded Tuner implementation
+ */
+public class R820TEmbeddedTuner extends R8xEmbeddedTuner
+{
+ private static final byte I2C_ADDRESS = (byte) 0x34;
+ private static final int VCO_POWER_REF = 2;
+
+ /**
+ * Constructs an instance
+ * @param adapter for accessing RTL2832USBController interfaces
+ */
+ public R820TEmbeddedTuner(RTL2832TunerController.ControllerAdapter adapter)
+ {
+ super(adapter, VCO_POWER_REF);
+ }
+
+ @Override
+ public TunerType getTunerType()
+ {
+ return TunerType.RAFAELMICRO_R820T;
+ }
+
+ @Override
+ public byte getI2CAddress()
+ {
+ return I2C_ADDRESS;
+ }
+
+ /**
+ * Sets the center frequency. Setting the frequency is a two-part process
+ * of setting the multiplexer and then setting the Oscillator (PLL).
+ */
+ @Override
+ public synchronized void setTunedFrequency(long frequency) throws SourceException
+ {
+ getAdapter().getLock().lock();
+
+ try
+ {
+ getAdapter().enableI2CRepeater();
+ boolean controlI2C = false;
+ long offsetFrequency = frequency + IF_FREQUENCY;
+ setMux(offsetFrequency, controlI2C);
+ setPLL(offsetFrequency, controlI2C);
+ getAdapter().disableI2CRepeater();
+ }
+ catch(UsbException e)
+ {
+ throw new SourceException("R820TTunerController - exception while setting frequency [" + frequency + "] - " +
+ e.getLocalizedMessage());
+ }
+ finally
+ {
+ getAdapter().getLock().unlock();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r820t/R820TTunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r820t/R820TTunerConfiguration.java
new file mode 100644
index 000000000..9932c009f
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r820t/R820TTunerConfiguration.java
@@ -0,0 +1,52 @@
+/*
+ * *****************************************************************************
+ * Copyright (C) 2014-2023 Dennis Sheirer
+ *
+ * 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
+ * ****************************************************************************
+ */
+package io.github.dsheirer.source.tuner.rtl.r8x.r820t;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.github.dsheirer.source.tuner.TunerType;
+import io.github.dsheirer.source.tuner.rtl.r8x.R8xTunerConfiguration;
+
+/**
+ * RTL-2832 with embedded R820T tuner configuration
+ */
+public class R820TTunerConfiguration extends R8xTunerConfiguration
+{
+ /**
+ * Empty constructor for Jackson serialization
+ */
+ public R820TTunerConfiguration()
+ {
+ }
+
+ /**
+ * Constructs an instance
+ * @param uniqueId for the tuner
+ */
+ public R820TTunerConfiguration(String uniqueId)
+ {
+ super(uniqueId);
+ }
+
+ @JsonIgnore
+ @Override
+ public TunerType getTunerType()
+ {
+ return TunerType.RAFAELMICRO_R820T;
+ }
+}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r828d/R828DEmbeddedTuner.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r828d/R828DEmbeddedTuner.java
new file mode 100644
index 000000000..910c1f04f
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r828d/R828DEmbeddedTuner.java
@@ -0,0 +1,127 @@
+/*
+ * *****************************************************************************
+ * Copyright (C) 2014-2023 Dennis Sheirer
+ *
+ * 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
+ * ****************************************************************************
+ */
+package io.github.dsheirer.source.tuner.rtl.r8x.r828d;
+
+import io.github.dsheirer.source.SourceException;
+import io.github.dsheirer.source.tuner.TunerType;
+import io.github.dsheirer.source.tuner.rtl.RTL2832TunerController;
+import io.github.dsheirer.source.tuner.rtl.r8x.R8xEmbeddedTuner;
+
+import javax.usb.UsbException;
+
+/**
+ * Rafael Micro R828D Embedded Tuner implementation
+ */
+public class R828DEmbeddedTuner extends R8xEmbeddedTuner
+{
+ private static final byte I2C_ADDRESS = (byte) 0x74;
+ private static final int VCO_POWER_REF = 1;
+ /**
+ * RTL-SDR.com blog V4 dongle indicator.
+ */
+ private final boolean mIsV4Dongle;
+
+ /**
+ * Constructs an instance
+ * @param adapter for accessing RTL2832USBController interfaces
+ */
+ public R828DEmbeddedTuner(RTL2832TunerController.ControllerAdapter adapter)
+ {
+ super(adapter, VCO_POWER_REF);
+
+ //Set flag to indicate if this is a V4 dongle that supports notch filtering.
+ mIsV4Dongle = adapter.isV4Dongle();
+ }
+
+ @Override
+ public TunerType getTunerType()
+ {
+ return TunerType.RAFAELMICRO_R828D;
+ }
+
+ @Override
+ public byte getI2CAddress()
+ {
+ return I2C_ADDRESS;
+ }
+
+ /**
+ * Sets the center frequency. Setting the frequency is a two-part process
+ * of setting the multiplexer and then setting the Oscillator (PLL).
+ */
+ @Override
+ public synchronized void setTunedFrequency(long frequency) throws SourceException
+ {
+ getAdapter().getLock().lock();
+
+ try
+ {
+ getAdapter().enableI2CRepeater();
+ boolean controlI2C = false;
+ long offsetFrequency = frequency + IF_FREQUENCY;
+ setMux(offsetFrequency, controlI2C);
+ setPLL(offsetFrequency, controlI2C);
+
+ //Select the RF input
+ if(mIsV4Dongle)
+ {
+ //Disable notch filtering if frequency falls into a notched band, otherwise enable it.
+ boolean isNotchFilterFrequency = (frequency < 2_200_000) ||
+ (85_000_000 < frequency && frequency < 112_000_000) ||
+ (172_000_000 < frequency && frequency < 242_000_000);
+ writeRegister(Register.DRAIN, isNotchFilterFrequency ? (byte)0x00 : (byte)0x08, controlI2C);
+
+ if(frequency <= 28_800_000) //Use cable 2 input
+ {
+ writeRegister(Register.INPUT_SELECTOR_AIR, (byte)0x20, controlI2C); //disabled
+ writeRegister(Register.INPUT_SELECTOR_CABLE_1, (byte)0x00, controlI2C); //disabled
+ writeRegister(Register.INPUT_SELECTOR_CABLE_2, (byte)0x08, controlI2C); //enabled
+ }
+ else if(frequency < 250_000_000)
+ {
+ writeRegister(Register.INPUT_SELECTOR_AIR, (byte)0x20, controlI2C); //disabled
+ writeRegister(Register.INPUT_SELECTOR_CABLE_1, (byte)0x40, controlI2C); //enabled
+ writeRegister(Register.INPUT_SELECTOR_CABLE_2, (byte)0x00, controlI2C); //disabled
+ }
+ else
+ {
+ writeRegister(Register.INPUT_SELECTOR_AIR, (byte)0x00, controlI2C); //enabled
+ writeRegister(Register.INPUT_SELECTOR_CABLE_1, (byte)0x00, controlI2C); //disabled
+ writeRegister(Register.INPUT_SELECTOR_CABLE_2, (byte)0x00, controlI2C); //disabled
+ }
+ }
+ else
+ {
+ byte air_cable_in = (frequency > 345_000_000) ? (byte)0x00 : (byte)0x60;
+ writeRegister(Register.INPUT_SELECTOR_AIR_AND_CABLE_1, air_cable_in, controlI2C);
+ }
+
+ getAdapter().disableI2CRepeater();
+ }
+ catch(UsbException e)
+ {
+ throw new SourceException("R820TTunerController - exception while setting frequency [" + frequency + "] - " +
+ e.getLocalizedMessage());
+ }
+ finally
+ {
+ getAdapter().getLock().unlock();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r828d/R828DTunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r828d/R828DTunerConfiguration.java
new file mode 100644
index 000000000..90710959f
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/source/tuner/rtl/r8x/r828d/R828DTunerConfiguration.java
@@ -0,0 +1,52 @@
+/*
+ * *****************************************************************************
+ * Copyright (C) 2014-2023 Dennis Sheirer
+ *
+ * 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
+ * ****************************************************************************
+ */
+package io.github.dsheirer.source.tuner.rtl.r8x.r828d;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.github.dsheirer.source.tuner.TunerType;
+import io.github.dsheirer.source.tuner.rtl.r8x.R8xTunerConfiguration;
+
+/**
+ * RTL-2832 with embedded R828D tuner configuration
+ */
+public class R828DTunerConfiguration extends R8xTunerConfiguration
+{
+ /**
+ * Empty constructor for Jackson serialization
+ */
+ public R828DTunerConfiguration()
+ {
+ }
+
+ /**
+ * Constructs an instance
+ * @param uniqueId for the tuner
+ */
+ public R828DTunerConfiguration(String uniqueId)
+ {
+ super(uniqueId);
+ }
+
+ @JsonIgnore
+ @Override
+ public TunerType getTunerType()
+ {
+ return TunerType.RAFAELMICRO_R828D;
+ }
+}