diff --git a/config/logback.xml b/config/logback.xml
index 1a627792..f52b54fe 100644
--- a/config/logback.xml
+++ b/config/logback.xml
@@ -12,9 +12,19 @@
%-25(%d{ddMMyyyy HHmmss} [%thread]) %-5level %logger{30} - %msg%n
-
+
-
+
+
+
+ %-16(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{30} - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/decode/am/AMDecoder.java b/src/decode/am/AMDecoder.java
index 6cf33587..113e6d34 100644
--- a/src/decode/am/AMDecoder.java
+++ b/src/decode/am/AMDecoder.java
@@ -6,6 +6,9 @@ import decode.Decoder;
import decode.DecoderType;
import dsp.am.AMDemodulator;
import dsp.filter.DCRemovalFilter2;
+import dsp.filter.FilterFactory;
+import dsp.filter.FloatFIRFilter;
+import dsp.filter.Window.WindowType;
public class AMDecoder extends Decoder
{
@@ -13,10 +16,11 @@ public class AMDecoder extends Decoder
* This value determines how quickly the DC remove filter responds to
* changes in frequency.
*/
- private static final double DC_REMOVAL_RATIO = 0.000003;
+ private static final double DC_REMOVAL_RATIO = 0.003;
private AMDemodulator mDemodulator;
private DCRemovalFilter2 mDCRemovalFilter;
+ private FloatFIRFilter mLowPassFilter;
public AMDecoder( SampleType sampleType )
{
@@ -50,7 +54,14 @@ public class AMDecoder extends Decoder
* Route the demodulated, filtered samples back to this class to send
* to all registered listeners
*/
- mDCRemovalFilter.setListener( this.getFloatReceiver() );
+
+ mLowPassFilter = new FloatFIRFilter(
+ FilterFactory.getLowPass( 48000, 3000, 31,
+ WindowType.COSINE ), 100.0 );
+
+ mDCRemovalFilter.setListener( mLowPassFilter );
+
+ mLowPassFilter.setListener( this.getFloatReceiver() );
}
}
diff --git a/src/dsp/am/AMDemodulator.java b/src/dsp/am/AMDemodulator.java
index f70fd318..4dd03175 100644
--- a/src/dsp/am/AMDemodulator.java
+++ b/src/dsp/am/AMDemodulator.java
@@ -14,7 +14,7 @@ public class AMDemodulator implements Listener
public AMDemodulator()
{
- this( FilterFactory.getLowPass( 48000, 2000, 73, WindowType.HAMMING ),
+ this( FilterFactory.getLowPass( 48000, 3000, 73, WindowType.HAMMING ),
1000.0 );
}
@@ -53,8 +53,8 @@ public class AMDemodulator implements Listener
public void receive( ComplexSample sample )
{
float demodulated = (float)Math.abs(
- Math.sqrt( ( sample.real() * sample.real() ) +
- ( sample.imaginery() * sample.imaginery() ) ) );
+ Math.sqrt( ( sample.real() * sample.real() ) +
+ ( sample.imaginery() * sample.imaginery() ) ) );
mBroadcaster.broadcast( demodulated * 30.0f );
}
diff --git a/src/gui/control/JFrequencyControl.java b/src/gui/control/JFrequencyControl.java
index 50a6fc59..b70ef0d9 100644
--- a/src/gui/control/JFrequencyControl.java
+++ b/src/gui/control/JFrequencyControl.java
@@ -138,7 +138,7 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
{
if( event.getAttribute() == Attribute.FREQUENCY )
{
- setFrequency( (int)event.getValue(), false );
+ setFrequency( (long)event.getValue(), false );
}
}
@@ -202,7 +202,7 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
{
private static final long serialVersionUID = 1L;
private int mPower = 0;
- private int mValue = 0;
+ private long mValue = 0;
private Digit( int position ) throws ParseException
{
@@ -225,17 +225,17 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
public void setFrequency( long frequency, boolean fireChangeEvent )
{
//Strip the digits higher than this one
- long lower = frequency % (int)( Math.pow( 10, mPower + 1) );
+ long lower = frequency % (long)( Math.pow( 10, mPower + 1) );
//Set the value to int value of dividing by 10 to this power
- int value = (int)( lower / (int)( Math.pow( 10, mPower ) ) );
+ long value = (long)( lower / (long)( Math.pow( 10, mPower ) ) );
set( value, fireChangeEvent );
}
public long getFrequency()
{
- return mValue * (int)Math.pow( 10, mPower );
+ return mValue * (long)Math.pow( 10, mPower );
}
public void increment()
@@ -261,7 +261,7 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
/**
* Convenience wrapper to change amount and fire change event
*/
- private void set( int amount )
+ private void set( long amount )
{
set( amount, true );
}
@@ -269,7 +269,7 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
/**
* Changes the value and optionally fires change event to listeners
*/
- private void set( int amount, boolean fireChangeEvent )
+ private void set( long amount, boolean fireChangeEvent )
{
mValue = amount;
diff --git a/src/source/mixer/MixerManager.java b/src/source/mixer/MixerManager.java
index c4a48f41..4948bf03 100644
--- a/src/source/mixer/MixerManager.java
+++ b/src/source/mixer/MixerManager.java
@@ -197,6 +197,11 @@ public class MixerManager
mLog.info( sb.toString() );
}
+ public HashMap getMixerTuners()
+ {
+ return mMixerTuners;
+ }
+
private TargetDataLine getTargetDataLine( Mixer.Info mixerInfo, AudioFormat format )
{
TargetDataLine retVal = null;
diff --git a/src/source/mixer/SampleAdapter.java b/src/source/mixer/SampleAdapter.java
index 1d73a0a1..d4ae6567 100644
--- a/src/source/mixer/SampleAdapter.java
+++ b/src/source/mixer/SampleAdapter.java
@@ -17,7 +17,6 @@
******************************************************************************/
package source.mixer;
-import source.Source.SampleType;
/*
* Adapter to convert byte data received from a data stream into float[]
diff --git a/src/source/tuner/FrequencyController.java b/src/source/tuner/FrequencyController.java
index cfcb0150..ccd1d2e7 100644
--- a/src/source/tuner/FrequencyController.java
+++ b/src/source/tuner/FrequencyController.java
@@ -38,7 +38,7 @@ public class FrequencyController
public FrequencyController( Tunable tunable,
long minFrequency,
long maxFrequency,
- double frequencyCorrection ) throws SourceException
+ double frequencyCorrection )
{
mTunable = tunable;
mMinimumFrequency = minFrequency;
@@ -148,7 +148,7 @@ public class FrequencyController
*/
private long getCorrectedFrequency( long tunedFrequency )
{
- return (int)( (double)tunedFrequency /
+ return (long)( (double)tunedFrequency /
( 1.0 - ( mFrequencyCorrection / 1000000.0 ) ) );
}
diff --git a/src/source/tuner/MixerTuner.java b/src/source/tuner/MixerTuner.java
index 00abe681..57d698fc 100644
--- a/src/source/tuner/MixerTuner.java
+++ b/src/source/tuner/MixerTuner.java
@@ -21,6 +21,9 @@ import java.util.ArrayList;
import javax.sound.sampled.TargetDataLine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import sample.Listener;
import sample.complex.ComplexSampleListListener;
import source.mixer.MixerSource;
@@ -28,6 +31,9 @@ import source.mixer.SampleAdapter;
public abstract class MixerTuner extends Tuner
{
+ private final static Logger mLog =
+ LoggerFactory.getLogger( MixerTuner.class );
+
private TargetDataLine mTargetDataLine;
protected MixerTunerType mMixerTunerType;
protected MixerSource mMixerSource;
diff --git a/src/source/tuner/Tuner.java b/src/source/tuner/Tuner.java
index 46392840..b8eb056e 100644
--- a/src/source/tuner/Tuner.java
+++ b/src/source/tuner/Tuner.java
@@ -48,6 +48,13 @@ public abstract class Tuner implements FrequencyChangeBroadcaster,
mName = name;
}
+ public String toString()
+ {
+ return mName;
+ }
+
+ public abstract void dispose();
+
public void setName( String name )
{
mName = name;
diff --git a/src/source/tuner/TunerController.java b/src/source/tuner/TunerController.java
index 71b51287..27621896 100644
--- a/src/source/tuner/TunerController.java
+++ b/src/source/tuner/TunerController.java
@@ -51,7 +51,6 @@ public abstract class TunerController implements Tunable
* class, tuning a frequency, or setting the bandwidth
*/
public TunerController( long minimumFrequency, long maximumFrequency )
- throws SourceException
{
mFrequencyController = new FrequencyController( this,
minimumFrequency,
diff --git a/src/source/tuner/TunerManager.java b/src/source/tuner/TunerManager.java
index 0693e72b..01e0f7e3 100644
--- a/src/source/tuner/TunerManager.java
+++ b/src/source/tuner/TunerManager.java
@@ -23,20 +23,17 @@ import java.util.Iterator;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
-import javax.usb.UsbDevice;
-import javax.usb.UsbException;
-import javax.usb.UsbHostManager;
-import javax.usb.UsbHub;
-import javax.usb.UsbServices;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
+import org.usb4java.DeviceList;
+import org.usb4java.LibUsb;
import source.Source;
import source.SourceException;
import source.config.SourceConfigTuner;
import source.mixer.MixerManager;
-import source.tuner.ettus.B100Tuner;
import source.tuner.fcd.FCDTuner;
import source.tuner.fcd.proV1.FCD1TunerController;
import source.tuner.fcd.proplusV2.FCD2TunerController;
@@ -46,27 +43,34 @@ import source.tuner.rtl.RTL2832Tuner;
import source.tuner.rtl.RTL2832TunerController;
import source.tuner.rtl.e4k.E4KTunerController;
import source.tuner.rtl.r820t.R820TTunerController;
-import source.tuner.usb.USBTunerDevice;
import controller.ResourceManager;
import controller.channel.ProcessingChain;
public class TunerManager
{
private final static Logger mLog =
- LoggerFactory.getLogger( TunerManager.class );
-
- private static final String sLOADED = "\t[LOADED]\t";
- private static final String sNOT_LOADED = "\t[NOT LOADED]\t";
+ LoggerFactory.getLogger( TunerManager.class );
private ResourceManager mResourceManager;
-
private ArrayList mTuners = new ArrayList();
-
+
public TunerManager( ResourceManager resourceManager )
{
mResourceManager = resourceManager;
- loadTuners();
+
+ /* initialize mixers */
+ MixerManager.getInstance();
+
+ initTuners();
}
+
+ /**
+ * Performs cleanup of USB related issues
+ */
+ public void dispose()
+ {
+ LibUsb.exit( null );
+ }
/**
* Iterates current tuners to get a tuner channel source for the frequency
@@ -121,127 +125,103 @@ public class TunerManager
/**
* Loads all USB tuners and USB/Mixer tuner devices
*/
- private void loadTuners()
+ private void initTuners()
{
- mTuners.clear();
+ DeviceList deviceList = new DeviceList();
- //Get list of attached USB tuner devices
- ArrayList devices = getUSBTunerDevices();
+ int result = LibUsb.init( null );
- StringBuilder sb = new StringBuilder();
-
- sb.append( "discovered and using [" + devices.size() +
- "] available tuner devices\n" );
-
- mLog.info( "inspecting [" + devices.size() + "] available usb tuner devices" );
-
- int counter = 0;
-
- for( USBTunerDevice device: devices )
+ if( result != LibUsb.SUCCESS )
{
- counter++;
+ mLog.error( "unable to initialize libusb [" +
+ LibUsb.errorName( result ) + "]" );
+ }
+ else
+ {
+ mLog.info( "LibUSB API Version: " + LibUsb.getApiVersion() );
+ mLog.info( "LibUSB Version: " + LibUsb.getVersion() );
- mLog.info( "inspecting usb device [" + counter + "] tuner class: "
- + device.getTunerClass().toString() );
+ result = LibUsb.getDeviceList( null, deviceList );
- String status = sNOT_LOADED;
- String name = "Unknown";
- String reason = "No device driver class available";
+ if( result < 0 )
+ {
+ mLog.error( "unable to get device list from libusb [" + result + " / " +
+ LibUsb.errorName( result ) + "]" );
+ }
+ else
+ {
+ mLog.info( "discovered [" + result + "] attached USB devices" );
+ }
+ }
+
+ for( Device device: deviceList )
+ {
+ DeviceDescriptor descriptor = new DeviceDescriptor();
- TunerClass tunerClass = device.getTunerClass();
+ result = LibUsb.getDeviceDescriptor( device, descriptor );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "unable to read device descriptor [" +
+ LibUsb.errorName( result ) + "]" );
+ }
+ else
+ {
+ TunerInitStatus status = initTuner( device, descriptor );
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "usb device [" );
+ sb.append( String.format( "%04X", descriptor.idVendor() ) );
+ sb.append( ":" );
+ sb.append( String.format( "%04X", descriptor.idProduct() ) );
+
+ if( status.isLoaded() )
+ {
+ Tuner tuner = status.getTuner();
+ sb.append( "] LOADED: " );
+ sb.append( tuner.toString() );
+ mTuners.add( tuner );
+ }
+ else
+ {
+ sb.append( "] NOT LOADED: " );
+ sb.append( status.getInfo() );
+ }
+
+ mLog.info( sb.toString() );
+ }
+ }
+
+ LibUsb.freeDeviceList( deviceList, true );
+ }
+
+ private TunerInitStatus initTuner( Device device,
+ DeviceDescriptor descriptor )
+ {
+ if( device != null && descriptor != null )
+ {
+ TunerClass tunerClass = TunerClass.valueOf( descriptor.idVendor(),
+ descriptor.idProduct() );
switch( tunerClass )
{
+ case ETTUS_USRP_B100:
+ return initEttusB100Tuner( device, descriptor );
case FUNCUBE_DONGLE_PRO:
- //Locate the matching mixer tuner dataline
- MixerTunerDataLine fcd1Dataline =
- getMixerTunerDataLine( tunerClass.getTunerType() );
- if( fcd1Dataline != null )
- {
- FCD1TunerController fcd1Controller;
-
- try
- {
- fcd1Controller = new FCD1TunerController( device );
-
- FCDTuner fcd1Tuner =
- new FCDTuner( fcd1Dataline, fcd1Controller );
-
- TunerConfiguration config =
- getTunerConfiguration( fcd1Tuner );
-
- if( config != null )
- {
- fcd1Tuner.apply( config );
- }
-
- mTuners.add( fcd1Tuner );
-
- name = fcd1Tuner.getName();
- status = sLOADED;
- reason = null;
- }
- catch ( SourceException e )
- {
- reason = "Controller Source Exception: " +
- e.getLocalizedMessage();
- }
-
- }
- else
- {
- reason = "Couldn't locate matching mixer/sound card device";
- }
- break;
+ return initFuncubeProTuner( device, descriptor );
case FUNCUBE_DONGLE_PRO_PLUS:
- //Locate the matching mixer tuner dataline
- MixerTunerDataLine fcd2Dataline =
- getMixerTunerDataLine( tunerClass.getTunerType() );
-
- if( fcd2Dataline != null )
- {
- FCD2TunerController fcd2Controller;
-
- try
- {
- fcd2Controller = new FCD2TunerController( device );
-
- FCDTuner fcd2Tuner =
- new FCDTuner( fcd2Dataline, fcd2Controller );
-
- TunerConfiguration config =
- getTunerConfiguration( fcd2Tuner );
-
- if( config != null )
- {
- fcd2Tuner.apply( config );
- }
-
- mTuners.add( fcd2Tuner );
-
- status = sLOADED;
- name = fcd2Tuner.getName();
- reason = null;
- }
- catch ( SourceException e )
- {
- reason = "Controller Source Exception: " +
- e.getLocalizedMessage();
- }
- }
- else
- {
- reason = "Couldn't locate matching mixer/sound card device";
- }
- break;
- case GENERIC_2832:
+ return initFuncubeProPlusTuner( device, descriptor );
+ case HACKRF_ONE:
+ return initHackRFTuner( device, descriptor );
case COMPRO_VIDEOMATE_U620F:
case COMPRO_VIDEOMATE_U650F:
case COMPRO_VIDEOMATE_U680F:
+ case GENERIC_2832:
+ case GENERIC_2838:
case DEXATEK_5217_DVBT:
case DEXATEK_DIGIVOX_MINI_II_REV3:
case DEXATEK_LOGILINK_VG002A:
- case GENERIC_2838:
case GIGABYTE_GTU7300:
case GTEK_T803:
case LIFEVIEW_LV5T_DELUXE:
@@ -259,254 +239,333 @@ public class TunerManager
case TERRATEC_T_STICK_PLUS:
case TWINTECH_UT40:
case ZAAPA_ZTMINDVBZP:
- TunerType tunerType = tunerClass.getTunerType();
-
- if( tunerType == TunerType.RTL2832_VARIOUS )
- {
- tunerType = RTL2832TunerController.identifyTunerType( device );
- }
-
- mLog.debug( "identified tuner class [" +
- tunerClass.toString() + "] with tuner type [" +
- tunerType.toString() + "]" );
-
- switch( tunerType )
- {
- case ELONICS_E4000:
- try
- {
- E4KTunerController controller =
- new E4KTunerController( device );
-
- controller.init();
-
- RTL2832Tuner rtlTuner =
- new RTL2832Tuner( tunerClass, controller );
-
- TunerConfiguration config =
- getTunerConfiguration( rtlTuner );
-
- if( config != null )
- {
- rtlTuner.apply( config );
- }
-
- mTuners.add( rtlTuner );
- status = sLOADED;
- name = rtlTuner.getName();
- reason = null;
- }
- catch( SourceException se )
- {
- status = sNOT_LOADED;
- reason = "Error constructing E4K tuner "
- + "controller - " + se.getLocalizedMessage();
- }
- break;
- case RAFAELMICRO_R820T:
- mLog.debug( "attempting to construct R820T "
- + "tuner controller" );
- try
- {
- R820TTunerController controller =
- new R820TTunerController( device );
-
- mLog.debug( "initializing R820T tuner controller" );
- controller.init();
-
- RTL2832Tuner rtlTuner =
- new RTL2832Tuner( tunerClass, controller );
-
-
- TunerConfiguration config =
- getTunerConfiguration( rtlTuner );
-
- if( config != null )
- {
- mLog.debug( "applying tuner config to R820T tuner" );
- rtlTuner.apply( config );
- }
- else
- {
- mLog.debug( "R820T tuner config was "
- + "null - not applied" );
- }
-
- mTuners.add( rtlTuner );
- status = sLOADED;
- name = rtlTuner.getName();
- reason = null;
- }
- catch( SourceException se )
- {
- status = sNOT_LOADED;
- reason = "Error constructing R820T tuner "
- + "controller - " + se.getLocalizedMessage();
-
- mLog.error( "error constructing tuner", se );
- }
- break;
- case FITIPOWER_FC0012:
- case FITIPOWER_FC0013:
- case RAFAELMICRO_R828D:
- case UNKNOWN:
- default:
- status = sNOT_LOADED;
- reason = "SDRTRunk doesn't currently support RTL2832 "
- + "Dongle with [" + tunerType.toString() +
- "] tuner for tuner class[" + tunerClass.toString() + "]";
- break;
- }
- break;
- case ETTUS_USRP_B100:
- mTuners.add( new B100Tuner( device ) );
- status = sLOADED;
- reason = null;
- break;
- case HACKRF_ONE:
-// try
-// {
-// HackRFTunerController hackRFController =
-// new HackRFTunerController( device );
-//
-// hackRFController.init();
-//
-// HackRFTuner hackRFTuner =
-// new HackRFTuner( hackRFController );
-//
-// mTuners.add( hackRFTuner );
-// name = hackRFTuner.getName();
-// status = sLOADED;
-// reason = null;
-// }
-// catch( SourceException se )
-// {
-// status = sNOT_LOADED;
-// reason = "Error constructing HackRF tuner "
-// + "controller - " + se.getLocalizedMessage();
-// }
- break;
+ return initRTL2832Tuner( tunerClass, device, descriptor );
case UNKNOWN:
default:
break;
}
-
- /**
- * Log the tuner loading status
- */
- sb.append( status );
- sb.append( String.format( "%04X",
- device.getDevice().getUsbDeviceDescriptor().idVendor() ) );
- sb.append( ":" );
- sb.append( String.format( "%04X",
- device.getDevice().getUsbDeviceDescriptor().idProduct() ) );
- sb.append( " " );
-
- sb.append( name );
-
- if( reason != null )
- {
- sb.append( " - " );
- sb.append( reason );
- }
-
- sb.append( "\n" );
}
- mLog.info( "Configuring USB Tuners" );
- mLog.info( sb.toString() );
+ return new TunerInitStatus( null, "Unknown Device" );
}
- /**
- * Get all USB tuner devices
- */
- private ArrayList getUSBTunerDevices()
+ private TunerInitStatus initEttusB100Tuner( Device device,
+ DeviceDescriptor descriptor )
{
- StringBuilder sb = new StringBuilder();
+ return new TunerInitStatus( null, "Ettus B100 tuner not currently "
+ + "supported" );
+// case ETTUS_USRP_B100:
+// mTuners.add( new B100Tuner( device ) );
+// status = sLOADED;
+// reason = null;
+// break;
+ }
+
+ private TunerInitStatus initFuncubeProTuner( Device device,
+ DeviceDescriptor descriptor )
+ {
+ String reason = "NOT LOADED";
- List devices = getUSBDevices();
+ MixerTunerDataLine dataline = getMixerTunerDataLine(
+ TunerClass.FUNCUBE_DONGLE_PRO.getTunerType() );
+
+ if( dataline != null )
+ {
+ FCD1TunerController controller =
+ new FCD1TunerController( device, descriptor );
- sb.append( "discovered [" + devices.size() +
- "] attached USB devices\n" );
-
- ArrayList tuners = new ArrayList();
-
- for (UsbDevice device : devices )
- {
- String status = "\t[NOT RECOGNIZED]\t";
-
- TunerClass type = TunerClass.valueOf( device.getUsbDeviceDescriptor() );
-
- if( type != TunerClass.UNKNOWN )
+ try
{
- status = "\t[RECOGNIZED] \t";
- tuners.add( new USBTunerDevice( device, type) );
+ controller.init();
+
+ FCDTuner tuner =
+ new FCDTuner( dataline, controller );
+
+ TunerConfiguration config = getTunerConfiguration( tuner );
+
+ if( config != null )
+ {
+ tuner.apply( config );
+ }
+
+ return new TunerInitStatus( tuner, "LOADED" );
}
-
- sb.append( status );
- sb.append( device.toString() );
-
- if( type != TunerClass.UNKNOWN )
+ catch ( SourceException e )
{
- sb.append( " " );
- sb.append( type.getVendorDescription() );
- sb.append( " " );
- sb.append( type.getDeviceDescription() );
+ mLog.error( "couldn't load funcube dongle pro tuner", e );
+
+ reason = "error during initialization - " + e.getLocalizedMessage();
}
+ }
+ else
+ {
+ reason = "couldn't find matching mixer dataline";
+ }
- sb.append( "\n" );
- }
-
- mLog.info( "USB Device Discovery" );
- mLog.info( sb.toString() );
-
- return tuners;
+ return new TunerInitStatus( null, "Funcube Dongle Pro tuner not "
+ + "loaded - " + reason );
}
- /**
- * Gets all USB devices from the root hub downward, recursively, or
- * returns empty list if none are discovered
- */
- public static List getUSBDevices()
- {
- ArrayList devices = new ArrayList();
-
- try
- {
- UsbServices services = UsbHostManager.getUsbServices();
- devices = getUsbChildDevices( services.getRootUsbHub() );
- }
- catch( SecurityException e )
- {
- mLog.error( "security exception while getting USB devices", e );
- }
- catch( UsbException e )
- {
- mLog.error( "usb exception while getting USB devices", e );
- }
+ private TunerInitStatus initFuncubeProPlusTuner( Device device,
+ DeviceDescriptor descriptor )
+ {
+ String reason = "NOT LOADED";
+
+ MixerTunerDataLine dataline = getMixerTunerDataLine(
+ TunerClass.FUNCUBE_DONGLE_PRO_PLUS.getTunerType() );
+
+ if( dataline != null )
+ {
+ FCD2TunerController controller =
+ new FCD2TunerController( device, descriptor );
- return devices;
- }
-
- /**
- * Get (recursively) all usb child devices below the usb hub
- */
- public static ArrayList getUsbChildDevices( UsbHub hub )
- {
- ArrayList devices = new ArrayList();
-
- for ( UsbDevice device : (List) hub.getAttachedUsbDevices() )
- {
- devices.add( device );
-
- if ( device.isUsbHub() )
+ try
{
- devices.addAll( getUsbChildDevices( (UsbHub)device ) );
+ controller.init();
+
+ FCDTuner tuner =
+ new FCDTuner( dataline, controller );
+
+ TunerConfiguration config = getTunerConfiguration( tuner );
+
+ if( config != null )
+ {
+ tuner.apply( config );
+ }
+
+ return new TunerInitStatus( tuner, "LOADED" );
}
- }
-
- return devices;
- }
+ catch ( SourceException e )
+ {
+ mLog.error( "couldn't load funcube dongle pro plus tuner", e );
+
+ reason = "error during initialization - " +
+ e.getLocalizedMessage();
+ }
+ }
+ else
+ {
+ reason = "couldn't find matching mixer dataline";
+ }
+
+ return new TunerInitStatus( null, "Funcube Dongle Pro tuner not "
+ + "loaded - " + reason );
+ }
+
+ private TunerInitStatus initHackRFTuner( Device device,
+ DeviceDescriptor descriptor )
+ {
+ try
+ {
+ HackRFTunerController hackRFController =
+ new HackRFTunerController( device, descriptor );
+
+ hackRFController.init();
+
+ HackRFTuner tuner = new HackRFTuner( hackRFController );
+
+ return new TunerInitStatus( tuner, "LOADED" );
+ }
+ catch( SourceException se )
+ {
+ mLog.error( "couldn't construct HackRF controller/tuner", se );
+
+ return new TunerInitStatus( null,
+ "error constructing HackRF tuner controller" );
+ }
+ }
+
+ private TunerInitStatus initRTL2832Tuner( TunerClass tunerClass,
+ Device device,
+ DeviceDescriptor deviceDescriptor )
+ {
+ String reason = "NOT LOADED";
+
+ TunerType tunerType = tunerClass.getTunerType();
+
+ if( tunerType == TunerType.RTL2832_VARIOUS )
+ {
+ try
+ {
+ tunerType = RTL2832TunerController.identifyTunerType( device );
+ }
+ catch( SourceException e )
+ {
+ mLog.error( "couldn't determine RTL2832 tuner type", e );
+ tunerType = TunerType.UNKNOWN;
+ }
+ }
+
+ switch( tunerType )
+ {
+ case ELONICS_E4000:
+ try
+ {
+ E4KTunerController controller =
+ new E4KTunerController( device, deviceDescriptor );
+
+ controller.init();
+
+ RTL2832Tuner rtlTuner =
+ new RTL2832Tuner( tunerClass, controller );
+
+ TunerConfiguration config =
+ getTunerConfiguration( rtlTuner );
+
+ if( config != null )
+ {
+ rtlTuner.apply( config );
+ }
+
+ return new TunerInitStatus( rtlTuner, "LOADED" );
+ }
+ catch( SourceException se )
+ {
+ return new TunerInitStatus( null, "Error constructing E4K tuner "
+ + "controller - " + se.getLocalizedMessage() );
+ }
+ case RAFAELMICRO_R820T:
+ mLog.debug( "attempting to construct R820T "
+ + "tuner controller" );
+ try
+ {
+ R820TTunerController controller =
+ new R820TTunerController( device, deviceDescriptor );
+
+ mLog.debug( "initializing R820T tuner controller" );
+ controller.init();
+
+ RTL2832Tuner rtlTuner =
+ new RTL2832Tuner( tunerClass, controller );
+
+ TunerConfiguration config =
+ getTunerConfiguration( rtlTuner );
+
+ if( config != null )
+ {
+ mLog.debug( "applying tuner config to R820T tuner" );
+ rtlTuner.apply( config );
+ }
+ else
+ {
+ mLog.debug( "R820T tuner config was "
+ + "null - not applied" );
+ }
+
+ return new TunerInitStatus( rtlTuner, "LOADED" );
+ }
+ catch( SourceException se )
+ {
+ mLog.error( "error constructing tuner", se );
+
+ return new TunerInitStatus( null, "Error constructing R820T "
+ + "tuner controller - " + se.getLocalizedMessage() );
+ }
+ case FITIPOWER_FC0012:
+ case FITIPOWER_FC0013:
+ case RAFAELMICRO_R828D:
+ case UNKNOWN:
+ default:
+ reason = "SDRTRunk doesn't currently support RTL2832 "
+ + "Dongle with [" + tunerType.toString() +
+ "] tuner for tuner class[" + tunerClass.toString() + "]";
+ break;
+ }
+
+ return new TunerInitStatus( null, reason );
+ }
+
+
+// /**
+// * Get all USB tuner devices
+// */
+// private ArrayList getUSBTunerDevices()
+// {
+// StringBuilder sb = new StringBuilder();
+//
+// List devices = getUSBDevices();
+//
+// sb.append( "discovered [" + devices.size() +
+// "] attached USB devices\n" );
+//
+// ArrayList tuners = new ArrayList();
+//
+// for (UsbDevice device : devices )
+// {
+// String status = "\t[NOT RECOGNIZED]\t";
+//
+// TunerClass type = TunerClass.valueOf( device.getUsbDeviceDescriptor() );
+//
+// if( type != TunerClass.UNKNOWN )
+// {
+// status = "\t[RECOGNIZED] \t";
+// tuners.add( new USBTunerDevice( device, type) );
+// }
+//
+// sb.append( status );
+// sb.append( device.toString() );
+//
+// if( type != TunerClass.UNKNOWN )
+// {
+// sb.append( " " );
+// sb.append( type.getVendorDescription() );
+// sb.append( " " );
+// sb.append( type.getDeviceDescription() );
+// }
+//
+// sb.append( "\n" );
+// }
+//
+// mLog.info( "USB Device Discovery" );
+// mLog.info( sb.toString() );
+//
+// return tuners;
+// }
+//
+// /**
+// * Gets all USB devices from the root hub downward, recursively, or
+// * returns empty list if none are discovered
+// */
+// public static List getUSBDevices()
+// {
+// ArrayList devices = new ArrayList();
+//
+// try
+// {
+// UsbServices services = UsbHostManager.getUsbServices();
+// devices = getUsbChildDevices( services.getRootUsbHub() );
+// }
+// catch( SecurityException e )
+// {
+// mLog.error( "security exception while getting USB devices", e );
+// }
+// catch( UsbException e )
+// {
+// mLog.error( "usb exception while getting USB devices", e );
+// }
+//
+// return devices;
+// }
+//
+// /**
+// * Get (recursively) all usb child devices below the usb hub
+// */
+// public static ArrayList getUsbChildDevices( UsbHub hub )
+// {
+// ArrayList devices = new ArrayList();
+//
+// for ( UsbDevice device : (List) hub.getAttachedUsbDevices() )
+// {
+// devices.add( device );
+//
+// if ( device.isUsbHub() )
+// {
+// devices.addAll( getUsbChildDevices( (UsbHub)device ) );
+// }
+// }
+//
+// return devices;
+// }
/**
* Get a stored tuner configuration or create a default tuner configuration
@@ -585,4 +644,31 @@ public class TunerManager
return null;
}
+
+ public class TunerInitStatus
+ {
+ private Tuner mTuner;
+ private String mInfo;
+
+ public TunerInitStatus( Tuner tuner, String info )
+ {
+ mTuner = tuner;
+ mInfo = info;
+ }
+
+ public Tuner getTuner()
+ {
+ return mTuner;
+ }
+
+ public String getInfo()
+ {
+ return mInfo;
+ }
+
+ public boolean isLoaded()
+ {
+ return mTuner != null;
+ }
+ }
}
diff --git a/src/source/tuner/ettus/B100Tuner.java b/src/source/tuner/ettus/B100Tuner.java
index 9ea8476e..d80190bb 100644
--- a/src/source/tuner/ettus/B100Tuner.java
+++ b/src/source/tuner/ettus/B100Tuner.java
@@ -51,6 +51,11 @@ public class B100Tuner extends Tuner
mDevice = device;
}
+ public void dispose()
+ {
+
+ }
+
@Override
public TunerClass getTunerClass()
{
diff --git a/src/source/tuner/fcd/FCDTuner.java b/src/source/tuner/fcd/FCDTuner.java
index 410ccfde..941ea4c7 100644
--- a/src/source/tuner/fcd/FCDTuner.java
+++ b/src/source/tuner/fcd/FCDTuner.java
@@ -50,6 +50,13 @@ public class FCDTuner extends MixerTuner
mController.addListener( (FrequencyChangeListener)this );
}
+ public void dispose()
+ {
+ //TODO: release the mixer tuner data line as well
+
+ mController.dispose();
+ }
+
public FCDTunerController getController()
{
return mController;
@@ -70,7 +77,7 @@ public class FCDTuner extends MixerTuner
@Override
public String getUniqueID()
{
- return mController.getAddress();
+ return mController.getUSBAddress();
}
@Override
diff --git a/src/source/tuner/fcd/FCDTunerController.java b/src/source/tuner/fcd/FCDTunerController.java
index cd1f9ca1..fbd4f1d6 100644
--- a/src/source/tuner/fcd/FCDTunerController.java
+++ b/src/source/tuner/fcd/FCDTunerController.java
@@ -17,18 +17,21 @@
******************************************************************************/
package source.tuner.fcd;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+
import javax.swing.JPanel;
import javax.usb.UsbClaimException;
-import javax.usb.UsbConfiguration;
-import javax.usb.UsbDevice;
-import javax.usb.UsbEndpoint;
import javax.usb.UsbException;
-import javax.usb.UsbInterface;
-import javax.usb.UsbInterfacePolicy;
-import javax.usb.UsbPipe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
+import org.usb4java.DeviceHandle;
+import org.usb4java.LibUsb;
+import org.usb4java.LibUsbException;
import source.SourceException;
import source.tuner.TunerClass;
@@ -36,7 +39,6 @@ import source.tuner.TunerConfiguration;
import source.tuner.TunerController;
import source.tuner.TunerType;
import source.tuner.fcd.proV1.FCD1TunerController.Block;
-import source.tuner.usb.USBTunerDevice;
import controller.ResourceManager;
public abstract class FCDTunerController extends TunerController
@@ -44,57 +46,105 @@ public abstract class FCDTunerController extends TunerController
private final static Logger mLog =
LoggerFactory.getLogger( FCDTunerController.class );
- public final static int sINT_NULL_VALUE = -1;
- public final static long sLONG_NULL_VALUE = -1l;
- public final static double sDOUBLE_NULL_VALUE = -1.0D;
+ public final static byte FCD_INTERFACE = (byte)0x2;
+ public final static byte FCD_ENDPOINT_IN = (byte)0x82;
+ public final static byte FCD_ENDPOINT_OUT = (byte)0x2;
- public final static byte sFCD_INTERFACE = (byte)0x2;
- public final static byte sFCD_ENDPOINT_IN = (byte)0x82;
- public final static byte sFCD_ENDPOINT_OUT = (byte)0x2;
+ private Device mDevice;
+ private DeviceDescriptor mDeviceDescriptor;
+ private DeviceHandle mDeviceHandle;
- public final static boolean sFCD_FORCE_CLAIM_HID_INTERFACE = true;
-
- private UsbDevice mFuncube;
- private UsbConfiguration mUsbConfiguration;
- private UsbInterface mFuncubeHID;
- private UsbPipe mPipeIn;
- private UsbPipe mPipeOut;
private FCDConfiguration mConfiguration = new FCDConfiguration();
-
- public FCDTunerController( USBTunerDevice device,
+
+ /**
+ * Generic FCD tuner controller - contains functionality common across both
+ * funcube dongle tuners
+ *
+ * @param device
+ * @param descriptor
+ * @param minTunableFrequency
+ * @param maxTunableFrequency
+ */
+ public FCDTunerController( Device device,
+ DeviceDescriptor descriptor,
int minTunableFrequency,
- int maxTunableFrequency ) throws SourceException
+ int maxTunableFrequency )
{
super( minTunableFrequency, maxTunableFrequency );
- mFuncube = device.getDevice();
- mUsbConfiguration = mFuncube.getActiveUsbConfiguration();
- mFuncubeHID = mUsbConfiguration.getUsbInterface( sFCD_INTERFACE );
+ mDevice = device;
+ mDeviceDescriptor = descriptor;
}
-
+
+ /**
+ * Initializes the controller by opening the USB device and claiming the
+ * HID interface.
+ *
+ * Invoke this method after constructing this class to setup the
+ * controller.
+ *
+ * @throws SourceException if cannot open and claim the USB device
+ */
+ public void init() throws SourceException
+ {
+ mDeviceHandle = new DeviceHandle();
+
+ int result = LibUsb.open( mDevice, mDeviceHandle );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mDeviceHandle = null;
+
+ throw new SourceException( "libusb couldn't open funcube usb "
+ + "device [" + LibUsb.errorName( result ) + "]" );
+ }
+
+ claimInterface();
+ }
+
+ /**
+ * Disposes of resources. Closes the USB device and interface.
+ */
+ public void dispose()
+ {
+ if( mDeviceHandle != null )
+ {
+ try
+ {
+ LibUsb.close( mDeviceHandle );
+ }
+ catch( Exception e )
+ {
+ mLog.error( "error while closing device handle", e );
+ }
+
+ mDeviceHandle = null;
+ }
+
+ mDeviceDescriptor = null;
+ mDevice = null;
+ }
+
+ /**
+ * Sample rate of the tuner
+ */
public abstract int getCurrentSampleRate() throws SourceException;
/**
- * Returns the tuner class. Since this is a generic container for both
- * types of funcube, we let the controller self identify the class and type
- *
- * @return - tuner class
+ * Tuner class
*/
public abstract TunerClass getTunerClass();
/**
- * Returns the tuner type. Since this is a generic container for both
- * types of funcube, we let the controller self identify the class and type
- *
- * @return - tuner type
+ * Tuner type
*/
public abstract TunerType getTunerType();
/**
- * FCD editor panel
+ * Editor panel (GUI) component.
*/
public abstract JPanel getEditor( FCDTuner tuner,
- ResourceManager resourceManager );
+ ResourceManager resourceManager );
/**
* Applies the settings in the tuner configuration
@@ -103,17 +153,81 @@ public abstract class FCDTunerController extends TunerController
throws SourceException;
/**
- * Returns the applied tuner configuration or null if one hasn't yet been
- * applied
+ * Returns the currently applied tuner configuration or null if one hasn't
+ * yet been applied
*/
public abstract TunerConfiguration getTunerConfiguration();
/**
- * USB address
+ * USB address (bus/port)
*/
- public String getAddress()
+ public String getUSBAddress()
{
- return mFuncube.toString();
+ if( mDevice != null )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "Bus:" );
+ int bus = LibUsb.getBusNumber( mDevice );
+ sb.append( bus );
+
+ sb.append( " Port:" );
+ int port = LibUsb.getPortNumber( mDevice );
+ sb.append( port );
+
+ return sb.toString();
+ }
+
+ return "UNKNOWN";
+ }
+
+ /**
+ * USB Vendor and Product ID
+ */
+ public String getUSBID()
+ {
+ if( mDeviceDescriptor != null )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( String.format( "%04X",
+ (int)( mDeviceDescriptor.idVendor() & 0xFFFF ) ) );
+
+ sb.append( ":" );
+
+ sb.append( String.format( "%04X",
+ (int)( mDeviceDescriptor.idProduct() & 0xFFFF ) ) );
+
+ return sb.toString();
+ }
+
+ return "UNKNOWN";
+ }
+
+ /**
+ * USB Port Speed. Should be 2.0 for both types of funcube dongles
+ */
+ public String getUSBSpeed()
+ {
+ if( mDevice != null )
+ {
+ int speed = LibUsb.getDeviceSpeed( mDevice );
+
+ switch( speed )
+ {
+ case 0:
+ return "1.1 LOW";
+ case 1:
+ return "1.1 FULL";
+ case 2:
+ return "2.0 HIGH";
+ case 3:
+ return "3.0 SUPER";
+ default:
+ }
+ }
+
+ return "UNKNOWN";
}
/**
@@ -121,20 +235,17 @@ public abstract class FCDTunerController extends TunerController
*/
public void setFCDMode( Mode mode ) throws UsbException, UsbClaimException
{
- byte[] response = null;
+ ByteBuffer response = null;
switch( mode )
{
case APPLICATION:
- response = send( FCDCommand.BL_QUERY.getRequestTemplate(),
- FCDCommand.BL_QUERY.getResponseTemplate() );
+ response = send( FCDCommand.BL_QUERY );
break;
case BOOTLOADER:
- response = send( FCDCommand.APP_RESET.getRequestTemplate(),
- FCDCommand.APP_RESET.getResponseTemplate() );
+ response = send( FCDCommand.APP_RESET );
break;
- case ERROR:
- case UNKNOWN:
+ default:
break;
}
@@ -171,7 +282,11 @@ public abstract class FCDTunerController extends TunerController
{
try
{
- return send( FCDCommand.APP_GET_FREQUENCY_HZ );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_FREQUENCY_HZ );
+
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ return (int)( buffer.getInt( 2 ) & 0xFFFFFFFF );
}
catch( Exception e )
{
@@ -189,185 +304,206 @@ public abstract class FCDTunerController extends TunerController
}
/**
- * Claims the FCD USB HID interface. If another application currently has
- * the interface claimed, the sFCD_FORCE_CLAIM_HID_INTERFACE setting
- * will dictate if the interface is forcibly claimed from the other
- * application
+ * Claims the USB interface. Attempts to detach the active kernel driver if
+ * one is currently attached.
*/
- private boolean claim() throws UsbException, UsbClaimException
+ private void claimInterface() throws SourceException
{
- boolean claimed = false;
-
- if( !mFuncubeHID.isClaimed() )
+ if( mDeviceHandle != null )
{
- mFuncubeHID.claim( new UsbInterfacePolicy()
- {
- @Override
- public boolean forceClaim( UsbInterface arg0 )
- {
- return sFCD_FORCE_CLAIM_HID_INTERFACE;
- }
- } );
+ int result = LibUsb.kernelDriverActive( mDeviceHandle, FCD_INTERFACE );
- claimed = true;
- }
- else
- {
- mLog.info( "Attempted to claim the Funcube HID interface, but "
- + "it's in use by another program" );
- }
-
- return claimed;
- }
-
- /**
- * Releases the claimed USB (FCD) interface
- */
- private void release()
- {
- mPipeIn = null;
- mPipeOut = null;
-
- try
- {
- mFuncubeHID.release();
- }
- catch ( Exception e )
- {
- mLog.error( "Exception thrown while releasing the funcube HID "
- + "interface", e );
- }
- }
-
- /**
- * Convenience wrapper for commands that don't take arguments
- */
- public long send( FCDCommand command ) throws UsbException, UsbClaimException
- {
- return send( command, sLONG_NULL_VALUE );
- }
-
- /**
- * Sends the command, optionally placing the argument value parsed into
- * little endian bytes in the request array. Returns any integer value that
- * part of the response, or sINT_NULL_VALUE (-1) if it fails.
- *
- * Note: we use a long return value to avoid any issues with the MSB of a
- * 32-bit response value being misinterpreted as the integer sign bit.
- *
- * @param command
- * @param commandArgument - command argument. Use -1 for no-argument commands
- * @return - response long value, or -1 if fails
- * @throws UsbException
- * @throws UsbClaimException
- */
- public long send( FCDCommand command, long commandArgument ) throws UsbException,
- UsbClaimException
- {
- long retVal = sLONG_NULL_VALUE;
-
- byte[] request = command.getRequestTemplate();
-
- if( commandArgument != sLONG_NULL_VALUE )
- {
- //Parse the value argument into the request byte indices, according to command length
- for( int x = 1; x < command.getArrayLength(); x++ )
+ if( result == 1 )
{
- //Little endian
- request[ x ] = (byte)( 0xFF &
- Long.rotateRight( commandArgument, ( x - 1 ) * 8 ) );
+ result = LibUsb.detachKernelDriver( mDeviceHandle,
+ FCD_INTERFACE );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "failed attempt to detach kernel driver [" +
+ LibUsb.errorName( result ) + "]" );
+ }
}
- }
-
- byte[] response = send( request, command.getResponseTemplate() );
-
- if( response != null )
- {
- retVal = parseResponse( command, response );
- }
-
- return retVal;
- }
-
- /**
- * Sends the request byte array to the device and returns the response array
- * filled with the response bytes from the device, or returns null if
- * something failed along the way
- */
- private byte[] send( byte[] request, byte[] response )
- throws UsbException, UsbClaimException
- {
- byte[] retVal = null;
-
- if( mPipeIn != null && mPipeOut != null )
- {
- mPipeOut.syncSubmit( request );
-
- mPipeIn.syncSubmit( response );
- retVal = response;
- }
-
- return retVal;
- }
-
- /**
- * Parses a multi-byte integer response value from a byte array that is
- * 2 or more bytes long
- */
- private long parseResponse( FCDCommand command, byte[] response )
- {
- long retVal = 0;
-
- //Parse the value argument into the request byte indices, according to command length
- for( int x = 2; x < command.getArrayLength(); x++ )
- {
- retVal += Long.rotateLeft( ( response[ x ] & 0xFF ), ( x - 2 ) * 8 );
- }
-
- return retVal;
- }
-
- protected void open() throws UsbException, UsbClaimException
- {
- if( claim() )
- {
- //Get the USB endpoints
- UsbEndpoint endpointIn =
- mFuncubeHID.getUsbEndpoint( sFCD_ENDPOINT_IN );
-
- UsbEndpoint endpointOut =
- mFuncubeHID.getUsbEndpoint( sFCD_ENDPOINT_OUT );
-
- //Setup the pipes
- if( endpointIn != null && endpointOut != null )
+ result = LibUsb.claimInterface( mDeviceHandle, FCD_INTERFACE );
+
+ if( result != LibUsb.SUCCESS )
{
- mPipeOut = endpointOut.getUsbPipe();
- mPipeOut.open();
-
- mPipeIn = endpointIn.getUsbPipe();
- mPipeIn.open();
-
- setFCDMode( Mode.APPLICATION );
- }
- else
- {
- mLog.error( "FCD Pro Tuner Controller - couldn't gain access " +
- "to the USB in/out endpoints or pipes." );
+ throw new SourceException( "couldn't claim usb interface [" +
+ LibUsb.errorName( result ) + "]" );
}
}
else
{
- mLog.error( "FCD Pro Tuner Controller - couldn't claim the USB " +
- "interface. Check to see if another program is using it." );
+ throw new SourceException( "couldn't claim usb hid interface - no "
+ + "device handle" );
+ }
+ }
+
+ /**
+ * Performs an interrupt write to the OUT endpoint.
+ * @param buffer - direct allocated buffer. Must be 64 bytes in length.
+ *
+ * @throws LibUsbException on error
+ */
+ private void write( ByteBuffer buffer ) throws LibUsbException
+ {
+ if( mDeviceHandle != null )
+ {
+ IntBuffer transferred = IntBuffer.allocate( 1 );
+
+ int result = LibUsb.interruptTransfer( mDeviceHandle,
+ FCD_ENDPOINT_OUT,
+ buffer,
+ transferred,
+ 500l );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ throw new LibUsbException( "error writing byte buffer",
+ result );
+ }
+ else if( transferred.get() != buffer.capacity() )
+ {
+ throw new LibUsbException( "transferred bytes [" +
+ transferred.get( 0 ) + "] is not what was expected [" +
+ buffer.capacity() + "]", result );
+ }
+ }
+ else
+ {
+ throw new LibUsbException( "device handle is null",
+ LibUsb.ERROR_NO_DEVICE );
}
}
- protected void close()
+ /**
+ * Performs an interrupt write to the OUT endpoint for the FCD command.
+ * @param command - no-argument command to write
+ * @throws LibUsbException - on error
+ */
+ private void write( FCDCommand command ) throws LibUsbException
{
- release();
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 64 );
+
+ buffer.put( 0, command.getCommand() );
+ buffer.put( 1, (byte)0x00 );
+
+ write( buffer );
}
+ /**
+ * Convenience logger for debugging read/write operations
+ */
+ @SuppressWarnings( "unused" )
+ private void log( String label, ByteBuffer buffer )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( label );
+
+ sb.append( " " );
+
+ sb.append( buffer.get( 0 ) );
+ sb.append( " | " );
+
+ for( int x = 0; x < 64; x++ )
+ {
+ sb.append( String.format( "%02X", (int)( buffer.get( x ) & 0xFF ) ) );
+ sb.append( " " );
+ }
+
+ mLog.debug( sb.toString() );
+ }
+
+ /**
+ * Performs an interrupt write to the OUT endpoint for the FCD command.
+ * @param command - command to write
+ * @param argument - value to write with the command
+ * @throws LibUsbException - on error
+ */
+ private void write( FCDCommand command, long argument ) throws LibUsbException
+ {
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 64 );
+
+ /* The FCD expects little-endian formatted values */
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ buffer.put( 0, command.getCommand() );
+ buffer.putLong( 1, argument );
+
+ write( buffer );
+ }
+
+ /**
+ * Performs an interrupt read against the endpoint
+ * @return buffer read from FCD
+ * @throws LibUsbException on error
+ */
+ private ByteBuffer read() throws LibUsbException
+ {
+ if( mDeviceHandle != null )
+ {
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 64 );
+
+ IntBuffer transferred = IntBuffer.allocate( 1 );
+
+
+ int result = LibUsb.interruptTransfer( mDeviceHandle,
+ FCD_ENDPOINT_IN,
+ buffer,
+ transferred,
+ 500l );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ throw new LibUsbException( "error reading byte buffer",
+ result );
+ }
+ else if( transferred.get( 0 ) != buffer.capacity() )
+ {
+ throw new LibUsbException( "received bytes [" +
+ transferred.get( 0 ) + "] didn't match expected "
+ + "length [" + buffer.capacity() + "]", result );
+ }
+
+ return buffer;
+ }
+
+ throw new LibUsbException( "device handle is null",
+ LibUsb.ERROR_NO_DEVICE );
+ }
+
+ /**
+ * Sends the FCD command and argument. Performs a read to complete the
+ * command.
+ *
+ * @param command - command to send
+ * @param argument - command argument to send
+ * @throws LibUsbException - on error
+ */
+ protected void send( FCDCommand command, long argument ) throws LibUsbException
+ {
+ write( command, argument );
+ read();
+ }
+
+ /**
+ * Sends the no-argument FCD command. Performs a read to complete the
+ * command.
+ *
+ * @param command - command to send
+ * @throws LibUsbException - on error
+ */
+ protected ByteBuffer send( FCDCommand command ) throws LibUsbException
+ {
+ write( command );
+ return read();
+ }
+
+ /**
+ * FCD configuration string parsing class
+ */
public class FCDConfiguration
{
private String mConfig;
@@ -385,11 +521,20 @@ public abstract class FCDTunerController extends TunerController
mMode = Mode.UNKNOWN;
}
- public void set( byte[] data )
+ /**
+ * Extracts the configuration string from the buffer
+ */
+ public void set( ByteBuffer buffer )
{
- if( FCDCommand.checkResponse( FCDCommand.BL_QUERY, data ) ||
- FCDCommand.checkResponse( FCDCommand.APP_RESET, data ) )
+ if( buffer.capacity() == 64 )
{
+ byte[] data = new byte[ 64 ];
+
+ for( int x = 0; x < 64; x++ )
+ {
+ data[ x ] = buffer.get( x );
+ }
+
mConfig = new String( data );
mMode = Mode.getMode( mConfig );
}
diff --git a/src/source/tuner/fcd/FCDTunerDetailsPanel.java b/src/source/tuner/fcd/FCDTunerDetailsPanel.java
index 1e020d72..05e3b51f 100644
--- a/src/source/tuner/fcd/FCDTunerDetailsPanel.java
+++ b/src/source/tuner/fcd/FCDTunerDetailsPanel.java
@@ -17,26 +17,27 @@
******************************************************************************/
package source.tuner.fcd;
-import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
-import source.tuner.rtl.RTL2832TunerController.Descriptor;
import net.miginfocom.swing.MigLayout;
public class FCDTunerDetailsPanel extends JPanel
{
private static final long serialVersionUID = 1L;
- private JLabel mAddress;
- private JLabel mCellBlock;
- private JLabel mFirmware;
public FCDTunerDetailsPanel( FCDTunerController controller )
{
- setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][grow]" ) );
+ setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][][][][grow]" ) );
+ add( new JLabel( "USB ID:" ) );
+ add( new JLabel( controller.getUSBID() ) );
+
add( new JLabel( "USB Address:" ) );
- add( new JLabel( controller.getAddress() ) );
+ add( new JLabel( controller.getUSBAddress() ) );
+
+ add( new JLabel( "USB Speed:" ) );
+ add( new JLabel( controller.getUSBSpeed() ) );
add( new JLabel( "Cellular Band:" ) );
add( new JLabel( controller.getConfiguration().getBandBlocking()
diff --git a/src/source/tuner/fcd/proV1/FCD1TunerConfigurationPanel.java b/src/source/tuner/fcd/proV1/FCD1TunerConfigurationPanel.java
index 417012c8..bfbe7fbb 100644
--- a/src/source/tuner/fcd/proV1/FCD1TunerConfigurationPanel.java
+++ b/src/source/tuner/fcd/proV1/FCD1TunerConfigurationPanel.java
@@ -511,7 +511,7 @@ public class FCD1TunerConfigurationPanel extends JPanel
mResourceManager.getSettingsManager()
.setSelectedTunerConfiguration(
TunerType.FUNCUBE_DONGLE_PRO,
- mController.getAddress(), config );
+ mController.getUSBAddress(), config );
}
catch ( SourceException e1 )
{
diff --git a/src/source/tuner/fcd/proV1/FCD1TunerController.java b/src/source/tuner/fcd/proV1/FCD1TunerController.java
index 11f267e7..9d56b0f4 100644
--- a/src/source/tuner/fcd/proV1/FCD1TunerController.java
+++ b/src/source/tuner/fcd/proV1/FCD1TunerController.java
@@ -17,12 +17,17 @@
******************************************************************************/
package source.tuner.fcd.proV1;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
import javax.swing.JPanel;
import javax.usb.UsbClaimException;
import javax.usb.UsbException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
import source.SourceException;
import source.tuner.TunerClass;
@@ -31,7 +36,6 @@ import source.tuner.TunerType;
import source.tuner.fcd.FCDCommand;
import source.tuner.fcd.FCDTuner;
import source.tuner.fcd.FCDTunerController;
-import source.tuner.usb.USBTunerDevice;
import controller.ResourceManager;
public class FCD1TunerController extends FCDTunerController
@@ -53,19 +57,22 @@ public class FCD1TunerController extends FCDTunerController
private FCD1TunerConfiguration mTunerConfiguration;
private FCD1TunerEditorPanel mEditor;
- public FCD1TunerController( USBTunerDevice device )
- throws SourceException
+ public FCD1TunerController( Device device, DeviceDescriptor descriptor )
{
- super( device,
+ super( device,
+ descriptor,
sMINIMUM_TUNABLE_FREQUENCY,
sMAXIMUM_TUNABLE_FREQUENCY );
+ }
+
+ public void init() throws SourceException
+ {
+ super.init();
mFrequencyController.setSampleRate( sSAMPLE_RATE );
try
{
- open();
-
setFCDMode( Mode.APPLICATION );
getPhaseAndGainCorrection();
getDCIQCorrection();
@@ -73,7 +80,7 @@ public class FCD1TunerController extends FCDTunerController
getLNAEnhanceSetting();
getMixerGainSetting();
- send( FCDCommand.APP_SET_MIXER_GAIN, 1 );
+ send( FCDCommand.APP_SET_MIXER_GAIN, 1l );
}
catch( Exception e )
{
@@ -156,10 +163,12 @@ public class FCD1TunerController extends FCDTunerController
*/
private void getLNAGainSetting() throws UsbClaimException, UsbException
{
- int gain = (int)send( FCDCommand.APP_GET_LNA_GAIN );
-
- mLog.info( "FCD1: lna gain setting is:" + gain );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_LNA_GAIN );
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ int gain = buffer.getInt( 2 );
+
mLNAGain = LNAGain.valueOf( gain );
}
@@ -286,7 +295,11 @@ public class FCD1TunerController extends FCDTunerController
private void getPhaseAndGainCorrection() throws UsbClaimException,
UsbException
{
- long correction = send( FCDCommand.APP_GET_IQ_CORRECTION );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_IQ_CORRECTION );
+
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ int correction = buffer.getInt( 2 );
/**
* Gain: mask the upper 16 phase bits and right shift to get the
@@ -305,8 +318,6 @@ public class FCD1TunerController extends FCDTunerController
short phase = (short)( correction & 0x0000FFFF );
mPhaseCorrection = ( (double)phase / (double)Short.MAX_VALUE );
-
- mLog.info( "FCD1: correction:" + correction + " gain:" + gain + " phase:" + phase );
}
/**
@@ -413,7 +424,11 @@ public class FCD1TunerController extends FCDTunerController
private void getDCIQCorrection() throws UsbClaimException,
UsbException
{
- long correction = send( FCDCommand.APP_GET_DC_CORRECTION );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_DC_CORRECTION );
+
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ int correction = buffer.getInt( 2 );
/**
* Quadrature: mask the upper 16 bits and divide by 32768 to get the
@@ -443,9 +458,11 @@ public class FCD1TunerController extends FCDTunerController
private void getLNAEnhanceSetting() throws UsbClaimException, UsbException
{
- int enhance = (int)send( FCDCommand.APP_GET_LNA_ENHANCE );
-
- mLog.info( "FCD1: lna enhance setting is: " + enhance );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_LNA_ENHANCE );
+
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ int enhance = buffer.getInt( 2 );
mLNAEnhance = LNAEnhance.valueOf( enhance );
}
@@ -463,9 +480,11 @@ public class FCD1TunerController extends FCDTunerController
private void getMixerGainSetting() throws UsbClaimException, UsbException
{
- int gain = (int)send( FCDCommand.APP_GET_MIXER_GAIN );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_MIXER_GAIN );
- mLog.info( "FCD1: mixer gain setting is:" + gain );
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ int gain = buffer.getInt( 2 );
mMixerGain = MixerGain.valueOf( gain );
}
diff --git a/src/source/tuner/fcd/proplusV2/FCD2TunerConfigurationPanel.java b/src/source/tuner/fcd/proplusV2/FCD2TunerConfigurationPanel.java
index 049d8a56..bb6acbea 100644
--- a/src/source/tuner/fcd/proplusV2/FCD2TunerConfigurationPanel.java
+++ b/src/source/tuner/fcd/proplusV2/FCD2TunerConfigurationPanel.java
@@ -221,7 +221,7 @@ public class FCD2TunerConfigurationPanel extends JPanel
TunerConfigurationAssignment savedConfig = mResourceManager
.getSettingsManager().getSelectedTunerConfiguration(
TunerType.FUNCUBE_DONGLE_PRO_PLUS,
- mController.getAddress() );
+ mController.getUSBAddress() );
if( savedConfig != null )
{
@@ -237,7 +237,7 @@ public class FCD2TunerConfigurationPanel extends JPanel
mResourceManager.getSettingsManager()
.setSelectedTunerConfiguration(
TunerType.FUNCUBE_DONGLE_PRO_PLUS,
- mController.getAddress(), mSelectedConfig );
+ mController.getUSBAddress(), mSelectedConfig );
}
mComboConfigurations.setSelectedItem( mSelectedConfig );
@@ -324,7 +324,7 @@ public class FCD2TunerConfigurationPanel extends JPanel
mResourceManager.getSettingsManager().setSelectedTunerConfiguration(
TunerType.FUNCUBE_DONGLE_PRO_PLUS,
- mController.getAddress(), config );
+ mController.getUSBAddress(), config );
}
catch ( SourceException e1 )
{
diff --git a/src/source/tuner/fcd/proplusV2/FCD2TunerController.java b/src/source/tuner/fcd/proplusV2/FCD2TunerController.java
index f6e27f42..8640ea50 100644
--- a/src/source/tuner/fcd/proplusV2/FCD2TunerController.java
+++ b/src/source/tuner/fcd/proplusV2/FCD2TunerController.java
@@ -17,12 +17,15 @@
******************************************************************************/
package source.tuner.fcd.proplusV2;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
import javax.swing.JPanel;
-import javax.usb.UsbClaimException;
-import javax.usb.UsbException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
import source.SourceException;
import source.tuner.TunerClass;
@@ -31,7 +34,6 @@ import source.tuner.TunerType;
import source.tuner.fcd.FCDCommand;
import source.tuner.fcd.FCDTuner;
import source.tuner.fcd.FCDTunerController;
-import source.tuner.usb.USBTunerDevice;
import controller.ResourceManager;
public class FCD2TunerController extends FCDTunerController
@@ -46,25 +48,27 @@ public class FCD2TunerController extends FCDTunerController
private FCD2TunerConfiguration mTunerConfiguration;
private FCD2TunerEditorPanel mEditor;
- public FCD2TunerController( USBTunerDevice device )
- throws SourceException
+ public FCD2TunerController( Device device, DeviceDescriptor descriptor )
{
super( device,
+ descriptor,
sMINIMUM_TUNABLE_FREQUENCY,
sMAXIMUM_TUNABLE_FREQUENCY );
+ }
+
+ public void init() throws SourceException
+ {
+ super.init();
mFrequencyController.setSampleRate( sSAMPLE_RATE );
try
{
- open();
-
setFCDMode( Mode.APPLICATION );
}
catch( Exception e )
{
- throw new SourceException( "FCDTunerController error " +
- "during construction", e );
+ throw new SourceException( "error setting Mode to APPLICATION", e );
}
}
@@ -109,7 +113,7 @@ public class FCD2TunerController extends FCDTunerController
{
if( plusConfig.getGainLNA() )
{
- send( FCDCommand.APP_SET_LNA_GAIN, 1 );
+ send( FCDCommand.APP_SET_LNA_GAIN, 1 );
}
else
@@ -117,34 +121,26 @@ public class FCD2TunerController extends FCDTunerController
send( FCDCommand.APP_SET_LNA_GAIN, 0 );
}
}
- catch ( UsbClaimException e )
+ catch ( Exception e )
{
- throw new SourceException( "Exception while setting LNA Gain", e );
- }
- catch ( UsbException e )
- {
- throw new SourceException( "Exception while setting LNA Gain", e );
+ throw new SourceException( "error while setting LNA Gain", e );
}
try
{
if( plusConfig.getGainMixer() )
{
- send( FCDCommand.APP_SET_MIXER_GAIN, 1 );
-
+ send( FCDCommand.APP_SET_MIXER_GAIN, 1 );
+
}
else
{
send( FCDCommand.APP_SET_MIXER_GAIN, 0 );
}
}
- catch ( UsbClaimException e )
+ catch ( Exception e )
{
- throw new SourceException( "Exception while setting mixer gain", e );
- }
- catch ( UsbException e )
- {
- throw new SourceException( "Exception while setting mixer gain", e );
+ throw new SourceException( "error while setting Mixer Gain", e );
}
mTunerConfiguration = plusConfig;
@@ -163,17 +159,15 @@ public class FCD2TunerController extends FCDTunerController
try
{
- dcCorrection = (int)send( FCDCommand.APP_GET_DC_CORRECTION );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_DC_CORRECTION );
+
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ return buffer.getInt( 2 );
}
- catch ( UsbClaimException e )
+ catch ( Exception e )
{
- mLog.error( "FCTTunerController - couldn't claim funcube HID to"
- + " get dc correction value", e );
- }
- catch ( UsbException e )
- {
- mLog.error( "FCTTunerController - error getting dc correction "
- + "value", e );
+ mLog.error( "error getting dc correction value", e );
}
return dcCorrection;
@@ -183,17 +177,11 @@ public class FCD2TunerController extends FCDTunerController
{
try
{
- send( FCDCommand.APP_SET_DC_CORRECTION, value );
+ send( FCDCommand.APP_SET_DC_CORRECTION, value );
}
- catch ( UsbClaimException e )
+ catch ( Exception e )
{
- mLog.error( "FCDTunerController - error claiming usb hid while "
- + "trying to set dc correction to [" + value + "]", e );
- }
- catch ( UsbException e )
- {
- mLog.error( "FCDTunerController - error while "
- + "trying to set dc correction to [" + value + "]", e );
+ mLog.error( "error setting dc correction to [" + value + "]", e );
}
}
@@ -203,20 +191,17 @@ public class FCD2TunerController extends FCDTunerController
try
{
- iqCorrection = (int)send( FCDCommand.APP_GET_IQ_CORRECTION );
+ ByteBuffer buffer = send( FCDCommand.APP_GET_IQ_CORRECTION );
+
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ return buffer.getInt( 2 );
}
- catch ( UsbClaimException e )
+ catch ( Exception e )
{
- mLog.error( "FCTTunerController - couldn't claim funcube HID to"
- + " get iq correction value", e );
+ mLog.error( "error reading IQ correction value", e );
}
- catch ( UsbException e )
- {
- mLog.error( "FCTTunerController - error getting iq correction "
- + "value", e );
- }
-
return iqCorrection;
}
@@ -226,15 +211,9 @@ public class FCD2TunerController extends FCDTunerController
{
send( FCDCommand.APP_SET_IQ_CORRECTION, value );
}
- catch ( UsbClaimException e )
+ catch ( Exception e )
{
- mLog.error( "FCDTunerController - error claiming usb hid while "
- + "trying to set iq correction to [" + value + "]", e );
- }
- catch ( UsbException e )
- {
- mLog.error( "FCDTunerController - error while "
- + "trying to set iq correction to [" + value + "]", e );
+ mLog.error( "error setting IQ correction to [" + value + "]", e );
}
}
@@ -272,98 +251,4 @@ public class FCD2TunerController extends FCDTunerController
return retVal;
}
}
-
- public enum TunerRFFilter
- {
- TRF_0_4,
- TRF_4_8,
- TRF_8_16,
- TRF_16_32,
- TRF_32_75,
- TRF_75_125,
- TRF_125_250,
- TRF_145,
- TRF_410_875,
- TRF_435,
- TRF_875_2000,
- UNKNOWN;
-
- public static TunerRFFilter get( int value )
- {
- TunerRFFilter retVal = UNKNOWN;
-
- if( 0 <= value && value <= 10 )
- {
- retVal = values()[ value ];
- }
-
- return retVal;
- }
- }
-
- public enum TunerIFFilter
- {
- TIF_200KHZ,
- TIF_300KHZ,
- TIF_600KHZ,
- TIF_1536KHZ,
- TIF_5MHZ,
- TIF_6MHZ,
- TIF_7MHZ,
- TIF_8MHZ,
- UNKNOWN;
-
- public static TunerIFFilter get( int value )
- {
- TunerIFFilter retVal = UNKNOWN;
-
- if( 0 <= value && value <= 7 )
- {
- retVal = values()[ value ];
- }
-
- return retVal;
- }
- }
-
- public enum LNAGain
- {
- LNA_GAIN_MINUS_5_0( 0, "-5.0 dB" ),
- LNA_GAIN_MINUS_2_5( 1, "-2.5 dB" ),
- LNA_GAIN_PLUS_0_0( 4, "0.0 dB" ),
- LNA_GAIN_PLUS_2_5( 5, "2.5 dB" ),
- LNA_GAIN_PLUS_5_0( 6, "5.0 dB" ),
- LNA_GAIN_PLUS_7_5( 7, "7.5 dB" ),
- LNA_GAIN_PLUS_10_0( 8, "10.0 dB" ),
- LNA_GAIN_PLUS_12_5( 9, "12.5 dB" ),
- LNA_GAIN_PLUS_15_0( 10, "15.0 dB" ),
- LNA_GAIN_PLUS_17_5( 11, "17.5 dB" ),
- LNA_GAIN_PLUS_20_0( 12, "20.0 dB" ),
- LNA_GAIN_PLUS_25_0( 13, "25.0 dB" ),
- LNA_GAIN_PLUS_30_0( 14, "30.0 dB" );
-
- private int mSetting;
- private String mLabel;
-
- private LNAGain( int setting, String label )
- {
- mSetting = setting;
- mLabel = label;
- }
-
- public int getSetting()
- {
- return mSetting;
- }
-
- public String getLabel()
- {
- return mLabel;
- }
-
- public String toString()
- {
- return getLabel();
- }
- }
}
diff --git a/src/source/tuner/hackrf/HackRFTuner.java b/src/source/tuner/hackrf/HackRFTuner.java
index c7204b54..8ac701a4 100644
--- a/src/source/tuner/hackrf/HackRFTuner.java
+++ b/src/source/tuner/hackrf/HackRFTuner.java
@@ -70,6 +70,11 @@ public class HackRFTuner extends Tuner
mLog.error( "couldn't read HackRF board id", e );
}
}
+
+ public void dispose()
+ {
+ //TODO: dispose of something here
+ }
public HackRFTunerController getController()
{
diff --git a/src/source/tuner/hackrf/HackRFTunerConfiguration.java b/src/source/tuner/hackrf/HackRFTunerConfiguration.java
index c3d5736f..a76ce581 100644
--- a/src/source/tuner/hackrf/HackRFTunerConfiguration.java
+++ b/src/source/tuner/hackrf/HackRFTunerConfiguration.java
@@ -31,6 +31,7 @@ public class HackRFTunerConfiguration extends TunerConfiguration
private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE2_016MHZ;
private HackRFLNAGain mLNAGain = HackRFLNAGain.GAIN_0;
private HackRFVGAGain mVGAGain = HackRFVGAGain.GAIN_10;
+ private boolean mAmplifierEnabled = false;
private double mFrequencyCorrection = 0.0d;
/**
@@ -52,6 +53,17 @@ public class HackRFTunerConfiguration extends TunerConfiguration
return TunerType.HACKRF;
}
+ @XmlAttribute( name = "amplifier_enabled" )
+ public boolean getAmplifierEnabled()
+ {
+ return mAmplifierEnabled;
+ }
+
+ public void setAmplifierEnabled( boolean enabled )
+ {
+ mAmplifierEnabled = enabled;
+ }
+
@XmlAttribute( name = "lna_gain" )
public HackRFLNAGain getLNAGain()
{
diff --git a/src/source/tuner/hackrf/HackRFTunerConfigurationPanel.java b/src/source/tuner/hackrf/HackRFTunerConfigurationPanel.java
index 462321bc..b5ec8acb 100644
--- a/src/source/tuner/hackrf/HackRFTunerConfigurationPanel.java
+++ b/src/source/tuner/hackrf/HackRFTunerConfigurationPanel.java
@@ -35,6 +35,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
+import javax.swing.JToggleButton;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
@@ -74,6 +75,7 @@ public class HackRFTunerConfigurationPanel extends JPanel
private JTextField mName;
private JSpinner mFrequencyCorrection;
+ private JToggleButton mAmplifier;
private JComboBox mComboLNAGain;
private JComboBox mComboVGAGain;
@@ -284,8 +286,38 @@ public class HackRFTunerConfigurationPanel extends JPanel
* Gain Controls
*/
JPanel gainPanel = new JPanel();
- gainPanel.setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill]" ) );
+ gainPanel.setLayout( new MigLayout( "",
+ "[][right][grow,fill][right][grow,fill]", "[grow,fill]" ) );
gainPanel.setBorder( BorderFactory.createTitledBorder( "Gain" ) );
+
+ /* Amplifier */
+ mAmplifier = new JToggleButton( "Amp" );
+ mAmplifier.setSelected( mSelectedConfig.getAmplifierEnabled() );
+ mAmplifier.addActionListener( new ActionListener()
+ {
+ @Override
+ public void actionPerformed( ActionEvent arg0 )
+ {
+ try
+ {
+ mController.setAmplifierEnabled( mAmplifier.isSelected() );
+ mSelectedConfig.setAmplifierEnabled( mAmplifier.isSelected() );
+ save();
+ }
+ catch ( UsbException e )
+ {
+ mLog.error( "couldn't enable/disable amplifier", e );
+ mAmplifier.setEnabled( !mAmplifier.isSelected() );
+
+ JOptionPane.showMessageDialog(
+ HackRFTunerConfigurationPanel.this,
+ "Couldn't change amplifier setting",
+ "Error changing amplifier setting",
+ JOptionPane.ERROR_MESSAGE );
+ }
+ }
+ } );
+ gainPanel.add( mAmplifier );
/* LNA Gain Control */
mComboLNAGain = new JComboBox( HackRFLNAGain.values() );
@@ -311,6 +343,7 @@ public class HackRFTunerConfigurationPanel extends JPanel
}
mSelectedConfig.setLNAGain( lnaGain );
+
save();
}
catch ( UsbException e )
@@ -325,8 +358,8 @@ public class HackRFTunerConfigurationPanel extends JPanel
}
}
} );
- mComboLNAGain.setToolTipText( "LNA Gain. Set master gain "
- + "to MANUAL to enable adjustment" );
+ mComboLNAGain.setToolTipText( "LNA Gain. Adjust to set "
+ + "the IF gain" );
gainPanel.add( new JLabel( "LNA" ) );
gainPanel.add( mComboLNAGain );
@@ -367,12 +400,12 @@ public class HackRFTunerConfigurationPanel extends JPanel
}
}
} );
- mComboVGAGain.setToolTipText( "VGA Gain. Set master gain "
- + "to MANUAL to enable adjustment" );
+ mComboVGAGain.setToolTipText( "VGA Gain. Adjust to set the "
+ + "baseband gain" );
gainPanel.add( new JLabel( "VGA" ) );
gainPanel.add( mComboVGAGain, "wrap" );
- add( gainPanel, "span" );
+ add( gainPanel, "span,growx" );
/**
* Create a new configuration
diff --git a/src/source/tuner/hackrf/HackRFTunerController.java b/src/source/tuner/hackrf/HackRFTunerController.java
index 38555d3e..5270e98f 100644
--- a/src/source/tuner/hackrf/HackRFTunerController.java
+++ b/src/source/tuner/hackrf/HackRFTunerController.java
@@ -1,5 +1,7 @@
package source.tuner.hackrf;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@@ -10,46 +12,34 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.usb.UsbClaimException;
-import javax.usb.UsbConfiguration;
-import javax.usb.UsbControlIrp;
-import javax.usb.UsbDevice;
-import javax.usb.UsbDisconnectedException;
-import javax.usb.UsbEndpoint;
-import javax.usb.UsbEndpointDescriptor;
import javax.usb.UsbException;
-import javax.usb.UsbInterface;
-import javax.usb.UsbInterfacePolicy;
-import javax.usb.UsbIrp;
-import javax.usb.UsbNotActiveException;
-import javax.usb.UsbNotOpenException;
-import javax.usb.UsbPipe;
-import javax.usb.event.UsbPipeDataEvent;
-import javax.usb.event.UsbPipeErrorEvent;
-import javax.usb.event.UsbPipeListener;
import org.apache.commons.io.EndianUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
+import org.usb4java.DeviceHandle;
import org.usb4java.LibUsb;
+import org.usb4java.LibUsbException;
+import org.usb4java.Transfer;
+import org.usb4java.TransferCallback;
import sample.Listener;
import source.SourceException;
import source.tuner.TunerConfiguration;
import source.tuner.TunerController;
import source.tuner.rtl.ByteSampleAdapter;
-import source.tuner.usb.USBTunerDevice;
public class HackRFTunerController extends TunerController
{
private final static Logger mLog =
LoggerFactory.getLogger( HackRFTunerController.class );
+ public final static long TIMEOUT_US = 1000000l; //uSeconds
public static final byte USB_ENDPOINT = (byte)0x81;
public static final byte USB_INTERFACE = (byte)0x0;
- public static final boolean USB_FORCE_CLAIM_INTERFACE = true;
public static final byte REQUEST_TYPE_IN =
(byte)( LibUsb.ENDPOINT_IN |
@@ -65,10 +55,10 @@ public class HackRFTunerController extends TunerController
public static final long MAX_FREQUENCY = 6000000000l;
public static final long DEFAULT_FREQUENCY = 101100000;
- public final static int USB_IRP_POOL_SIZE = 10;
+ public final static int TRANSFER_BUFFER_POOL_SIZE = 16;
- private LinkedTransferQueue mReceivedBuffers =
- new LinkedTransferQueue();
+ private LinkedTransferQueue mFilledBuffers =
+ new LinkedTransferQueue();
private CopyOnWriteArrayList> mSampleListeners =
new CopyOnWriteArrayList>();
@@ -76,63 +66,42 @@ public class HackRFTunerController extends TunerController
private ByteSampleAdapter mSampleAdapter = new ByteSampleAdapter();
private BufferProcessor mBufferProcessor = new BufferProcessor();
- private UsbDevice mUSBDevice;
- private UsbInterface mUSBInterface;
- private UsbPipe mUSBPipe;
+ private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE2_016MHZ;
+ public int mBufferSize = 262144;
+ private boolean mAmplifierEnabled = false;
- private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE4_464MHZ;
- public int mBufferSize = mSampleRate.getBufferSize();
+ private Device mDevice;
+ private DeviceDescriptor mDeviceDescriptor;
+ private DeviceHandle mDeviceHandle;
- public HackRFTunerController( USBTunerDevice tunerDevice )
+ public HackRFTunerController( Device device, DeviceDescriptor descriptor )
throws SourceException
{
super( MIN_FREQUENCY, MAX_FREQUENCY );
-
- mUSBDevice = tunerDevice.getDevice();
+
+ mDevice = device;
+ mDeviceDescriptor = descriptor;
}
public void init() throws SourceException
{
- mLog.info( "HackRF Tuner Controller init() starting" );
-
- UsbConfiguration config = mUSBDevice.getActiveUsbConfiguration();
+ mDeviceHandle = new DeviceHandle();
+
+ LibUsb.open( mDevice, mDeviceHandle );
- mUSBInterface = config.getUsbInterface( USB_INTERFACE );
-
try
{
- if( claim( mUSBInterface ) )
- {
- /* Get the USB endpoint */
- UsbEndpoint endpoint = mUSBInterface.getUsbEndpoint( USB_ENDPOINT );
-
- UsbEndpointDescriptor d = endpoint.getUsbEndpointDescriptor();
- System.out.println( "Endpoint max packet size:" + d.wMaxPacketSize() );
-
- mUSBPipe = endpoint.getUsbPipe();
-
- setMode( Mode.RECEIVE );
-
- setFrequency( DEFAULT_FREQUENCY );
- }
- else
- {
- throw new SourceException( "HackRF Tuner Controller - couldn't "
- + "claim USB interface" );
- }
+ claimInterface();
+
+ setMode( Mode.RECEIVE );
+
+ setFrequency( DEFAULT_FREQUENCY );
}
- catch( UsbException e )
+ catch( Exception e )
{
throw new SourceException( "HackRF Tuner Controller - couldn't "
+ "claim USB interface or get endpoint or pipe", e );
}
- catch ( UsbDisconnectedException e )
- {
- throw new SourceException( "HackRF Tuner Controller - usb device "
- + "is disconnected", e );
- }
-
- mLog.info( "HackRF Tuner Controller init() complete" );
}
/**
@@ -141,29 +110,39 @@ public class HackRFTunerController extends TunerController
* will dictate if the interface is forcibly claimed from the other
* application
*/
- public static boolean claim( UsbInterface iface ) throws UsbException,
- UsbClaimException
+ private void claimInterface() throws SourceException
{
- if( !iface.isClaimed() )
+ if( mDeviceHandle != null )
{
- iface.claim( new UsbInterfacePolicy()
+ int result = LibUsb.kernelDriverActive( mDeviceHandle, USB_INTERFACE );
+
+ if( result == 1 )
{
- @Override
- public boolean forceClaim( UsbInterface arg0 )
- {
- return USB_FORCE_CLAIM_INTERFACE;
- }
- } );
+ result = LibUsb.detachKernelDriver( mDeviceHandle, USB_INTERFACE );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "failed attempt to detach kernel driver [" +
+ LibUsb.errorName( result ) + "]" );
+
+ throw new SourceException( "couldn't detach kernel driver "
+ + "from device" );
+ }
+ }
- return iface.isClaimed();
+ result = LibUsb.claimInterface( mDeviceHandle, USB_INTERFACE );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ throw new SourceException( "couldn't claim usb interface [" +
+ LibUsb.errorName( result ) + "]" );
+ }
}
else
{
- mLog.error( "attempt to claim USB interface failed - in use by "
- + "another application" );
+ throw new SourceException( "couldn't claim usb interface - no "
+ + "device handle" );
}
-
- return false;
}
/**
@@ -181,19 +160,13 @@ public class HackRFTunerController extends TunerController
*/
public String getFirmwareVersion() throws UsbException
{
- byte[] data = readArray( Request.VERSION_STRING_READ, 0, 0, 255 );
+ ByteBuffer buffer = readArray( Request.VERSION_STRING_READ, 0, 0, 255 );
+
+ byte[] data = new byte[ 255 ];
- StringBuilder sb = new StringBuilder();
-
- for( byte b: data )
- {
- if( b != (byte)0 )
- {
- sb.append( (char)b );
- }
- }
-
- return sb.toString();
+ buffer.get( data );
+
+ return new String( data );
}
/**
@@ -201,9 +174,9 @@ public class HackRFTunerController extends TunerController
*/
public Serial getSerial() throws UsbException
{
- byte[] data = readArray( Request.BOARD_PARTID_SERIALNO_READ, 0, 0, 24 );
+ ByteBuffer buffer = readArray( Request.BOARD_PARTID_SERIALNO_READ, 0, 0, 24 );
- return new Serial( data );
+ return new Serial( buffer );
}
/**
@@ -230,6 +203,13 @@ public class HackRFTunerController extends TunerController
public void setAmplifierEnabled( boolean enabled ) throws UsbException
{
write( Request.AMP_ENABLE, ( enabled ? 1 : 0 ), 0 );
+
+ mAmplifierEnabled = enabled;
+ }
+
+ public boolean getAmplifier()
+ {
+ return mAmplifierEnabled;
}
/**
@@ -269,17 +249,20 @@ public class HackRFTunerController extends TunerController
@Override
public void setTunedFrequency( long frequency ) throws SourceException
{
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 8 );
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
int mhz = (int)( frequency / 1E6 );
int hz = (int)( frequency - ( mhz * 1E6 ) );
-
- byte[] data = new byte[ 8 ];
-
- EndianUtils.writeSwappedInteger( data, 0, mhz );
- EndianUtils.writeSwappedInteger( data, 4, hz );
+
+ buffer.putInt( mhz );
+ buffer.putInt( hz );
+
+ buffer.rewind();
try
{
- write( Request.SET_FREQUENCY, 0, 0, data );
+ write( Request.SET_FREQUENCY, 0, 0, buffer );
}
catch( UsbException e )
{
@@ -288,7 +271,6 @@ public class HackRFTunerController extends TunerController
throw new SourceException( "error setting frequency [" +
frequency + "]", e );
}
-
}
@Override
@@ -302,15 +284,15 @@ public class HackRFTunerController extends TunerController
{
if( config instanceof HackRFTunerConfiguration )
{
- HackRFTunerConfiguration hackConfig =
+ HackRFTunerConfiguration hackRFConfig =
(HackRFTunerConfiguration)config;
try
{
- setSampleRate( hackConfig.getSampleRate() );
- setFrequencyCorrection( hackConfig.getFrequencyCorrection() );
- setLNAGain( hackConfig.getLNAGain() );
- setVGAGain( hackConfig.getVGAGain() );
+ setSampleRate( hackRFConfig.getSampleRate() );
+ setFrequencyCorrection( hackRFConfig.getFrequencyCorrection() );
+ setLNAGain( hackRFConfig.getLNAGain() );
+ setVGAGain( hackRFConfig.getVGAGain() );
setFrequency( getFrequency() );
}
catch ( UsbException e )
@@ -326,21 +308,35 @@ public class HackRFTunerController extends TunerController
}
}
- public byte[] readArray( Request request,
+ public ByteBuffer readArray( Request request,
int value,
int index,
int length ) throws UsbException
{
- UsbControlIrp irp = mUSBDevice.createUsbControlIrp( REQUEST_TYPE_IN,
- request.getRequestNumber(), (short)value, (short)index );
+ if( mDeviceHandle != null )
+ {
+ ByteBuffer buffer = ByteBuffer.allocateDirect( length );
+
+ int transferred = LibUsb.controlTransfer( mDeviceHandle,
+ REQUEST_TYPE_IN,
+ request.getRequestNumber(),
+ (short)value,
+ (short)index,
+ buffer,
+ TIMEOUT_US );
- byte[] data = new byte[ length ];
-
- irp.setData( data );
-
- mUSBDevice.syncSubmit( irp );
-
- return data;
+ if( transferred < 0 )
+ {
+ throw new LibUsbException( "read error", transferred );
+ }
+
+ return buffer;
+ }
+ else
+ {
+ throw new LibUsbException( "device handle is null",
+ LibUsb.ERROR_NO_DEVICE );
+ }
}
public int read( Request request, int value, int index, int length )
@@ -349,10 +345,14 @@ public class HackRFTunerController extends TunerController
if( !( length == 1 || length == 2 || length == 4 ) )
{
throw new IllegalArgumentException( "invalid length [" + length +
- "] must be: byte=1, short=2, int=3 to read a primitive" );
+ "] must be: byte=1, short=2, int=4 to read a primitive" );
}
- byte[] data = readArray( request, value, index, length );
+ ByteBuffer buffer = readArray( request, value, index, length );
+
+ byte[] data = new byte[ buffer.capacity() ];
+
+ buffer.get( data );
switch( data.length )
{
@@ -371,29 +371,50 @@ public class HackRFTunerController extends TunerController
public int readByte( Request request, int value, int index, boolean signed )
throws UsbException
{
- byte[] data = readArray( request, value, index, 1 );
+ ByteBuffer buffer = readArray( request, value, index, 1 );
if( signed )
{
- return (int)( data[ 0 ] );
+ return (int)( buffer.get() );
}
else
{
- return (int)( data[ 0 ] & 0xFF );
+ return (int)( buffer.get() & 0xFF );
}
}
public void write( Request request,
int value,
int index,
- byte[] data ) throws UsbException
+ ByteBuffer buffer ) throws UsbException
{
- UsbControlIrp irp = mUSBDevice.createUsbControlIrp( REQUEST_TYPE_OUT,
- request.getRequestNumber(), (short)value, (short)index );
+ if( mDeviceHandle != null )
+ {
+ int transferred = LibUsb.controlTransfer( mDeviceHandle,
+ REQUEST_TYPE_OUT,
+ request.getRequestNumber(),
+ (short)value,
+ (short)index,
+ buffer,
+ TIMEOUT_US );
- irp.setData( data );
-
- mUSBDevice.syncSubmit( irp );
+ if( transferred < 0 )
+ {
+ throw new LibUsbException( "error writing byte buffer",
+ transferred );
+ }
+ else if( transferred != buffer.capacity() )
+ {
+ throw new LibUsbException( "transferred bytes [" +
+ transferred + "] is not what was expected [" +
+ buffer.capacity() + "]", transferred );
+ }
+ }
+ else
+ {
+ throw new LibUsbException( "device handle is null",
+ LibUsb.ERROR_NO_DEVICE );
+ }
}
/**
@@ -403,64 +424,22 @@ public class HackRFTunerController extends TunerController
int value,
int index ) throws UsbException
{
- write( request, value, index, new byte[ 0 ] );
+ write( request, value, index, ByteBuffer.allocateDirect( 0 ) );
}
/**
* Sample Rate
*
- * Note: this is direct translation of the libhackrf code, because I still
- * can't figure out how it works ... one day, maybe.
+ * Note: the libhackrf set sample rate method is designed to allow fractional
+ * sample rates. However, since we're only using integral sample rates, we
+ * simply invoke the setSampleRateManual method directly.
*/
public void setSampleRate( HackRFSampleRate rate ) throws UsbException
{
-// int MAX_N = 32;
-//
-// double freq = (double)rate.getRate() / 1E6d;
-//
-// double freq_frac = 1.0d + freq - (int)freq;
-//
-// long u64 = Double.doubleToLongBits( freq );
-//
-// int e = (int)( ( u64 >> 52 ) - 1023 );
-//
-// long m = (long)( 1l << 52 ) - 1l;
-//
-// u64 = Double.doubleToLongBits( freq_frac );
-//
-// u64 &= m;
-//
-// m &= ~( ( 1 << ( e + 4 ) ) - 1 );
-//
-// long a = 0;
-//
-// int x;
-//
-// for( x = 1; x < MAX_N; x++ )
-// {
-// a += u64;
-//
-// if( ( ( a & m ) == 0 ) || ( ( ~a & m ) == 0 ) )
-// {
-// break;
-// }
-// }
-//
-// if( x == MAX_N )
-// {
-// x = 1;
-// }
-//
-// int freq_hz = (int)( freq * (double)x * 0.5d );
-//
-// setSampleRateManual( freq_hz, x );
-
setSampleRateManual( rate.getRate(), 1 );
mFrequencyController.setSampleRate( rate.getRate() );
- mBufferSize = rate.getBufferSize();
-
setBasebandFilter( rate.getFilter() );
mSampleRate = rate;
@@ -469,12 +448,14 @@ public class HackRFTunerController extends TunerController
public void setSampleRateManual( int frequency, int divider )
throws UsbException
{
- byte[] data = new byte[ 8 ];
-
- EndianUtils.writeSwappedInteger( data, 0, frequency );
- EndianUtils.writeSwappedInteger( data, 4, divider );
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 8 );
- write( Request.SET_SAMPLE_RATE, 0, 0, data );
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
+
+ buffer.putInt( frequency );
+ buffer.putInt( divider );
+
+ write( Request.SET_SAMPLE_RATE, 0, 0, buffer );
}
public int getSampleRate()
@@ -522,29 +503,26 @@ public class HackRFTunerController extends TunerController
public enum HackRFSampleRate
{
- RATE2_016MHZ( 2016000, 65536, "2.016 MHz", BasebandFilter.F2_50 ),
- RATE3_024MHZ( 3024000, 98304, "3.024 MHz", BasebandFilter.F3_50 ),
- RATE4_464MHZ( 4464000, 131072, "4.464 MHz", BasebandFilter.F5_00 ),
- RATE5_472MHZ( 5472000, 196608, "5.472 MHz", BasebandFilter.F6_00 ),
- RATE7_488MHZ( 7488000, 262144, "7.488 MHz", BasebandFilter.F8_00 ),
- RATE10_032MHZ( 9984000, 131072, " 9.984 MHz", BasebandFilter.F10_00 ),
- RATE12_000MHZ( 12000000, 262144, "12.000 MHz", BasebandFilter.F12_00 ),
- RATE13_488MHZ( 13488000, 262144, "13.488 MHz", BasebandFilter.F14_00 ),
- RATE14_976MHZ( 14976000, 262144, "14.976 MHz", BasebandFilter.F15_00 ),
- RATE19_968MHZ( 19968000, 262144, "19.968 MHz", BasebandFilter.F20_00 );
+ RATE2_016MHZ( 2016000, "2.016 MHz", BasebandFilter.F3_50 ),
+ RATE3_024MHZ( 3024000, "3.024 MHz", BasebandFilter.F5_00 ),
+ RATE4_464MHZ( 4464000, "4.464 MHz", BasebandFilter.F6_00 ),
+ RATE5_472MHZ( 5472000, "5.472 MHz", BasebandFilter.F7_00 ),
+ RATE7_488MHZ( 7488000, "7.488 MHz", BasebandFilter.F9_00 ),
+ RATE10_032MHZ( 9984000, " 9.984 MHz", BasebandFilter.F12_00 ),
+ RATE12_000MHZ( 12000000, "12.000 MHz", BasebandFilter.F14_00 ),
+ RATE13_488MHZ( 13488000, "13.488 MHz", BasebandFilter.F15_00 ),
+ RATE14_976MHZ( 14976000, "14.976 MHz", BasebandFilter.F20_00 ),
+ RATE19_968MHZ( 19968000, "19.968 MHz", BasebandFilter.F24_00 );
private int mRate;
- private int mBufferSize;
private String mLabel;
private BasebandFilter mFilter;
private HackRFSampleRate( int rate,
- int bufferSize,
String label,
BasebandFilter filter )
{
mRate = rate;
- mBufferSize = bufferSize;
mLabel = label;
mFilter = filter;
}
@@ -554,11 +532,6 @@ public class HackRFTunerController extends TunerController
return mRate;
}
- public int getBufferSize()
- {
- return mBufferSize;
- }
-
public String getLabel()
{
return mLabel;
@@ -577,6 +550,7 @@ public class HackRFTunerController extends TunerController
public enum BasebandFilter
{
+ FAUTO( 0, "AUTO" ),
F1_75( 1750000, "1.75 MHz" ),
F2_50( 2500000, "2.50 MHz" ),
F3_50( 3500000, "3.50 MHz" ),
@@ -793,9 +767,11 @@ public class HackRFTunerController extends TunerController
{
private byte[] mData;
- public Serial( byte[] data )
+ public Serial( ByteBuffer buffer )
{
- mData = data;
+ mData = new byte[ buffer.capacity() ];
+
+ buffer.get( mData );
}
public String getPartID()
@@ -841,8 +817,16 @@ public class HackRFTunerController extends TunerController
{
mSampleListeners.add( listener );
- System.out.println( "HackRF - listener added - count:" + mSampleListeners.size() );
- mBufferProcessor.start();
+ if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
+ {
+ mBufferProcessor = new BufferProcessor();
+
+ Thread thread = new Thread( mBufferProcessor );
+ thread.setDaemon( true );
+ thread.setName( "Sample Processor" );
+
+ thread.start();
+ }
}
/**
@@ -889,93 +873,72 @@ public class HackRFTunerController extends TunerController
}
/**
- * Buffer processing thread. Fetches samples from the RTL2832 Tuner and
+ * Buffer processing thread. Fetches samples from the HackRF Tuner and
* dispatches them to all registered listeners
*/
- public class BufferProcessor implements UsbPipeListener
+ public class BufferProcessor implements Runnable, TransferCallback
{
private ScheduledExecutorService mExecutor =
- Executors.newScheduledThreadPool( 2 );
+ Executors.newScheduledThreadPool( 1 );
private ScheduledFuture> mSampleDispatcherTask;
-// private ScheduledFuture> mSampleRateCounterTask;
-
+ private ArrayList mTransfers;
private AtomicBoolean mRunning = new AtomicBoolean();
- private AtomicBoolean mResetting = new AtomicBoolean();
- private Boolean mTransitioning = false;
- public void start()
+ @Override
+ public void run()
{
- synchronized( mTransitioning )
+ if( mRunning.compareAndSet( false, true ) )
{
- if( mRunning.compareAndSet( false, true ) )
+ mLog.debug( "starting sample fetch thread" );
+
+ prepareTransfers();
+
+ for( Transfer transfer: mTransfers )
{
- mLog.debug( "HackRF - starting sample fetch thread" );
-
- ArrayList irps = new ArrayList();
+ int result = LibUsb.submitTransfer( transfer );
- for( int x = 0; x < USB_IRP_POOL_SIZE; x++ )
+ if( result != LibUsb.SUCCESS )
{
- UsbIrp irp = mUSBPipe.createUsbIrp();
- irp.setData( new byte[ mBufferSize ] );
- irps.add( irp );
+ mLog.error( "error submitting transfer [" +
+ LibUsb.errorName( result ) + "]" );
+ break;
}
-
- try
- {
- if( mUSBPipe.isActive() )
- {
- if( !mUSBPipe.isOpen() )
- {
- mUSBPipe.open();
-
- mUSBPipe.addUsbPipeListener( this );
- }
-
- if( mUSBPipe.isOpen() )
- {
- mSampleDispatcherTask = mExecutor
- .scheduleAtFixedRate( new BufferDispatcher(),
- 0, 20, TimeUnit.MILLISECONDS );
-
-// mSampleRateMonitor =
-// new SampleRateMonitor( mSampleRate.getRate() );
-
-// mSampleRateCounterTask = mExecutor
-// .scheduleAtFixedRate( mSampleRateMonitor,
-// 10, 10, TimeUnit.SECONDS );
-
- mUSBPipe.asyncSubmit( irps );
- }
- }
- }
- catch ( Exception e )
- {
- mLog.error( "Error in buffer processor thread", e );
- }
}
- }
- }
+
+ mSampleDispatcherTask = mExecutor
+ .scheduleAtFixedRate( new BufferDispatcher(),
+ 0, 20, TimeUnit.MILLISECONDS );
+
+ while( mRunning.get() )
+ {
+ ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
+
+ int result = LibUsb.handleEventsTimeoutCompleted(
+ null, TIMEOUT_US, completed.asIntBuffer() );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "error handling events for libusb" );
+ }
+ }
+ }
+ }
/**
* Stops the sample fetching thread
*/
public void stop()
{
- synchronized( mTransitioning )
+ if( mRunning.compareAndSet( true, false ) )
{
- if( mRunning.compareAndSet( true, false ) )
- {
- mLog.debug( "HackRF - stopping sample fetch thread" );
+ mLog.debug( "stopping sample fetch thread" );
- mUSBPipe.abortAllSubmissions();
-
- if( mSampleDispatcherTask != null )
- {
- mSampleDispatcherTask.cancel( true );
-// mSampleRateCounterTask.cancel( true );
-// mRawSampleBuffer.clear();
-// mSampleCounter.set( 0 );
- }
+ cancel();
+
+ if( mSampleDispatcherTask != null )
+ {
+ mSampleDispatcherTask.cancel( true );
+ mFilledBuffers.clear();
}
}
}
@@ -987,85 +950,150 @@ public class HackRFTunerController extends TunerController
{
return mRunning.get();
}
-
- /**
- * Receives filled data buffers and places them in the queue for the
- * BufferDispatcher to process
- */
+
@Override
- public synchronized void dataEventOccurred( UsbPipeDataEvent event )
- {
- mReceivedBuffers.add( event.getUsbIrp() );
- }
-
- @Override
- public void errorEventOccurred( UsbPipeErrorEvent e )
- {
- /* When an error occurs, we'll get errors on all of the
- * queued IRPS in succession. We use the mResetting to control
- * the reset process and ignore all subsequent errors */
- if( mResetting.compareAndSet( false, true ) )
+ public void processTransfer( Transfer transfer )
+ {
+ if( transfer.status() == LibUsb.TRANSFER_COMPLETED )
{
- mLog.error( "error during data transfer resetting USB pipe to "
- + "HackRF", e );
+ ByteBuffer buffer = transfer.buffer();
- stop();
-
- if( !mSampleListeners.isEmpty() )
- {
- start();
- }
+ byte[] data = new byte[ transfer.actualLength() ];
+
+ buffer.get( data );
- mResetting.set( false );
+ buffer.rewind();
+
+ mFilledBuffers.add( data );
+
+ if( !isRunning() )
+ {
+ LibUsb.cancelTransfer( transfer );
+ }
}
- }
+
+ switch( transfer.status() )
+ {
+ case LibUsb.TRANSFER_COMPLETED:
+ /* resubmit the transfer */
+ int result = LibUsb.submitTransfer( transfer );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "couldn't resubmit buffer transfer to tuner" );
+ LibUsb.freeTransfer( transfer );
+ mTransfers.remove( transfer );
+ }
+ break;
+ case LibUsb.TRANSFER_CANCELLED:
+ /* free the transfer and remove it */
+ LibUsb.freeTransfer( transfer );
+ mTransfers.remove( transfer );
+ break;
+ default:
+ /* unexpected error */
+ mLog.error( "transfer error [" +
+ getTransferStatus( transfer.status() ) +
+ "] transferred actual: " + transfer.actualLength() );
+ }
+ }
+
+ private void cancel()
+ {
+ for( Transfer transfer: mTransfers )
+ {
+ LibUsb.cancelTransfer( transfer );
+ }
+
+ ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
+
+ int result = LibUsb.handleEventsTimeoutCompleted(
+ null, TIMEOUT_US, completed.asIntBuffer() );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "error handling usb events during cancel [" +
+ LibUsb.errorName( result ) + "]" );
+ }
+ }
+
+ /**
+ * Prepares (allocates) a set of transfer buffers for use in
+ * transferring data from the tuner via the bulk interface
+ */
+ private void prepareTransfers() throws LibUsbException
+ {
+ mTransfers = new ArrayList();
+
+ for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
+ {
+ Transfer transfer = LibUsb.allocTransfer();
+
+ if( transfer == null )
+ {
+ throw new LibUsbException( "couldn't allocate transfer",
+ LibUsb.ERROR_NO_MEM );
+ }
+
+ final ByteBuffer buffer =
+ ByteBuffer.allocateDirect( mBufferSize );
+
+ LibUsb.fillBulkTransfer( transfer,
+ mDeviceHandle,
+ USB_ENDPOINT,
+ buffer,
+ BufferProcessor.this,
+ "Buffer #" + x,
+ TIMEOUT_US );
+
+ mTransfers.add( transfer );
+ }
+ }
}
/**
- * Fetches received UsbIrp buffers from the received queue, dispatches them
- * and resubmits the processed buffer for more samples
+ * Fetches byte[] chunks from the raw sample buffer. Converts each byte
+ * array and broadcasts the array to all registered listeners
*/
public class BufferDispatcher implements Runnable
{
@Override
public void run()
{
- ArrayList buffers = new ArrayList();
+ ArrayList buffers = new ArrayList();
- mReceivedBuffers.drainTo( buffers );
-
- for( UsbIrp buffer: buffers )
+ mFilledBuffers.drainTo( buffers );
+
+ for( byte[] buffer: buffers )
{
- Float[] samples = mSampleAdapter.convert( buffer.getData() );
+ //TODO: convert this to float primitive
+ Float[] samples = mSampleAdapter.convert( buffer );
broadcast( samples );
-
- if( mBufferProcessor != null && mBufferProcessor.isRunning() )
- {
- try
- {
- /* We adjust the buffer size according to sample rate.
- * If this byte array matches the current buffer size
- * then we reuse the byte array, otherwise create a
- * new one. */
- if( buffer.getData().length == mBufferSize )
- {
- mUSBPipe.asyncSubmit( buffer.getData() );
- }
- else
- {
- mUSBPipe.asyncSubmit( new byte[ mBufferSize ] );
- }
- }
- catch ( UsbNotActiveException | UsbNotOpenException
- | IllegalArgumentException | UsbDisconnectedException
- | UsbException e )
- {
- mLog.error( "error submitting a byte array to the usb "
- + "pipe for samples", e );
- }
- }
}
}
}
+
+ public static String getTransferStatus( int status )
+ {
+ switch( status )
+ {
+ case 0:
+ return "TRANSFER COMPLETED (0)";
+ case 1:
+ return "TRANSFER ERROR (1)";
+ case 2:
+ return "TRANSFER TIMED OUT (2)";
+ case 3:
+ return "TRANSFER CANCELLED (3)";
+ case 4:
+ return "TRANSFER STALL (4)";
+ case 5:
+ return "TRANSFER NO DEVICE (5)";
+ case 6:
+ return "TRANSFER OVERFLOW (6)";
+ default:
+ return "UNKNOWN TRANSFER STATUS (" + status + ")";
+ }
+ }
}
diff --git a/src/source/tuner/rtl/RTL2832Tuner.java b/src/source/tuner/rtl/RTL2832Tuner.java
index a72a0312..0e70a26b 100644
--- a/src/source/tuner/rtl/RTL2832Tuner.java
+++ b/src/source/tuner/rtl/RTL2832Tuner.java
@@ -20,10 +20,10 @@ package source.tuner.rtl;
import java.util.concurrent.RejectedExecutionException;
import javax.swing.JPanel;
-import javax.usb.UsbException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.LibUsbException;
import sample.Listener;
import source.SourceException;
@@ -59,6 +59,11 @@ public class RTL2832Tuner extends Tuner
mController.addListener( (FrequencyChangeListener)this );
}
+ public void dispose()
+ {
+ //TODO: dispose of something here
+ }
+
public RTL2832TunerController getController()
{
return mController;
@@ -115,7 +120,7 @@ public class RTL2832Tuner extends Tuner
{
mController.setSampleRate( sampleRate );
}
- catch( UsbException e )
+ catch( LibUsbException e )
{
throw new SourceException( "RTL2832 Tuner - error setting "
+ "sample rate", e );
@@ -139,7 +144,18 @@ public class RTL2832Tuner extends Tuner
throws RejectedExecutionException,
SourceException
{
- return mController.getChannel( threadPoolManager, this, channel );
+ TunerChannelSource source = null;
+
+ try
+ {
+ source = mController.getChannel( threadPoolManager, this, channel );
+ }
+ catch( Exception e )
+ {
+ mLog.error( "couldn't provide source channel", e );
+ }
+
+ return source;
}
/**
* Releases the tuned channel so that the tuner controller can tune to
diff --git a/src/source/tuner/rtl/RTL2832TunerController.java b/src/source/tuner/rtl/RTL2832TunerController.java
index 0ea89eb1..51eee6cd 100644
--- a/src/source/tuner/rtl/RTL2832TunerController.java
+++ b/src/source/tuner/rtl/RTL2832TunerController.java
@@ -21,6 +21,8 @@
******************************************************************************/
package source.tuner.rtl;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -36,27 +38,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.JPanel;
-import javax.usb.UsbClaimException;
-import javax.usb.UsbConfiguration;
-import javax.usb.UsbControlIrp;
-import javax.usb.UsbDevice;
import javax.usb.UsbDisconnectedException;
-import javax.usb.UsbEndpoint;
import javax.usb.UsbException;
-import javax.usb.UsbInterface;
-import javax.usb.UsbInterfacePolicy;
-import javax.usb.UsbIrp;
-import javax.usb.UsbNotActiveException;
-import javax.usb.UsbNotOpenException;
-import javax.usb.UsbPipe;
-import javax.usb.event.UsbPipeDataEvent;
-import javax.usb.event.UsbPipeErrorEvent;
-import javax.usb.event.UsbPipeListener;
-import javax.usb.util.DefaultUsbControlIrp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
+import org.usb4java.DeviceHandle;
import org.usb4java.LibUsb;
+import org.usb4java.LibUsbException;
+import org.usb4java.Transfer;
+import org.usb4java.TransferCallback;
import sample.Listener;
import source.SourceException;
@@ -64,7 +57,6 @@ import source.tuner.FrequencyChangeEvent;
import source.tuner.FrequencyChangeEvent.Attribute;
import source.tuner.TunerController;
import source.tuner.TunerType;
-import source.tuner.usb.USBTunerDevice;
import util.TimeStamp;
import buffer.FloatAveragingBuffer;
import controller.ResourceManager;
@@ -74,60 +66,26 @@ public abstract class RTL2832TunerController extends TunerController
private final static Logger mLog =
LoggerFactory.getLogger( RTL2832TunerController.class );
- public final static int sINT_NULL_VALUE = -1;
- public final static long sLONG_NULL_VALUE = -1l;
- public final static double sDOUBLE_NULL_VALUE = -1.0D;
+ public final static int INT_NULL_VALUE = -1;
+ public final static long LONG_NULL_VALUE = -1l;
+ public final static double DOUBLE_NULL_VALUE = -1.0D;
+ public final static int TWO_TO_22_POWER = 4194304;
- public final static byte sUSB_INTERFACE = (byte)0x0;
- public final static byte sUSB_ENDPOINT = (byte)0x81;
- public final static boolean sUSB_FORCE_CLAIM_INTERFACE = true;
-
- public final static byte sREQUEST_TYPE_IN =
+ public final static byte USB_INTERFACE = (byte)0x0;
+ public final static byte BULK_ENDPOINT_IN = (byte)0x81;
+ public final static byte CONTROL_ENDPOINT_IN =
(byte)( LibUsb.ENDPOINT_IN | LibUsb.REQUEST_TYPE_VENDOR );
- public final static byte sREQUEST_TYPE_OUT =
+ public final static byte CONTROL_ENDPOINT_OUT =
(byte)( LibUsb.ENDPOINT_OUT | LibUsb.REQUEST_TYPE_VENDOR );
- public final static byte sREQUEST_ZERO = (byte)0;
+
+ public final static long TIMEOUT_US = 1000000l; //uSeconds
+
+ public final static byte REQUEST_ZERO = (byte)0;
- public final static int sUSB_IRP_POOL_SIZE = 10;
+ public final static int TRANSFER_BUFFER_POOL_SIZE = 16;
public final static byte EEPROM_ADDRESS = (byte)0xA0;
- public final static byte BIT_0 = (byte)0x01;
- public final static byte BIT_1 = (byte)0x02;
- public final static byte BIT_2 = (byte)0x04;
- public final static byte BIT_3 = (byte)0x08;
- public final static byte BIT_4 = (byte)0x10;
- public final static byte BIT_5 = (byte)0x20;
- public final static byte BIT_6 = (byte)0x40;
- public final static byte BIT_7 = (byte)0x80;
-
- public final static byte E4K_I2C_ADDRESS = (byte)0xC8;
- public final static byte E4K_CHECK_ADDRESS = (byte)0x02;
- public final static byte E4K_CHECK_VALUE = (byte)0x40;
-
- public final static byte FC0012_I2C_ADDRESS = (byte)0xC6;
- public final static byte FC0012_CHECK_ADDRESS = (byte)0x00;
- public final static byte FC0012_CHECK_VALUE = (byte)0xA1;
-
- public final static byte FC0013_I2C_ADDRESS = (byte)0xC6;
- public final static byte FC0013_CHECK_ADDRESS = (byte)0x00;
- public final static byte FC0013_CHECK_VALUE = (byte)0xA3;
-
- public final static byte FC2580_I2C_ADDRESS = (byte)0xAC;
- public final static byte FC2580_CHECK_ADDRESS = (byte)0x01;
- public final static byte FC2580_CHECK_VALUE = (byte)0x56;
-
- public final static byte R820T_I2C_ADDRESS = (byte)0x34;
- public final static byte R820T_CHECK_ADDRESS = (byte)0x00;
- public final static byte R820T_CHECK_VALUE = (byte)0x69;
-
- public final static byte R828D_I2C_ADDRESS = (byte)0x74;
- public final static byte R828D_CHECK_ADDRESS = (byte)0x00;
- public final static byte R828D_CHECK_VALUE = (byte)0x69;
-
- public static final int sMIN_OSCILLATOR_FREQUENCY = 28799000;
- public static final int sMAX_OSCILLATOR_FREQUENCY = 28801000;
-
public final static byte[] sFIR_COEFFICIENTS =
{
(byte)0xCA, (byte)0xDC, (byte)0xD7, (byte)0xD8, (byte)0xE0,
@@ -136,22 +94,14 @@ public abstract class RTL2832TunerController extends TunerController
(byte)0x71, (byte)0x74, (byte)0x19, (byte)0x41, (byte)0xA5
};
- private static final DecimalFormat mDecimalFormatter =
- new DecimalFormat( "###,###,###.0" );
- private static final DecimalFormat mPercentFormatter =
- new DecimalFormat( "###.00" );
-
- private USBTunerDevice mUSBTunerDevice;
- protected UsbDevice mUSBDevice;
- private UsbConfiguration mUSBConfiguration;
- protected UsbInterface mUSBInterface;
- private UsbPipe mUSBPipe;
- private Descriptor mDescriptor;
+ public static final SampleRate DEFAULT_SAMPLE_RATE =
+ SampleRate.RATE_0_960MHZ;
- public static final int sTWO_TO_22_POWER = 4194304;
- public static final SampleRate sDEFAULT_SAMPLE_RATE = SampleRate.RATE_0_960MHZ;
+ protected Device mDevice;
+ protected DeviceDescriptor mDeviceDescriptor;
+ protected DeviceHandle mDeviceHandle;
- private SampleRate mSampleRate = sDEFAULT_SAMPLE_RATE;
+ private SampleRate mSampleRate = DEFAULT_SAMPLE_RATE;
private BufferProcessor mBufferProcessor = new BufferProcessor();
@@ -160,64 +110,58 @@ public abstract class RTL2832TunerController extends TunerController
private CopyOnWriteArrayList> mSampleListeners =
new CopyOnWriteArrayList>();
- private LinkedTransferQueue mRawSampleBuffer =
+ private LinkedTransferQueue mFilledBuffers =
new LinkedTransferQueue();
- private AtomicInteger mSampleCounter = new AtomicInteger();
- private double mSampleRateAverageSum;
- private int mSampleRateAverageCount;
- protected int mOscillatorFrequency = 28800000; //28.8 MHz
-
+
private SampleRateMonitor mSampleRateMonitor;
- public int mBufferSize = 16384;
+ private AtomicInteger mSampleCounter = new AtomicInteger();
+ private double mSampleRateAverageSum;
+ private int mSampleRateAverageCount;
+ private static final DecimalFormat mDecimalFormatter =
+ new DecimalFormat( "###,###,###.0" );
+ private static final DecimalFormat mPercentFormatter =
+ new DecimalFormat( "###.00" );
+
+ protected int mOscillatorFrequency = 28800000; //28.8 MHz
+ public int mBufferSize = 131072;
+
+ protected Descriptor mDescriptor;
/**
* Abstract tuner controller device. Use the static getTunerClass() method
* to determine the tuner type, and construct the corresponding child
* tuner controller class for that tuner type.
*/
- public RTL2832TunerController( USBTunerDevice tunerDevice,
+ public RTL2832TunerController( Device device,
+ DeviceDescriptor deviceDescriptor,
long minTunableFrequency,
long maxTunableFrequency ) throws SourceException
{
super( minTunableFrequency, maxTunableFrequency );
- mUSBTunerDevice = tunerDevice;
- mUSBDevice = tunerDevice.getDevice();
- mUSBConfiguration = mUSBDevice.getActiveUsbConfiguration();
- mUSBInterface = mUSBConfiguration.getUsbInterface( sUSB_INTERFACE );
-
- try
- {
- if( claim( mUSBInterface ) )
- {
- /* Get the USB endpoint */
- UsbEndpoint endpoint = mUSBInterface.getUsbEndpoint( sUSB_ENDPOINT );
- mUSBPipe = endpoint.getUsbPipe();
- }
- else
- {
- throw new SourceException( "RTL2832 Tuner Controller - couldn't "
- + "claim USB interface" );
- }
- }
- catch( UsbException e )
- {
- throw new SourceException( "RTL2832 Tuner Controller - couldn't "
- + "claim USB interface or get endpoint or pipe", e );
- }
- catch ( UsbDisconnectedException e )
- {
- throw new SourceException( "RTL2832 Tuner Controller - usb device "
- + "is disconnected", e );
- }
-
+ mDevice = device;
+ mDeviceDescriptor = deviceDescriptor;
}
public void init() throws SourceException
{
+ mDeviceHandle = new DeviceHandle();
+
+ int result = LibUsb.open( mDevice, mDeviceHandle );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mDeviceHandle = null;
+
+ throw new SourceException( "libusb couldn't open RTL2832 usb "
+ + "device [" + LibUsb.errorName( result ) + "]" );
+ }
+
+ claimInterface( mDeviceHandle );
+
try
{
- setSampleRate( sDEFAULT_SAMPLE_RATE );
+ setSampleRate( DEFAULT_SAMPLE_RATE );
}
catch( Exception e )
{
@@ -230,7 +174,7 @@ public abstract class RTL2832TunerController extends TunerController
try
{
/* Read the contents of the 256-byte EEPROM */
- eeprom = readEEPROM( mUSBDevice, (short)0, 256 );
+ eeprom = readEEPROM( mDeviceHandle, (short)0, 256 );
}
catch( Exception e )
{
@@ -254,6 +198,57 @@ public abstract class RTL2832TunerController extends TunerController
( eeprom == null ? "[null]" : Arrays.toString( eeprom )), e );
}
}
+
+ /**
+ * Claims the USB interface. Attempts to detach the active kernel driver
+ * if one is currently attached.
+ */
+ public static void claimInterface( DeviceHandle handle ) throws SourceException
+ {
+ if( handle != null )
+ {
+ int result = LibUsb.kernelDriverActive( handle, USB_INTERFACE );
+
+ if( result == 1 )
+ {
+ result = LibUsb.detachKernelDriver( handle, USB_INTERFACE );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "failed attempt to detach kernel driver [" +
+ LibUsb.errorName( result ) + "]" );
+
+ throw new SourceException( "couldn't detach kernel driver "
+ + "from device" );
+ }
+ }
+
+ result = LibUsb.claimInterface( handle, USB_INTERFACE );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ throw new SourceException( "couldn't claim usb interface [" +
+ LibUsb.errorName( result ) + "]" );
+ }
+ }
+ else
+ {
+ throw new SourceException( "couldn't claim usb interface - no "
+ + "device handle" );
+ }
+ }
+
+ public static void releaseInterface( DeviceHandle handle )
+ throws SourceException
+ {
+ int result = LibUsb.releaseInterface( handle, USB_INTERFACE );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ throw new SourceException( "couldn't release interface [" +
+ LibUsb.errorName( result ) + "]" );
+ }
+ }
/**
* Descriptor contains all identifiers and labels parsed from the EEPROM.
@@ -272,28 +267,7 @@ public abstract class RTL2832TunerController extends TunerController
return null;
}
-// public void start()
-// {
-// if( !mBufferProcessor.isRunning() )
-// {
-// try
-// {
-// resetUSBBuffer();
-//
-// /* Open the USB pipe */
-// openPipe();
-//
-// mBufferProcessor.start();
-// }
-// catch ( UsbException e )
-// {
-// Log.error( "RTL2832TunerController - error starting sample "
-// + "buffer processor - " + e.getLocalizedMessage() );
-// }
-// }
-// }
-
- public void setSamplingMode( SampleMode mode ) throws UsbException
+ public void setSamplingMode( SampleMode mode ) throws LibUsbException
{
switch( mode )
{
@@ -302,56 +276,54 @@ public abstract class RTL2832TunerController extends TunerController
setIFFrequency( 0 );
/* Enable I/Q ADC Input */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ZERO,
(short)0x08,
(short)0xCD,
1 );
/* Enable zero-IF mode */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0xB1,
(short)0x1B,
1 );
/* Set default i/q path */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ZERO,
(short)0x06,
(short)0x80,
1 );
break;
case DIRECT:
- //TODO: add code for direct sampling
- break;
default:
- break;
-
+ throw new LibUsbException( "QUADRATURE mode is the only mode "
+ + "currently supported", LibUsb.ERROR_NOT_SUPPORTED );
}
}
- public void setIFFrequency( int frequency ) throws UsbException
+ public void setIFFrequency( int frequency ) throws LibUsbException
{
- long ifFrequency = ( (long)sTWO_TO_22_POWER * (long)frequency ) /
+ long ifFrequency = ( (long)TWO_TO_22_POWER * (long)frequency ) /
(long)mOscillatorFrequency * -1;
/* Write byte 2 (high) */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0x19,
(short)( Long.rotateRight( ifFrequency, 16 ) & 0x3F ),
1 );
/* Write byte 1 (middle) */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0x1A,
(short)( Long.rotateRight( ifFrequency, 8 ) & 0xFF ),
1 );
/* Write byte 0 (low) */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0x1B,
(short)( ifFrequency & 0xFF ),
@@ -377,7 +349,7 @@ public abstract class RTL2832TunerController extends TunerController
else
{
int serial =
- ( 0xFF & mUSBDevice.getUsbDeviceDescriptor().iSerialNumber() );
+ ( 0xFF & mDeviceDescriptor.iSerialNumber() );
return "SER#" + serial;
}
@@ -385,74 +357,118 @@ public abstract class RTL2832TunerController extends TunerController
public abstract JPanel getEditor( ResourceManager resourceManager );
- public abstract void setSampleRateFilters( int sampleRate ) throws UsbException;
+ public abstract void setSampleRateFilters( int sampleRate )
+ throws SourceException;
public abstract TunerType getTunerType();
- public static TunerType identifyTunerType( USBTunerDevice tunerDevice )
+ public static TunerType identifyTunerType( Device device )
+ throws SourceException
{
+ DeviceHandle handle = new DeviceHandle();
+
+ int reason = LibUsb.open( device, handle );
+
+ if( reason != LibUsb.SUCCESS )
+ {
+ throw new SourceException( "couldn't open device - check permissions"
+ + " (udev.rule) [" + LibUsb.errorName( reason ) + "]" );
+ }
+
TunerType tunerClass = TunerType.UNKNOWN;
try
{
- UsbDevice device = tunerDevice.getDevice();
- UsbConfiguration config = device.getActiveUsbConfiguration();
- UsbInterface iface = config.getUsbInterface( sUSB_INTERFACE );
+ claimInterface( handle );
- if( claim( iface ) )
+ /* Perform a dummy write to see if the device needs reset */
+ boolean resetRequired = false;
+
+ try
{
- mLog.debug( "usb interface claimed" );
-
- /* Perform a dummy write to see if the device needs reset */
- writeRegister( device, Block.USB, Address.USB_SYSCTL.getAddress(), 0x09, 1 );
-
- mLog.debug( "initializing baseband" );
-
- /* Initialize the baseband */
- initBaseband( device );
-
- mLog.debug( "enabling I2C repeater" );
-
- enableI2CRepeater( device, true );
-
- boolean controlI2CRepeater = false;
-
- mLog.debug( "testing for tuner types" );
-
- /* Test for each tuner type until we find the correct one */
- if( isE4000Tuner( device, controlI2CRepeater ) )
- {
- tunerClass = TunerType.ELONICS_E4000;
- }
- else if( isFC0013Tuner( device, controlI2CRepeater ) )
- {
- tunerClass = TunerType.FITIPOWER_FC0013;
- }
- else if( isR820TTuner( device, controlI2CRepeater ) )
- {
- tunerClass = TunerType.RAFAELMICRO_R820T;
- }
- else if( isR828DTuner( device, controlI2CRepeater ) )
- {
- tunerClass = TunerType.RAFAELMICRO_R828D;
- }
- else if( isFC2580Tuner( device, controlI2CRepeater ) )
- {
- tunerClass = TunerType.FCI_FC2580;
- }
- else if( isFC0012Tuner( device, controlI2CRepeater ) )
- {
- tunerClass = TunerType.FITIPOWER_FC0012;
- }
-
- mLog.debug( "disabling I2C repeater -- detected tuner type:" + tunerClass.toString() );
-
- enableI2CRepeater( device, false );
-
- mLog.debug( "releasing USB interface" );
-
- iface.release();
+ writeRegister( handle,
+ Block.USB,
+ Address.USB_SYSCTL.getAddress(),
+ 0x09,
+ 1 );
}
+ catch( LibUsbException e )
+ {
+
+ if( e.getErrorCode() < 0 )
+ {
+ mLog.error( "error performing dummy write - attempting "
+ + "device reset", e );
+
+ resetRequired = true;
+ }
+ else
+ {
+ throw new SourceException( "error performing dummy write "
+ + "to device [" + LibUsb.errorName(
+ e.getErrorCode() ) + "]", e );
+ }
+ }
+
+ if( resetRequired )
+ {
+ reason = LibUsb.resetDevice( handle );
+
+ try
+ {
+ writeRegister( handle,
+ Block.USB,
+ Address.USB_SYSCTL.getAddress(),
+ 0x09,
+ 1 );
+ }
+ catch( LibUsbException e2 )
+ {
+ mLog.error( "device reset attempted, but lost device handle. "
+ + "Try restarting the application to use this device" );
+
+ throw new SourceException( "couldn't reset device" );
+ }
+ }
+
+ /* Initialize the baseband */
+ initBaseband( handle );
+
+ enableI2CRepeater( handle, true );
+
+ boolean controlI2CRepeater = false;
+
+ /* Test for each tuner type until we find the correct one */
+ if( isTuner( TunerTypeCheck.E4K, handle, controlI2CRepeater ) )
+ {
+ tunerClass = TunerType.ELONICS_E4000;
+ }
+ else if( isTuner( TunerTypeCheck.FC0013, handle, controlI2CRepeater ) )
+ {
+ tunerClass = TunerType.FITIPOWER_FC0013;
+ }
+ else if( isTuner( TunerTypeCheck.R820T, handle, controlI2CRepeater ) )
+ {
+ tunerClass = TunerType.RAFAELMICRO_R820T;
+ }
+ else if( isTuner( TunerTypeCheck.R828D, handle, controlI2CRepeater ) )
+ {
+ tunerClass = TunerType.RAFAELMICRO_R828D;
+ }
+ else if( isTuner( TunerTypeCheck.FC2580, handle, controlI2CRepeater ) )
+ {
+ tunerClass = TunerType.FCI_FC2580;
+ }
+ else if( isTuner( TunerTypeCheck.FC0012, handle, controlI2CRepeater ) )
+ {
+ tunerClass = TunerType.FITIPOWER_FC0012;
+ }
+
+ enableI2CRepeater( handle, false );
+
+ releaseInterface( handle );
+
+ LibUsb.close( handle );
}
catch( Exception e )
{
@@ -462,88 +478,6 @@ public abstract class RTL2832TunerController extends TunerController
return tunerClass;
}
- public USBTunerDevice getUSBTunerDevice()
- {
- return mUSBTunerDevice;
- }
-
-// protected void openPipe() throws UsbException, UsbClaimException
-// {
-// /* Get the USB endpoint */
-// UsbEndpoint endpoint = mUSBInterface.getUsbEndpoint( sUSB_ENDPOINT );
-//
-// /* Get the pipe from the endpoint */
-// if( endpoint != null )
-// {
-// mUSBPipe = endpoint.getUsbPipe();
-//
-// if( mUSBPipe != null )
-// {
-// if( !mUSBPipe.isOpen() )
-// {
-// try
-// {
-// resetUSBBuffer();
-//
-// mUSBPipe.open();
-// }
-// catch( Exception e )
-// {
-// Log.error( "RTL2832 Tuner Controller - exception while " +
-// "opening the endpoint pipe." +
-// e.getLocalizedMessage() );
-// }
-// }
-// }
-// else
-// {
-// Log.error( "RTL2832 Tuner Controller - returned endpoint "
-// + "OUT pipe is null" );
-// }
-// }
-// }
-//
- /**
- * Claims the USB interface. If another application currently has
- * the interface claimed, the sFCD_FORCE_CLAIM_HID_INTERFACE setting
- * will dictate if the interface is forcibly claimed from the other
- * application
- */
- public static boolean claim( UsbInterface iface ) throws UsbException,
- UsbClaimException
- {
- if( !iface.isClaimed() )
- {
- iface.claim( new UsbInterfacePolicy()
- {
- @Override
- public boolean forceClaim( UsbInterface arg0 )
- {
- return sUSB_FORCE_CLAIM_INTERFACE;
- }
- } );
-
- return iface.isClaimed();
- }
- else
- {
- mLog.error( "attempt to claim USB interface failed - in use by "
- + "another application" );
- }
-
- return false;
- }
-
- /**
- * Releases the claimed USB interface
- */
- private void closePipe() throws UsbException
- {
- mBufferProcessor.stop();
-
- mUSBPipe.close();
- }
-
/**
* Releases the USB interface
*/
@@ -556,12 +490,9 @@ public abstract class RTL2832TunerController extends TunerController
mBufferProcessor.stop();
}
- if( mUSBPipe.isOpen() )
- {
- mUSBPipe.close();
- }
-
- mUSBInterface.release();
+ LibUsb.releaseInterface( mDeviceHandle, USB_INTERFACE );
+
+ LibUsb.exit( null );
}
catch ( Exception e )
{
@@ -569,44 +500,43 @@ public abstract class RTL2832TunerController extends TunerController
}
}
- public void resetUSBBuffer() throws UsbException
+ public void resetUSBBuffer() throws LibUsbException
{
- writeRegister( mUSBDevice, Block.USB, Address.USB_EPA_CTL.getAddress(), 0x1002, 2 );
- writeRegister( mUSBDevice, Block.USB, Address.USB_EPA_CTL.getAddress(), 0x0000, 2 );
+ writeRegister( mDeviceHandle, Block.USB, Address.USB_EPA_CTL.getAddress(), 0x1002, 2 );
+ writeRegister( mDeviceHandle, Block.USB, Address.USB_EPA_CTL.getAddress(), 0x0000, 2 );
}
- public static void initBaseband( UsbDevice device )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ public static void initBaseband( DeviceHandle handle ) throws LibUsbException
{
/* Initialize USB */
- writeRegister( device, Block.USB, Address.USB_SYSCTL.getAddress(), 0x09, 1 );
- writeRegister( device, Block.USB, Address.USB_EPA_MAXPKT.getAddress(), 0x0002, 2 );
- writeRegister( device, Block.USB, Address.USB_EPA_CTL.getAddress(), 0x1002, 2 );
+ writeRegister( handle, Block.USB, Address.USB_SYSCTL.getAddress(), 0x09, 1 );
+ writeRegister( handle, Block.USB, Address.USB_EPA_MAXPKT.getAddress(), 0x0002, 2 );
+ writeRegister( handle, Block.USB, Address.USB_EPA_CTL.getAddress(), 0x1002, 2 );
/* Power on demod */
- writeRegister( device, Block.SYS, Address.DEMOD_CTL_1.getAddress(), 0x22, 1 );
- writeRegister( device, Block.SYS, Address.DEMOD_CTL.getAddress(), 0xE8, 1 );
+ writeRegister( handle, Block.SYS, Address.DEMOD_CTL_1.getAddress(), 0x22, 1 );
+ writeRegister( handle, Block.SYS, Address.DEMOD_CTL.getAddress(), 0xE8, 1 );
/* Reset demod */
- writeDemodRegister( device, Page.ONE, (short)0x01, 0x14, 1 ); //Bit 3 = soft reset
- writeDemodRegister( device, Page.ONE, (short)0x01, 0x10, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x01, 0x14, 1 ); //Bit 3 = soft reset
+ writeDemodRegister( handle, Page.ONE, (short)0x01, 0x10, 1 );
/* Disable spectrum inversion and adjacent channel rejection */
- writeDemodRegister( device, Page.ONE, (short)0x15, 0x00, 1 );
- writeDemodRegister( device, Page.ONE, (short)0x16, 0x0000, 2 );
+ writeDemodRegister( handle, Page.ONE, (short)0x15, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x16, 0x0000, 2 );
/* Clear DDC shift and IF frequency registers */
- writeDemodRegister( device, Page.ONE, (short)0x16, 0x00, 1 );
- writeDemodRegister( device, Page.ONE, (short)0x17, 0x00, 1 );
- writeDemodRegister( device, Page.ONE, (short)0x18, 0x00, 1 );
- writeDemodRegister( device, Page.ONE, (short)0x19, 0x00, 1 );
- writeDemodRegister( device, Page.ONE, (short)0x1A, 0x00, 1 );
- writeDemodRegister( device, Page.ONE, (short)0x1B, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x16, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x17, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x18, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x19, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x1A, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x1B, 0x00, 1 );
/* Set FIR coefficients */
for( int x = 0; x < sFIR_COEFFICIENTS.length; x++ )
{
- writeDemodRegister( device,
+ writeDemodRegister( handle,
Page.ONE,
(short)( 0x1C + x ),
sFIR_COEFFICIENTS[ x ],
@@ -614,47 +544,43 @@ public abstract class RTL2832TunerController extends TunerController
}
/* Enable SDR mode, disable DAGC (bit 5) */
- writeDemodRegister( device, Page.ZERO, (short)0x19, 0x05, 1 );
+ writeDemodRegister( handle, Page.ZERO, (short)0x19, 0x05, 1 );
/* Init FSM state-holding register */
- writeDemodRegister( device, Page.ONE, (short)0x93, 0xF0, 1 );
- writeDemodRegister( device, Page.ONE, (short)0x94, 0x0F, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x93, 0xF0, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x94, 0x0F, 1 );
/* Disable AGC (en_dagc, bit 0) (seems to have no effect) */
- writeDemodRegister( device, Page.ONE, (short)0x11, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x11, 0x00, 1 );
/* Disable RF and IF AGC loop */
- writeDemodRegister( device, Page.ONE, (short)0x04, 0x00, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0x04, 0x00, 1 );
/* Disable PID filter */
- writeDemodRegister( device, Page.ZERO, (short)0x61, 0x60, 1 );
+ writeDemodRegister( handle, Page.ZERO, (short)0x61, 0x60, 1 );
/* opt_adc_iq = 0, default ADC_I/ADC_Q datapath */
- writeDemodRegister( device, Page.ZERO, (short)0x06, 0x80, 1 );
+ writeDemodRegister( handle, Page.ZERO, (short)0x06, 0x80, 1 );
/* Enable Zero-if mode (en_bbin bit),
* DC cancellation (en_dc_est),
* IQ estimation/compensation (en_iq_comp, en_iq_est) */
- writeDemodRegister( device, Page.ONE, (short)0xB1, 0x1B, 1 );
+ writeDemodRegister( handle, Page.ONE, (short)0xB1, 0x1B, 1 );
/* Disable 4.096 MHz clock output on pin TP_CK0 */
- writeDemodRegister( device, Page.ZERO, (short)0x0D, 0x83, 1 );
+ writeDemodRegister( handle, Page.ZERO, (short)0x0D, 0x83, 1 );
}
- protected void deinitBaseband( UsbDevice device )
+ protected void deinitBaseband( DeviceHandle handle )
throws IllegalArgumentException, UsbDisconnectedException, UsbException
{
-// setI2CRepeater( device, true );
-
- writeRegister( device, Block.SYS, Address.DEMOD_CTL.getAddress(), 0x20, 1);
-
-// setI2CRepeater( device, false );
+ writeRegister( handle, Block.SYS, Address.DEMOD_CTL.getAddress(), 0x20, 1);
}
/**
* Sets the General Purpose Input/Output (GPIO) register bit
*
- * @param device - USB tuner device
+ * @param handle - USB tuner device
* @param bitMask - bit mask with one for targeted register bits and zero
* for the non-targeted register bits
* @param enabled - true to set the bit and false to clear the bit
@@ -662,11 +588,12 @@ public abstract class RTL2832TunerController extends TunerController
* @throws UsbException - if there is a USB error while communicating with
* the device
*/
- protected static void setGPIOBit( UsbDevice device, byte bitMask, boolean enabled )
- throws UsbDisconnectedException, UsbException
+ protected static void setGPIOBit( DeviceHandle handle,
+ byte bitMask,
+ boolean enabled ) throws LibUsbException
{
//Get current register value
- int value = readRegister( device, Block.SYS, Address.GPO.getAddress(), 1 );
+ int value = readRegister( handle, Block.SYS, Address.GPO.getAddress(), 1 );
//Update the masked bits
if( enabled )
@@ -679,36 +606,37 @@ public abstract class RTL2832TunerController extends TunerController
}
//Write the change back to the device
- writeRegister( device, Block.SYS, Address.GPO.getAddress(), value, 1 );
+ writeRegister( handle, Block.SYS, Address.GPO.getAddress(), value, 1 );
}
/**
* Enables GPIO Output
- * @param device - usb tuner device
+ * @param handle - usb tuner device
* @param bitMask - mask containing one bit value in targeted bit field(s)
* @throws UsbDisconnectedException
* @throws UsbException
*/
- protected static void setGPIOOutput( UsbDevice device, byte bitMask )
- throws UsbDisconnectedException, UsbException
+ protected static void setGPIOOutput( DeviceHandle handle, byte bitMask )
+ throws LibUsbException
{
//Get current register value
- int value = readRegister( device, Block.SYS, Address.GPD.getAddress(), 1 );
+ int value = readRegister( handle, Block.SYS, Address.GPD.getAddress(), 1 );
//Mask the value and rewrite it
- writeRegister( device, Block.SYS, Address.GPO.getAddress(),
+ writeRegister( handle, Block.SYS, Address.GPO.getAddress(),
value & ~bitMask, 1 );
//Get current register value
- value = readRegister( device, Block.SYS, Address.GPOE.getAddress(), 1 );
+ value = readRegister( handle, Block.SYS, Address.GPOE.getAddress(), 1 );
//Mask the value and rewrite it
- writeRegister( device, Block.SYS, Address.GPOE.getAddress(),
+ writeRegister( handle, Block.SYS, Address.GPOE.getAddress(),
value | bitMask, 1 );
}
- protected static void enableI2CRepeater( UsbDevice device, boolean enabled )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static void enableI2CRepeater( DeviceHandle handle,
+ boolean enabled )
+ throws LibUsbException
{
Page page = Page.ONE;
short address = 1;
@@ -723,89 +651,91 @@ public abstract class RTL2832TunerController extends TunerController
value = 0x10; //OFF
}
- writeDemodRegister( device, page, address, value, 1 );
+ writeDemodRegister( handle, page, address, value, 1 );
}
- protected boolean isI2CRepeaterEnabled() throws UsbException
+ protected boolean isI2CRepeaterEnabled() throws SourceException
{
- int register = readDemodRegister( mUSBDevice, Page.ONE, (short)0x1, 1 );
+ int register = readDemodRegister( mDeviceHandle, Page.ONE, (short)0x1, 1 );
return register == 0x18;
}
- protected static int readI2CRegister( UsbDevice device,
+ protected static int readI2CRegister( DeviceHandle handle,
byte i2CAddress,
byte i2CRegister,
boolean controlI2CRepeater )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ throws LibUsbException
{
short address = (short)( i2CAddress & 0xFF );
- byte[] writeData = new byte[ 1 ];
- writeData[ 0 ] = i2CRegister;
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 1 );
+ buffer.put( i2CRegister );
+ buffer.rewind();
- byte[] readData = new byte[ 1 ];
+ ByteBuffer data = ByteBuffer.allocateDirect( 1 );
if( controlI2CRepeater )
{
- enableI2CRepeater( device, true );
+ enableI2CRepeater( handle, true );
- write( device, Block.IIC, address, writeData );
- read( device, Block.IIC, address, readData );
+ write( handle, address, Block.I2C, buffer );
+ read( handle, address, Block.I2C, data );
- enableI2CRepeater( device, false );
+ enableI2CRepeater( handle, false );
}
else
{
- write( device, Block.IIC, address, writeData );
- read( device, Block.IIC, address, readData );
+ write( handle, address, Block.I2C, buffer );
+ read( handle, address, Block.I2C, data );
}
-
- return (int)( readData[ 0 ] & 0xFF );
+
+ return (int)( data.get() & 0xFF );
}
- protected void writeI2CRegister( UsbDevice device,
+ protected void writeI2CRegister( DeviceHandle handle,
byte i2CAddress,
byte i2CRegister,
byte value,
- boolean controlI2CRepeater ) throws UsbException
+ boolean controlI2CRepeater ) throws LibUsbException
{
short address = (short)( i2CAddress & 0xFF );
- byte[] data = new byte[ 2 ];
-
- data[ 0 ] = i2CRegister;
- data[ 1 ] = value;
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 2 );
+ buffer.put( i2CRegister );
+ buffer.put( value );
+
+ buffer.rewind();
if( controlI2CRepeater )
{
- enableI2CRepeater( device, true );
- write( mUSBDevice, Block.IIC, address, data );
- enableI2CRepeater( device, false );
+ enableI2CRepeater( handle, true );
+ write( handle, address, Block.I2C, buffer );
+ enableI2CRepeater( handle, false );
}
else
{
- write( mUSBDevice, Block.IIC, address, data );
+ write( handle, address, Block.I2C, buffer );
}
}
- protected static void writeDemodRegister( UsbDevice device, Page page,
- short address, int value, int length )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static void writeDemodRegister( DeviceHandle handle,
+ Page page,
+ short address,
+ int value,
+ int length ) throws LibUsbException
{
- byte[] data;
+ ByteBuffer buffer = ByteBuffer.allocateDirect( length );
+ buffer.order( ByteOrder.BIG_ENDIAN );
if( length == 1 )
{
- data = new byte[ 1 ];
- data[0] = (byte)( value & 0xFF );
+ buffer.put( (byte)( value & 0xFF ) );
}
else if( length == 2 )
{
- data = new byte[ 2 ];
- data[1] = (byte)( value & 0xFF ); //LSB
- data[0] = (byte)( ( value >> 8 ) & 0xFF ); //MSB
+ buffer.putShort( (short)( value & 0xFFFF ) );
}
else
{
@@ -817,301 +747,224 @@ public abstract class RTL2832TunerController extends TunerController
short newAddress = (short)( address << 8 | 0x20 );
- write( device, newAddress, index, data );
+ write( handle, newAddress, index, buffer );
- readDemodRegister( device, Page.TEN, (short)1, length );
+ readDemodRegister( handle, Page.TEN, (short)1, length );
}
- protected static int readDemodRegister( UsbDevice device,
+ protected static int readDemodRegister( DeviceHandle handle,
Page page,
short address,
- int length )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ int length ) throws LibUsbException
{
short index = page.getPage();
short newAddress = (short)( ( address << 8 ) | 0x20 );
- byte[] empty = new byte[ 2 ];
- byte[] data = read( device, newAddress, index, empty );
+ ByteBuffer buffer = ByteBuffer.allocateDirect( length );
+
+ read( handle, newAddress, index, buffer );
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
if( length == 2 )
{
- return (int)( ( data[ 1 ] << 8 | data[ 0 ] ) & 0xFFFF );
+ return (int)( buffer.getShort() & 0xFFFF );
}
else
{
- return (int)( data[ 0 ] & 0xFF );
+ return (int)( buffer.get() & 0xFF );
}
}
- protected static void writeRegister( UsbDevice device, Block block, short address,
- int value, int length )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static void writeRegister( DeviceHandle handle,
+ Block block,
+ short address,
+ int value,
+ int length ) throws LibUsbException
{
- byte[] data;
+ ByteBuffer buffer = ByteBuffer.allocateDirect( length );
+ buffer.order( ByteOrder.BIG_ENDIAN );
if( length == 1 )
{
- data = new byte[ 1 ];
- data[0] = (byte)( value & 0xFF );
+ buffer.put( (byte)( value & 0xFF ) ) ;
}
else if( length == 2 )
{
- data = new byte[ 2 ];
- data[1] = (byte)( value & 0xFF ); //LSB
- data[0] = (byte)( ( value >> 8 ) & 0xFF ); //MSB
+ buffer.putShort( (short)value );
}
else
{
throw new IllegalArgumentException( "Cannot write value greater "
+ "than 16 bits to the register - length [" + length + "]" );
}
+
+ buffer.rewind();
- write( device, block, address, data );
+ write( handle, address, block, buffer );
}
- protected static int readRegister( UsbDevice device, Block block, short address, int length )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static int readRegister( DeviceHandle handle,
+ Block block,
+ short address,
+ int length ) throws LibUsbException
{
- byte[] empty = new byte[ 2 ];
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 2 );
- byte[] data = read( device, block, address, empty );
+ read( handle, address, block, buffer );
+
+ buffer.order( ByteOrder.LITTLE_ENDIAN );
if( length == 2 )
{
- return (int)( ( data[ 1 ] << 8 | data[ 0 ] ) & 0xFFFF );
+ return (int)( buffer.getShort() & 0xFFFF );
}
else
{
- return (int)( data[ 0 ] & 0xFF );
+ return (int)( buffer.get() & 0xFF );
}
}
/**
- * Write array convenience method. Allow you to specify the Block that you
- * are writing to.
- *
- * @param device
- * @param block
- * @param address
- * @param data
- * @throws IllegalArgumentException
- * @throws UsbDisconnectedException
- * @throws UsbException
*/
- protected static void write( UsbDevice device, Block block, short address, byte[] data )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static void write( DeviceHandle handle,
+ short address,
+ Block block,
+ ByteBuffer buffer ) throws LibUsbException
{
- write( device, address, block.getWriteIndex(), data );
+ write( handle, address, block.getWriteIndex(), buffer );
}
- /**
- * Write byte array
- * @param device - tuner
- * @param value -
- * @param index - start
- * @param data - to write
- * @throws IllegalArgumentException
- * @throws UsbDisconnectedException
- * @throws UsbException
- */
- protected static void write( UsbDevice device, short value, short index, byte[] data )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static void write( DeviceHandle handle,
+ short value,
+ short index,
+ ByteBuffer buffer ) throws LibUsbException
{
- UsbControlIrp irp =
- device.createUsbControlIrp( sREQUEST_TYPE_OUT,
- sREQUEST_ZERO,
- value,
- index );
+ if( handle != null )
+ {
+ int transferred = LibUsb.controlTransfer( handle,
+ CONTROL_ENDPOINT_OUT,
+ REQUEST_ZERO,
+ value,
+ index,
+ buffer,
+ TIMEOUT_US );
- irp.setData( data );
-
- device.syncSubmit( irp );
+ if( transferred < 0 )
+ {
+ throw new LibUsbException( "error writing byte buffer",
+ transferred );
+ }
+ else if( transferred != buffer.capacity() )
+ {
+ throw new LibUsbException( "transferred bytes [" +
+ transferred + "] is not what was expected [" +
+ buffer.capacity() + "]", transferred );
+ }
+ }
+ else
+ {
+ throw new LibUsbException( "device handle is null",
+ LibUsb.ERROR_NO_DEVICE );
+ }
}
+ /**
+ * Performs a control type read
+ */
+ protected static void read( DeviceHandle handle,
+ short address,
+ short index,
+ ByteBuffer buffer ) throws LibUsbException
+ {
+ if( handle != null )
+ {
+ int transferred = LibUsb.controlTransfer( handle,
+ CONTROL_ENDPOINT_IN,
+ REQUEST_ZERO,
+ address,
+ index,
+ buffer,
+ TIMEOUT_US );
+
+ if( transferred < 0 )
+ {
+ throw new LibUsbException( "read error", transferred );
+ }
+ else if( transferred != buffer.capacity() )
+ {
+ throw new LibUsbException( "transferred bytes [" +
+ transferred + "] is not what was expected [" +
+ buffer.capacity() + "]", transferred );
+ }
+ }
+ else
+ {
+ throw new LibUsbException( "device handle is null",
+ LibUsb.ERROR_NO_DEVICE );
+ }
+ }
+
/**
* Reads byte array from index at the address.
*
* @return big-endian byte array (needs to be swapped to be usable)
*
*/
- protected static byte[] read( UsbDevice device, Block block, short address, byte[] data )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static void read( DeviceHandle handle,
+ short address,
+ Block block,
+ ByteBuffer buffer ) throws LibUsbException
{
- byte[] retVal;
-
- retVal = read( device, address, block.getReadIndex(), data );
-
- return retVal;
+ read( handle, address, block.getReadIndex(), buffer );
}
/**
- * Reads the byte array from the index at the address with the length of the
- * read determined by the size of the data array
+ * Tests if the specified tuner type is contained in the usb tuner device.
*
- * @return - big-endian byte array (needs to be swapped to be usable)
+ * @param type - tuner type to test for
+ * @param handle - handle to the usb tuner device
+ * @param controlI2CRepeater - indicates if the method should control the
+ * I2C repeater independently
+ *
+ * @return - true if the device is the specified tuner type
*/
- protected static byte[] read( UsbDevice device, short address, short index, byte[] data )
- throws IllegalArgumentException, UsbDisconnectedException, UsbException
+ protected static boolean isTuner( TunerTypeCheck type,
+ DeviceHandle handle,
+ boolean controlI2CRepeater )
{
- DefaultUsbControlIrp irp =
- new DefaultUsbControlIrp( sREQUEST_TYPE_IN,
- (byte)0,
- address,
- index );
-
- irp.setData( data );
-
- device.syncSubmit( irp );
-
- return irp.getData();
- }
-
- protected static boolean isE4000Tuner( UsbDevice device,
- boolean controlI2CRepeater ) throws UsbClaimException
- {
- mLog.debug( "testing for E4000 tuner" );
-
try
{
- int value = readI2CRegister( device, E4K_I2C_ADDRESS,
- E4K_CHECK_ADDRESS, controlI2CRepeater );
+ if( type == TunerTypeCheck.FC0012 ||
+ type == TunerTypeCheck.FC2580 )
+ {
+ /* Initialize the GPIOs */
+ setGPIOOutput( handle, (byte)0x20 );
+
+ /* Reset tuner before probing */
+ setGPIOBit( handle, (byte)0x20, true );
+ setGPIOBit( handle, (byte)0x20, false );
+ }
- return ( value == E4K_CHECK_VALUE );
+ int value = readI2CRegister( handle, type.getI2CAddress(),
+ type.getCheckAddress(), controlI2CRepeater );
+
+ if( type == TunerTypeCheck.FC2580 )
+ {
+ return ( ( value & 0x7F ) == type.getCheckValue() );
+ }
+ else
+ {
+ return ( value == type.getCheckValue() );
+ }
}
- catch( UsbException e )
+ catch( LibUsbException e )
{
- //Do nothing ... it's not an E4000
+ //Do nothing ... it's not the specified tuner
}
return false;
}
-
- protected static boolean isFC0012Tuner( UsbDevice device,
- boolean controlI2CRepeater ) throws UsbClaimException
- {
- try
- {
- /* Initialize the GPIOs */
- setGPIOOutput( device, BIT_5 );
- /* Reset tuner before probing */
- setGPIOBit( device, BIT_5, true );
- setGPIOBit( device, BIT_5, false );
-
-
- int value = readI2CRegister( device,
- FC0012_I2C_ADDRESS,
- FC0012_CHECK_ADDRESS,
- controlI2CRepeater );
-
- return ( value == FC0012_CHECK_VALUE );
- }
- catch( UsbException e )
- {
- //Do nothing, it's not an FC0012
- }
-
- return false;
- }
-
- protected static boolean isFC0013Tuner( UsbDevice device,
- boolean controlI2CRepeater )
- throws UsbClaimException
- {
- mLog.debug( "testing for F0013 tuner" );
-
- try
- {
- int value = readI2CRegister( device, FC0013_I2C_ADDRESS,
- FC0013_CHECK_ADDRESS, controlI2CRepeater );
-
- return ( value == FC0013_CHECK_VALUE );
- }
- catch( UsbException e )
- {
- //Do nothing ... it's probably not an FC0013
- }
-
- return false;
- }
-
- /**
- * Determines if the device's tuner is an FC2580 Tuner.
- *
- * Note: call initBaseband(device) prior to calling this method.
- *
- * @param device - usb tuner device
- * @return true if the tuner is an FC2580
- * @throws UsbException
- * @throws UsbClaimException
- */
- protected static boolean isFC2580Tuner( UsbDevice device,
- boolean controlI2CRepeater ) throws UsbClaimException
- {
- try
- {
- /* Initialize the GPIOs */
- setGPIOOutput( device, BIT_5 );
-
- /* Reset tuner before probing */
- setGPIOBit( device, BIT_5, true );
- setGPIOBit( device, BIT_5, false );
-
-
- /* Read the check value */
- int value = readI2CRegister( device, FC2580_I2C_ADDRESS,
- FC2580_CHECK_ADDRESS, controlI2CRepeater );
-
- /* Compare masked return value to the known check value */
- return ( ( value & 0x7F ) == FC2580_CHECK_VALUE );
- }
- catch( UsbException e )
- {
- //Do nothing, it's not an FC2580
- }
-
- return false;
- }
-
- protected static boolean isR820TTuner( UsbDevice device,
- boolean controlI2CRepeater ) throws UsbClaimException
- {
- mLog.debug( "testing for R820T tuner" );
-
- try
- {
- int value = readI2CRegister( device, R820T_I2C_ADDRESS,
- R820T_CHECK_ADDRESS, controlI2CRepeater );
-
- return ( value == R820T_CHECK_VALUE );
- }
- catch( UsbException e )
- {
- //Do nothing, it's not an R820T
- }
-
- return false;
- }
-
- protected static boolean isR828DTuner( UsbDevice device,
- boolean controlI2CRepeater ) throws UsbClaimException
- {
- try
- {
- int value = readI2CRegister( device, R828D_I2C_ADDRESS,
- R828D_CHECK_ADDRESS, controlI2CRepeater );
-
- return ( value == R828D_CHECK_VALUE );
- }
- catch( UsbException e )
- {
- //Do nothing, it's not an R828D
- }
-
- return false;
- }
-
public int getCurrentSampleRate() throws SourceException
{
return mSampleRate.getRate();
@@ -1121,12 +974,12 @@ public abstract class RTL2832TunerController extends TunerController
{
try
{
- int high= readDemodRegister( mUSBDevice, Page.ONE, (short)0x9F, 2 );
- int low = readDemodRegister( mUSBDevice, Page.ONE, (short)0xA1, 2 );
+ int high= readDemodRegister( mDeviceHandle, Page.ONE, (short)0x9F, 2 );
+ int low = readDemodRegister( mDeviceHandle, Page.ONE, (short)0xA1, 2 );
int ratio = Integer.rotateLeft( high, 16 ) | low;
- int rate = (int)( mOscillatorFrequency * sTWO_TO_22_POWER / ratio );
+ int rate = (int)( mOscillatorFrequency * TWO_TO_22_POWER / ratio );
SampleRate sampleRate = SampleRate.getClosest( rate );
@@ -1144,37 +997,31 @@ public abstract class RTL2832TunerController extends TunerController
+ "current sample rate", e );
}
- return sDEFAULT_SAMPLE_RATE.getRate();
+ return DEFAULT_SAMPLE_RATE.getRate();
}
- public void setSampleRate( SampleRate sampleRate )
- throws SourceException, UsbException
+ public void setSampleRate( SampleRate sampleRate ) throws SourceException
{
/* Write high-order 16-bits of sample rate ratio to demod register */
- writeDemodRegister( mUSBDevice, Page.ONE, (short)0x9F,
+ writeDemodRegister( mDeviceHandle, Page.ONE, (short)0x9F,
sampleRate.getRatioHighBits(), 2 );
/* Write low-order 16-bits of sample rate ratio to demod register */
- writeDemodRegister( mUSBDevice, Page.ONE, (short)0xA1,
+ writeDemodRegister( mDeviceHandle, Page.ONE, (short)0xA1,
sampleRate.getRatioLowBits(), 2 );
/* Set sample rate correction to 0 */
setSampleRateFrequencyCorrection( 0 );
/* Reset the demod for the changes to take effect */
- writeDemodRegister( mUSBDevice, Page.ONE, (short)0x01, 0x14, 1 );
- writeDemodRegister( mUSBDevice, Page.ONE, (short)0x01, 0x10, 1 );
+ writeDemodRegister( mDeviceHandle, Page.ONE, (short)0x01, 0x14, 1 );
+ writeDemodRegister( mDeviceHandle, Page.ONE, (short)0x01, 0x10, 1 );
/* Apply any tuner specific sample rate filter settings */
setSampleRateFilters( sampleRate.getRate() );
mSampleRate = sampleRate;
- /**
- * Adjust the size of the byte array buffers sent over the USB bus
- */
- mBufferSize = mSampleRate.getBufferSize();
-
mFrequencyController.setSampleRate( sampleRate.getRate() );
if( mSampleRateMonitor != null )
@@ -1183,29 +1030,35 @@ public abstract class RTL2832TunerController extends TunerController
}
}
- public void setSampleRateFrequencyCorrection( int ppm )
- throws SourceException, UsbException
+ public void setSampleRateFrequencyCorrection( int ppm ) throws SourceException
{
- int offset = -ppm * sTWO_TO_22_POWER / 1000000;
+ int offset = -ppm * TWO_TO_22_POWER / 1000000;
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0x3F,
( offset & 0xFF ),
1 );
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0x3E,
( Integer.rotateRight( offset, 8 ) & 0xFF ),
1 );
/* Test to retune controller to apply frequency correction */
- mFrequencyController.setFrequency( mFrequencyController.getFrequency() );
+ try
+ {
+ mFrequencyController.setFrequency( mFrequencyController.getFrequency() );
+ }
+ catch( Exception e )
+ {
+ throw new SourceException( "couldn't set sample rate frequency correction", e );
+ }
}
public int getSampleRateFrequencyCorrection() throws UsbException
{
- int high = readDemodRegister( mUSBDevice, Page.ONE, (short)0x3E, 1 );
- int low = readDemodRegister( mUSBDevice, Page.ONE, (short)0x3F, 1 );
+ int high = readDemodRegister( mDeviceHandle, Page.ONE, (short)0x3E, 1 );
+ int low = readDemodRegister( mDeviceHandle, Page.ONE, (short)0x3F, 1 );
return ( Integer.rotateLeft( high, 8 ) | low );
}
@@ -1229,7 +1082,7 @@ public abstract class RTL2832TunerController extends TunerController
* Label 3: serial
* Label 4,5 ... (user defined)
*/
- public byte[] readEEPROM( UsbDevice device, short offset, int length )
+ public byte[] readEEPROM( DeviceHandle handle, short offset, int length )
throws IllegalArgumentException
{
if( offset + length > 256 )
@@ -1240,14 +1093,14 @@ public abstract class RTL2832TunerController extends TunerController
}
byte[] data = new byte[ length ];
- byte[] onebyte = new byte[ 1 ];
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 1 );
try
{
/* Tell the RTL-2832 to address the EEPROM */
- writeRegister( device, Block.IIC, EEPROM_ADDRESS, (byte)offset, 1 );
+ writeRegister( handle, Block.I2C, EEPROM_ADDRESS, (byte)offset, 1 );
}
- catch( UsbException e )
+ catch( LibUsbException e )
{
mLog.error( "usb error while attempting to set read address to "
+ "EEPROM register, prior to reading the EEPROM device "
@@ -1258,8 +1111,9 @@ public abstract class RTL2832TunerController extends TunerController
{
try
{
- byte[] temp = read( device, Block.IIC, EEPROM_ADDRESS, onebyte );
- data[ x ] = temp[ 0 ];
+ read( handle, EEPROM_ADDRESS, Block.I2C, buffer );
+ data[ x ] = buffer.get();
+ buffer.rewind();
}
catch( Exception e )
{
@@ -1279,7 +1133,7 @@ public abstract class RTL2832TunerController extends TunerController
* Note: introduce a 5 millisecond delay between each successive write to
* the EEPROM or subsequent writes may fail.
*/
- public void writeEEPROMByte( UsbDevice device, byte offset, byte value )
+ public void writeEEPROMByte( DeviceHandle handle, byte offset, byte value )
throws IllegalArgumentException, UsbDisconnectedException, UsbException
{
if( offset < 0 || offset > 255 )
@@ -1291,7 +1145,7 @@ public abstract class RTL2832TunerController extends TunerController
int offsetAndValue = Integer.rotateLeft( ( 0xFF & offset ), 8 ) |
( 0xFF & value );
- writeRegister( device, Block.IIC, EEPROM_ADDRESS, offsetAndValue, 2 );
+ writeRegister( handle, Block.I2C, EEPROM_ADDRESS, offsetAndValue, 2 );
}
public enum Address
@@ -1363,7 +1217,7 @@ public abstract class RTL2832TunerController extends TunerController
TUN( 3 ),
ROM( 4 ),
IR( 5 ),
- IIC( 6 ); //I2C controller
+ I2C( 6 ); //I2C controller
private int mValue;
@@ -1409,37 +1263,34 @@ public abstract class RTL2832TunerController extends TunerController
public enum SampleRate
{
/* Note: sample rates below 1.0MHz are subject to aliasing */
- RATE_0_240MHZ( 0x0DFC, 0x0000, 240000, "0.240 MHz", 16384 ),
- RATE_0_288MHZ( 0x08FC, 0x0000, 288000, "0.288 MHz", 16384 ),
- RATE_0_912MHZ( 0x07E4, 0x0000, 912000, "0.912 MHz", 32768 ),
- RATE_0_960MHZ( 0x0778, 0x0000, 960000, "0.960 MHz", 32768 ),
- RATE_1_200MHZ( 0x05F4, 0x0000, 1200000, "1.200 MHz", 65536 ),
- RATE_1_440MHZ( 0x04FC, 0x0000, 1440000, "1.440 MHz", 65536 ),
- RATE_1_680MHZ( 0x0448, 0x0000, 1680000, "1.680 MHz", 65536 ),
- RATE_1_824MHZ( 0x03F0, 0x0000, 1824000, "1.824 MHz", 65536 ),
- RATE_2_016MHZ( 0x038C, 0x0000, 2016000, "2.016 MHz", 131072 ),
- RATE_2_208MHZ( 0x0340, 0x0000, 2208000, "2.208 MHz", 131072 ),
- RATE_2_400MHZ( 0x02FC, 0x0000, 2400000, "2.400 MHz", 131072 ),
- RATE_2_640MHZ( 0x02B4, 0x8000, 2640000, "2.640 MHz", 262144 ),
- RATE_2_880MHZ( 0x027C, 0x0000, 2880000, "2.880 MHz", 262144 );
+ RATE_0_240MHZ( 0x0DFC, 0x0000, 240000, "0.240 MHz" ),
+ RATE_0_288MHZ( 0x08FC, 0x0000, 288000, "0.288 MHz" ),
+ RATE_0_912MHZ( 0x07E4, 0x0000, 912000, "0.912 MHz" ),
+ RATE_0_960MHZ( 0x0778, 0x0000, 960000, "0.960 MHz" ),
+ RATE_1_200MHZ( 0x05F4, 0x0000, 1200000, "1.200 MHz" ),
+ RATE_1_440MHZ( 0x04FC, 0x0000, 1440000, "1.440 MHz" ),
+ RATE_1_680MHZ( 0x0448, 0x0000, 1680000, "1.680 MHz" ),
+ RATE_1_824MHZ( 0x03F0, 0x0000, 1824000, "1.824 MHz" ),
+ RATE_2_016MHZ( 0x038C, 0x0000, 2016000, "2.016 MHz" ),
+ RATE_2_208MHZ( 0x0340, 0x0000, 2208000, "2.208 MHz" ),
+ RATE_2_400MHZ( 0x02FC, 0x0000, 2400000, "2.400 MHz" ),
+ RATE_2_640MHZ( 0x02B4, 0x8000, 2640000, "2.640 MHz" ),
+ RATE_2_880MHZ( 0x027C, 0x0000, 2880000, "2.880 MHz" );
private int mRatioHigh;
private int mRatioLow;
private int mRate;
private String mLabel;
- private int mBufferSize;
private SampleRate( int ratioHigh,
int ratioLow,
int rate,
- String label,
- int bufferSize )
+ String label )
{
mRatioHigh = ratioHigh;
mRatioLow = ratioLow;
mRate = rate;
mLabel = label;
- mBufferSize = bufferSize;
}
public int getRatioHighBits()
@@ -1467,11 +1318,6 @@ public abstract class RTL2832TunerController extends TunerController
return mLabel;
}
- public int getBufferSize()
- {
- return mBufferSize;
- }
-
/**
* Returns the sample rate that is equal to the argument or the next
* higher sample rate
@@ -1488,7 +1334,7 @@ public abstract class RTL2832TunerController extends TunerController
}
}
- return sDEFAULT_SAMPLE_RATE;
+ return DEFAULT_SAMPLE_RATE;
}
}
@@ -1500,7 +1346,16 @@ public abstract class RTL2832TunerController extends TunerController
{
mSampleListeners.add( listener );
- mBufferProcessor.start();
+ if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
+ {
+ mBufferProcessor = new BufferProcessor();
+
+ Thread thread = new Thread( mBufferProcessor );
+ thread.setDaemon( true );
+ thread.setName( "Sample Processor" );
+
+ thread.start();
+ }
}
/**
@@ -1545,95 +1400,93 @@ public abstract class RTL2832TunerController extends TunerController
* Buffer processing thread. Fetches samples from the RTL2832 Tuner and
* dispatches them to all registered listeners
*/
- public class BufferProcessor implements UsbPipeListener
+ public class BufferProcessor implements Runnable, TransferCallback
{
private ScheduledExecutorService mExecutor =
Executors.newScheduledThreadPool( 2 );
private ScheduledFuture> mSampleDispatcherTask;
- private ScheduledFuture> mSampleRateCounterTask;
-
+ private ScheduledFuture> mSampleRateCounterTask;
+ private ArrayList mTransfers;
private AtomicBoolean mRunning = new AtomicBoolean();
- private AtomicBoolean mResetting = new AtomicBoolean();
- private Boolean mTransitioning = false;
- public void start()
+ @Override
+ public void run()
{
- synchronized( mTransitioning )
+ if( mRunning.compareAndSet( false, true ) )
{
- if( mRunning.compareAndSet( false, true ) )
+ mLog.debug( "rtl2832 [" + getUniqueID() +
+ "] - starting sample fetch thread" );
+
+ try
{
- mLog.debug( "rtl2832 [" + getUniqueID() +
- "] - starting sample fetch thread" );
+ setSampleRate( mSampleRate );
- ArrayList irps = new ArrayList();
-
- for( int x = 0; x < sUSB_IRP_POOL_SIZE; x++ )
- {
- UsbIrp irp = mUSBPipe.createUsbIrp();
- irp.setData( new byte[ mBufferSize ] );
- irps.add( irp );
- }
-
- try
- {
- if( mUSBPipe.isActive() )
- {
- if( !mUSBPipe.isOpen() )
- {
- resetUSBBuffer();
-
- mUSBPipe.open();
-
- //TODO: move this to the constructor
- mUSBPipe.addUsbPipeListener( this );
- }
-
- if( mUSBPipe.isOpen() )
- {
- mSampleDispatcherTask = mExecutor
- .scheduleAtFixedRate( new BufferDispatcher(),
- 0, 20, TimeUnit.MILLISECONDS );
-
- mSampleRateMonitor =
- new SampleRateMonitor( mSampleRate.getRate() );
-
- mSampleRateCounterTask = mExecutor
- .scheduleAtFixedRate( mSampleRateMonitor,
- 10, 10, TimeUnit.SECONDS );
-
- mUSBPipe.asyncSubmit( irps );
- }
- }
- }
- catch ( Exception e )
- {
- e.printStackTrace();
- }
+ resetUSBBuffer();
}
- }
- }
+ catch( SourceException e )
+ {
+ mLog.error( "couldn't start buffer processor", e );
+
+ mRunning.set( false );
+ }
+
+ prepareTransfers();
+
+ for( Transfer transfer: mTransfers )
+ {
+ int result = LibUsb.submitTransfer( transfer );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "error submitting transfer [" +
+ LibUsb.errorName( result ) + "]" );
+ break;
+ }
+ }
+
+ mSampleDispatcherTask = mExecutor
+ .scheduleAtFixedRate( new BufferDispatcher(),
+ 0, 20, TimeUnit.MILLISECONDS );
+
+ mSampleRateMonitor =
+ new SampleRateMonitor( mSampleRate.getRate() );
+
+ mSampleRateCounterTask = mExecutor
+ .scheduleAtFixedRate( mSampleRateMonitor,
+ 10, 10, TimeUnit.SECONDS );
+
+ while( mRunning.get() )
+ {
+ ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
+
+ int result = LibUsb.handleEventsTimeoutCompleted(
+ null, TIMEOUT_US, completed.asIntBuffer() );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "error handling events for libusb" );
+ }
+ }
+ }
+ }
/**
* Stops the sample fetching thread
*/
public void stop()
{
- synchronized( mTransitioning )
+ if( mRunning.compareAndSet( true, false ) )
{
- if( mRunning.compareAndSet( true, false ) )
- {
- mLog.debug( "rtl2832 [" + getUniqueID() +
- "] - stopping sample fetch thread" );
+ mLog.debug( "rtl2832 [" + getUniqueID() +
+ "] - stopping sample fetch thread" );
- mUSBPipe.abortAllSubmissions();
-
- if( mSampleDispatcherTask != null )
- {
- mSampleDispatcherTask.cancel( true );
- mSampleRateCounterTask.cancel( true );
- mRawSampleBuffer.clear();
- mSampleCounter.set( 0 );
- }
+ cancel();
+
+ if( mSampleDispatcherTask != null )
+ {
+ mSampleDispatcherTask.cancel( true );
+ mSampleRateCounterTask.cancel( true );
+ mFilledBuffers.clear();
}
}
}
@@ -1645,66 +1498,107 @@ public abstract class RTL2832TunerController extends TunerController
{
return mRunning.get();
}
-
- /**
- * This method is invoked by the usb pipe when a response is returned
- * from the data request. If there is byte sample data in the response
- * then we will buffer it and allow the buffer processor to convert it
- * and dispatch it to listeners. We automatically insert another
- * irp to get more data.
- *
- * This method runs on the usb4java library processing thread, so we
- * don't want to weigh it down.
- */
+
@Override
- public synchronized void dataEventOccurred( UsbPipeDataEvent event )
- {
- UsbIrp irp = event.getUsbIrp();
-
- byte[] data = irp.getData();
-
- if( data.length > 0 )
+ public void processTransfer( Transfer transfer )
+ {
+ if( transfer.status() == LibUsb.TRANSFER_COMPLETED )
{
- mRawSampleBuffer.add( data );
- mSampleCounter.addAndGet( data.length );
- }
-
- if( mRunning.get() )
- {
- try
- {
- mUSBPipe.asyncSubmit( new byte[ mBufferSize ] );
- }
- catch ( UsbNotActiveException | UsbNotOpenException
- | IllegalArgumentException | UsbDisconnectedException
- | UsbException e )
- {
- mLog.error( "error while processing samples", e );
- }
- }
- }
-
- @Override
- public void errorEventOccurred( UsbPipeErrorEvent e )
- {
- /* When an error occurs, we'll get errors on all of the
- * queued IRPS in succession. We use the mResetting to control
- * the reset process and ignore all subsequent errors */
- if( mResetting.compareAndSet( false, true ) )
- {
- mLog.error( "error during data transfer resetting USB pipe to "
- + "RTL-2832", e );
+ ByteBuffer buffer = transfer.buffer();
- stop();
-
- if( !mSampleListeners.isEmpty() )
- {
- start();
- }
+ byte[] data = new byte[ transfer.actualLength() ];
+
+ buffer.get( data );
- mResetting.set( false );
+ buffer.rewind();
+
+ mFilledBuffers.add( data );
+
+ mSampleCounter.addAndGet( transfer.actualLength() );
+
+ if( !isRunning() )
+ {
+ LibUsb.cancelTransfer( transfer );
+ }
}
- }
+
+ switch( transfer.status() )
+ {
+ case LibUsb.TRANSFER_COMPLETED:
+ /* resubmit the transfer */
+ int result = LibUsb.submitTransfer( transfer );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "couldn't resubmit buffer transfer to tuner" );
+ LibUsb.freeTransfer( transfer );
+ mTransfers.remove( transfer );
+ }
+ break;
+ case LibUsb.TRANSFER_CANCELLED:
+ /* free the transfer and remove it */
+ LibUsb.freeTransfer( transfer );
+ mTransfers.remove( transfer );
+ break;
+ default:
+ /* unexpected error */
+ mLog.error( "transfer error [" +
+ getTransferStatus( transfer.status() ) +
+ "] transferred actual: " + transfer.actualLength() );
+ }
+ }
+
+ private void cancel()
+ {
+ for( Transfer transfer: mTransfers )
+ {
+ LibUsb.cancelTransfer( transfer );
+ }
+
+ ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
+
+ int result = LibUsb.handleEventsTimeoutCompleted(
+ null, TIMEOUT_US, completed.asIntBuffer() );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mLog.error( "error handling usb events during cancel [" +
+ LibUsb.errorName( result ) + "]" );
+ }
+ }
+
+ /**
+ * Prepares (allocates) a set of transfer buffers for use in
+ * transferring data from the tuner via the bulk interface
+ */
+ private void prepareTransfers() throws LibUsbException
+ {
+ mTransfers = new ArrayList();
+
+ for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
+ {
+ Transfer transfer = LibUsb.allocTransfer();
+
+ if( transfer == null )
+ {
+ throw new LibUsbException( "couldn't allocate transfer",
+ LibUsb.ERROR_NO_MEM );
+ }
+
+ final ByteBuffer buffer =
+ ByteBuffer.allocateDirect( mBufferSize );
+
+ LibUsb.fillBulkTransfer( transfer,
+ mDeviceHandle,
+ BULK_ENDPOINT_IN,
+ buffer,
+ BufferProcessor.this,
+ "Buffer #" + x,
+ TIMEOUT_US );
+
+ mTransfers.add( transfer );
+ }
+ }
}
/**
@@ -1718,16 +1612,41 @@ public abstract class RTL2832TunerController extends TunerController
{
ArrayList buffers = new ArrayList();
- mRawSampleBuffer.drainTo( buffers );
-
+ mFilledBuffers.drainTo( buffers );
+
for( byte[] buffer: buffers )
{
+ //TODO: convert this to float primitive
Float[] samples = mSampleAdapter.convert( buffer );
+
broadcast( samples );
}
}
}
-
+
+ public static String getTransferStatus( int status )
+ {
+ switch( status )
+ {
+ case 0:
+ return "TRANSFER COMPLETED (0)";
+ case 1:
+ return "TRANSFER ERROR (1)";
+ case 2:
+ return "TRANSFER TIMED OUT (2)";
+ case 3:
+ return "TRANSFER CANCELLED (3)";
+ case 4:
+ return "TRANSFER STALL (4)";
+ case 5:
+ return "TRANSFER NO DEVICE (5)";
+ case 6:
+ return "TRANSFER OVERFLOW (6)";
+ default:
+ return "UNKNOWN TRANSFER STATUS (" + status + ")";
+ }
+ }
+
/**
* Averages the sample rate over a 10-second period. The count is for the
* number of bytes received from the tuner. There are two bytes for each
@@ -1778,7 +1697,6 @@ public abstract class RTL2832TunerController extends TunerController
mSampleCounter.set( 0 );
mLog.info( "monitor reset for new sample rate [" + mTargetSampleRate + "]" );
- System.out.println( "monitor reset for new sample rate [" + mTargetSampleRate + "]" );
}
else
{
@@ -1809,8 +1727,7 @@ public abstract class RTL2832TunerController extends TunerController
}
StringBuilder sb = new StringBuilder();
- sb.append( TimeStamp.getTimeStamp( " " ) );
- sb.append( " RTL-2832 [" );
+ sb.append( "[" );
if( mDescriptor != null )
{
sb.append( mDescriptor.getSerial() );
@@ -1823,12 +1740,10 @@ public abstract class RTL2832TunerController extends TunerController
sb.append( mDecimalFormatter.format( current ) );
sb.append( " Hz " );
sb.append( mPercentFormatter.format( 100.0f * ( current / (float)mTargetSampleRate ) ) );
- sb.append( "% ] average error [" );
+ sb.append( "% ] error [" );
sb.append( average );
sb.append( " Hz ] target " );
- sb.append( mTargetSampleRate );
-
- System.out.println( sb.toString() );
+ sb.append( mDecimalFormatter.format( mTargetSampleRate ) );
mLog.info( sb.toString() );
}
@@ -2004,4 +1919,75 @@ public abstract class RTL2832TunerController extends TunerController
return sb.toString();
}
}
+
+ public class USBEventHandlingThread implements Runnable
+ {
+ /** If thread should abort. */
+ private volatile boolean mAbort;
+
+ /**
+ * Aborts the event handling thread.
+ */
+ public void abort()
+ {
+ mAbort = true;
+ }
+
+ @Override
+ public void run()
+ {
+ while ( !mAbort )
+ {
+ int result = LibUsb.handleEventsTimeout( null, 1000 );
+
+ if ( result != LibUsb.SUCCESS )
+ {
+ mAbort = true;
+
+ mLog.error( "error handling usb events [" +
+ LibUsb.errorName( result ) + "]" );
+
+ throw new LibUsbException("Unable to handle USB "
+ + "events", result );
+ }
+ }
+ }
+ }
+
+ public enum TunerTypeCheck
+ {
+ E4K( 0xC8, 0x02, 0x40 ),
+ FC0012( 0xC6, 0x00, 0xA1 ),
+ FC0013( 0xC6, 0x00, 0xA3 ),
+ FC2580( 0xAC, 0x01, 0x56 ),
+ R820T( 0x34, 0x00, 0x69 ),
+ R828D( 0x74, 0x00, 0x69 );
+
+ private int mI2CAddress;
+ private int mCheckAddress;
+ private int mCheckValue;
+
+ private TunerTypeCheck( int i2c, int address, int value )
+ {
+ mI2CAddress = i2c;
+ mCheckAddress = address;
+ mCheckValue = value;
+ }
+
+ public byte getI2CAddress()
+ {
+ return (byte)mI2CAddress;
+ }
+
+ public byte getCheckAddress()
+ {
+ return (byte)mCheckAddress;
+ }
+
+ public byte getCheckValue()
+ {
+ return (byte)mCheckValue;
+ }
+ }
+
}
diff --git a/src/source/tuner/rtl/e4k/E4KTunerConfigurationPanel.java b/src/source/tuner/rtl/e4k/E4KTunerConfigurationPanel.java
index d9d675d3..cce675b4 100644
--- a/src/source/tuner/rtl/e4k/E4KTunerConfigurationPanel.java
+++ b/src/source/tuner/rtl/e4k/E4KTunerConfigurationPanel.java
@@ -46,6 +46,7 @@ import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.LibUsbException;
import source.SourceException;
import source.tuner.TunerConfiguration;
@@ -258,7 +259,7 @@ public class E4KTunerConfigurationPanel extends JPanel
mSelectedConfig.setSampleRate( sampleRate );
save();
}
- catch ( SourceException | UsbException eSampleRate )
+ catch ( SourceException | LibUsbException eSampleRate )
{
JOptionPane.showMessageDialog(
E4KTunerConfigurationPanel.this,
diff --git a/src/source/tuner/rtl/e4k/E4KTunerController.java b/src/source/tuner/rtl/e4k/E4KTunerController.java
index 76a0ba42..09577e01 100644
--- a/src/source/tuner/rtl/e4k/E4KTunerController.java
+++ b/src/source/tuner/rtl/e4k/E4KTunerController.java
@@ -17,37 +17,39 @@
******************************************************************************/
package source.tuner.rtl.e4k;
+import java.util.Arrays;
+
import javax.swing.JPanel;
import javax.usb.UsbException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
+import org.usb4java.DeviceHandle;
+import org.usb4java.LibUsb;
+import org.usb4java.LibUsbException;
+
import source.SourceException;
import source.tuner.TunerConfiguration;
import source.tuner.TunerType;
import source.tuner.rtl.RTL2832TunerController;
-import source.tuner.usb.USBTunerDevice;
+import source.tuner.rtl.RTL2832TunerController.Descriptor;
import controller.ResourceManager;
public class E4KTunerController extends RTL2832TunerController
{
- /**
- * Note: E4K tuner max frequency range is 2200 MHz, but the
- * max value that can be assigned to a signed integer is
- * 2147xxxxxx, so we constrain the E4K to the max integer value, for now
- *
- * TODO: change frequency to a long primitive type
- */
- public static final long sMIN_FREQUENCY = 52000000;
- public static final long sMIN_FREQUENCY_EXTENDED = 52000000;
- public static final long sMAX_FREQUENCY = 2200000000l;
- public static final long sMAX_FREQUENCY_EXTENDED = 2200000000l;
- public static final long sMIN_VCO = 2600000000l; //2.6 GHz
- public static final long sMAX_VCO = 3900000000l; //3.9 GHz
+ private final static Logger mLog =
+ LoggerFactory.getLogger( E4KTunerController.class );
+
+ public static final long MIN_FREQUENCY = 52000000;
+ public static final long MAX_FREQUENCY = 2200000000l;
/* The local oscillator is defined by whole (integer) units of the oscillator
* frequency and fractional units representing 1/65536th of the oscillator
* frequency, meaning we can only tune the local oscillator in units of
* 439.453125 hertz. */
- public static final long sE4K_PLL_Y = 65536l; /* 16-bit fractional register */
+ public static final long E4K_PLL_Y = 65536l; /* 16-bit fractional register */
public static final byte MASTER1_RESET = (byte)0x01;
public static final byte MASTER1_NORM_STBY = (byte)0x02;
public static final byte MASTER1_POR_DET = (byte)0x04;
@@ -108,9 +110,11 @@ public class E4KTunerController extends RTL2832TunerController
private E4KTunerEditorPanel mEditor;
- public E4KTunerController( USBTunerDevice device ) throws SourceException
+ public E4KTunerController( Device device,
+ DeviceDescriptor deviceDescriptor )
+ throws SourceException
{
- super( device, sMIN_FREQUENCY, sMAX_FREQUENCY );
+ super( device, deviceDescriptor, MIN_FREQUENCY, MAX_FREQUENCY );
}
@Override
@@ -166,24 +170,75 @@ public class E4KTunerController extends RTL2832TunerController
public void init() throws SourceException
{
+ mDeviceHandle = new DeviceHandle();
+
+ int result = LibUsb.open( mDevice, mDeviceHandle );
+
+ if( result != LibUsb.SUCCESS )
+ {
+ mDeviceHandle = null;
+
+ throw new SourceException( "libusb couldn't open RTL2832 usb "
+ + "device [" + LibUsb.errorName( result ) + "]" );
+ }
+
+ claimInterface( mDeviceHandle );
+
+ byte[] eeprom = null;
+
+ try
+ {
+ /* Read the contents of the 256-byte EEPROM */
+ eeprom = readEEPROM( mDeviceHandle, (short)0, 256 );
+ }
+ catch( Exception e )
+ {
+ mLog.error( "error while reading the EEPROM device descriptor", e );
+ }
+
+ try
+ {
+ mDescriptor = new Descriptor( eeprom );
+
+ if( eeprom == null )
+ {
+ mLog.error( "eeprom byte array was null - constructed "
+ + "empty descriptor object" );
+ }
+ }
+ catch( Exception e )
+ {
+ mLog.error( "error while constructing device descriptor using "
+ + "descriptor byte array " +
+ ( eeprom == null ? "[null]" : Arrays.toString( eeprom )), e );
+ }
+
try
{
/* Dummy write to test USB interface */
- writeRegister( mUSBDevice, Block.USB,
+ writeRegister( mDeviceHandle, Block.USB,
Address.USB_SYSCTL.getAddress(), (short)0x09, 1 );
- initBaseband( mUSBDevice );
+ initBaseband( mDeviceHandle );
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
boolean i2CRepeaterControl = false;
initTuner( i2CRepeaterControl );
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
- /* Initialize the super class */
- super.init();
+ try
+ {
+ setSampleRate( DEFAULT_SAMPLE_RATE );
+ }
+ catch( Exception e )
+ {
+ throw new SourceException( "RTL2832 Tuner Controller - couldn't "
+ + "set default sample rate", e );
+ }
+
}
catch( UsbException e )
{
@@ -208,14 +263,14 @@ public class E4KTunerController extends RTL2832TunerController
* for the selected bandwidth/sample rate
*/
@Override
- public void setSampleRateFilters( int bandwidth ) throws UsbException
+ public void setSampleRateFilters( int bandwidth ) throws SourceException
{
/* Determine repeater state so we can restore it when done */
boolean i2CRepeaterEnabled = isI2CRepeaterEnabled();
if( !i2CRepeaterEnabled )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
boolean controlI2CRepeater = false;
@@ -231,7 +286,7 @@ public class E4KTunerController extends RTL2832TunerController
if( !i2CRepeaterEnabled )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
@@ -245,7 +300,7 @@ public class E4KTunerController extends RTL2832TunerController
if( !i2CRepeaterEnabled )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
boolean controlI2CRepeater = false;
@@ -263,12 +318,12 @@ public class E4KTunerController extends RTL2832TunerController
/* Return the repeater to its previous state */
if( !i2CRepeaterEnabled )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
return calculateActualFrequency( pll, z, x );
}
- catch( UsbException e )
+ catch( LibUsbException e )
{
throw new SourceException( "E4K tuner controller - couldn't get "
+ "tuned frequency", e );
@@ -291,7 +346,7 @@ public class E4KTunerController extends RTL2832TunerController
int remainder = (int)( frequency - ( ( z & 0xFF ) * pll.getScaledOscillator() ) );
/* X is a 16-bit representation of the remainder */
- int x = (int)( (double)remainder / (double)pll.getScaledOscillator() * sE4K_PLL_Y );
+ int x = (int)( (double)remainder / (double)pll.getScaledOscillator() * E4K_PLL_Y );
/* Calculate the exact (tunable) frequency and apply that to the tuner */
long actualFrequency = calculateActualFrequency( pll, z, x );
@@ -310,7 +365,7 @@ public class E4KTunerController extends RTL2832TunerController
/* Apply the actual frequency */
try
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
boolean controlI2CRepeater = false;
@@ -341,10 +396,10 @@ public class E4KTunerController extends RTL2832TunerController
{
throw new SourceException( "E4K tuner controller - couldn't "
+ "achieve PLL lock for frequency [" +
- actualFrequency + "]" );
+ actualFrequency + "] lock value [" + lock + "]" );
}
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
catch( UsbException e )
{
@@ -358,7 +413,7 @@ public class E4KTunerController extends RTL2832TunerController
long whole = pll.getScaledOscillator() * ( z & 0xFF );
int fractional = (int)( pll.getScaledOscillator() *
- ( (double)x / (double)sE4K_PLL_Y ) );
+ ( (double)x / (double)E4K_PLL_Y ) );
return whole + fractional;
}
@@ -367,7 +422,7 @@ public class E4KTunerController extends RTL2832TunerController
{
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
boolean i2CRepeaterControl = false;
@@ -473,7 +528,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
@@ -484,7 +539,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
/* Capture current gain settings to reapply at the end */
@@ -548,7 +603,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
@@ -584,7 +639,7 @@ public class E4KTunerController extends RTL2832TunerController
{
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
if( gain == E4KLNAGain.AUTOMATIC )
@@ -610,7 +665,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
@@ -661,7 +716,7 @@ public class E4KTunerController extends RTL2832TunerController
{
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
boolean localI2CRepeaterControl = false;
@@ -689,7 +744,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
@@ -810,7 +865,7 @@ public class E4KTunerController extends RTL2832TunerController
}
public void setMixerFilter( MixerFilter filter,
- boolean controlI2CRepeater ) throws UsbException
+ boolean controlI2CRepeater ) throws LibUsbException
{
writeMaskedE4KRegister( MixerFilter.getRegister(),
MixerFilter.getMask(),
@@ -828,7 +883,7 @@ public class E4KTunerController extends RTL2832TunerController
}
public void setRCFilter( RCFilter filter,
- boolean controlI2CRepeater ) throws UsbException
+ boolean controlI2CRepeater ) throws LibUsbException
{
writeMaskedE4KRegister( RCFilter.getRegister(),
RCFilter.getMask(),
@@ -844,7 +899,7 @@ public class E4KTunerController extends RTL2832TunerController
}
public void setChannelFilter( ChannelFilter filter,
- boolean controlI2CRepeater ) throws UsbException
+ boolean controlI2CRepeater ) throws LibUsbException
{
writeMaskedE4KRegister( ChannelFilter.getRegister(),
ChannelFilter.getMask(),
@@ -885,7 +940,7 @@ public class E4KTunerController extends RTL2832TunerController
{
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
Band band = Band.fromFrequency( frequency );
@@ -914,7 +969,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
@@ -946,7 +1001,7 @@ public class E4KTunerController extends RTL2832TunerController
{
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
boolean i2CRepeaterControl = false;
@@ -957,7 +1012,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
}
@@ -969,7 +1024,7 @@ public class E4KTunerController extends RTL2832TunerController
{
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
}
writeE4KRegister( Register.MAGIC_1, (byte)0x01, false );
@@ -983,7 +1038,7 @@ public class E4KTunerController extends RTL2832TunerController
if( controlI2CRepeater )
{
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
}
@@ -999,7 +1054,7 @@ public class E4KTunerController extends RTL2832TunerController
private void writeMaskedE4KRegister( Register register,
byte mask,
byte value,
- boolean controlI2CRepeater ) throws UsbException
+ boolean controlI2CRepeater ) throws LibUsbException
{
int temp = readE4KRegister( register, controlI2CRepeater );
@@ -1009,22 +1064,24 @@ public class E4KTunerController extends RTL2832TunerController
writeE4KRegister( register,
(byte)( ( temp & ~mask ) | ( value & mask ) ),
controlI2CRepeater );
+
+ int temp2 = readE4KRegister( register, controlI2CRepeater );
}
}
private int readE4KRegister( Register register,
- boolean controlI2CRepeater ) throws UsbException
+ boolean controlI2CRepeater ) throws LibUsbException
{
- return readI2CRegister( mUSBDevice, Register.I2C_REGISTER.getValue(),
+ return readI2CRegister( mDeviceHandle, Register.I2C_REGISTER.getValue(),
register.getValue(), controlI2CRepeater );
}
private void writeE4KRegister( Register register,
byte value,
- boolean controlI2CRepeater ) throws UsbException
+ boolean controlI2CRepeater ) throws LibUsbException
{
- writeI2CRegister( mUSBDevice, Register.I2C_REGISTER.getValue(),
+ writeI2CRegister( mDeviceHandle, Register.I2C_REGISTER.getValue(),
register.getValue(), value, controlI2CRepeater );
}
diff --git a/src/source/tuner/rtl/r820t/R820TTunerConfigurationPanel.java b/src/source/tuner/rtl/r820t/R820TTunerConfigurationPanel.java
index 0fe7ce29..c80af5ab 100644
--- a/src/source/tuner/rtl/r820t/R820TTunerConfigurationPanel.java
+++ b/src/source/tuner/rtl/r820t/R820TTunerConfigurationPanel.java
@@ -46,6 +46,7 @@ import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.LibUsbException;
import source.SourceException;
import source.tuner.TunerConfiguration;
@@ -252,7 +253,7 @@ public class R820TTunerConfigurationPanel extends JPanel
mSelectedConfig.setSampleRate( sampleRate );
save();
}
- catch ( SourceException | UsbException eSampleRate )
+ catch ( SourceException | LibUsbException eSampleRate )
{
JOptionPane.showMessageDialog(
R820TTunerConfigurationPanel.this,
@@ -308,7 +309,7 @@ public class R820TTunerConfigurationPanel extends JPanel
{
mController.setSampleRateFrequencyCorrection( value );
}
- catch ( SourceException | UsbException e1 )
+ catch ( SourceException | LibUsbException e1 )
{
JOptionPane.showMessageDialog(
R820TTunerConfigurationPanel.this,
diff --git a/src/source/tuner/rtl/r820t/R820TTunerController.java b/src/source/tuner/rtl/r820t/R820TTunerController.java
index e4852814..375a79b2 100644
--- a/src/source/tuner/rtl/r820t/R820TTunerController.java
+++ b/src/source/tuner/rtl/r820t/R820TTunerController.java
@@ -22,17 +22,21 @@
******************************************************************************/
package source.tuner.rtl.r820t;
+import java.nio.ByteBuffer;
+
import javax.swing.JPanel;
import javax.usb.UsbException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.usb4java.Device;
+import org.usb4java.DeviceDescriptor;
+import org.usb4java.LibUsbException;
import source.SourceException;
import source.tuner.TunerConfiguration;
import source.tuner.TunerType;
import source.tuner.rtl.RTL2832TunerController;
-import source.tuner.usb.USBTunerDevice;
import controller.ResourceManager;
public class R820TTunerController extends RTL2832TunerController
@@ -68,9 +72,11 @@ public class R820TTunerController extends RTL2832TunerController
private JPanel mEditor;
- public R820TTunerController( USBTunerDevice device ) throws SourceException
+ public R820TTunerController( Device device,
+ DeviceDescriptor deviceDescriptor )
+ throws SourceException
{
- super( device, MIN_FREQUENCY, MAX_FREQUENCY );
+ super( device, deviceDescriptor, MIN_FREQUENCY, MAX_FREQUENCY );
}
@Override
@@ -80,7 +86,7 @@ public class R820TTunerController extends RTL2832TunerController
}
@Override
- public void setSampleRateFilters( int sampleRate ) throws UsbException
+ public void setSampleRateFilters( int sampleRate ) throws LibUsbException
{
//TODO: why is this being forced as an abstract method on sub classes?
}
@@ -155,7 +161,7 @@ public class R820TTunerController extends RTL2832TunerController
{
try
{
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
boolean controlI2C = false;
@@ -165,7 +171,7 @@ public class R820TTunerController extends RTL2832TunerController
setPLL( offsetFrequency, controlI2C );
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
}
catch( UsbException e )
{
@@ -179,7 +185,7 @@ public class R820TTunerController extends RTL2832TunerController
* Overrides the same method from the RTL2832 tuner controller to apply
* settings specific to the R820T tuner.
*/
- public void setSamplingMode( SampleMode mode ) throws UsbException
+ public void setSamplingMode( SampleMode mode ) throws LibUsbException
{
switch( mode )
{
@@ -188,14 +194,14 @@ public class R820TTunerController extends RTL2832TunerController
setIFFrequency( R820T_IF_FREQUENCY );
/* Enable spectrum inversion */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0x15,
(short)0x01,
1 );
/* Set default i/q path */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ZERO,
(short)0x06,
(short)0x80,
@@ -239,18 +245,16 @@ public class R820TTunerController extends RTL2832TunerController
*/
public void init() throws SourceException
{
+ /* Initialize the super class to open and claim the usb interface*/
+ super.init();
+
try
{
- mLog.debug( "testing USB interface" );
- /* Dummy write to test USB interface */
- writeRegister( mUSBDevice, Block.USB,
- Address.USB_SYSCTL.getAddress(), (short)0x09, 1 );
-
mLog.debug( "initializing RTL2832 tuner baseband" );
- initBaseband( mUSBDevice );
+ initBaseband( mDeviceHandle );
mLog.debug( "enabling I2C repeater" );
- enableI2CRepeater( mUSBDevice, true );
+ enableI2CRepeater( mDeviceHandle, true );
boolean i2CRepeaterControl = false;
@@ -258,11 +262,9 @@ public class R820TTunerController extends RTL2832TunerController
initTuner( i2CRepeaterControl );
mLog.debug( "disabling I2C repeater" );
- enableI2CRepeater( mUSBDevice, false );
+ enableI2CRepeater( mDeviceHandle, false );
mLog.debug( "initializing RTL2832 tuner controller super class" );
- /* Initialize the super class */
- super.init();
}
catch( UsbException e )
{
@@ -276,14 +278,14 @@ public class R820TTunerController extends RTL2832TunerController
public void initTuner( boolean controlI2C ) throws UsbException
{
/* Disable zero IF mode */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0xB1,
(short)0x1A,
1 );
/* Only enable in-phase ADC input */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ZERO,
(short)0x08,
(short)0x4D,
@@ -293,7 +295,7 @@ public class R820TTunerController extends RTL2832TunerController
setIFFrequency( R820T_IF_FREQUENCY );
/* Enable spectrum inversion */
- writeDemodRegister( mUSBDevice,
+ writeDemodRegister( mDeviceHandle,
Page.ONE,
(short)0x15,
(short)0x01,
@@ -570,7 +572,7 @@ public class R820TTunerController extends RTL2832TunerController
{
for( int x = 5; x < mShadowRegister.length; x++ )
{
- writeI2CRegister( mUSBDevice,
+ writeI2CRegister( mDeviceHandle,
mI2CAddress,
(byte)x,
(byte)mShadowRegister[ x ],
@@ -583,11 +585,11 @@ public class R820TTunerController extends RTL2832TunerController
*/
private int getStatusRegister( int register, boolean controlI2C ) throws UsbException
{
- byte[] data = new byte[ 5 ];
+ ByteBuffer buffer = ByteBuffer.allocateDirect( 5 );
- byte[] statusRegisters = read( mUSBDevice, Block.IIC, mI2CAddress, data );
+ read( mDeviceHandle, mI2CAddress, Block.I2C, buffer );
- return bitReverse( statusRegisters[ register ] & 0xFF );
+ return bitReverse( buffer.get( register ) & 0xFF );
}
/**
@@ -615,7 +617,7 @@ public class R820TTunerController extends RTL2832TunerController
( value & register.getMask() ) );
}
- writeI2CRegister( mUSBDevice, mI2CAddress,
+ writeI2CRegister( mDeviceHandle, mI2CAddress,
(byte)register.getRegister(), value, controlI2C );
mShadowRegister[ register.getRegister() ] = value;
@@ -631,7 +633,7 @@ public class R820TTunerController extends RTL2832TunerController
public int readR820TRegister( Register register, boolean controlI2C )
throws UsbException
{
- int value = readI2CRegister( mUSBDevice,
+ int value = readI2CRegister( mDeviceHandle,
mI2CAddress,
(byte)register.getRegister(),
controlI2C );