diff options
| -rw-r--r-- | README.md | 17 | ||||
| -rw-r--r-- | src/lib.rs | 36 | ||||
| -rw-r--r-- | src/tuners/fc0013.rs (renamed from src/devices/fc0013.rs) | 0 | ||||
| -rw-r--r-- | src/tuners/mod.rs (renamed from src/devices/mod.rs) | 0 | ||||
| -rw-r--r-- | src/tuners/r820t.rs (renamed from src/devices/r820t.rs) | 8 | ||||
| -rw-r--r-- | src/usb.rs | 33 |
6 files changed, 60 insertions, 34 deletions
@@ -44,7 +44,22 @@ Since there isn't (?) any good USB device mocking setup, for tests to pass an RT ## Design -Similarly to the original rtl-sdr driver, we use libusb via the `rusb` bindings as the main interface to issue commands to the rtl-sdr USB dongle. +### Overview + +RusTL-SDR is very similar to the original rtl-sdr driver. It uses libusb, via the [rusb](https://github.com/a1ien/rusb/) bindings, as the main interface to issue commands to the rtl-sdr USB dongle. + +### Lifecycle + +Devices generally go through the following lifecycle: + +1. Get a libusb context/handle, and find a compatible and supported RTL-SDR device +2. Initialize the device baseband +3. Probe the device for known tuners via the I2C interface +4. Run any special initialization required for the detected tuner +5. Interact with the device, usually this is where samples are read +6. Deinitialize the tuner +7. Deinitialize the baseband +8. Close the USB handle ## License @@ -1,9 +1,9 @@ extern crate rusb; -mod devices; +mod tuners; mod usb; -use devices::*; +use tuners::*; use usb::RtlSdrDeviceHandle; const INTERFACE_ID: u8 = 0; @@ -51,28 +51,24 @@ impl RtlSdr { handle.init_baseband(); handle.set_i2c_repeater(true); - let tuner: Box<dyn Tuner> = match self.search_tuner(&handle) { - Some(tuner) => match tuner { - r820t::TUNER_ID => Box::new(r820t::R820T::new(&handle)), - fc0013::TUNER_ID => Box::new(fc0013::FC0013::new(&handle)), - _ => { + { + let tuner: Box<dyn Tuner> = match self.search_tuner(&handle) { + Some(tuner) => match tuner { + r820t::TUNER_ID => Box::new(r820t::R820T::new(&handle)), + fc0013::TUNER_ID => Box::new(fc0013::FC0013::new(&handle)), + _ => { + println!("No valid tuner found"); + return; + } + }, + None => { println!("No valid tuner found"); return; } - }, - None => { - println!("No valid tuner found"); - return; - } - }; + }; - tuner.init(); - - // handle.deinit_baseband(); - - // if kernel_driver_attached { - // handle.attach_kernel_driver(); - // } + tuner.init(); + } } else { println!("No match for vid {} and pid {}", vid, pid); } diff --git a/src/devices/fc0013.rs b/src/tuners/fc0013.rs index 9eb03f4..9eb03f4 100644 --- a/src/devices/fc0013.rs +++ b/src/tuners/fc0013.rs diff --git a/src/devices/mod.rs b/src/tuners/mod.rs index cbd7edf..cbd7edf 100644 --- a/src/devices/mod.rs +++ b/src/tuners/mod.rs diff --git a/src/devices/r820t.rs b/src/tuners/r820t.rs index ec0f173..2638917 100644 --- a/src/devices/r820t.rs +++ b/src/tuners/r820t.rs @@ -28,7 +28,9 @@ impl<'a> R820T<'a> { } impl<'a> Drop for R820T<'a> { - fn drop(&mut self) {} + fn drop(&mut self) { + self.exit(); + } } impl<'a> Tuner for R820T<'a> { @@ -47,9 +49,7 @@ impl<'a> Tuner for R820T<'a> { self.handle.demod_write_reg(1, 0x15, 0x01, 1); } - fn exit(&self) { - unimplemented!() - } + fn exit(&self) {} fn set_freq(&self, _freq: u32) { unimplemented!() @@ -36,27 +36,37 @@ const CTRL_TIMEOUT: Duration = Duration::from_millis(300); pub struct RtlSdrDeviceHandle { handle: DeviceHandle<GlobalContext>, iface_id: u8, + kernel_driver_active: bool, } +/// A wrapper around libusb's DeviceHandle that implements +/// various rtl-sdr specific methods impl RtlSdrDeviceHandle { - /// A wrapper around libusb's DeviceHandle that implements - /// various rtl-sdr specific methods pub fn new(handle: DeviceHandle<GlobalContext>, iface_id: u8) -> RtlSdrDeviceHandle { - RtlSdrDeviceHandle { handle, iface_id } + let mut handle = RtlSdrDeviceHandle { + handle, + iface_id, + kernel_driver_active: false, + }; + handle.detach_kernel_driver(); + handle } - pub fn detach_kernel_driver(&mut self) -> bool { - match self.handle.kernel_driver_active(self.iface_id) { + pub fn detach_kernel_driver(&mut self) { + let active = match self.handle.kernel_driver_active(self.iface_id) { Ok(true) => { self.handle.detach_kernel_driver(self.iface_id).ok(); true } _ => false, - } + }; + self.kernel_driver_active = active; } pub fn attach_kernel_driver(&mut self) { - self.handle.attach_kernel_driver(self.iface_id).ok(); + if self.kernel_driver_active { + self.handle.attach_kernel_driver(self.iface_id).ok(); + } } pub fn claim_interface(&mut self) { @@ -237,9 +247,14 @@ impl RtlSdrDeviceHandle { } pub fn deinit_baseband(&self) { - // deinit tuner? - // power off demod and ADCs self.write_reg(BLOCK_SYSB, ADDR_SYS_DEMOD_CTL, 0x20, 1); } } + +impl Drop for RtlSdrDeviceHandle { + fn drop(&mut self) { + self.deinit_baseband(); + self.attach_kernel_driver(); + } +} |
