summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2021-04-16 23:56:40 +0300
committerYuval Adam <_@yuv.al>2021-04-17 10:33:57 +0300
commitc430b4b2f5467a0b86d2312f742e5b4ece4f4bad (patch)
treefab4ed16477ee94a3527f131bfe9c521345427de
parentcc3a300afcba8fffaee5feb5f56792cfd697bf28 (diff)
Cleanup deinit and document lifecyclev0.2
-rw-r--r--README.md17
-rw-r--r--src/lib.rs36
-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.rs33
6 files changed, 60 insertions, 34 deletions
diff --git a/README.md b/README.md
index 94e1af1..c114db7 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/src/lib.rs b/src/lib.rs
index d068e57..b350616 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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!()
diff --git a/src/usb.rs b/src/usb.rs
index 92f99d1..0a0003f 100644
--- a/src/usb.rs
+++ b/src/usb.rs
@@ -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();
+ }
+}