Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more ftdi wrappers #2

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions examples/dlp-loopback-tester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ extern crate ftdi;

use std::io::{Read, Write};


fn main() {
println!("Starting tester...");
let mut context = ftdi::Context::new();
Expand Down Expand Up @@ -50,9 +49,11 @@ fn main() {
context.read_to_end(&mut reply).unwrap();
let complement = 255 - num;
if reply != vec![complement] {
println!("Wrong complement reply {:?} (expected {:?}",
reply,
vec![complement]);
println!(
"Wrong complement reply {:?} (expected {:?}",
reply,
vec![complement]
);
}
}
println!("Testing finished");
Expand Down
167 changes: 132 additions & 35 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ extern crate num;
extern crate libftdi1_sys as ffi;

use std::io;
use std::io::{Read, Write, ErrorKind};
use std::io::{ErrorKind, Read, Write};

use num::traits::ToPrimitive;


/// The target interface
pub enum Interface {
A,
Expand All @@ -33,14 +32,64 @@ impl Into<ffi::ftdi_interface> for Interface {
}
}

pub enum BitMode {
RESET,
BITBANG,
MPSSE,
SYNCBB,
MCU,
OPTO,
CBUS,
SYNCFF,
FT1284,
}

impl Into<u8> for BitMode {
fn into(self) -> u8 {
let mode = match self {
BitMode::RESET => ffi::ftdi_mpsse_mode::BITMODE_RESET,
BitMode::BITBANG => ffi::ftdi_mpsse_mode::BITMODE_BITBANG,
BitMode::MPSSE => ffi::ftdi_mpsse_mode::BITMODE_MPSSE,
BitMode::SYNCBB => ffi::ftdi_mpsse_mode::BITMODE_SYNCBB,
BitMode::MCU => ffi::ftdi_mpsse_mode::BITMODE_MCU,
BitMode::OPTO => ffi::ftdi_mpsse_mode::BITMODE_OPTO,
BitMode::CBUS => ffi::ftdi_mpsse_mode::BITMODE_CBUS,
BitMode::SYNCFF => ffi::ftdi_mpsse_mode::BITMODE_SYNCFF,
BitMode::FT1284 => ffi::ftdi_mpsse_mode::BITMODE_FT1284,
};

mode as u8
}
}

#[allow(non_camel_case_types)]
pub enum FlowControl {
SIO_DISABLE_FLOW_CTRL,
SIO_RTS_CTS_HS,
SIO_DTR_DSR_HS,
SIO_XON_XOFF_HS,
}

impl Into<i32> for FlowControl {
fn into(self) -> i32 {
match self {
FlowControl::SIO_DISABLE_FLOW_CTRL => 0x0,
FlowControl::SIO_RTS_CTS_HS => (0x1 << 8),
FlowControl::SIO_DTR_DSR_HS => (0x2 << 8),
FlowControl::SIO_XON_XOFF_HS => (0x4 << 8),
}
}
}

pub struct Context {
native: ffi::ftdi_context,
}

impl Context {
pub fn new() -> Context {
let mut context = Context { native: Default::default() };
let mut context = Context {
native: Default::default(),
};
let result = unsafe { ffi::ftdi_init(&mut context.native) };
// Can be non-zero on either OOM or libusb_init failure
assert!(result == 0);
Expand All @@ -55,7 +104,10 @@ impl Context {
-1 => Err(io::Error::new(ErrorKind::InvalidInput, "unknown interface")),
-2 => Err(io::Error::new(ErrorKind::NotFound, "device not found")),
-3 => Err(io::Error::new(ErrorKind::Other, "device already opened")),
_ => Err(io::Error::new(ErrorKind::Other, "unknown set latency error")),
_ => Err(io::Error::new(
ErrorKind::Other,
"unknown set latency error",
)),
}
}

Expand All @@ -70,8 +122,14 @@ impl Context {
-7 => Err(io::Error::new(ErrorKind::Other, "set baudrate failed")),
-8 => Err(io::Error::new(ErrorKind::Other, "get description failed")),
-9 => Err(io::Error::new(ErrorKind::Other, "get serial failed")),
-12 => Err(io::Error::new(ErrorKind::Other, "libusb_get_device_list failed")),
-13 => Err(io::Error::new(ErrorKind::Other, "libusb_get_device_descriptor failed")),
-12 => Err(io::Error::new(
ErrorKind::Other,
"libusb_get_device_list failed",
)),
-13 => Err(io::Error::new(
ErrorKind::Other,
"libusb_get_device_descriptor failed",
)),
_ => Err(io::Error::new(ErrorKind::Other, "unknown usb_open error")),
}
}
Expand All @@ -97,14 +155,27 @@ impl Context {
}
}

pub fn usb_close(&mut self) -> io::Result<()> {
let result = unsafe { ffi::ftdi_usb_close(&mut self.native) };
match result {
0 => Ok(()),
-1 => Err(io::Error::new(ErrorKind::Other, "usb release failed")),
-3 => Err(io::Error::new(ErrorKind::NotFound, "unknown ftdi context")),
_ => Err(io::Error::new(ErrorKind::Other, "unknown usb_open error")),
}
}

pub fn set_latency_timer(&mut self, value: u8) -> io::Result<()> {
let result = unsafe { ffi::ftdi_set_latency_timer(&mut self.native, value) };
match result {
0 => Ok(()),
-1 => Err(io::Error::new(ErrorKind::InvalidInput, "bad latency value")),
-2 => Err(io::Error::new(ErrorKind::Other, "set latency failed")),
-3 => Err(io::Error::new(ErrorKind::NotFound, "device not found")),
_ => Err(io::Error::new(ErrorKind::Other, "unknown set latency error")),
_ => Err(io::Error::new(
ErrorKind::Other,
"unknown set latency error",
)),
}
}

Expand All @@ -115,49 +186,70 @@ impl Context {
0 => Ok(value),
-1 => Err(io::Error::new(ErrorKind::Other, "set latency failed")),
-2 => Err(io::Error::new(ErrorKind::NotFound, "device not found")),
_ => Err(io::Error::new(ErrorKind::Other, "unknown get latency error")),
_ => Err(io::Error::new(
ErrorKind::Other,
"unknown get latency error",
)),
}
}

pub fn set_write_chunksize(&mut self, value: u32) {
let result = unsafe {
ffi::ftdi_write_data_set_chunksize(&mut self.native, value)
};
let result = unsafe { ffi::ftdi_write_data_set_chunksize(&mut self.native, value) };
match result {
0 => (),
err => panic!("unknown set_write_chunksize retval {:?}", err)
err => panic!("unknown set_write_chunksize retval {:?}", err),
}
}

pub fn write_chunksize(&mut self) -> u32 {
let mut value = 0;
let result = unsafe {
ffi::ftdi_write_data_get_chunksize(&mut self.native, &mut value)
};
let result = unsafe { ffi::ftdi_write_data_get_chunksize(&mut self.native, &mut value) };
match result {
0 => value,
err => panic!("unknown get_write_chunksize retval {:?}", err)
err => panic!("unknown get_write_chunksize retval {:?}", err),
}
}

pub fn set_read_chunksize(&mut self, value: u32) {
let result = unsafe {
ffi::ftdi_read_data_set_chunksize(&mut self.native, value)
};
let result = unsafe { ffi::ftdi_read_data_set_chunksize(&mut self.native, value) };
match result {
0 => (),
err => panic!("unknown set_write_chunksize retval {:?}", err)
err => panic!("unknown set_write_chunksize retval {:?}", err),
}
}

pub fn read_chunksize(&mut self) -> u32 {
let mut value = 0;
let result = unsafe {
ffi::ftdi_read_data_get_chunksize(&mut self.native, &mut value)
};
let result = unsafe { ffi::ftdi_read_data_get_chunksize(&mut self.native, &mut value) };
match result {
0 => value,
err => panic!("unknown get_write_chunksize retval {:?}", err)
err => panic!("unknown get_write_chunksize retval {:?}", err),
}
}

pub fn set_flow_control(&mut self, flowctrl: FlowControl) -> io::Result<()> {
let result = unsafe { ffi::ftdi_setflowctrl(&mut self.native, flowctrl.into()) };
match result {
0 => Ok(()),
-1 => Err(io::Error::new(ErrorKind::Other, "set flow control failed")),
-2 => Err(io::Error::new(ErrorKind::NotFound, "device not found")),
_ => Err(io::Error::new(
ErrorKind::Other,
"unknown set flow control error",
)),
}
}

pub fn set_bitmode(&mut self, bitmask: u8, mode: BitMode) -> io::Result<()> {
let result = unsafe { ffi::ftdi_set_bitmode(&mut self.native, bitmask, mode.into()) };
match result {
0 => Ok(()),
-1 => Err(io::Error::new(ErrorKind::Other, "set bitmode failed")),
-2 => Err(io::Error::new(ErrorKind::NotFound, "device not found")),
_ => Err(io::Error::new(
ErrorKind::Other,
"unknown set bitmode error",
)),
}
}
}
Expand All @@ -174,11 +266,14 @@ impl Read for Context {
let result = unsafe { ffi::ftdi_read_data(&mut self.native, buf.as_mut_ptr(), len) };
match result {
count if count >= 0 => Ok(count as usize),
-666 => Err(io::Error::new(ErrorKind::NotFound, "device not found in read")),
libusb_error => {
Err(io::Error::new(ErrorKind::Other,
format!("libusb_bulk_transfer error {}", libusb_error)))
}
-666 => Err(io::Error::new(
ErrorKind::NotFound,
"device not found in read",
)),
libusb_error => Err(io::Error::new(
ErrorKind::Other,
format!("libusb_bulk_transfer error {}", libusb_error),
)),
}
}
}
Expand All @@ -189,11 +284,14 @@ impl Write for Context {
let result = unsafe { ffi::ftdi_write_data(&mut self.native, buf.as_ptr(), len) };
match result {
count if count >= 0 => Ok(count as usize),
-666 => Err(io::Error::new(ErrorKind::NotFound, "device not found in write")),
libusb_error => {
Err(io::Error::new(ErrorKind::Other,
format!("usb_bulk_write error {}", libusb_error)))
}
-666 => Err(io::Error::new(
ErrorKind::NotFound,
"device not found in write",
)),
libusb_error => Err(io::Error::new(
ErrorKind::Other,
format!("usb_bulk_write error {}", libusb_error),
)),
}
}

Expand All @@ -202,7 +300,6 @@ impl Write for Context {
}
}


#[cfg(test)]
mod test {
#[test]
Expand Down