diff options
| author | Yuval Adam <_@yuv.al> | 2021-04-28 09:48:55 +0300 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2021-04-28 09:48:55 +0300 |
| commit | 25db452b3fb9c83ff8600362467bcde63591d67f (patch) | |
| tree | 80e35e5ec18c6559917829f810d64b1be0f66070 | |
| parent | 5979051bd97b61762567fb4710de3dc8a69135c6 (diff) | |
WIP
| -rw-r--r-- | src/lib.rs | 111 | ||||
| -rw-r--r-- | src/tuners/fc0013.rs | 12 | ||||
| -rw-r--r-- | src/tuners/mod.rs | 12 | ||||
| -rw-r--r-- | src/tuners/r820t.rs | 16 | ||||
| -rw-r--r-- | src/usb.rs | 124 | ||||
| -rw-r--r-- | src/utils/rustl_test.rs | 6 |
6 files changed, 136 insertions, 145 deletions
@@ -5,11 +5,17 @@ extern crate rusb; mod tuners; mod usb; -use log::{info, trace}; +use log::{error, info, trace, warn}; +use std::convert::TryInto; +use tuners::*; use usb::RtlSdrDeviceHandle; const INTERFACE_ID: u8 = 0; +const DEF_RTL_XTAL_FREQ: u32 = 28800000; +// const MIN_RTL_XTAL_FREQ: u32 = DEF_RTL_XTAL_FREQ - 1000; +// const MAX_RTL_XTAL_FREQ: u32 = DEF_RTL_XTAL_FREQ + 1000; + const KNOWN_DEVICES: [(u16, u16, &str); 2] = [ (0x0bda, 0x2832, "Generic RTL2832U"), (0x0bda, 0x2838, "Generic RTL2832U OEM"), @@ -17,13 +23,17 @@ const KNOWN_DEVICES: [(u16, u16, &str); 2] = [ pub struct RtlSdr { handle: RtlSdrDeviceHandle, + tuner: Option<Box<dyn Tuner>>, } impl RtlSdr { pub fn new() -> RtlSdr { pretty_env_logger::init(); let handle = Self::open_device().unwrap(); - RtlSdr { handle } + let tuner_id = Self::search_tuner(&handle).unwrap(); + let tuner = Self::init_tuner(tuner_id, &handle); + + RtlSdr { handle, tuner } } pub fn open_device() -> Option<RtlSdrDeviceHandle> { @@ -49,8 +59,6 @@ impl RtlSdr { handle.init_baseband(); handle.set_i2c_repeater(true); - handle.init_tuner(); - return Some(handle); } } @@ -58,8 +66,99 @@ impl RtlSdr { None } - pub fn set_sample_rate(&self, samp_rate: u32) { - self.handle.set_sample_rate(samp_rate); + 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 tuner {} at I2C address {:#02x} and checking address {:#02x}", + tuner_info.name, + 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(e) => { + warn!("Reading failed with {}, continuing", e); + } + }; + } + None + } + + pub fn init_tuner(tuner_id: &str, handle: &RtlSdrDeviceHandle) -> Option<Box<dyn Tuner>> { + let tuner: Option<Box<dyn Tuner>> = match tuner_id { + // r820t::TUNER_ID => Some(Tuners::R820T(r820t::R820T::new(&self))), + // fc0013::TUNER_ID => Some(Tuners::FC0013(fc0013::FC0013::new(&self))), + 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."); + None + } + }; + info!("Found tuner r820t"); + tuner + } + + pub fn set_freq(&self) {} + + pub fn set_sample_rate(self, samp_rate: u32) { + let real_rsamp_ratio: u32; + + // check if the rate is supported by the resampler + if (samp_rate <= 225000) + || (samp_rate > 3200000) + || ((samp_rate > 300000) && (samp_rate <= 900000)) + { + error!("Invalid sample rate: {} Hz", samp_rate); + } + + let mut rsamp_ratio: u32 = (DEF_RTL_XTAL_FREQ * (2 ^ 22)) / samp_rate; + rsamp_ratio &= 0x0ffffffc; + + real_rsamp_ratio = rsamp_ratio | ((rsamp_ratio & 0x08000000) << 1); + let real_rate: f64 = ((DEF_RTL_XTAL_FREQ * (2 ^ 22)) / real_rsamp_ratio).into(); + info!("Exact sample rate is: {} Hz", real_rate); + + self.handle.set_i2c_repeater(true); + self.tuner + .unwrap() + .set_bandwidth(real_rate as u32, &self.handle); + self.handle.set_i2c_repeater(false); + + let mut tmp: u16 = (rsamp_ratio >> 16).try_into().unwrap(); + self.handle.demod_write_reg(1, 0x9f, tmp, 2); + tmp = (rsamp_ratio & 0xffff).try_into().unwrap(); + self.handle.demod_write_reg(1, 0xa1, tmp, 2); + // self.set_sample_freq_corr(); + + // reset demod (bit 3, soft_rst) + self.handle.demod_write_reg(1, 0x01, 0x14, 1); + self.handle.demod_write_reg(1, 0x01, 0x10, 1); + + // self.set_offset_tuning(); + } + + pub fn set_if_freq(&self, freq: u32) { + let rtl_xtal: u32 = DEF_RTL_XTAL_FREQ; // need to apply PPM correction + let base = 1u32 << 22; + let if_freq: i32 = (freq as f64 * base as f64 / rtl_xtal as f64 * -1f64) as i32; + + let tmp = ((if_freq >> 16) as u16) & 0x3f; + self.handle.demod_write_reg(1, 0x19, tmp, 1); + let tmp = ((if_freq >> 8) as u16) & 0xff; + self.handle.demod_write_reg(1, 0x1a, tmp, 1); + let tmp = if_freq as u16 & 0xff; + self.handle.demod_write_reg(1, 0x1b, tmp, 1); } pub fn set_test_mode(&self, on: bool) { diff --git a/src/tuners/fc0013.rs b/src/tuners/fc0013.rs index b7d5398..b67b6c3 100644 --- a/src/tuners/fc0013.rs +++ b/src/tuners/fc0013.rs @@ -33,27 +33,27 @@ impl Tuner for FC0013 { unimplemented!() } - fn exit(&self) { + fn exit(&self, handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_freq(&self, _freq: u32) { + fn set_frequency(&self, _freq: u32, handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_bandwidth(&mut self, _bw: u32, _rate: u32, _handle: &RtlSdrDeviceHandle) { + fn set_bandwidth(&mut self, _bw: u32, _handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_gain(&self, _gain: u32) { + fn set_gain(&self, _gain: u32, handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_if_gain(&self, _if_gain: u32) { + fn set_if_gain(&self, _if_gain: u32, handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_gain_mode(&self, _mode: bool) { + fn set_gain_mode(&self, _mode: bool, handle: &RtlSdrDeviceHandle) { unimplemented!() } diff --git a/src/tuners/mod.rs b/src/tuners/mod.rs index ac354b1..7734126 100644 --- a/src/tuners/mod.rs +++ b/src/tuners/mod.rs @@ -16,12 +16,12 @@ pub struct TunerInfo { pub trait Tuner { fn init(&self, handle: &RtlSdrDeviceHandle); - fn exit(&self); - fn set_freq(&self, freq: u32); - fn set_bandwidth(&mut self, bw: u32, rate: u32, handle: &RtlSdrDeviceHandle); - fn set_gain(&self, gain: u32); - fn set_if_gain(&self, if_gain: u32); - fn set_gain_mode(&self, mode: bool); + fn exit(&self, handle: &RtlSdrDeviceHandle); + fn set_frequency(&self, freq: u32, handle: &RtlSdrDeviceHandle); + fn set_bandwidth(&mut self, rate: u32, handle: &RtlSdrDeviceHandle); + fn set_gain(&self, gain: u32, handle: &RtlSdrDeviceHandle); + fn set_if_gain(&self, if_gain: u32, handle: &RtlSdrDeviceHandle); + fn set_gain_mode(&self, mode: bool, handle: &RtlSdrDeviceHandle); fn display(&self) -> &str; } diff --git a/src/tuners/r820t.rs b/src/tuners/r820t.rs index 85f57ad..1c685ce 100644 --- a/src/tuners/r820t.rs +++ b/src/tuners/r820t.rs @@ -208,8 +208,8 @@ impl R820T { handle.demod_write_reg(1, 0x15, 0x01, 1); } - fn shadow_store(&self, reg: u8, _val: u8, len: usize) { - let r = reg as usize - REG_SHADOW_START; + fn shadow_store(&self, reg: u8, _val: u8, _len: usize) { + let _r = reg as usize - REG_SHADOW_START; // if r < 0 { // len = len + r; // } @@ -275,13 +275,13 @@ impl Tuner for R820T { handle.demod_write_reg(1, 0x15, 0x01, 1); } - fn exit(&self) {} + fn exit(&self, _handle: &RtlSdrDeviceHandle) {} - fn set_freq(&self, _freq: u32) { + fn set_frequency(&self, _freq: u32, _handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_bandwidth(&mut self, mut bw: u32, rate: u32, handle: &RtlSdrDeviceHandle) { + fn set_bandwidth(&mut self, mut bw: u32, _handle: &RtlSdrDeviceHandle) { const FILT_HP_BW1: u32 = 350000; const FILT_HP_BW2: u32 = 380000; @@ -340,15 +340,15 @@ impl Tuner for R820T { self.write_reg_mask(0x0b, reg_0b, 0xef); } - fn set_gain(&self, _gain: u32) { + fn set_gain(&self, _gain: u32, _handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_if_gain(&self, _if_gain: u32) { + fn set_if_gain(&self, _if_gain: u32, _handle: &RtlSdrDeviceHandle) { unimplemented!() } - fn set_gain_mode(&self, _mode: bool) { + fn set_gain_mode(&self, _mode: bool, _handle: &RtlSdrDeviceHandle) { unimplemented!() } @@ -4,7 +4,6 @@ extern crate rusb; use log::{error, info, trace, warn}; use rusb::{DeviceHandle, Direction, GlobalContext, Recipient, RequestType}; -use std::convert::TryInto; use std::time::Duration; use tuners::*; @@ -32,16 +31,12 @@ const FIR_DEFAULT: [u8; FIR_LENGTH] = [ 0x74, 0x19, 0x41, 0xa5, ]; -const DEF_RTL_XTAL_FREQ: u32 = 28800000; -// const MIN_RTL_XTAL_FREQ: u32 = DEF_RTL_XTAL_FREQ - 1000; -// const MAX_RTL_XTAL_FREQ: u32 = DEF_RTL_XTAL_FREQ + 1000; - const CTRL_TIMEOUT: Duration = Duration::from_millis(300); pub struct RtlSdrDeviceHandle { handle: DeviceHandle<GlobalContext>, - tuner: Option<Tuners>, - // tuner: Option<Box<dyn Tuner>>, + // tuner: Option<Tuners>, + tuner: Option<Box<dyn Tuner>>, iface_id: u8, kernel_driver_active: bool, } @@ -61,61 +56,6 @@ impl RtlSdrDeviceHandle { handle } - pub fn init_tuner(&mut self) { - let tuner_id: &str = match self.search_tuner() { - Some(tid) => { - trace!("Found tuner ID {}", tid); - tid - } - None => "", - }; - - let tuner: Option<Tuners> = match tuner_id { - r820t::TUNER_ID => Some(Tuners::R820T(r820t::R820T::new(&self))), - fc0013::TUNER_ID => Some(Tuners::FC0013(fc0013::FC0013::new(&self))), - // r820t::TUNER_ID => Some(Box::new(r820t::R820T::new(&self))), - // fc0013::TUNER_ID => Some(Box::new(fc0013::FC0013::new(&self))), - _ => { - error!("Could not find any valid tuner."); - None - } - }; - - self.tuner = tuner; - - info!("Found tuner r820t"); - } - - /// Probe all known tuners at their I2C addresses - /// and search for expected return values - fn search_tuner(&self) -> Option<&str> { - for tuner_info in KNOWN_TUNERS.iter() { - let regval = self.i2c_read_reg(tuner_info.i2c_addr, tuner_info.check_addr); - trace!( - "Probing tuner {} at I2C address {:#02x} and checking address {:#02x}", - tuner_info.name, - 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(e) => { - warn!("Reading failed with {}, continuing", e); - } - }; - } - None - } - pub fn detach_kernel_driver(&mut self) { let active = match self.handle.kernel_driver_active(self.iface_id) { Ok(true) => { @@ -305,54 +245,6 @@ impl RtlSdrDeviceHandle { self.demod_write_reg(0, 0x0d, 0x83, 1); } - pub fn set_if_freq(&self, freq: u32) { - let rtl_xtal: u32 = DEF_RTL_XTAL_FREQ; // need to apply PPM correction - let base = 1u32 << 22; - let if_freq: i32 = (freq as f64 * base as f64 / rtl_xtal as f64 * -1f64) as i32; - - let tmp = ((if_freq >> 16) as u16) & 0x3f; - self.demod_write_reg(1, 0x19, tmp, 1); - let tmp = ((if_freq >> 8) as u16) & 0xff; - self.demod_write_reg(1, 0x1a, tmp, 1); - let tmp = if_freq as u16 & 0xff; - self.demod_write_reg(1, 0x1b, tmp, 1); - } - - pub fn set_sample_rate(&self, samp_rate: u32) { - let real_rsamp_ratio: u32; - - // check if the rate is supported by the resampler - if (samp_rate <= 225000) - || (samp_rate > 3200000) - || ((samp_rate > 300000) && (samp_rate <= 900000)) - { - error!("Invalid sample rate: {} Hz", samp_rate); - } - - let mut rsamp_ratio: u32 = (DEF_RTL_XTAL_FREQ * (2 ^ 22)) / samp_rate; - rsamp_ratio &= 0x0ffffffc; - - real_rsamp_ratio = rsamp_ratio | ((rsamp_ratio & 0x08000000) << 1); - let real_rate: f64 = ((DEF_RTL_XTAL_FREQ * (2 ^ 22)) / real_rsamp_ratio).into(); - info!("Exact sample rate is: {} Hz", real_rate); - - self.set_i2c_repeater(true); - // 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(); - self.demod_write_reg(1, 0x9f, tmp, 2); - tmp = (rsamp_ratio & 0xffff).try_into().unwrap(); - self.demod_write_reg(1, 0xa1, tmp, 2); - // self.set_sample_freq_corr(); - - // reset demod (bit 3, soft_rst) - self.demod_write_reg(1, 0x01, 0x14, 1); - self.demod_write_reg(1, 0x01, 0x10, 1); - - // self.set_offset_tuning(); - } - pub fn reset_buffer(&self) { self.write_reg(BLOCK_USBB, ADDR_USB_EPA_CTL, 0x1002, 2); self.write_reg(BLOCK_USBB, ADDR_USB_EPA_CTL, 0x0000, 2); @@ -364,9 +256,9 @@ impl RtlSdrDeviceHandle { } } -// impl Drop for RtlSdrDeviceHandle { -// fn drop(self) { -// self.deinit_baseband(); -// self.attach_kernel_driver(); -// } -// } +impl Drop for RtlSdrDeviceHandle { + fn drop(&mut self) { + self.deinit_baseband(); + self.attach_kernel_driver(); + } +} diff --git a/src/utils/rustl_test.rs b/src/utils/rustl_test.rs index d1a45c8..b71f094 100644 --- a/src/utils/rustl_test.rs +++ b/src/utils/rustl_test.rs @@ -4,9 +4,9 @@ const DEFAULT_BUF_LENGTH: usize = 16 * 16384; pub fn main() { println!("Starting rustl_test"); let r = rustl_sdr::RtlSdr::new(); - // r.set_sample_rate(DEFAULT_SAMPLE_RATE); - // r.set_test_mode(true); - // r.reset_buffer(); + r.set_sample_rate(DEFAULT_SAMPLE_RATE); + r.set_test_mode(true); + r.reset_buffer(); println!("Reading buffers in sync mode"); loop { let samples = r.read_sync(DEFAULT_BUF_LENGTH); |
