ftdi: A thin layer over USB to communicate with FTDI chips

[ bsd3, hardware, library, system ] [ Propose Tags ]

This library enables you to communicate with FTDI devices. It is implemented as a lightweight wrapper around the usb library.

[Skip to Readme]


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


  • No Candidates
Versions [RSS] 0.1, 0.2,,,,
Change log CHANGELOG.md
Dependencies async (>=2.2 && <2.3), base (>=4.5 && <4.16), base-unicode-symbols (>=0.1.1 && <0.3), bytestring (>=0.10 && <0.12), transformers (>=0.5 && <0.7), usb (>=1.3 && <1.4), vector (>=0.12 && <0.13) [details]
License BSD-3-Clause
Copyright (c) 2009, 2010 Roel van Dijk, (c) 2018 Ben Gamari, (c) 2021 David Cox
Author Roel van Dijk <vandijk.roel@gmail.com>, Ben Gamari <ben@smart-cactus.org>, David Cox <standardsemiconductor@gmail.com>
Maintainer David Cox <standardsemiconductor@gmail.com
Category System, Hardware
Source repo head: git clone https://github.com/standardsemiconductor/ftdi
Uploaded by dopamane at 2021-09-26T00:22:01Z
Reverse Dependencies 1 direct, 0 indirect [details]
Downloads 3097 total (16 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user [build log]
All reported builds failed as of 2021-09-26 [all 2 reports]

Readme for ftdi-

[back to package description]


Haskell CI Hackage Hackage Dependencies

This library enables you to communicate with FTDI USB devices. It is implemented as a lightweight wrapper around the usb library.

See bindings-libusb for instructions to install libusb.

Build Source (Ubuntu)

$ sudo apt install libusb-1.0-0-dev
$ git clone https://github.com/standardsemiconductor/ftdi.git
$ cd ftdi/
$ cabal build
$ cabal test

Sample Usage

Find the first USB device matching the vendor ID and product ID:

import qualified System.USB as USB
import qualified Data.Vector as V (toList)
import Data.List (find)
import System.FTDI

data Failure = FailureNotFound
             | FailureOther

  :: USB.VendorId 
  -> USB.ProductId 
  -> IO (Either Failure (USB.Device, USB.Ctx))
findUSBDevice vendorId productId = do
  ctx <- USB.newCtx
  devDescs <- getDeviceDescs ctx
  return $ case fst <$> find (match . snd) devDescs of
    Nothing -> Left FailureNotFound
    Just dev -> Right (dev, ctx)
    match :: USB.DeviceDesc -> Bool
    match devDesc =  USB.deviceVendorId  devDesc == vendorId
                  && USB.deviceProductId devDesc == productId

getDeviceDescs :: USB.Ctx -> IO [(USB.Device, USB.DeviceDesc)]
getDeviceDescs ctx = do
  devs <- V.toList <$> USB.getDevices ctx
  deviceDescs <- mapM USB.getDeviceDesc devs
  return $ zip devs deviceDescs

Setup an FT2232 FTDI device on interface A using MPSSE (Multi-Protocol Synchronous Serial Engine):

  :: USB.VendorId 
  -> USB.productId
  -> (InterfaceHandle -> IO (Either Failure a) 
  -> IO (Either Failure a)
withFTDI vendorId productId action = findUSBDevice vendorId productId >>= \case
  Left failure -> return $ Left failure
  Right (usbDevice, ctx) -> do
    ftdiDevice <- fromUSBDevice usbDevice ChipType_2232H
    withDeviceHandle ftdiDevice $ \devHndl -> do
      resetUSB devHndl
      withDetachedKernelDriver devHndl Interface_A $
        withInterfaceHandle devHndl Interface_A $ \ifHndl -> do
          reset ifHndl
          purgeReadBuffer ifHndl
          purgeWriteBuffer ifHndl
          setLatencyTimer ifHndl 1
          setBitMode ifHndl 0xFF BitMode_MPSSE
          action ifHndl