summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2021-04-28 09:48:55 +0300
committerYuval Adam <_@yuv.al>2021-04-28 09:48:55 +0300
commit25db452b3fb9c83ff8600362467bcde63591d67f (patch)
tree80e35e5ec18c6559917829f810d64b1be0f66070
parent5979051bd97b61762567fb4710de3dc8a69135c6 (diff)
WIP
-rw-r--r--src/lib.rs111
-rw-r--r--src/tuners/fc0013.rs12
-rw-r--r--src/tuners/mod.rs12
-rw-r--r--src/tuners/r820t.rs16
-rw-r--r--src/usb.rs124
-rw-r--r--src/utils/rustl_test.rs6
6 files changed, 136 insertions, 145 deletions
diff --git a/src/lib.rs b/src/lib.rs
index b5664a5..ca9d634 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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!()
}
diff --git a/src/usb.rs b/src/usb.rs
index 4a51db1..3499692 100644
--- a/src/usb.rs
+++ b/src/usb.rs
@@ -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);