Open silvioprog opened 4 years ago
Oooooooh! That's what that function was for!
I thought it was for reading the BitMode
set with FT_SetBitMode
, but it's the state of the bus! I added this method a while ago, but it never returned the BitMode
I set with FT_SetBitMode
; I assumed I had a bug somewhere and left it out.
Anyway, moment of clarity aside I pushed a branch bitmode
with the change, there is now a bit_mode
method on FtdiCommon
and an example that contains similar code to yours (but without the while(1)
since rust was not too keen on the unreachable FT_Close
at the bottom).
use libftd2xx::{BitMode, Ftdi, FtdiCommon, TimeoutError};
fn main() -> Result<(), TimeoutError> {
let mut ft = Ftdi::new()?;
let mask: u8 = 0x00;
ft.set_bit_mode(mask, BitMode::AsyncBitbang)?;
let mode = ft.bit_mode()?;
for pin_index in 0..8 {
if mode & (1 << pin_index) == 0 {
println!("Pin {}: Off", pin_index);
} else {
println!("Pin {}: On", pin_index);
}
}
ft.close()?;
Ok(())
}
Gave it a go with my FT232H, and it seems to work as expected when I tie ADBUS6 to GND.
$ cargo run --example async_bitbang
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/examples/async_bitbang`
Pin 0: On
Pin 1: On
Pin 2: On
Pin 3: On
Pin 4: On
Pin 5: On
Pin 6: Off
Pin 7: On
Can you give this a go and let me know if it solves the issue?
I did a 0.13.0 release with the content of the bitmode
branch (now deleted), if it doesn't solve the issue I can always do another release, not too concerned about releases right now because this crate is not yet 1.x
.
Wow, this is great news! I'm going to test it in my board and back with some feedback.
Indeed, the FT_GetBitMode()
sounds like game cheats hehe. :-)
Another awesome feature to use with FT_GetBitMode()
is the FT_SetEventNotification()
notifier. It allows to get the pins state asynchronous using events (WaitForSingleObject()
/ pthread_cond_wait()
) instead of locking like while(1)
.
That's a neat function that I have not gotten to yet!
Do you know what WaitForSingleObject()
/pthread_cond_wait()
would look like in rust?
It looks like I can just call into libc
on the linux side of things, and there is a crate here for Windows things; but I am not sure if there are any higher level abstractions I should be using.
The example async_bitbang.rs
worked like a charm with my board. Thank you very much for implementing it! :-)
Regarding FT_SetEventNotification()
, I totally agree with you by using libc
/winapi-rs
. The topic 3.28 FT_SetEventNotification
of D2XX_Programmer's_Guide.pdf provides two examples that can be a good start point to understand how to use the function on Linux and Windows.
I implemented the dependency methods (FT_GetStatus
and FT_GetModemStatus
) on the master branch, and there is a topic branch issue/9 with dirty work.
I did hit one snag on the Windows side.
The Windows example in the D2XX Programmer's Guide uses CreateEvent
, which appears to be deprecated? At any rate there are only functions for CreateEventA
, and CreateEventW
in the winapi
crate.
There is a disconnect that needs to be resolved here - but I am not yet sure where.
Thinking out loud:
CreateEvent
be in the winapi
crate?CreateEvent
be replaced with CreateEventA
or CreateEventW
?Do you have any guidance here? I usually use Linux at work and at home so these Windows things are still new to me :smile:
Thanks for starting this great feature!
The wide strings are commonly used in Rust world, so the CreateEventW()
is a good choice. Passing its last parameter lpName
as something like libftd2xx-event
(in UTF-16) would be welcome too. :-)
I have a naive tip. Maybe adding files like linux.rs
and windows.rs
would make it easy to implement the event logic for each OS. This small library provides some idea how to separate the OS-specific logic in separated files: lock_keys/src.
You have written clean and easy-to-use interfaces. I'm going to check the new branch and back with some feedback ... (and try to help you in the implementation for Windows)
The wide strings are commonly used in Rust world, so the CreateEventW() is a good choice. Passing its last parameter lpName as something like libftd2xx-event (in UTF-16) would be welcome too. :-)
Oh, whoops, I missed the giant purple box at the bottom of the Microsoft docs that explains this, thanks for pointing that out, makes much more sense now!
The synchapi.h header defines CreateEvent as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.
I have a naive tip. Maybe adding files like linux.rs and windows.rs would make it easy to implement the event logic for each OS. This small library provides some idea how to separate the OS-specific logic in separated files: lock_keys/src.
That's definitely a better more ergonomic way to lay this out than what I was thinking of :+1:
Hi.
Thanks for this awesome library!
So, it would be nice to allow to receive the data
D0
..D7
from the board in asynchronous bit bang mode. For example, supposing a circuit uses a FT232R with its pins 1 (D0), 5 (D1), 3 (D2), 11 (D3), 2 (D4), 9 (D5), 10 (D6) and 6 (D7) mapped to eight switches with pull-up resistors, it would be possible to detect if the switches are ON or OFF. Below a small example showing how to do that in C code:A good reference for implementation is the official app note AN_232R-01 (topic 2 Asynchronous Bit Bang Mode) available at: https://www.ftdichip.com/Support/Documents/AppNotes/AN_232R-01_Bit_Bang_Mode_Available_For_FT232R_and_Ft245R.pdf
cheers