NAME
Device::FTDI::MPSSE
- use the MPSSE mode of an FDTI chip
DESCRIPTION
This module provides convenient methods to access the Multi-Protocol Synchronous Serial Engine (MPSSE) mode of certain FTDI chips. It provides methods to wrap the various commands that control the MPSSE and interpret their responses.
The following subclasses exist to simplify implementation of particular serial protocols:
Device::FTDI::I2C for I²C
Device::FTDI::SPI for SPI
FUTURES AND BUFFERING
Unlike most Future-returning modules, it is not usually necessary to actually store the results of returned Future instances from most of these methods. The $mpsse
object itself will store them.
Especially in cases of set_*
or write_
methods, the caller is free to drop them in void context.
You should, however, be aware of the deferred nature of the activities of these methods. The reason they return futures is that none of these methods really acts immediately on the chip. Instead, pending commands are stored internally in a buffer, and emitted at once to the chip over USB, where it can act on them all, and send all the responses at once. The reason to do this is to gain a much improved performance over the USB connection.
Because of this, while it is not necessary to wait on or call "get" in Future on every returned future, it is required that the very last of a sequence of operations is waited on (usually by calling its get
method). When implementing library functions it is usually sufficient simply to let the last operation be returned in non-void context to the caller, so the caller can await it themself.
CONSTRUCTOR
new
$mpsse = Device::FTDI::MPSSE->new( %args )
An instance of this class needs a Device::FTDI object to operate on. Either it can be provided as a single named argument called ftdi
, or this constructor will build one by passing the other named arguments to "new" in Device::FTDI, except that it applies a default product
parameter of the product ID identifying the FT232H device.
This constructor performs all the necessary setup to initialse the MPSSE.
METHODS
Any of the following methods documented with a trailing ->get
call return Future instances.
set_bit_order
$mpsse->set_bit_order( $lsbfirst )
Configures the bit order of subsequent "write_bytes" or "readwrite_bytes" calls.
Takes either of the following exported constants
MSBFIRST, LSBFIRST
set_clock_edges
$mpsse->set_clock_edges( $rdclock, $wrclock )
Configures the clocking sense of subsequent read or write operations.
Each value should be one of the following constants
CLOCK_FALLING, CLOCK_RISING
write_bytes
read_bytes
readwrite_bytes
$mpsse->write_bytes( $data_out )->get
$data_in = $mpsse->read_bytes( $len )->get
$data_in = $mpsse->readwrite_bytes( $data_out )->get
Perform a bytewise clocked serial transfer. These are the "main" methods of the class; they invoke the main core of the MPSSE.
In each case, the CLK
pin will count the specified length of bytes of transfer. For the write_
and readwrite_
methods this count is implied by the length of the inbound buffer; during the operation the specified bytes will be sent out of the DO
pin.
For the read_
and readwrite_
methods, the returned future will yield the bytes that were received in the DI
pin during this time.
write_bits
read_bits
readwrite_bits
$mpsse->write_bits( $bitlen, $bits_out )->get
$bits_in = $mpsse->read_bits( $bitlen )->get
$bits_in = $mpsse->readwrite_bits( $bitlen, $bits_out )->get
Performs a bitwise clocked serial transfer of between 1 and 8 single bits.
In each case, the CLK
pin will count the specified length of bits of transfer.
For the write_
and readwrite_
methods individal bits of the given byte will be clocked out of the DO
pin. In MSBFIRST
mode, this will start from the highest bit of the byte; in LSBFIRST
mode, this will start from the lowest. The remaining bits will be ignored.
For the read_
and readwrite_
methods, the returned future will yield the bits that were received in the DI
pin during this time. In MSBFIRST
mode, the bits returned by the chip will start from the highest bit of the byte; in LSBFIRST
they will start from the lowest. The other bits will be set to zero.
write_gpio
$mpsse->write_gpio( $port, $val, $mask )->get
Write a new value to the pins on a GPIO port, setting them to outputs. This method affects only the pins specified by the $mask
bitmask, on the specified port. Pins not covered by the mask remain unaffected; they remain in their previous driven or input state.
read_gpio
$val = $mpsse->read_gpio( $port, $mask )->get
Reads the state of the pins on a GPIO port. The returned future will yield an 8-bit integer. This method sets the pins covered by $mask
as inputs. Pins not covered by the mask remain unaffected; they remain in their previous driven or input state.
tris_gpio
$mpsse->tris_gpio( $port, $mask )->get
"tristate" the pins on a GPIO port; i.e. set them as high-Z inputs rather than driven outputs. This method affects only the pins specified by the $mask
bitmask, on the specified port. Pin not covered by the mask remain unaffected. This is equivalent to read_gpio
except that it does not consume an extra byte of return value.
In each of the above methods, the GPIO port is specified by one of the following exported constants
DBUS, CBUS
set_loopback
$mpsse->set_loopback( $on )->get
If enabled, loopback mode bypasses the actual IO pins from the chip and connects the chip's internal output to its own input. This can be useful for testing whether the chip is mostly functioning correctly.
set_clock_divisor
$mpsse->set_clock_divisor( $div )->get
Sets the divider the chip uses to determine the output clock frequency. The eventual frequency will be
$freq_Hz = 12E6 / (( 1 + $div ) * 2 )
set_clkdiv5
$mpsse->set_clkdiv5( $on )->get
Disables or enables the divide-by-5 clock prescaler.
Some FTDI chips are capable of faster clock speeds. These chips use a base frequency of 60MHz rather than 12MHz, but divide it down by 5 by default to remain compatible with code unaware of this. To access the higher speeds available on these chips, disable the divider by using this method. The clock rate implied by set_clock_divisor
will then be 5 times faster.
set_3phase_clock
$mpsse->set_3phase_clock( $on )->get
If enabled, data is clocked in/out using a 3-phase strategy compatible with the I2C protocol. If this is set, the effective clock rate becomes 2/3 that implied by the clock divider.
set_adaptive_clock
$mpsse->set_adaptive_clock( $on )->get
If enabled, the chip waits for acknowledgement of a clock signal on the GPIOL3
pin before continuing for every bit transferred. This may be used by ARM processors.
set_open_collector
$mpsse->set_open_collector( $dbus, $cbus )->get
Only on FT232H chips.
Enables open-collector mode on the output pins given by the bitmasks. This mode is useful to avoid bus drive contention, especially when implementing I2C.
sleep
$mpsse->sleep( $secs )->get
Returns a future that becomes done after the given delay time, in (fractional) seconds.
Note that this method is currently experimental, and only behaves correctly when either a read future or a sleep future are outstanding. If there are both then the current implementation will fail with an exception.
TODO
Implement future await semantics when pending read and alarms are both present. This will require working out how libftdi works with timeouts.
AUTHOR
Paul Evans <leonerd@leonerd.org.uk>