### Simple LED Control Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md A basic example demonstrating how to control an LED connected to a GPIO pin using `set_high` and `set_low`. ```APIDOC ## Simple LED Control ```rust use ftdi_embedded_hal as hal; use eh1::digital::OutputPin; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut led = hal.ad6()?; led.set_high()?; std::thread::sleep(std::time::Duration::from_millis(500)); led.set_low()?; ``` ``` -------------------------------- ### Simple Initialization Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Demonstrates basic initialization patterns for the ftdi-embedded-hal library. ```rust use ftdi_embedded_hal as hal; fn main() { // Example of simple initialization let mut ftdi = hal::FtHal::new().unwrap(); // ... further operations ... } ``` -------------------------------- ### GPIO Output Pin Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/README.md Demonstrates controlling a GPIO pin as an output. This example initializes the device with default settings and toggles a pin (connected to an LED) high and low. ```rust use ftdi_embedded_hal as hal; use eh1::digital::OutputPin; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut led = hal.ad6()?; led.set_high()?; std::thread::sleep(std::time::Duration::from_millis(500)); led.set_low()?; ``` -------------------------------- ### Blinking LED Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md An example showing how to create a blinking effect with an LED by repeatedly toggling the GPIO pin's state. ```APIDOC ## Blinking LED ```rust use ftdi_embedded_hal as hal; use eh1::digital::OutputPin; use std::thread; use std::time::Duration; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut led = hal.ad6()?; for _ in 0..10 { led.set_high()?; thread::sleep(Duration::from_millis(250)); led.set_low()?; thread::sleep(Duration::from_millis(250)); } ``` ``` -------------------------------- ### Generate README with cargo-readme Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/CONTRIBUTING.md Install cargo-readme and use it to generate the README.md file for the project. ```bash cargo install cargo-readme ``` ```bash cargo readme > README.md ``` -------------------------------- ### GPIO-Controlled Relay Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md A practical example showing how to control a relay connected to an FTDI device's GPIO pin using the embedded HAL. ```rust use ftdi_embedded_hal as hal; use eh1::digital::OutputPin; use std::thread; use std::time::Duration; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; // Control a relay on pin AD4 let mut relay = hal.ad4()?; // Power on sequence relay.set_high()?; println!("Relay ON"); thread::sleep(Duration::from_secs(5)); relay.set_low()?; println!("Relay OFF"); ``` -------------------------------- ### Initialize FTDI HAL with Default Settings Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/INDEX.md Use `init_default()` for a standard setup. Ensure the device is correctly passed and handle potential errors. ```rust FtHal::init_default(device)? ``` -------------------------------- ### SPI EEPROM Operations Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Shows how to interact with an SPI EEPROM for read and write operations. ```rust use ftdi_embedded_hal as hal; use embedded_hal::blocking::spi::{Transfer, Write as SpiWrite}; fn main() { let mut ftdi = hal::FtHal::new().unwrap(); let spi = hal::Spi::new(ftdi.into_inner()); let mut write_buffer = [0x02, 0x00, 0xFF]; // Command + Address + Data let mut read_buffer = [0u8; 3]; // Example of SPI EEPROM write operation spi.transfer(&mut write_buffer).unwrap(); // Example of SPI EEPROM read operation (requires specific command/address setup) // spi.transfer(&mut read_buffer).unwrap(); // Placeholder for read } ``` -------------------------------- ### Retry Logic Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Demonstrates implementing retry logic for operations that might transiently fail. ```rust use ftdi_embedded_hal as hal; use std::thread::sleep; use std::time::Duration; fn perform_operation_with_retry(ftdi: &mut hal::FtHal) -> Result<(), hal::Error> { let max_retries = 3; for attempt in 0..max_retries { match ftdi.some_operation() { // Replace with actual operation Ok(result) => return Ok(result), Err(e) => { eprintln!("Attempt {} failed: {:?}", attempt, e); if attempt == max_retries - 1 { return Err(e); } sleep(Duration::from_millis(100 * (attempt + 1))); // Exponential backoff } } } unreachable!(); // Should be covered by the loop logic } fn main() { let mut ftdi = hal::FtHal::new().unwrap(); // Example of using retry logic if let Err(e) = perform_operation_with_retry(&mut ftdi) { eprintln!("Operation ultimately failed: {:?}", e); } } ``` -------------------------------- ### I2C Sensor Communication Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Illustrates how to perform I2C communication with a sensor using the library. ```rust use ftdi_embedded_hal as hal; use embedded_hal::blocking::i2c::{Write, Read}; fn main() { let mut ftdi = hal::FtHal::new().unwrap(); let mut i2c = hal::I2c::new(ftdi.into_inner()); let sensor_addr = 0x42; let mut data_to_write = [0x01, 0x02]; let mut data_read = [0u8; 2]; // Example of I2C sensor write operation i2c.write(sensor_addr, &data_to_write).unwrap(); // Example of I2C sensor read operation i2c.read(sensor_addr, &mut data_read).unwrap(); } ``` -------------------------------- ### SPI Communication Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/README.md Shows how to set up an FTDI device for SPI communication and perform a transfer in place. The SPI bus frequency should be specified during initialization. ```rust use ftdi_embedded_hal as hal; use eh1::spi::SpiBus; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 3_000_000)?; let mut spi = hal.spi()?; let mut buffer = [0xAA, 0xBB]; spi.transfer_in_place(&mut buffer)?; println!("Received: {:?}", buffer); ``` -------------------------------- ### GPIO LED Blink Pattern Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Demonstrates blinking an LED connected to a GPIO pin. ```rust use ftdi_embedded_hal as hal; use embedded_hal::digital::v2::OutputPin; use std::thread::sleep; use std::time::Duration; fn main() { let mut ftdi = hal::FtHal::new().unwrap(); let mut led = hal::Gpio::new(ftdi.into_inner(), 0); // Assuming GPIO pin 0 loop { // Example of turning LED on led.set_high().unwrap(); sleep(Duration::from_millis(500)); // Example of turning LED off led.set_low().unwrap(); sleep(Duration::from_millis(500)); } } ``` -------------------------------- ### I2C Communication Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/README.md Demonstrates how to initialize an FTDI device for I2C communication and perform a write-read operation. Ensure the device is correctly described and the frequency is set. ```rust use ftdi_embedded_hal as hal; use eh1::i2c::I2c; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 400_000)?; let mut i2c = hal.i2c()?; let mut buffer = [0u8; 2]; i2c.write_read(0x68, &[0x00], &mut buffer)?; println!("Read: {:?}", buffer); ``` -------------------------------- ### Troubleshooting: I2C NAK Errors Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Example demonstrating how to increase the start/stop command count to resolve I2C NAK errors caused by insufficient start/stop condition timing. ```rust let mut i2c = hal.i2c()?; i2c.set_stop_start_len(10); ``` -------------------------------- ### DelayUs Implementation Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Delay.md Demonstrates using the DelayUs trait with different unsigned integer types for microsecond delays. ```rust use ftdi_embedded_hal::Delay; use eh0::blocking::delay::DelayUs; let mut delay = Delay::new(); delay.delay_us(100u32); // 100 microseconds delay.delay_us(1000u16); // 1000 microseconds ``` -------------------------------- ### Troubleshooting: Slow I2C Speed Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Example showing how to request a higher frequency to compensate for the actual I2C speed being lower than configured. ```rust let hal = hal.FtHal::init_freq(device, 600_000)?; ``` -------------------------------- ### SPI Write Operation Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Demonstrates how to handle potential errors during an SPI write operation. Errors are returned as a Result>. ```rust match spi.write(&[0xAA]) { Ok(()) => println!("Write successful"), Err(e) => eprintln!("SPI error: {}", e), } ``` -------------------------------- ### Standard Development I2C Configuration Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Initializes the FTDI HAL for I2C communication at 400kHz. Use this for standard development setups. ```rust use ftdi_embedded_hal as hal; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let mut hal = hal::FtHal::init_freq(device, 400_000)?; let mut i2c = hal.i2c()?; i2c.set_fast(false); // Detailed error reporting ``` -------------------------------- ### Complex Multi-Operation Transaction Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Illustrates performing a sequence of operations within a single transaction. ```rust use ftdi_embedded_hal as hal; use embedded_hal::blocking::spi::Write; fn main() { let mut ftdi = hal::FtHal::new().unwrap(); let mut spi = hal::Spi::new(ftdi.into_inner()); // Example of a complex transaction involving multiple steps let mut transaction_data = vec![0x01, 0x02, 0x03, 0x04]; spi.write(&mut transaction_data).unwrap(); // ... potentially more operations chained ... } ``` -------------------------------- ### Initialize SPI with Frequency Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Creates an Spi instance using FtHal, setting the initial frequency. This is the starting point for SPI communication. ```rust let hal = FtHal::init_freq(device, 3_000_000)?; let spi = hal.spi()?; ``` -------------------------------- ### DelayMs Implementation Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Delay.md Demonstrates using the DelayMs trait with different unsigned integer types for millisecond delays. ```rust use ftdi_embedded_hal::Delay; use eh0::blocking::delay::DelayMs; let mut delay = Delay::new(); delay.delay_ms(500u32); // 500 milliseconds delay.delay_ms(2u8); // 2 milliseconds ``` -------------------------------- ### Troubleshooting: Pin Already Allocated Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Example demonstrating how to resolve 'Pin Already Allocated' panics by using upper byte pins for GPIO when lower byte pins are used by SPI. ```rust let spi = hal.spi()?; let gpio_c0 = hal.c0()?; ``` -------------------------------- ### Error Handling Pattern Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Shows a common pattern for handling errors returned by the library's operations. ```rust use ftdi_embedded_hal as hal; fn main() { match hal::FtHal::new() { Ok(ftdi) => { // Proceed with operations using ftdi } Err(e) => { // Example of error handling eprintln!("Failed to initialize FTDI: {:?}", e); // Potentially implement recovery or exit } } } ``` -------------------------------- ### High-Precision Delays (with Limitations) Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Delay.md Shows examples of using delay_us and delay_ns. Note that the actual precision for sub-millisecond delays is limited and may not be exact. ```rust use ftdi_embedded_hal::Delay; use eh1::delay::DelayNs; let mut delay = Delay::new(); // These work but precision is limited to ~1-10ms delay.delay_us(100); // May take 1-10ms actually delay.delay_us(1000); // More reliable: ~1-2ms delay.delay_ns(500_000); // Same as 500us ``` -------------------------------- ### Handle ftdi-rs Backend Errors Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/errors.md Example of matching and handling specific ftdi-rs backend errors during HAL initialization. This pattern is useful for diagnosing issues like device not found or communication errors. ```rust use ftdi_embedded_hal as hal; match FtHal::init_default(device) { Err(hal::Error::Backend(ftdi_err)) => { eprintln!("ftdi-rs error: {}", ftdi_err); } Ok(hal) => println!("Initialized successfully"), Err(e) => eprintln!("Other error: {}", e), } ``` -------------------------------- ### eh1::spi::SpiBus Transfer Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Demonstrates performing a simultaneous SPI transfer with different data for reading and writing using eh1::spi::SpiBus. The lengths of the read and write buffers can differ. ```rust let write_data = [0x11, 0x22, 0x33]; let mut read_buffer = [0u8; 5]; spi.transfer(&mut read_buffer, &write_data)?; ``` -------------------------------- ### eh1::spi::SpiBus Transfer In Place Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Shows how to perform a simultaneous SPI transfer where the data is read into and written from the same buffer using eh1::spi::SpiBus. The buffer is modified in place. ```rust let mut buffer = [0xAA, 0xBB, 0xCC]; spi.transfer_in_place(&mut buffer)?; ``` -------------------------------- ### Polling Multiple Input Pins Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Continuously polls the state of multiple input pins (adi0, adi1, adi2) and prints their states every 100 milliseconds. ```rust use ftdi_embedded_hal as hal; use eh1::digital::InputPin; use std::thread; use std::time::Duration; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut pin0 = hal.adi0()?; let mut pin1 = hal.adi1()?; let mut pin2 = hal.adi2()?; loop { let state0 = pin0.is_high()?; let state1 = pin1.is_high()?; let state2 = pin2.is_high()?; println!("States: {:?}", (state0, state1, state2)); thread::sleep(Duration::from_millis(100)); } ``` -------------------------------- ### Simple Button Reading Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Reads the state of a button connected to an ADI pin. Prints 'Button pressed' if the pin is high, otherwise 'Button not pressed'. ```rust use ftdi_embedded_hal as hal; use eh1::digital::InputPin; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut button = hal.adi5()?; if button.is_high()? { println!("Button pressed"); } else { println!("Button not pressed"); } ``` -------------------------------- ### eh1::spi::SpiBus Read Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Demonstrates reading data from an SPI bus using the eh1::spi::SpiBus trait's read method. This clocks data in on MISO while clocking out zeros on MOSI. ```rust let mut buffer = [0u8; 3]; spi.read(&mut buffer)?; ``` -------------------------------- ### Pin Allocation Conflict Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/README.md Demonstrates how attempting to allocate a pin that is already in use by another peripheral (like SPI) will result in a panic. Pins are exclusively allocated to their first user. ```rust let spi = hal.spi()?; // Allocates AD0, AD1, AD2 let i2c = hal.i2c()?; // PANIC - also needs AD0, AD1, AD2 ``` -------------------------------- ### Configure I2C Start/Stop Condition Length Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Sets the number of MPSSE commands used for I2C start and stop conditions. Increase this value for devices with slow clock recovery or for low-latency applications. ```rust let mut i2c = hal.i2c()?; i2c.set_stop_start_len(10); // Increase duration for slow devices ``` -------------------------------- ### eh0::spi::FullDuplex Non-blocking SPI Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Illustrates non-blocking byte-by-byte SPI operations using the eh0::spi::FullDuplex trait and the nb crate. This is useful for scenarios where blocking is not desired. ```rust use eh0::spi::FullDuplex; use nb::block; block!(spi.send(0xAA))?; let received = block!(spi.read())?; ``` -------------------------------- ### eh1::spi::SpiBus Write Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Shows how to write data to an SPI bus using the eh1::spi::SpiBus trait's write method. This operation clocks data out on MOSI without reading any response. ```rust spi.write(&[0xAA, 0xBB])?; ``` -------------------------------- ### eh0::blocking::spi::Transfer Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Shows how to perform a simultaneous SPI data transfer using eh0::blocking::spi::Transfer. Data is clocked out on MOSI and read in on MISO, modifying the buffer in place. ```rust use eh0::blocking::spi::Transfer; let mut data = [0xAA, 0xBB, 0xCC]; spi.transfer(&mut data)?; println!("Received: {:?}", data); ``` -------------------------------- ### EEPROM SPI Read Transaction Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/SpiDevice.md Reads 256 bytes from an EEPROM starting at address 0x0000 using the SpiDevice transaction API. This example demonstrates constructing a sequence of read and write operations for an EEPROM read command. ```rust use ftdi_embedded_hal as hal; use eh1::spi::{Operation, SpiDevice}; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 1_000_000)?; let mut spi = hal.spi_device(5)?; // Read 256 bytes from EEPROM starting at address 0x0000 let mut status = [0u8; 1]; let mut data = [0u8; 256]; let mut ops = [ Operation::Write(&[0x03]), // Read opcode Operation::Write(&[0x00, 0x00]), // Address (16-bit) Operation::Read(&mut data), // Read 256 bytes ]; spi.transaction(&mut ops)?; println!("EEPROM data: {:?}", &data[..16]); ``` -------------------------------- ### init Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/FtHal.md Initializes the FTDI device with custom MPSSE settings. ```APIDOC ## init ### Description Initialize the FTDI device with custom MPSSE settings. ### Method `pub fn init(mut device: Device, mpsse_settings: &MpsseSettings) -> Result, E>` ### Parameters #### Path Parameters - **device** (`Device`) - Required - FTDI device instance - **mpsse_settings** (`&MpsseSettings`) - Required - Custom MPSSE configuration ### Returns `Result, E>` **Panics:** If the `clock_frequency` field of `MpsseSettings` is `None`. **Note:** The `mask` field of `MpsseSettings` is ignored for this function. ### Request Example ```rust use ftdi_embedded_hal as hal; use ftdi_mpsse::MpsseSettings; use std::time::Duration; let mpsse = MpsseSettings { reset: false, in_transfer_size: 4096, read_timeout: Duration::from_secs(5), write_timeout: Duration::from_secs(5), latency_timer: Duration::from_millis(32), mask: 0x00, clock_frequency: Some(400_000), }; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init(device, &mpsse)?; ``` ``` -------------------------------- ### Initialize FTDI HAL with Full Control Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/INDEX.md Use `init()` for complete control over initialization settings. This method requires a `settings` object and allows fine-grained configuration. Handle potential errors. ```rust FtHal::init(device, &settings)? ``` -------------------------------- ### Initialize FtHal with Default Settings Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/FtHal.md Use this method to initialize the FTDI device with default configurations. Ensure the `libftd2xx` crate is imported and a compatible device is available. ```rust use ftdi_embedded_hal as hal; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; ``` -------------------------------- ### I2C Sensor Initialization with Delay Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Delay.md Demonstrates initializing an I2C sensor using the `ftdi-embedded-hal` crate. It shows how to create a `Delay` instance and use `delay_ms` for a power-on delay before reading sensor data. ```rust use ftdi_embedded_hal as hal; use eh1::i2c::I2c; use eh1::delay::DelayNs; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 400_000)?; let mut i2c = hal.i2c()?; let mut delay = hal::Delay::new(); // Example: Sensor initialization with timing println!("Initializing sensor..."); delay.delay_ms(100); // Power-on delay // Read sensor data let mut data = [0u8; 2]; i2c.write_read(0x48, &[0x00], &mut data)?; println!("Sensor data: {:?}", data); ``` -------------------------------- ### Custom Initialization Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Initializes the HAL with completely custom settings, providing fine-grained control over USB timeouts, buffer sizes, and other advanced parameters. Panics if `clock_frequency` is `None`. ```rust pub fn init(mut device: Device, mpsse_settings: &MpsseSettings) -> Result, E> ``` ```rust use ftdi_mpsse::MpsseSettings; use std::time::Duration; let settings = MpsseSettings { reset: false, in_transfer_size: 8192, read_timeout: Duration::from_secs(5), write_timeout: Duration::from_secs(5), latency_timer: Duration::from_millis(32), mask: 0x00, clock_frequency: Some(400_000), }; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = FtHal::init(device, &settings)?; ``` -------------------------------- ### Create GPIO Output Pins Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Demonstrates how to initialize the FTDI HAL and create output pins for both the lower (AD0-AD7) and upper (C0-C7) bytes. ```rust let hal = FtHal::init_default(device)?; let mut gpio_out = hal.ad6()?; let mut gpio_c0 = hal.c0()?; ``` -------------------------------- ### init_default Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/FtHal.md Initializes the FTDI device with default settings, including reset, USB transfer size, timeouts, latency timer, and clock frequency. ```APIDOC ## init_default ### Description Initializes the FTDI device with default settings. ### Method `pub fn init_default(device: Device) -> Result, Error>` ### Parameters #### Path Parameters - **device** (`Device`) - Required - FTDI device instance ### Returns `Result, Error>` **Default configuration:** - Reset the FTDI device - 4KB USB transfer size - 1s USB read timeout - 1s USB write timeout - 16ms latency timer - 100 kHz clock frequency ### Request Example ```rust use ftdi_embedded_hal as hal; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; ``` ``` -------------------------------- ### OutputPin Creation Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Demonstrates how to create `OutputPin` instances for both lower (AD0-AD7) and upper (C0-C7) byte GPIO pins using `FtHal`. ```APIDOC ## OutputPin Creation Output pins are created via methods on `FtHal`: ```rust let hal = FtHal::init_default(device)?; let mut gpio_out = hal.ad6()?; // AD6 as output let mut gpio_c0 = hal.c0()?; // C0 (upper byte) as output ``` Available methods: - Lower byte: `ad0()`, `ad1()`, `ad2()`, `ad3()`, `ad4()`, `ad5()`, `ad6()`, `ad7()` - Upper byte: `c0()`, `c1()`, `c2()`, `c3()`, `c4()`, `c5()`, `c6()`, `c7()` **Returns:** `Result, Error>` **Panics:** If the pin is already allocated to another peripheral (SPI, I2C, etc.). ``` -------------------------------- ### eh1::spi::SpiBus Flush Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Illustrates the flush operation for the eh1::spi::SpiBus trait. For FTDI SPI, this is a no-operation and always succeeds. ```rust spi.flush()?; ``` -------------------------------- ### Initialize and Use I2C with ftdi-embedded-hal Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/START_HERE.md Demonstrates how to initialize an I2C device using ftdi-embedded-hal and perform a write-read operation. Ensure the libftd2xx crate is available and the FT232H device is connected. ```rust use ftdi_embedded_hal as hal; use eh1::i2c::I2c; // Initialize let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 400_000)?; let mut i2c = hal.i2c()?; // Use let mut buffer = [0u8; 2]; i2c.write_read(0x68, &[0x00], &mut buffer)?; println!("Read: {:?}", buffer); ``` -------------------------------- ### set_stop_start_len Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/I2c.md Configures the number of MPSSE commands used for I2C start and stop conditions. Increasing this value can be useful for devices that require a specific timing window. ```APIDOC ## Methods ### set_stop_start_len ```rust pub fn set_stop_start_len(&mut self, start_stop_cmds: u8) ``` Configure the number of MPSSE commands used for I2C start and stop conditions. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | start_stop_cmds | `u8` | yes | Number of MPSSE commands per start/stop condition (default: 3) | **Default:** 3 commands **Behavior:** Increasing this value adds more MPSSE commands, which roughly correlates to a longer duration for start/stop conditions. This can be useful for devices that require a specific timing window. **Example:** ```rust use ftdi_embedded_hal as hal; let device = libftd2xx::Ft2232h::with_description("Dual RS232-HS A")?; let hal = hal::FtHal::init_freq(device, 3_000_000)?; let mut i2c = hal.i2c()?; i2c.set_stop_start_len(10); ``` ``` -------------------------------- ### Initialize FtHal with Custom MPSSE Settings Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/FtHal.md Initializes the FTDI device using custom MPSSE settings. The `clock_frequency` in `MpsseSettings` must be `Some`. The `mask` field is ignored. ```rust use ftdi_embedded_hal as hal; use ftdi_mpsse::MpsseSettings; use std::time::Duration; let mpsse = MpsseSettings { reset: false, in_transfer_size: 4096, read_timeout: Duration::from_secs(5), write_timeout: Duration::from_secs(5), latency_timer: Duration::from_millis(32), mask: 0x00, clock_frequency: Some(400_000), }; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init(device, &mpsse)?; ``` -------------------------------- ### Reading Temperature from LM75 Sensor Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/I2c.md Example of reading temperature data from an LM75 sensor using I2C. Requires initializing the FT232H device and setting the I2C frequency. ```rust use ftdi_embedded_hal as hal; use eh0::blocking::i2c::WriteRead; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 400_000)?; let mut i2c = hal.i2c()?; // LM75 temperature sensor at address 0x48 let mut temp_bytes = [0u8; 2]; i2c.write_read(0x48, &[0x00], &mut temp_bytes)?; let temp_raw = ((temp_bytes[0] as i16) << 8) | (temp_bytes[1] as i16); let temp_celsius = (temp_raw >> 7) as f32 * 0.5; println!("Temperature: {:.1}°C", temp_celsius); ``` -------------------------------- ### GPIO Control Initialization Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Initializes the FTDI HAL for GPIO control, demonstrating access to specific pins like AD6, ADI5, and C0. ```rust let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut led = hal.ad6()?; let mut button = hal.adi5()?; let mut relay_c0 = hal.c0()?; ``` -------------------------------- ### Debounced Button Reading Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Reads a button state with a debounce delay to prevent false triggers. If the button remains high after a short delay, an LED is activated. ```rust use ftdi_embedded_hal as hal; use eh1::digital::InputPin; use std::thread; use std::time::Duration; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut button = hal.adi5()?; let mut led = hal.ad6()?; if button.is_high()? { thread::sleep(Duration::from_millis(20)); // Debounce delay if button.is_high()? { led.set_high()?; } } ``` -------------------------------- ### Sequential Read from AT24C256 EEPROM Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/I2c.md Demonstrates a sequential read operation from an AT24C256 EEPROM using I2C transactions. This involves writing the starting address and then reading the data. ```rust use ftdi_embedded_hal as hal; use eh1::i2c::{I2c, Operation}; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 400_000)?; let mut i2c = hal.i2c()?; // AT24C256 EEPROM at 0x50, read from address 0x0000 let addr_bytes = [0x00, 0x00]; let mut data = [0u8; 64]; let mut ops = [ Operation::Write(&addr_bytes), Operation::Read(&mut data), ]; i2c.transaction(0x50, &mut ops)?; println!("EEPROM data: {:?}", &data[..16]); ``` -------------------------------- ### High-Speed SPI Configuration Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Initializes the FTDI HAL for SPI communication at 3MHz. Ensure correct device selection for SPI. ```rust let device = libftd2xx::Ft2232h::with_description("Dual RS232-HS A")?; let hal = hal::FtHal::init_freq(device, 3_000_000)?; let mut spi = hal.spi()?; spi.set_clock_polarity(eh1::spi::Polarity::IdleLow)?; ``` -------------------------------- ### Default Initialization Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Initializes the HAL with sensible defaults optimized for common use cases, suitable for I2C at 100 kHz. ```rust pub fn init_default(device: Device) -> Result, Error> ``` ```rust MpsseSettings { reset: true, in_transfer_size: 4096, read_timeout: Duration::from_secs(1), write_timeout: Duration::from_secs(1), latency_timer: Duration::from_millis(16), mask: 0x00, clock_frequency: Some(100_000), } ``` ```rust let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = FtHal::init_default(device)?; ``` -------------------------------- ### Handling FTDI SPI Write I/O Errors Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/errors.md This example demonstrates how to match and handle specific I/O error kinds, such as disconnection or timeouts, that may occur during an SPI write operation. ```rust match spi.write(&data) { Err(hal::Error::Io(e)) => { match e.kind() { std::io::ErrorKind::NotConnected => { eprintln!("FTDI device disconnected"); } std::io::ErrorKind::TimedOut => { eprintln!("USB operation timed out"); } _ => eprintln!("I/O error: {}", e), } } Ok(()) => println!("Success"), Err(e) => eprintln!("Other error: {}", e), } ``` -------------------------------- ### Enable libftd2xx Driver Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/configuration.md Add the libftd2xx-based FTDI driver to your project dependencies. For static linking, include the `libftd2xx-static` feature. ```toml [dependencies] ftdi-embedded-hal = { version = "0.24", features = ["libftd2xx"] } ``` ```toml [dependencies] ftdi-embedded-hal = { version = "0.24", features = ["libftd2xx", "libftd2xx-static"] } ``` -------------------------------- ### Control GPIO with ftdi-rs Driver Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/README.md Initializes GPIO control for an FTDI device using the ftdi-rs driver. ```rust use ftdi_embedded_hal as hal; let device = ftdi::find_by_vid_pid(0x0403, 0x6010) .interface(ftdi::Interface::A) .open()?; let hal = hal::FtHal::init_default(device)?; let gpio = hal.ad6(); ``` -------------------------------- ### Reading GPIO Pin State Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Demonstrates how to read the state of a GPIO pin and handle potential USB communication errors. ```rust match pin.is_high() { Ok(true) => println!("Pin is HIGH"), Ok(false) => println!("Pin is LOW"), Err(e) => eprintln!("Error reading pin: {}", e), } ``` -------------------------------- ### eh0::blocking::spi::Write Example Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Spi.md Demonstrates writing data to an SPI bus using the eh0::blocking::spi::Write trait. This operation clocks data out on MOSI without reading the response. ```rust use eh0::blocking::spi::Write; let data = [0xAA, 0xBB, 0xCC]; spi.write(&data)?; ``` -------------------------------- ### FtHal API Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/README.md The main HAL wrapper and device initialization for ftdi-embedded-hal. ```APIDOC ## FtHal ### Description Main HAL wrapper and device initialization. ### Methods - `init_default()`: Initializes the HAL with default settings. - `init_freq(freq: u32)`: Initializes the HAL with a specified frequency. - `init()`: Initializes the HAL. - `spi()`: Provides access to the SPI bus interface. - `spi_device()`: Provides access to the SPI device interface with automatic chip select. - `i2c()`: Provides access to the I2C master interface. - `ad0()` through `ad7()`: Provides access to the lower byte GPIO pins as output or input variants. - `c0()` through `c7()`: Provides access to the upper byte GPIO pins as output or input variants. - `with_device(device)`: Allows access to the underlying FTDI device. ``` -------------------------------- ### Simple LED Control with GPIO Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Controls an LED connected to a GPIO pin by setting it high to turn on and low to turn off. Includes a delay for visibility. ```rust use ftdi_embedded_hal as hal; use eh1::digital::OutputPin; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut led = hal.ad6()?; led.set_high()?; // Turn on LED std::thread::sleep(std::time::Duration::from_millis(500)); led.set_low()?; // Turn off LED ``` -------------------------------- ### eh0::blocking::i2c::WriteRead Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/I2c.md Writes data to an I2C slave and then reads a response, commonly used for register-based devices. It performs a write operation followed by a repeated start condition and a read operation. ```APIDOC ## eh0::blocking::i2c::WriteRead ### Description Writes data to a slave, then reads a response (common for register-based devices). ### Method Signature `fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error>` ### Parameters #### Path Parameters - **address** (`u8`) - Required - 7-bit I2C slave address - **bytes** (`&[u8]`) - Required - Data to write first - **buffer** (`&mut [u8]`) - Required - Buffer for read response ### Returns `Result<(), Error>` ### Throws Same as `read()` and `write()` above. ### I2C Protocol 1. Start condition 2. Send slave address + write bit 3. Wait for slave ACK 4. Send N write bytes, waiting for ACK after each 5. Repeated start condition 6. Send slave address + read bit 7. Read M bytes 8. Stop condition ### Example ```rust use eh0::blocking::i2c::WriteRead; let mut data = [0u8; 2]; i2c.write_read(0x68, &[0x00], &mut data)?; println!("Register value: {:?}", data); ``` ``` -------------------------------- ### Enable Debug Output for Errors Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/errors.md This snippet shows how to print the main error message and its underlying cause using `eprintln!` and the `source()` method. It's useful for getting immediate feedback on error conditions. ```rust use ftdi_embedded_hal as hal; match operation() { Err(e) => { eprintln!("Error: {}", e); if let Some(source) = e.source() { eprintln!("Caused by: {}", source); } } Ok(_) => {} } ``` -------------------------------- ### Create SpiDevice Instance Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/SpiDevice.md Instantiate SpiDevice using FtHal. This requires an initialized FtHal instance and the index of the chip select pin to be used. The chip select pin is active low. ```rust let hal = FtHal::init_freq(device, 3_000_000)?; let spi = hal.spi_device(3)?; ``` -------------------------------- ### Blinking LED with GPIO Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/GPIO.md Demonstrates blinking an LED connected to a GPIO pin by repeatedly setting it high and low with delays. Executes the blink cycle 10 times. ```rust use ftdi_embedded_hal as hal; use eh1::digital::OutputPin; use std::thread; use std::time::Duration; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut led = hal.ad6()?; for _ in 0..10 { led.set_high()?; thread::sleep(Duration::from_millis(250)); led.set_low()?; thread::sleep(Duration::from_millis(250)); } ``` -------------------------------- ### Using Delay with GPIO for LED Blinking Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/Delay.md Demonstrates controlling an LED pin and using delays to create a blinking effect. The LED is turned on, delayed, turned off, and delayed again, repeated five times. ```rust use ftdi_embedded_hal as hal; use eh1::digital::OutputPin; use eh1::delay::DelayNs; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_default(device)?; let mut led = hal.ad6()?; let mut delay = hal::Delay::new(); // Blink LED 5 times for _ in 0..5 { led.set_high()?; delay.delay_ms(250); led.set_low()?; delay.delay_ms(250); } ``` -------------------------------- ### Write then Read from I2C Slave Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/I2c.md Use this function for operations that require writing a command or register address before reading data, common in register-based devices. It handles the sequence of writing, followed by a repeated start and reading the response. ```rust use eh0::blocking::i2c::WriteRead; let mut data = [0u8; 2]; i2c.write_read(0x68, &[0x00], &mut data)?; println!("Register value: {:?}", data); ``` -------------------------------- ### Configure I2C Stop/Start Condition Length Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/I2c.md Configures the number of MPSSE commands used for I2C start and stop conditions. Increasing this value can extend the duration of these conditions, which may be necessary for devices with specific timing requirements. ```rust use ftdi_embedded_hal as hal; let device = libftd2xx::Ft2232h::with_description("Dual RS232-HS A")?; let hal = hal::FtHal::init_freq(device, 3_000_000)?; let mut i2c = hal.i2c()?; i2c.set_stop_start_len(10); ``` -------------------------------- ### init_freq Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/api-reference/FtHal.md Initializes the FTDI device with default settings and a custom clock frequency. ```APIDOC ## init_freq ### Description Initialize the FTDI device with default settings and a custom clock frequency. ### Method `pub fn init_freq(device: Device, freq: u32) -> Result, Error>` ### Parameters #### Path Parameters - **device** (`Device`) - Required - FTDI device instance - **freq** (`u32`) - Required - Clock frequency in Hz ### Returns `Result, Error>` **Note:** The clock frequency will be 2/3 of the specified value when in I2C mode. ### Request Example ```rust use ftdi_embedded_hal as hal; let device = libftd2xx::Ft232h::with_description("Single RS232-HS")?; let hal = hal::FtHal::init_freq(device, 3_000_000)?; ``` ``` -------------------------------- ### SpiDevice Methods Source: https://github.com/ftdi-rs/ftdi-embedded-hal/blob/main/_autodocs/ANALYSIS_SCOPE.md Methods for configuring the SPI bus, specifically for SPI devices with chip select. ```APIDOC ## SpiDevice Methods ### Description Methods for configuring the SPI bus when used with a chip select, such as setting clock polarity. ### Methods - `set_clock_polarity(polarity: Polarity)`: Sets the clock polarity for the SPI device. ```