diff options
| author | Yuval Adam <_@yuv.al> | 2021-04-18 15:13:39 +0300 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2021-04-18 15:13:39 +0300 |
| commit | a4fb29bee94d68b8956158f603b0366af98507e9 (patch) | |
| tree | 75d5cd328c37360371d27c87e28687a109a9cb2e /src | |
| parent | 4271c0e5e6ea1ccc5f57500530c772636dd08736 (diff) | |
Move tuner into USB handle
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 68 | ||||
| -rw-r--r-- | src/tuners/mod.rs | 2 | ||||
| -rw-r--r-- | src/usb.rs | 65 |
3 files changed, 66 insertions, 69 deletions
@@ -5,8 +5,7 @@ extern crate rusb; mod tuners; mod usb; -use log::{error, info, trace, warn}; -use tuners::*; +use log::{info, trace}; use usb::RtlSdrDeviceHandle; const INTERFACE_ID: u8 = 0; @@ -16,24 +15,15 @@ const KNOWN_DEVICES: [(u16, u16, &str); 2] = [ (0x0bda, 0x2838, "Generic RTL2832U OEM"), ]; -const KNOWN_TUNERS: [TunerInfo; 2] = [r820t::TUNER_INFO, fc0013::TUNER_INFO]; - pub struct RtlSdr { handle: RtlSdrDeviceHandle, - tuner: Box<dyn Tuner>, } impl RtlSdr { pub fn new() -> RtlSdr { pretty_env_logger::init(); - let handle = Self::open_device().unwrap(); - let tuner = Self::open_tuner(&handle).unwrap(); - - RtlSdr { - handle: handle, - tuner: tuner, - } + RtlSdr { handle: handle } } pub fn open_device() -> Option<RtlSdrDeviceHandle> { @@ -66,60 +56,6 @@ impl RtlSdr { return None; } - fn open_tuner(handle: &RtlSdrDeviceHandle) -> Option<Box<dyn Tuner>> { - let tuner_id = match Self::search_tuner(&handle) { - Some(tid) => { - info!("Got tuner ID {}", tid); - tid - } - None => { - error!("Could not find a value tuner, aborting."); - return None; - } - }; - - let tuner: Option<Box<dyn Tuner>> = match tuner_id { - r820t::TUNER_ID => Some(Box::new(r820t::R820T::new(&handle))), - fc0013::TUNER_ID => Some(Box::new(fc0013::FC0013::new(&handle))), - _ => { - error!("Could not find any valid tuner, aborting."); - return None; - } - }; - - // info!("Found tuner {}", self.tuner.unwrap().display()); - return tuner; - } - - /// Probe all known tuners at their I2C addresses - /// and search for expected return values - fn search_tuner(handle: &RtlSdrDeviceHandle) -> Option<&str> { - for tuner_info in KNOWN_TUNERS.iter() { - let regval = handle.i2c_read_reg(tuner_info.i2c_addr, tuner_info.check_addr); - trace!( - "Probing I2C address {:#02x} checking address {:#02x}", - tuner_info.i2c_addr, - tuner_info.check_addr, - ); - match regval { - Ok(val) => { - trace!( - "Expecting value {:#02x}, got value {:#02x}", - tuner_info.check_val, - val - ); - if val == tuner_info.check_val { - return Some(tuner_info.id); - } - } - Err(_) => { - warn!("Reading failed, continuing"); - } - }; - } - None - } - pub fn set_sample_rate(&self, samp_rate: u32) { self.handle.set_sample_rate(samp_rate); } diff --git a/src/tuners/mod.rs b/src/tuners/mod.rs index 269ff26..626fc9e 100644 --- a/src/tuners/mod.rs +++ b/src/tuners/mod.rs @@ -3,6 +3,8 @@ use super::RtlSdrDeviceHandle; pub mod fc0013; pub mod r820t; +pub const KNOWN_TUNERS: [TunerInfo; 2] = [r820t::TUNER_INFO, fc0013::TUNER_INFO]; + pub struct TunerInfo { pub id: &'static str, pub name: &'static str, @@ -2,10 +2,11 @@ extern crate log; extern crate pretty_env_logger; extern crate rusb; -use log::{error, info}; +use log::{error, info, trace, warn}; use rusb::{DeviceHandle, Direction, GlobalContext, Recipient, RequestType}; use std::convert::TryInto; use std::time::Duration; +use tuners::*; // const BLOCK_DEMODB: u16 = 0; const BLOCK_USBB: u16 = 1; @@ -39,6 +40,7 @@ const CTRL_TIMEOUT: Duration = Duration::from_millis(300); pub struct RtlSdrDeviceHandle { handle: DeviceHandle<GlobalContext>, + tuner: Option<Box<dyn Tuner>>, iface_id: u8, kernel_driver_active: bool, } @@ -47,16 +49,73 @@ pub struct RtlSdrDeviceHandle { /// various rtl-sdr specific methods impl RtlSdrDeviceHandle { pub fn new(handle: DeviceHandle<GlobalContext>, iface_id: u8) -> RtlSdrDeviceHandle { - pretty_env_logger::init(); let mut handle = RtlSdrDeviceHandle { handle, + tuner: None, iface_id, kernel_driver_active: false, }; + + handle.tuner = Self::open_tuner(&handle); + handle.detach_kernel_driver(); handle } + fn open_tuner(handle: &RtlSdrDeviceHandle) -> Option<Box<dyn Tuner>> { + let tuner_id = match Self::search_tuner(&handle) { + Some(tid) => { + info!("Got tuner ID {}", tid); + tid + } + None => { + error!("Could not find a value tuner, aborting."); + return None; + } + }; + + let tuner: Option<Box<dyn Tuner>> = match tuner_id { + r820t::TUNER_ID => Some(Box::new(r820t::R820T::new(&handle))), + fc0013::TUNER_ID => Some(Box::new(fc0013::FC0013::new(&handle))), + _ => { + error!("Could not find any valid tuner, aborting."); + return None; + } + }; + + // info!("Found tuner {}", self.tuner.unwrap().display()); + return tuner; + } + + /// Probe all known tuners at their I2C addresses + /// and search for expected return values + fn search_tuner(handle: &RtlSdrDeviceHandle) -> Option<&str> { + for tuner_info in KNOWN_TUNERS.iter() { + let regval = handle.i2c_read_reg(tuner_info.i2c_addr, tuner_info.check_addr); + trace!( + "Probing I2C address {:#02x} checking address {:#02x}", + tuner_info.i2c_addr, + tuner_info.check_addr, + ); + match regval { + Ok(val) => { + trace!( + "Expecting value {:#02x}, got value {:#02x}", + tuner_info.check_val, + val + ); + if val == tuner_info.check_val { + return Some(tuner_info.id); + } + } + Err(_) => { + warn!("Reading failed, continuing"); + } + }; + } + None + } + pub fn detach_kernel_driver(&mut self) { let active = match self.handle.kernel_driver_active(self.iface_id) { Ok(true) => { @@ -270,7 +329,7 @@ impl RtlSdrDeviceHandle { info!("Exact sample rate is: {} Hz", real_rate); self.set_i2c_repeater(true); - // self.tuner.set_bw(self.handle); + self.tuner.as_ref().unwrap().set_bw(real_rate as u32, &self); self.set_i2c_repeater(false); let mut tmp: u16 = (rsamp_ratio >> 16).try_into().unwrap(); |
