libftdi: (tomj) initial submission of C++ wrapper
authorThomas Jarosch <opensource@intra2net.com>
Mon, 13 Oct 2008 15:47:52 +0000 (15:47 +0000)
committerThomas Jarosch <opensource@intra2net.com>
Mon, 13 Oct 2008 15:47:52 +0000 (15:47 +0000)
Makefile.am
configure.in
ftdipp/Makefile.am [new file with mode: 0644]
ftdipp/ftdi.cpp [new file with mode: 0644]
ftdipp/ftdi.hpp [new file with mode: 0644]
libftdipp.pc.in [new file with mode: 0644]

index 801ccf5..9c6cb10 100644 (file)
@@ -2,7 +2,7 @@
 # have all needed files, that a GNU package needs
 AUTOMAKE_OPTIONS = foreign 1.4
 
-SUBDIRS = src examples doc
+SUBDIRS = src ftdipp examples doc
 
 EXTRA_DIST = libftdi.spec libftdi.spec.in COPYING.LIB README AUTHORS ChangeLog libftdi-config.in
 
index ac62645..4ea7482 100644 (file)
@@ -52,4 +52,4 @@ AC_PATH_PROG(DOXYGEN, doxygen)
 AM_CONDITIONAL(HAVE_DOXYGEN, test -n $DOXYGEN)
 
 AC_OUTPUT([libftdi-config],[chmod a+x libftdi-config])
-AC_OUTPUT(Makefile src/Makefile examples/Makefile doc/Doxyfile doc/Makefile libftdi.pc libftdi.spec)
+AC_OUTPUT(Makefile src/Makefile ftdipp/Makefile examples/Makefile doc/Doxyfile doc/Makefile libftdi.pc libftdipp.pc libftdi.spec)
diff --git a/ftdipp/Makefile.am b/ftdipp/Makefile.am
new file mode 100644 (file)
index 0000000..a06822c
--- /dev/null
@@ -0,0 +1,12 @@
+# set the include path found by configure
+INCLUDES= -I$(top_srcdir)/src $(all_includes)
+
+# the library search path.
+lib_LTLIBRARIES = libftdipp.la
+include_HEADERS = ftdi.hpp
+libftdipp_la_SOURCES = $(top_builddir)/src/libftdi.la ftdi.cpp
+
+# Note:  If you specify a:b:c as the version in the next line,
+#  the library that is made has version (a-c).c.b.  In this
+#  example, the version is 2.1.2. (3:2:1)
+libftdipp_la_LDFLAGS = -version-info 15:0:14 $(all_libraries)
diff --git a/ftdipp/ftdi.cpp b/ftdipp/ftdi.cpp
new file mode 100644 (file)
index 0000000..0515f56
--- /dev/null
@@ -0,0 +1,423 @@
+#include "ftdi.hpp"
+#include "ftdi.h"
+
+namespace Ftdi
+{
+
+class Context::Private
+{
+   public:
+      Private()
+      :  ftdi(0), dev(0), open(false)
+      {}
+
+      bool open;
+      
+      struct ftdi_context* ftdi;
+      struct usb_device*   dev;
+      
+      std::string vendor;
+      std::string description;
+      std::string serial;
+};
+
+/*! \brief Constructor.
+ */
+Context::Context()
+   : d( new Private() )
+{
+   d->ftdi = ftdi_new();
+}
+
+/*! \brief Destructor.
+ */
+Context::~Context()
+{
+   if(d->open)
+      close();
+   
+   ftdi_free(d->ftdi);
+   delete d;
+}
+
+bool Context::is_open()
+{
+   return d->open;
+}
+
+int Context::open(int vendor, int product, const std::string& description, const std::string& serial)
+{
+   int ret = 0;
+   if(description.empty() && serial.empty())
+      ret = ftdi_usb_open(d->ftdi, vendor, product);
+   else
+      ret = ftdi_usb_open_desc(d->ftdi, vendor, product, description.c_str(), serial.c_str());
+
+   d->dev = usb_device(d->ftdi->usb_dev);
+
+   if((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
+   {
+      d->open = true;
+      get_strings();
+   }
+
+   return ret;
+}
+
+int Context::open(struct usb_device *dev)
+{
+   int ret = 0;
+   
+   if(dev != 0)
+      d->dev = dev;
+
+   if(d->dev == 0)
+      return -1;
+   
+   if((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
+   {
+      d->open = true;
+      get_strings();
+   }
+
+   return ret;
+}
+
+int Context::close()
+{
+   d->open = false;
+   return ftdi_usb_close(d->ftdi);
+}
+
+int Context::reset()
+{
+   return ftdi_usb_reset(d->ftdi);
+}
+
+int Context::flush(int mask)
+{
+   int ret = 1;
+   if(mask & Input)
+      ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
+   if(mask & Output)
+      ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
+
+   return ret;
+}
+
+int Context::set_interface(enum ftdi_interface interface)
+{
+   return ftdi_set_interface(d->ftdi, interface);
+}
+
+void Context::set_usb_device(struct usb_dev_handle *dev)
+{
+   ftdi_set_usbdev(d->ftdi, dev);
+   d->dev = usb_device(dev);
+}
+
+int Context::set_baud_rate(int baudrate)
+{
+   return ftdi_set_baudrate(d->ftdi, baudrate);
+}
+
+int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
+{
+   return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
+}
+
+int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity, enum ftdi_break_type break_type)
+{
+   return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
+}
+
+int Context::read(unsigned char *buf, int size)
+{
+   return ftdi_read_data(d->ftdi, buf, size);
+}
+
+int Context::set_read_chunk_size(unsigned int chunksize)
+{
+   return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
+}
+
+int Context::read_chunk_size()
+{
+   unsigned chunk = -1;
+   if(ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
+      return -1;
+   
+   return chunk;
+}
+
+
+int Context::write(unsigned char *buf, int size)
+{
+   return ftdi_write_data(d->ftdi, buf, size);
+}
+
+int Context::set_write_chunk_size(unsigned int chunksize)
+{
+   return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
+}
+
+int Context::write_chunk_size()
+{
+   unsigned chunk = -1;
+   if(ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
+      return -1;
+
+   return chunk;
+}
+
+int Context::set_flow_control(int flowctrl)
+{
+   return ftdi_setflowctrl(d->ftdi, flowctrl);
+}
+
+int Context::set_modem_control(int mask)
+{
+   int dtr = 0, rts = 0;
+   
+   if(mask & Dtr)
+      dtr = 1;
+   if(mask & Rts)
+      rts = 1;
+
+   return ftdi_setdtr_rts(d->ftdi, dtr, rts);
+}
+
+int Context::set_dtr(bool state)
+{
+   return ftdi_setdtr(d->ftdi, state);
+}
+
+int Context::set_rts(bool state)
+{
+   return ftdi_setrts(d->ftdi, state);
+}
+
+int Context::set_latency(unsigned char latency)
+{
+   return ftdi_set_latency_timer(d->ftdi, latency);
+}
+
+unsigned Context::latency()
+{
+   unsigned char latency = 0;
+   ftdi_get_latency_timer(d->ftdi, &latency);
+   return latency;
+}
+
+unsigned short Context::poll_modem_status()
+{
+   unsigned short status = 0;
+   ftdi_poll_modem_status(d->ftdi, &status);
+   return status;
+}
+
+
+int Context::set_event_char(unsigned char eventch, unsigned char enable)
+{
+   return ftdi_set_event_char(d->ftdi, eventch, enable);
+}
+
+int Context::set_error_char(unsigned char errorch, unsigned char enable)
+{
+   return ftdi_set_error_char(d->ftdi, errorch, enable);
+}
+
+int Context::bitbang_enable(unsigned char bitmask)
+{
+   return ftdi_enable_bitbang(d->ftdi, bitmask);
+}
+
+int Context::bitbang_disable()
+{
+   return ftdi_disable_bitbang(d->ftdi);
+}
+
+int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
+{
+   return ftdi_set_bitmode(d->ftdi, bitmask, mode);
+}
+
+int Context::read_pins(unsigned char *pins)
+{
+   return ftdi_read_pins(d->ftdi, pins);
+}
+
+char* Context::error_string()
+{
+   return ftdi_get_error_string(d->ftdi);
+}
+
+int Context::get_strings()
+{
+   // Prepare buffers
+   char vendor[512], desc[512], serial[512];
+   
+   int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
+
+   if(ret < 0)
+      return -1;
+   
+   d->vendor = vendor;
+   d->description = desc;
+   d->serial = serial;
+
+   return 1;
+}
+
+/*! \fn vendor
+ * \fn description
+ * \fn serial
+ * \brief Device strings properties.
+ */
+const std::string& Context::vendor()
+{
+   return d->vendor;
+}
+
+const std::string& Context::description()
+{
+   return d->description;
+}
+
+const std::string& Context::serial()
+{
+   return d->serial;
+}
+
+void Context::set_context(struct ftdi_context* context)
+{
+   ftdi_free(d->ftdi);
+   d->ftdi = context;
+}
+
+void Context::set_usb_device(struct usb_device *dev)
+{
+   d->dev = dev;
+}
+
+struct ftdi_context* Context::context()
+{
+   return d->ftdi;
+}
+
+class Eeprom::Private
+{
+   public:
+      Private()
+      : context(0)
+      {}
+
+      struct ftdi_eeprom eeprom;
+      struct ftdi_context* context;
+};
+
+Eeprom::Eeprom(Context* parent)
+   : d ( new Private() )
+{
+   d->context = parent->context();
+}
+
+Eeprom::~Eeprom()
+{
+   delete d;
+}
+
+void Eeprom::init_defaults()
+{
+   return ftdi_eeprom_initdefaults(&d->eeprom);
+}
+
+void Eeprom::set_size(int size)
+{
+   return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
+}
+
+int Eeprom::size(unsigned char *eeprom, int maxsize)
+{
+   return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize);
+}
+
+int Eeprom::chip_id(unsigned int *chipid)
+{
+   return ftdi_read_chipid(d->context, chipid);
+}
+
+int Eeprom::build(unsigned char *output)
+{
+   return ftdi_eeprom_build(&d->eeprom, output);
+}
+
+int Eeprom::read(unsigned char *eeprom)
+{
+   return ftdi_read_eeprom(d->context, eeprom);
+}
+
+int Eeprom::write(unsigned char *eeprom)
+{
+   return ftdi_write_eeprom(d->context, eeprom);
+}
+
+int Eeprom::erase()
+{
+   return ftdi_erase_eeprom(d->context);
+}
+
+class List::Private
+{
+   public:
+      Private()
+      : list(0)
+      {}
+
+      struct ftdi_device_list* list;
+};
+
+List::List(struct ftdi_device_list* devlist)
+   : ListBase(), d( new Private() )
+{
+   if(devlist != 0)
+   {
+      // Iterate list
+      Context* c = 0;
+      for(d->list = devlist; d->list != 0; d->list = d->list->next)
+      {
+         c = new Context();
+         c->set_usb_device(d->list->dev);
+         push_back(c);
+      }
+
+      // Store pointer
+      d->list = devlist;
+   }
+}
+
+List::~List()
+{
+   // Deallocate instances
+   for(iterator it = begin(); it != end(); it++)
+      delete *it;
+
+   // Clear list
+   clear();
+   ftdi_list_free(&d->list);
+
+   // Delete d-ptr
+   delete d;
+}
+
+List* List::find_all(int vendor, int product)
+{
+   struct ftdi_device_list* dlist = 0;
+   struct ftdi_context ftdi;
+   ftdi_init(&ftdi);
+   ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
+   ftdi_deinit(&ftdi);
+   return new List(dlist);
+}
+
+}
diff --git a/ftdipp/ftdi.hpp b/ftdipp/ftdi.hpp
new file mode 100644 (file)
index 0000000..7b6a9a0
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef FTDICPP_H
+#define FTDICPP_H
+
+#include <list>
+#include <string>
+#include "ftdi.h"
+
+namespace Ftdi
+{
+
+/* Forward declarations*/
+class List;
+class Eeprom;
+
+/*! \brief FTDI device context.
+ * Represents single FTDI device context.
+ */
+class Context
+{
+   /* Friends */
+   friend class Eeprom;
+   friend class List;
+   
+   public:
+
+      /*! \brief Direction flags for flush().
+       */
+      enum Direction
+      {
+         Input,
+         Output
+      };
+
+      /*! \brief Modem control flags.
+       */
+      enum ModemCtl
+      {
+         Dtr,
+         Rts
+      };
+
+      /* Constructor, Destructor */
+      Context();
+      ~Context();
+      
+      /* Properties */
+      Eeprom* eeprom();
+      const std::string& vendor();
+      const std::string& description();
+      const std::string& serial();
+
+      /* Device manipulators */
+      bool is_open();
+      int open(struct usb_device *dev = 0);
+      int open(int vendor, int product, const std::string& description = std::string(), const std::string& serial = std::string());
+      int close();
+      int reset();
+      int flush(int mask = Input|Output);
+      int set_interface(enum ftdi_interface interface);
+      void set_usb_device(struct usb_dev_handle *dev);
+      /* Line manipulators */
+      int set_baud_rate(int baudrate);
+      int set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity);
+      int set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity, enum ftdi_break_type break_type);
+
+      /* I/O */
+      int read(unsigned char *buf, int size);
+      int write(unsigned char *buf, int size);
+      int set_read_chunk_size(unsigned int chunksize);
+      int set_write_chunk_size(unsigned int chunksize);
+      int read_chunk_size();
+      int write_chunk_size();
+
+      /* Async IO
+      TODO: should wrap?
+      int writeAsync(unsigned char *buf, int size);
+      void asyncComplete(int wait_for_more);
+      */
+
+      /* Flow control */
+      int set_event_char(unsigned char eventch, unsigned char enable);
+      int set_error_char(unsigned char errorch, unsigned char enable);
+      int set_flow_control(int flowctrl);
+      int set_modem_control(int mask = Dtr|Rts);
+      int set_latency(unsigned char latency);
+      int set_dtr(bool state);
+      int set_rts(bool state);
+      
+      unsigned short poll_modem_status();
+      unsigned latency();
+
+      /* BitBang mode */
+      int set_bitmode(unsigned char bitmask, unsigned char mode);
+      int bitbang_enable(unsigned char bitmask);
+      int bitbang_disable();
+      int read_pins(unsigned char *pins);
+
+      /* Misc */
+      char* error_string();
+
+   protected:
+      int get_strings();
+
+      /* Properties */
+      struct ftdi_context* context();
+      void set_context(struct ftdi_context* context);
+      void set_usb_device(struct usb_device *dev);
+
+   private:
+      class Private;
+      Private *d;
+
+      /* Disable copy constructor */
+      Context(const Context &) {}
+      Context& operator=(const Context &) {}
+};
+
+/*! \brief Device EEPROM.
+ */
+class Eeprom
+{
+   public:
+      Eeprom(Context* parent);
+      ~Eeprom();
+
+      void init_defaults();
+      void set_size(int size);
+      int size(unsigned char *eeprom, int maxsize);
+      int chip_id(unsigned int *chipid);
+      int build(unsigned char *output);
+      int read(unsigned char *eeprom);
+      int write(unsigned char *eeprom);
+      int erase();
+
+   private:
+      class Private;
+      Private *d;
+};
+
+typedef std::list<Context*> ListBase;
+
+/*! \brief Device list.
+ */
+class List : public ListBase
+{
+   public:
+      List(struct ftdi_device_list* devlist = 0);
+      ~List();
+
+      static List* find_all(int vendor, int product);
+
+   private:
+      class Private;
+      Private *d;
+};
+
+}
+
+#endif
diff --git a/libftdipp.pc.in b/libftdipp.pc.in
new file mode 100644 (file)
index 0000000..ee81fef
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libftdipp
+Description: C++ wrapper for libftdi
+Requires: libftdi
+Version: @VERSION@
+Libs: -L${libdir} -lftdipp
+Cflags: -I${includedir}