Updates to account, ui, etc
This commit is contained in:
@@ -21,25 +21,42 @@ pub const DEVICE_RTL2832U: DeviceInfo = DeviceInfo {
|
||||
pid: 0x2832,
|
||||
};
|
||||
|
||||
// Timeout
|
||||
pub const TIMEOUT: Duration = Duration::from_secs(1);
|
||||
|
||||
// pub const DEFAULT_BUFFER_LENGTH: usize = 4096;
|
||||
pub const DEFAULT_BUFFER_LENGTH: usize = 64;
|
||||
pub const FIR_LENGTH: usize = 16;
|
||||
|
||||
// Request Types
|
||||
pub const REQ_CTRL_OUT: u8 =
|
||||
rusb::constants::LIBUSB_ENDPOINT_OUT | rusb::constants::LIBUSB_REQUEST_TYPE_VENDOR;
|
||||
|
||||
// Blocks
|
||||
pub const BLOCK_DEMOD: u16 = 0;
|
||||
pub const BLOCK_USB: u16 = 1;
|
||||
pub const BLOCK_SYS: u16 = 2;
|
||||
pub const BLOCK_TUN: u16 = 3;
|
||||
pub const BLOCK_ROM: u16 = 4;
|
||||
pub const BLOCK_IRB: u16 = 5;
|
||||
pub const BLOCK_IIC: u16 = 6;
|
||||
|
||||
// Registers
|
||||
pub const DEMOD_CTL: u16 = 0x3000;
|
||||
pub const DEMOD_CTL_1: u16 = 0x300b;
|
||||
|
||||
// USB
|
||||
pub const USB_EPA_CTL: u16 = 0x2148;
|
||||
pub const USB_SYSCTL: u16 = 0x2000;
|
||||
pub const USB_EPA_MAXPKT: u16 = 0x2158;
|
||||
|
||||
/// ADS-B downlink frequency (1090 MHz)
|
||||
pub const ADSB_FREQUENCY_HZ: u32 = 1_090_000_000;
|
||||
|
||||
/// RTL-SDR sample rate in samples/second.
|
||||
pub const SAMPLE_RATE_HZ: u32 = 2_048_000;
|
||||
|
||||
pub const DEFAULT_FIR: &'static [i32; FIR_LENGTH] = &[
|
||||
-54, -36, -41, -40, -32, -14, 14, 53, 101, 156, 215, 273, 327, 372, 404, 421,
|
||||
];
|
||||
// pub const DEFAULT_BUFFER_LENGTH: usize = 4096;
|
||||
pub const DEFAULT_BUFFER_LENGTH: usize = 64;
|
||||
pub const DEFAULT_RTL_XTAL_FREQ: u32 = 28_800_000;
|
||||
pub const MIN_RTL_XTAL_FREQ: u32 = DEFAULT_RTL_XTAL_FREQ - 1000;
|
||||
pub const MAX_RTL_XTAL_FREQ: u32 = DEFAULT_RTL_XTAL_FREQ + 1000;
|
||||
|
||||
@@ -7,8 +7,9 @@ use rusb::{
|
||||
};
|
||||
use crate::error::{Error, Result};
|
||||
use crate::constants::{
|
||||
ADSB_FREQUENCY_HZ, BLOCK_USB, DEFAULT_BUFFER_LENGTH, REQ_CTRL_OUT, SAMPLE_RATE_HZ, TIMEOUT,
|
||||
USB_EPA_CTL, USB_SYSCTL,
|
||||
ADSB_FREQUENCY_HZ, BLOCK_SYS, BLOCK_USB, DEFAULT_BUFFER_LENGTH, DEFAULT_FIR,
|
||||
DEFAULT_RTL_XTAL_FREQ, DEMOD_CTL, DEMOD_CTL_1, REQ_CTRL_OUT, SAMPLE_RATE_HZ, TIMEOUT,
|
||||
USB_EPA_CTL, USB_EPA_MAXPKT, USB_SYSCTL,
|
||||
};
|
||||
|
||||
/// rusb/libusb implementation of `RtlSdrDevice`
|
||||
@@ -83,7 +84,7 @@ impl RtlSdrDevice {
|
||||
Some(e) => e,
|
||||
None => return Err(Error::new("Unable to find endpoint on device")),
|
||||
};
|
||||
log::debug!("Found readable endpoint: {:?}", endpoint.to_string());
|
||||
log::debug!("Found readable endpoint: {}", endpoint.to_string());
|
||||
|
||||
let mut sdr = Self::new(handle, endpoint);
|
||||
|
||||
@@ -158,6 +159,10 @@ impl RtlSdrDevice {
|
||||
|
||||
self.test_write()?;
|
||||
|
||||
self.initialize_baseband()?;
|
||||
|
||||
self.set_i2c_repeater(true)?;
|
||||
|
||||
// Reset the internal USB buffer
|
||||
self.reset_buffer()?;
|
||||
|
||||
@@ -191,6 +196,7 @@ impl RtlSdrDevice {
|
||||
.map_err(|err| Error::new(format!("Failed to set alternate setting: {:?}", err)))
|
||||
}
|
||||
|
||||
/// Attempt to write a test message, and reset the device on a failure
|
||||
fn test_write(&self) -> Result<()> {
|
||||
log::trace!("Testing write to device...");
|
||||
let length = ctrl_write_register(&self.handle, BLOCK_USB, USB_SYSCTL, 0x89, 1)?;
|
||||
@@ -215,6 +221,66 @@ impl RtlSdrDevice {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset_demod(&self) -> Result<()> {
|
||||
log::trace!("Resetting demod...");
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x01, 0x14, 1)
|
||||
.map_err(|err| Error::new(format!("Failed to reset the internal demod: {:?}", err)))?;
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x01, 0x10, 1)
|
||||
.map_err(|err| Error::new(format!("Failed to reset the internal demod: {:?}", err)))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn initialize_baseband(&self) -> Result<()> {
|
||||
// Initialize the USB
|
||||
ctrl_write_register(&self.handle, BLOCK_USB, USB_SYSCTL, 0x09, 1)?;
|
||||
ctrl_write_register(&self.handle, BLOCK_USB, USB_EPA_MAXPKT, 0x0002, 2)?;
|
||||
ctrl_write_register(&self.handle, BLOCK_USB, USB_EPA_CTL, 0x1002, 2)?;
|
||||
|
||||
// Power on demod
|
||||
ctrl_write_register(&self.handle, BLOCK_SYS, DEMOD_CTL_1, 0x22, 1)?;
|
||||
ctrl_write_register(&self.handle, BLOCK_SYS, DEMOD_CTL, 0xe8, 1)?;
|
||||
|
||||
// Reset demod
|
||||
self.reset_demod()?;
|
||||
|
||||
// Disable spectrum inversion and adjust channel rejection
|
||||
ctrl_write_register(&self.handle, 1, 0x15, 0x00, 1)?;
|
||||
ctrl_write_register(&self.handle, 1, 0x16, 0x00, 2)?;
|
||||
|
||||
// Clear DDC shift and IF registers
|
||||
for i in 0..5 {
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x16 + i, 0x00, 1)?;
|
||||
}
|
||||
self.set_fir(DEFAULT_FIR)?;
|
||||
|
||||
// info!("Enable SDR mode, disable DAGC (bit 5)");
|
||||
demod_ctrl_write_register(&self.handle, 0, 0x19, 0x05, 1)?;
|
||||
|
||||
// info!("Init FSM state-holding register");
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x93, 0xf0, 1)?;
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x94, 0x0f, 1)?;
|
||||
|
||||
// Disable AGC (en_dagc, bit 0) (seems to have no effect)
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x11, 0x00, 1)?;
|
||||
|
||||
// Disable RF and IF AGC loop
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x04, 0x00, 1)?;
|
||||
|
||||
// Disable PID filter
|
||||
demod_ctrl_write_register(&self.handle, 0, 0x61, 0x60, 1)?;
|
||||
|
||||
// opt_adc_iq = 0, default ADC_I/ADC_Q datapath
|
||||
demod_ctrl_write_register(&self.handle, 0, 0x06, 0x80, 1)?;
|
||||
|
||||
// Enable Zero-IF mode, DC cancellation, and IQ estimation/compensation
|
||||
demod_ctrl_write_register(&self.handle, 1, 0xb1, 0x1b, 1)?;
|
||||
|
||||
// Disable 4.096 MHz clock output on pin TP_CK0
|
||||
demod_ctrl_write_register(&self.handle, 0, 0x0d, 0x83, 1)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_center_frequency(&mut self, frequency: u32) -> Result<()> {
|
||||
log::trace!("Setting center_frequency to {}Hz", frequency);
|
||||
self.frequency = frequency;
|
||||
@@ -223,7 +289,77 @@ impl RtlSdrDevice {
|
||||
|
||||
fn set_sample_rate(&mut self, rate: u32) -> Result<()> {
|
||||
log::trace!("Setting sample_rate to {}Hz", rate);
|
||||
self.rate = rate;
|
||||
if rate <= 225_000 || rate > 3_200_000 || (rate > 300000 && rate <= 900000) {
|
||||
return Err(Error::new(format!("Invalid sample rate: {} Hz", rate)));
|
||||
}
|
||||
|
||||
let rsamp_ratio =
|
||||
((DEFAULT_RTL_XTAL_FREQ as u128 * 2_u128.pow(22) / rate as u128) & 0x0ffffffc) as u128;
|
||||
log::trace!(
|
||||
"Sample rate: {}, xtal: {}, rsamp_ratio: {}",
|
||||
rate,
|
||||
DEFAULT_RTL_XTAL_FREQ,
|
||||
rsamp_ratio
|
||||
);
|
||||
let real_resamp_ratio = rsamp_ratio | ((rsamp_ratio & 0x08000000) << 1);
|
||||
let real_rate =
|
||||
(DEFAULT_RTL_XTAL_FREQ as u128 * 2_u128.pow(22)) as f64 / real_resamp_ratio as f64;
|
||||
if rate as f64 != real_rate {
|
||||
log::trace!("Exact sample rate is {} Hz", real_rate);
|
||||
}
|
||||
|
||||
self.rate = real_rate as u32;
|
||||
|
||||
let mut tmp: u16 = (rsamp_ratio >> 16) as u16;
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x9f, tmp, 2)?;
|
||||
tmp = (rsamp_ratio & 0xffff) as u16;
|
||||
demod_ctrl_write_register(&self.handle, 1, 0xa1, tmp, 2)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_fir(&self, fir: &[i32; 16]) -> Result<()> {
|
||||
log::trace!("Setting fir to {:?}", fir);
|
||||
const TMP_LEN: usize = 20;
|
||||
let mut tmp: [u8; TMP_LEN] = [0; TMP_LEN];
|
||||
// First 8 values are i8
|
||||
for i in 0..8 {
|
||||
let val = fir[i];
|
||||
if val < -128 || val > 127 {
|
||||
panic!("i8 FIR coefficient out of bounds! {}", val);
|
||||
}
|
||||
tmp[i] = val as u8;
|
||||
}
|
||||
// Next 12 are i12, so don't line up with byte boundaries and need to unpack
|
||||
// 12 i12 values from 4 pairs of bytes in fir. Example:
|
||||
// fir: 4b5, 7f8, 3e8, 619
|
||||
// tmp: 4b, 57, f8, 3e, 86, 19
|
||||
for i in (0..8).step_by(2) {
|
||||
let val0 = fir[8 + i];
|
||||
let val1 = fir[8 + i + 1];
|
||||
if val0 < -2048 || val0 > 2047 {
|
||||
panic!("i12 FIR coefficient out of bounds: {}", val0)
|
||||
} else if val1 < -2048 || val1 > 2047 {
|
||||
panic!("i12 FIR coefficient out of bounds: {}", val1)
|
||||
}
|
||||
tmp[8 + i * 3 / 2] = (val0 >> 4) as u8;
|
||||
tmp[8 + i * 3 / 2 + 1] = ((val0 << 4) | ((val1 >> 8) & 0x0f)) as u8;
|
||||
tmp[8 + i * 3 / 2 + 2] = val1 as u8;
|
||||
}
|
||||
|
||||
for i in 0..TMP_LEN {
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x1c + i as u16, tmp[i] as u16, 1)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_i2c_repeater(&self, enabled: bool) -> Result<()> {
|
||||
let value = match enabled {
|
||||
true => 0x18,
|
||||
false => 0x10,
|
||||
};
|
||||
|
||||
demod_ctrl_write_register(&self.handle, 1, 0x01, value, 1)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -397,5 +533,18 @@ fn demod_ctrl_write_register<T: UsbContext>(
|
||||
let buffer = if length == 1 { &data[1..2] } else { &data };
|
||||
let index = 0x10 | page;
|
||||
let address = (address << 8) | 0x20;
|
||||
log::trace!(
|
||||
"Received page {}, address 0x{:04X}, value 0x{:04X}, length {} \
|
||||
- writing control register: {} 0x{:04X} 0x{:04X} {:?}",
|
||||
page,
|
||||
address,
|
||||
value,
|
||||
length,
|
||||
REQ_CTRL_OUT,
|
||||
address,
|
||||
index,
|
||||
buffer
|
||||
);
|
||||
|
||||
handle.write_control(REQ_CTRL_OUT, 0x00, address, index, buffer, TIMEOUT)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user