Struct libftd2xx::MpsseCmdBuilder
source · 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
impl MpsseCmdBuilder
sourcepub const fn new() -> MpsseCmdBuilder
pub const fn new() -> MpsseCmdBuilder
sourcepub const fn with_vec(vec: Vec<u8>) -> MpsseCmdBuilder
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());
sourcepub fn as_slice(&self) -> &[u8] ⓘ
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())?;
sourcepub fn set_clock(self, divisor: u32, clkdiv: Option<bool>) -> MpsseCmdBuilder
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));
sourcepub fn enable_loopback(self) -> MpsseCmdBuilder
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())?;
sourcepub fn disable_loopback(self) -> MpsseCmdBuilder
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())?;
sourcepub fn disable_3phase_data_clocking(self) -> MpsseCmdBuilder
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:
- Data setup for 1/2 clock period
- 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())?;
sourcepub fn enable_3phase_data_clocking(self) -> MpsseCmdBuilder
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:
- Data setup for 1/2 clock period
- Pulse clock for 1/2 clock period
- 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())?;
sourcepub fn enable_adaptive_data_clocking(self) -> MpsseCmdBuilder
pub fn enable_adaptive_data_clocking(self) -> MpsseCmdBuilder
Enable adaptive data clocking.
This is only available on FTx232H devices.
sourcepub fn disable_adaptive_data_clocking(self) -> MpsseCmdBuilder
pub fn disable_adaptive_data_clocking(self) -> MpsseCmdBuilder
Enable adaptive data clocking.
This is only available on FTx232H devices.
sourcepub fn set_gpio_lower(self, state: u8, direction: u8) -> MpsseCmdBuilder
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())?;
sourcepub fn set_gpio_upper(self, state: u8, direction: u8) -> MpsseCmdBuilder
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())?;
sourcepub fn gpio_lower(self) -> MpsseCmdBuilder
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]);
sourcepub fn gpio_upper(self) -> MpsseCmdBuilder
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]);
sourcepub fn send_immediate(self) -> MpsseCmdBuilder
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();
sourcepub fn wait_on_io_high(self) -> MpsseCmdBuilder
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();
sourcepub fn wait_on_io_low(self) -> MpsseCmdBuilder
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();
sourcepub fn clock_data_out(self, mode: ClockDataOut, data: &[u8]) -> MpsseCmdBuilder
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
.
sourcepub fn clock_data_in(self, mode: ClockDataIn, len: usize) -> MpsseCmdBuilder
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 thanu16::MAX + 1
.
sourcepub fn clock_data(self, mode: ClockData, data: &[u8]) -> MpsseCmdBuilder
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
.
sourcepub fn clock_bits_out(
self,
mode: ClockBitsOut,
data: u8,
len: u8
) -> MpsseCmdBuilder
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.
sourcepub fn clock_bits_in(self, mode: ClockBitsIn, len: u8) -> MpsseCmdBuilder
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.
sourcepub fn clock_bits(self, mode: ClockBits, data: u8, len: u8) -> MpsseCmdBuilder
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.
sourcepub fn clock_tms_out(
self,
mode: ClockTMSOut,
data: u8,
tdi: bool,
len: u8
) -> MpsseCmdBuilder
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.
sourcepub fn clock_tms(
self,
mode: ClockTMS,
data: u8,
tdi: bool,
len: u8
) -> MpsseCmdBuilder
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.