Speaking SPI & I2C With The FT-2232 – /dev/ttyS0

For a while now I’ve been looking for an easy way to interface with external SPI and I2C devices over USB in a manner that can be easily integrated into future projects as well as used in a simple stand-alone system.

Although there are many existing SPI/I2C interface solutions, most of them are microcontroller based and connect to the PC though a USB to serial converter. This works fine, but I wanted something with a bit more speed while also remaining simple, cheap, and readily available.

After some searching, the FTDI FT-2232 family of chips seemed to fit the bill nicely. Although they are more commonly used to interface with JTAG devices, the FT-2232’s Multi-Protocol Synchronous Serial Engine (MPSSE) also supports the SPI and I2C protocols, clock rates of up to 30MHz, and a full-speed USB interface. Development boards are also cheap – the UM232H is $20 from DigiKey or Mouser in single quantities.

I’ve written libmpsse, a Linux wrapper library around libftdi that provides an easy to use API for interfacing with SPI and I2C devices using C and Python.

So how does this relate to hacking embedded systems you ask? Let’s take a look…

Although convenient, firmware update files are not always sufficient for performing code analysis on an embedded device. The firmware update file may be encrypted/obfuscated, or it may only be a partial update for the embedded system. In some cases, there may be no firmware update available at all. In these situations, being able to dump the firmware directly from the target device’s flash storage is invaluable.

SPI flash chips are increasingly replacing parallel flash chips, in both embedded devices as well as traditional PCs, and using libmpsse we can easily read and modify their contents.

As an example, let’s read the entire contents of a 1MB SPI flash chip. After making the appropriate hardware connections between the target flash chip and the FTDI chip, we can use the following Python script to dump the flash contents:


from mpsse import *

MPSSE(SPI0, THIRTY_MHZ, MSB)

Start()
Write("x03x00x00x00")
data = Read(0x100000)
Stop()

Close()

open('flash.bin', 'wb').write(data)

Although simple, the above script can read data from the flash chip very quickly:

eve@eve:~/libmpsse/src/examples$ time sudo python spiflash.py 
FT232H Future Technology Devices International, Ltd initialized at 30000000Hz (SPI mode 0)
Dumped 1048576 bytes to flash.bin

real	0m0.556s
user	0m0.020s
sys	0m0.016s

With the data extracted from the flash chip, we can now analyze it using our standard tools and techniques.

Of course libmpsse can be used to interface with other SPI/I2C devices such as data sensors, frequency synthesizers and EEPROM chips. It can be an easy way to add USB functionality to existing or future hardware designs, or to just have a simple SPI/I2C interface for development and testing.

The libmpsse source, documentation and examples are available from the Google Code project page.

Bookmark the permalink.

Comments are closed.