pub struct MpsseCmdBuilder(pub Vec<u8>);
Expand description

FTDI Multi-Protocol Synchronous Serial Engine (MPSSE) command builder.

For details about the MPSSE read the FTDI MPSSE Basics.

This structure is a Vec<u8> that the methods push bytewise commands onto. These commands can then be written to the device with the appropriate implementations of send and xfer methods.

This is useful for creating commands that need to do multiple operations quickly, since individual write calls can be expensive. For example, this can be used to set a GPIO low and clock data out for SPI operations.

If dynamic command layout is not required, the mpsse macro can build command [u8; N] arrays at compile-time.

Tuple Fields§

§0: Vec<u8>

Implementations§

source§

impl MpsseCmdBuilder

source

pub const fn new() -> MpsseCmdBuilder

Create a new command builder.

§Example
use ftdi_mpsse::MpsseCmdBuilder;

MpsseCmdBuilder::new();
source

pub const fn with_vec(vec: Vec<u8>) -> MpsseCmdBuilder

Create a new command builder from a vector.

§Example
use ftdi_mpsse::MpsseCmdBuilder;

MpsseCmdBuilder::with_vec(Vec::new());
source

pub fn as_slice(&self) -> &[u8]

Get the MPSSE command as a slice.

§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new().enable_loopback();

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.set_clock(100_000);
ft.write_all(cmd.as_slice())?;
source

pub fn set_clock(self, divisor: u32, clkdiv: Option<bool>) -> MpsseCmdBuilder

Set the MPSSE clock frequency using provided divisor value and clock divider configuration. Both parameters are device dependent.

§Example
use ftdi_mpsse::MpsseCmdBuilder;

let cmd = MpsseCmdBuilder::new().set_clock(9, Some(false));
source

pub fn enable_loopback(self) -> MpsseCmdBuilder

Enable the MPSSE loopback state.

§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new().enable_loopback();

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
source

pub fn disable_loopback(self) -> MpsseCmdBuilder

Disable the MPSSE loopback state.

§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new().disable_loopback();

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
source

pub fn disable_3phase_data_clocking(self) -> MpsseCmdBuilder

Disable 3 phase data clocking.

This is only available on FTx232H devices.

This will give a 2 stage data shift which is the default state.

It will appears as:

  1. Data setup for 1/2 clock period
  2. Pulse clock for 1/2 clock period
§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new().disable_3phase_data_clocking();

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
source

pub fn enable_3phase_data_clocking(self) -> MpsseCmdBuilder

Enable 3 phase data clocking.

This is only available on FTx232H devices.

This will give a 3 stage data shift for the purposes of supporting interfaces such as I2C which need the data to be valid on both edges of the clock.

It will appears as:

  1. Data setup for 1/2 clock period
  2. Pulse clock for 1/2 clock period
  3. Data hold for 1/2 clock period
§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new().enable_3phase_data_clocking();

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
source

pub fn enable_adaptive_data_clocking(self) -> MpsseCmdBuilder

Enable adaptive data clocking.

This is only available on FTx232H devices.

source

pub fn disable_adaptive_data_clocking(self) -> MpsseCmdBuilder

Enable adaptive data clocking.

This is only available on FTx232H devices.

source

pub fn set_gpio_lower(self, state: u8, direction: u8) -> MpsseCmdBuilder

Set the pin direction and state of the lower byte (0-7) GPIO pins on the MPSSE interface.

The pins that this controls depends on the device.

  • On the FT232H this will control the AD0-AD7 pins.
§Arguments
  • state - GPIO state mask, 0 is low (or input pin), 1 is high.
  • direction - GPIO direction mask, 0 is input, 1 is output.
§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new()
    .set_gpio_lower(0xFF, 0xFF)
    .set_gpio_lower(0x00, 0xFF);

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
source

pub fn set_gpio_upper(self, state: u8, direction: u8) -> MpsseCmdBuilder

Set the pin direction and state of the upper byte (8-15) GPIO pins on the MPSSE interface.

The pins that this controls depends on the device. This method may do nothing for some devices, such as the FT4232H that only have 8 pins per port.

§Arguments
  • state - GPIO state mask, 0 is low (or input pin), 1 is high.
  • direction - GPIO direction mask, 0 is input, 1 is output.
§FT232H Corner Case

On the FT232H only CBUS5, CBUS6, CBUS8, and CBUS9 can be controlled. These pins confusingly map to the first four bits in the direction and state masks.

§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new()
    .set_gpio_upper(0xFF, 0xFF)
    .set_gpio_upper(0x00, 0xFF);

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
source

pub fn gpio_lower(self) -> MpsseCmdBuilder

Get the pin state state of the lower byte (0-7) GPIO pins on the MPSSE interface.

§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new().gpio_lower().send_immediate();

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
let mut buf: [u8; 1] = [0; 1];
ft.read_all(&mut buf)?;
println!("GPIO lower state: 0x{:02X}", buf[0]);
source

pub fn gpio_upper(self) -> MpsseCmdBuilder

Get the pin state state of the upper byte (8-15) GPIO pins on the MPSSE interface.

See set_gpio_upper for additional information about physical pin mappings.

§Example
use ftdi_mpsse::MpsseCmdBuilder;
use libftd2xx::{Ft232h, FtdiCommon, FtdiMpsse};

let cmd = MpsseCmdBuilder::new().gpio_upper().send_immediate();

let mut ft = Ft232h::with_serial_number("FT5AVX6B")?;
ft.initialize_mpsse_default()?;
ft.write_all(cmd.as_slice())?;
let mut buf: [u8; 1] = [0; 1];
ft.read_all(&mut buf)?;
println!("GPIO upper state: 0x{:02X}", buf[0]);
source

pub fn send_immediate(self) -> MpsseCmdBuilder

Send the preceding commands immediately.

§Example
use ftdi_mpsse::MpsseCmdBuilder;

let cmd = MpsseCmdBuilder::new()
    .set_gpio_upper(0xFF, 0xFF)
    .set_gpio_upper(0x00, 0xFF)
    .send_immediate();
source

pub fn wait_on_io_high(self) -> MpsseCmdBuilder

Make controller wait until GPIOL1 or I/O1 is high before running further commands.

§Example
use ftdi_mpsse::{ClockData, MpsseCmdBuilder};

// Assume a "chip ready" signal is connected to GPIOL1. This signal is pulled high
// shortly after AD3 (chip select) is pulled low. Data will not be clocked out until
// the chip is ready.
let cmd = MpsseCmdBuilder::new()
    .set_gpio_lower(0x0, 0xb)
    .wait_on_io_high()
    .clock_data(ClockData::MsbPosIn, &[0x12, 0x34, 0x56])
    .set_gpio_lower(0x8, 0xb)
    .send_immediate();
source

pub fn wait_on_io_low(self) -> MpsseCmdBuilder

Make controller wait until GPIOL1 or I/O1 is low before running further commands.

§Example
use ftdi_mpsse::{ClockData, MpsseCmdBuilder};

// Assume a "chip ready" signal is connected to GPIOL1. This signal is pulled low
// shortly after AD3 (chip select) is pulled low. Data will not be clocked out until
// the chip is ready.
let cmd = MpsseCmdBuilder::new()
    .set_gpio_lower(0x0, 0xb)
    .wait_on_io_low()
    .clock_data(ClockData::MsbPosIn, &[0x12, 0x34, 0x56])
    .set_gpio_lower(0x8, 0xb)
    .send_immediate();
source

pub fn clock_data_out(self, mode: ClockDataOut, data: &[u8]) -> MpsseCmdBuilder

Clock data out.

This will clock out bytes on TDI/DO. No data is clocked into the device on TDO/DI.

This will panic for data lengths greater than u16::MAX + 1.

source

pub fn clock_data_in(self, mode: ClockDataIn, len: usize) -> MpsseCmdBuilder

Clock data in.

This will clock in bytes on TDO/DI. No data is clocked out of the device on TDI/DO.

§Arguments
  • mode - Data clocking mode.
  • len - Number of bytes to clock in. This will panic for values greater than u16::MAX + 1.
source

pub fn clock_data(self, mode: ClockData, data: &[u8]) -> MpsseCmdBuilder

Clock data in and out simultaneously.

This will panic for data lengths greater than u16::MAX + 1.

source

pub fn clock_bits_out( self, mode: ClockBitsOut, data: u8, len: u8 ) -> MpsseCmdBuilder

Clock data bits out.

§Arguments
  • mode - Bit clocking mode.
  • data - Data bits.
  • len - Number of bits to clock out. This will panic for values greater than 8.
source

pub fn clock_bits_in(self, mode: ClockBitsIn, len: u8) -> MpsseCmdBuilder

Clock data bits in.

§Arguments
  • mode - Bit clocking mode.
  • len - Number of bits to clock in. This will panic for values greater than 8.
source

pub fn clock_bits(self, mode: ClockBits, data: u8, len: u8) -> MpsseCmdBuilder

Clock data bits in and out simultaneously.

§Arguments
  • mode - Bit clocking mode.
  • len - Number of bits to clock in. This will panic for values greater than 8.
source

pub fn clock_tms_out( self, mode: ClockTMSOut, data: u8, tdi: bool, len: u8 ) -> MpsseCmdBuilder

Clock TMS bits out.

§Arguments
  • mode - TMS clocking mode.
  • data - TMS bits.
  • tdi - Value to place on TDI while clocking.
  • len - Number of bits to clock out. This will panic for values greater than 7.
source

pub fn clock_tms( self, mode: ClockTMS, data: u8, tdi: bool, len: u8 ) -> MpsseCmdBuilder

Clock TMS bits out while clocking TDO bits in.

§Arguments
  • mode - TMS clocking mode.
  • data - TMS bits.
  • tdi - Value to place on TDI while clocking.
  • len - Number of bits to clock out. This will panic for values greater than 7.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.