diff options
| author | Yuval Adam <_@yuv.al> | 2021-04-16 15:05:22 +0300 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2021-04-17 10:33:57 +0300 |
| commit | ef64d358a25e69e440305e1216824921536d5587 (patch) | |
| tree | 4fccfa6d8655aff2259cbb37aec5f52c95b398e3 | |
| parent | 43e56d7e4c5ce653a52a678a14411125d682b7e6 (diff) | |
Initial rusb version that actually compiles!
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/devices/fc0013.rs | 88 | ||||
| -rw-r--r-- | src/devices/mod.rs | 2 | ||||
| -rw-r--r-- | src/devices/r820t.rs | 39 | ||||
| -rw-r--r-- | src/lib.rs | 89 | ||||
| -rw-r--r-- | src/usb.rs | 91 |
6 files changed, 169 insertions, 142 deletions
@@ -4,4 +4,4 @@ version = "0.2.0" authors = ["Yuval Adam <_@yuv.al>"] [dependencies] -libusb = "0.3" +rusb = "0.8" diff --git a/src/devices/fc0013.rs b/src/devices/fc0013.rs index 8404b90..a8302b4 100644 --- a/src/devices/fc0013.rs +++ b/src/devices/fc0013.rs @@ -1,54 +1,54 @@ -use super::{DeviceInfo, Device}; +// use super::{Device, DeviceInfo}; -#[allow(dead_code)] -pub struct FC0013 { - pub device: DeviceInfo -} +// #[allow(dead_code)] +// pub struct FC0013 { +// pub device: DeviceInfo, +// } -#[allow(dead_code)] -pub const DEVICE_INFO: DeviceInfo = DeviceInfo { - id: "fc0013", - name: "Fitipower FC0013", - i2c_addr: 0xc6, - check_addr: 0x00, - check_val: 0xa3 -}; +// #[allow(dead_code)] +// pub const DEVICE_INFO: DeviceInfo = DeviceInfo { +// id: "fc0013", +// name: "Fitipower FC0013", +// i2c_addr: 0xc6, +// check_addr: 0x00, +// check_val: 0xa3, +// }; -#[allow(dead_code)] -impl FC0013 { - pub fn new() -> FC0013 { - FC0013 { - device: DEVICE_INFO - } - } -} +// #[allow(dead_code)] +// impl FC0013 { +// pub fn new() -> FC0013 { +// FC0013 { +// device: DEVICE_INFO, +// } +// } +// } -impl Device for FC0013 { - fn init(&self) { - println!("Init {}", self.device.name); - } +// impl Device for FC0013 { +// fn init(&self) { +// println!("Init {}", self.device.name); +// } - fn exit(&self){ - unimplemented!() - } +// fn exit(&self) { +// unimplemented!() +// } - fn set_freq(&self, _freq: u32){ - unimplemented!() - } +// fn set_freq(&self, _freq: u32) { +// unimplemented!() +// } - fn set_bw(&self, _bw: u32){ - unimplemented!() - } +// fn set_bw(&self, _bw: u32) { +// unimplemented!() +// } - fn set_gain(&self, _gain: u32){ - unimplemented!() - } +// fn set_gain(&self, _gain: u32) { +// unimplemented!() +// } - fn set_if_gain(&self, _if_gain: u32){ - unimplemented!() - } +// fn set_if_gain(&self, _if_gain: u32) { +// unimplemented!() +// } - fn set_gain_mode(&self, _mode: bool){ - unimplemented!() - } -} +// fn set_gain_mode(&self, _mode: bool) { +// unimplemented!() +// } +// } diff --git a/src/devices/mod.rs b/src/devices/mod.rs index 18f08e6..a48531d 100644 --- a/src/devices/mod.rs +++ b/src/devices/mod.rs @@ -6,7 +6,7 @@ pub struct DeviceInfo { pub name: &'static str, pub i2c_addr: u8, pub check_addr: u8, - pub check_val: u8 + pub check_val: u8, } pub trait Device { diff --git a/src/devices/r820t.rs b/src/devices/r820t.rs index d08fc76..92ba509 100644 --- a/src/devices/r820t.rs +++ b/src/devices/r820t.rs @@ -1,11 +1,11 @@ -use super::{DeviceInfo, Device}; -use usb::Usb; +use super::{Device, DeviceInfo}; +use usb::RtlSdrDeviceHandle; const R82XX_IF_FREQ: u32 = 3570000; -pub struct R820T<'a> { +pub struct R820T { pub device: DeviceInfo, - pub usb: &'a Usb<'a> + pub handle: RtlSdrDeviceHandle, } pub const DEVICE_INFO: DeviceInfo = DeviceInfo { @@ -13,56 +13,55 @@ pub const DEVICE_INFO: DeviceInfo = DeviceInfo { name: "Rafael Micro R820T", i2c_addr: 0x34, check_addr: 0x00, - check_val: 0x69 + check_val: 0x69, }; -impl<'a> R820T<'a> { - pub fn new(usb: &'a Usb) -> R820T<'a> { +impl R820T { + pub fn new(handle: RtlSdrDeviceHandle) -> R820T { R820T { device: DEVICE_INFO, - usb + handle: handle, } } } -impl<'a> Device for R820T<'a> { +impl Device for R820T { fn init(&self) { // disable Zero-IF mode - self.usb.demod_write_reg(1, 0xb1, 0x1a, 1); + self.handle.demod_write_reg(1, 0xb1, 0x1a, 1); // only enable In-phase ADC input - self.usb.demod_write_reg(0, 0x08, 0x4d, 1); + self.handle.demod_write_reg(0, 0x08, 0x4d, 1); // the R82XX use 3.57 MHz IF for the DVB-T 6 MHz mode, and // 4.57 MHz for the 8 MHz mode - self.usb.set_if_freq(R82XX_IF_FREQ); + self.handle.set_if_freq(R82XX_IF_FREQ); // enable spectrum inversion - self.usb.demod_write_reg(1, 0x15, 0x01, 1); + self.handle.demod_write_reg(1, 0x15, 0x01, 1); } - fn exit(&self){ + fn exit(&self) { unimplemented!() } - fn set_freq(&self, _freq: u32){ + fn set_freq(&self, _freq: u32) { unimplemented!() } - fn set_bw(&self, _bw: u32){ + fn set_bw(&self, _bw: u32) { unimplemented!() } - fn set_gain(&self, _gain: u32){ + fn set_gain(&self, _gain: u32) { unimplemented!() } - fn set_if_gain(&self, _if_gain: u32){ + fn set_if_gain(&self, _if_gain: u32) { unimplemented!() } - fn set_gain_mode(&self, _mode: bool){ + fn set_gain_mode(&self, _mode: bool) { unimplemented!() } - } @@ -1,82 +1,71 @@ -extern crate libusb; +extern crate rusb; mod devices; mod usb; use devices::*; -use usb::Usb; +use usb::RtlSdrDeviceHandle; const INTERFACE_ID: u8 = 0; const KNOWN_DEVICES: [(u16, u16, &str); 2] = [ (0x0bda, 0x2832, "Generic RTL2832U"), - (0x0bda, 0x2838, "Generic RTL2832U OEM") + (0x0bda, 0x2838, "Generic RTL2832U OEM"), ]; -pub struct RtlSdr<'a> { - ctx: &'a libusb::Context, - iface_id: u8 +pub struct RtlSdr { + // ctx: rusb::Context, + // device: UsbDevice, + iface_id: u8, } -impl<'a> RtlSdr<'a> { - - pub fn new(ctx: &'a libusb::Context) -> RtlSdr<'a> { +impl RtlSdr { + pub fn new() -> RtlSdr { RtlSdr { - ctx, - iface_id: INTERFACE_ID + // ctx: rusb::Context::new().unwrap(), + iface_id: INTERFACE_ID, } } pub fn open(&mut self) { - for dev in self.ctx.devices().unwrap().iter() { + for dev in rusb::devices().unwrap().iter() { let desc = dev.device_descriptor().unwrap(); let vid = desc.vendor_id(); let pid = desc.product_id(); for kd in KNOWN_DEVICES.iter() { if kd.0 == vid && kd.1 == pid { - let mut handle = dev.open().unwrap(); + let usb_handle = dev.open().unwrap(); + let mut handle = RtlSdrDeviceHandle::new(usb_handle, self.iface_id); + let kernel_driver_attached = handle.detach_kernel_driver(); - let has_kernel_driver = match handle.kernel_driver_active(self.iface_id) { - Ok(true) => { - handle.detach_kernel_driver(self.iface_id).ok(); - true - }, - _ => false - }; + let _iface = handle.claim_interface(); - let _iface = handle.claim_interface(self.iface_id).unwrap(); + handle.test_write(); + // reset device if write didn't succeed - { - let usb = Usb::new(&handle); + handle.init_baseband(); + handle.set_i2c_repeater(true); - usb.test_write(); - // reset device if write didn't succeed + let d = r820t::R820T::new(handle); + // let _found = match handle.i2c_read_reg(d.device.i2c_addr, d.device.check_addr) { + // Ok(reg) => { + // if reg == d.device.check_val { + // println!("Found {} tuner\n", d.device.name); + // true + // } else { + // false + // } + // } + // Err(_) => false, + // }; - usb.init_baseband(); - usb.set_i2c_repeater( true); + d.init(); - let d = r820t::R820T::new(&usb); - let _found = match usb.i2c_read_reg(d.device.i2c_addr, d.device.check_addr) { - Ok(reg) => { - if reg == d.device.check_val { - println!("Found {} tuner\n", d.device.name); - true - } - else { - false - } - }, - Err(_) => false - }; + // handle.deinit_baseband(); - d.init(); - - usb.deinit_baseband(); - } - - if has_kernel_driver { - handle.attach_kernel_driver(self.iface_id).ok(); + if kernel_driver_attached { + // handle.attach_kernel_driver(); } } } @@ -90,8 +79,8 @@ mod tests { #[test] fn test_init() { - let ctx = libusb::Context::new().unwrap(); - let mut rtlsdr = RtlSdr::new(&ctx); - rtlsdr.open(); + let mut rtlsdr = RtlSdr::new(); + let x = rtlsdr.open(); + assert_eq!(x, 1); } } @@ -1,7 +1,6 @@ -extern crate libusb; +extern crate rusb; -use libusb::DeviceHandle; -use libusb::{Direction, RequestType, Recipient}; +use rusb::{DeviceHandle, Direction, GlobalContext, Recipient, RequestType}; use std::time::Duration; // const BLOCK_DEMODB: u16 = 0; @@ -24,8 +23,8 @@ const ADDR_SYS_DEMOD_CTL_1: u16 = 0x300b; const FIR_LENGTH: usize = 20; const FIR_DEFAULT: [u8; FIR_LENGTH] = [ - 0xca, 0xdc, 0xd7, 0xd8, 0xe0, 0xf2, 0x0e, 0x35, 0x06, 0x50, - 0x9c, 0x0d, 0x71, 0x11, 0x14, 0x71, 0x74, 0x19, 0x41, 0xa5, + 0xca, 0xdc, 0xd7, 0xd8, 0xe0, 0xf2, 0x0e, 0x35, 0x06, 0x50, 0x9c, 0x0d, 0x71, 0x11, 0x14, 0x71, + 0x74, 0x19, 0x41, 0xa5, ]; const DEF_RTL_XTAL_FREQ: u32 = 28800000; @@ -34,19 +33,39 @@ const DEF_RTL_XTAL_FREQ: u32 = 28800000; const CTRL_TIMEOUT: Duration = Duration::from_millis(300); -pub struct Usb<'a> { - handle: &'a DeviceHandle<'a> +pub struct RtlSdrDeviceHandle { + handle: DeviceHandle<GlobalContext>, + iface_id: u8, } -impl<'a> Usb<'a> { - pub fn new(handle: &'a DeviceHandle) -> Usb<'a> { - Usb { - handle +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 } + } + + pub fn detach_kernel_driver(&mut self) -> bool { + match self.handle.kernel_driver_active(self.iface_id) { + Ok(true) => { + self.handle.detach_kernel_driver(self.iface_id).ok(); + true + } + _ => false, } } + pub fn attach_kernel_driver(&mut self) { + self.handle.attach_kernel_driver(self.iface_id).ok(); + } + + pub fn claim_interface(&mut self) { + self.handle.claim_interface(self.iface_id).unwrap() + } + pub fn write_reg(&self, block: u16, addr: u16, val: u16, len: u8) -> usize { - let type_vendor_out = libusb::request_type(Direction::Out, RequestType::Vendor, Recipient::Device); + let type_vendor_out = + rusb::request_type(Direction::Out, RequestType::Vendor, Recipient::Device); let mut data: [u8; 2] = [0, 0]; let index: u16 = (block << 8) | 0x10; @@ -58,24 +77,31 @@ impl<'a> Usb<'a> { }; data[1] = (val & 0xff) as u8; - match self.handle.write_control(type_vendor_out, 0, addr, index, &data, CTRL_TIMEOUT) { + match self + .handle + .write_control(type_vendor_out, 0, addr, index, &data, CTRL_TIMEOUT) + { Ok(n) => n, - Err(_) => 0 + Err(_) => 0, } } pub fn demod_read_reg(&self, page: u8, addr: u16, _len: u8) -> u16 { - let type_vendor_in = libusb::request_type(Direction::In, RequestType::Vendor, Recipient::Device); + let type_vendor_in = + rusb::request_type(Direction::In, RequestType::Vendor, Recipient::Device); let data: [u8; 2] = [0, 0]; let index: u16 = page.into(); let addr = (addr << 8) | 0x20; - let _res = self.handle.write_control(type_vendor_in, 0, addr, index, &data, CTRL_TIMEOUT); + let _res = self + .handle + .write_control(type_vendor_in, 0, addr, index, &data, CTRL_TIMEOUT); let reg: u16 = ((data[1] as u16) << 8) | (data[0] as u16); return reg; } pub fn demod_write_reg(&self, page: u8, addr: u16, val: u16, len: u8) -> u16 { - let type_vendor_out = libusb::request_type(Direction::Out, RequestType::Vendor, Recipient::Device); + let type_vendor_out = + rusb::request_type(Direction::Out, RequestType::Vendor, Recipient::Device); let mut data: [u8; 2] = [0, 0]; let index: u16 = (0x10 | page).into(); let addr = (addr << 8) | 0x20; @@ -87,20 +113,33 @@ impl<'a> Usb<'a> { }; data[1] = (val & 0xff) as u8; - let _res = self.handle.write_control(type_vendor_out, 0, addr, index, &data, CTRL_TIMEOUT); + let _res = self + .handle + .write_control(type_vendor_out, 0, addr, index, &data, CTRL_TIMEOUT); self.demod_read_reg(0x0a, 0x01, 1) } pub fn read_array(&self, block: u8, addr: u16, arr: &mut [u8], _len: u8) -> usize { - let type_vendor_in = libusb::request_type(Direction::In, RequestType::Vendor, Recipient::Device); + let type_vendor_in = + rusb::request_type(Direction::In, RequestType::Vendor, Recipient::Device); let index: u16 = (block as u16) << 8; - self.handle.read_control(type_vendor_in, 0, addr, index, arr, CTRL_TIMEOUT).unwrap() + self.handle + .read_control(type_vendor_in, 0, addr, index, arr, CTRL_TIMEOUT) + .unwrap() } - pub fn write_array(&self, block: u8, addr: u16, arr: &[u8], _len: u8) -> Result<usize, libusb::Error> { - let type_vendor_out = libusb::request_type(Direction::Out, RequestType::Vendor, Recipient::Device); + pub fn write_array( + &self, + block: u8, + addr: u16, + arr: &[u8], + _len: u8, + ) -> Result<usize, rusb::Error> { + let type_vendor_out = + rusb::request_type(Direction::Out, RequestType::Vendor, Recipient::Device); let index: u16 = ((block as u16) << 8) | 0x10; - self.handle.write_control(type_vendor_out, 0, addr, index, arr, CTRL_TIMEOUT) + self.handle + .write_control(type_vendor_out, 0, addr, index, arr, CTRL_TIMEOUT) } pub fn i2c_read_reg(&self, i2c_addr: u8, reg: u8) -> Result<u8, &str> { @@ -112,15 +151,15 @@ impl<'a> Usb<'a> { Ok(_res) => { self.read_array(BLOCK_IICB, addr, &mut data, 1); Ok(data[0]) - }, - Err(_) => Err("Error") + } + Err(_) => Err("Error"), } } pub fn set_i2c_repeater(&self, on: bool) { let val = match on { true => 0x18, - false => 0x10 + false => 0x10, }; self.demod_write_reg(1, 0x01, val, 1); } |
