Categories
Blog

SPI on FT232H

In a few days, my new OLED display should arrive in the post. In the meantime I’ve been brushing up on my understanding of SPI to control it. Rather than test via an embedded device, I’d like to confirm it’s working OK by driving it directly from my PC. I bought an FT232H board a while ago, so this is a good opportunity to try it out.

Drivers, libraries, connections

After an evening fiddling with FTDI drivers, looking at various libraries, and rummaging around by scrap bin for SPI devices to talk to. I decided the best way to understand things was to build from absolute basics. The Adafruit libraries are invaluable, but they wrap up so much I felt I was missing the nuts and bolts of how one talks to a device.

For SPI the devices SCL, MOSI, MISO and CS are connected to FT232H pins AD0, AD1, AD2 and AD3 respectively. I’m experimenting with an LIS302DL accelerometer because it’s the simplest SPI thing in my bin of random bits.

To control the board I’m using Python with pyftdi. It’s a neat and well documented library. Initially my FT232H couldn’t be found when plugged in, but it turns out that on windows you have to change the driver to LibusbK, via Zadig (see links at bottom for more info). Once that’s installed correctly, you can connect via pyftdi using spi.configure('ftdi:///1').

I mooched around various bits of example code and in the datasheet to figure out how to get a response from the board. There is a WHO_AM_I message with address 0x0f, but I didn’t get any response. From the data sheet I saw the reason was that, for a read request, one must set the first bit. (Actually, it’s the last bit because MSB is sent first). Calling port.exchange with WHO_AM_I | READ_FLAG as the message, will return the ID of the device which can be matched to 0b00111011 to confirm it’s the correct device.

 

Then I tried reading off the axes but got nothing back. It’s necessary to enable the axes by writing to CTRL_REG1. After that the values may be read out fine.

from pyftdi.spi import SpiController
import time

spi = SpiController()
spi.configure('ftdi:///1')
spi.flush()
port = spi.get_port(0)
port.set_frequency(1E6)

WHO_AM_I = 0x0f
WHO_AM_I_ID = 0b00111011
CTRL_REG1 = 0x20
CTRL_REG1_MODE = 0b1100111
OUT_X = 0x29
OUT_Y = 0x2b
OUT_Z = 0x2d
READ_FLAG = 0x80

if port.exchange([WHO_AM_I | READ_FLAG], 1)[0] == WHO_AM_I_ID:
  print('yep')
else:
  print('nope')

port.write([CTRL_REG1, CTRL_REG1_MODE])

for _ in range(50):
  x = port.exchange([OUT_X | READ_FLAG], 1)[0]
  y = port.exchange([OUT_Y | READ_FLAG], 1)[0]
  z = port.exchange([OUT_Z | READ_FLAG], 1)[0]
  print(x, y, z)
  time.sleep(.1)

spi.terminate()
print('done')
Grok

Leave a Reply

Your email address will not be published. Required fields are marked *