goto do_deinit;
}
ftdi_list_free(&devlist);
- int err = ftdi_usb_purge_buffers(ftdi);
+ int err = ftdi_tcioflush(ftdi);
if (err != 0) {
- fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n",
+ fprintf(stderr, "ftdi_tcioflush: %d: %s\n",
err, ftdi_get_error_string(ftdi));
retval = -1;
goto do_deinit;
on this file might be covered by the GNU General Public License.
*/
#include <libusb.h>
+#define _FTDI_DISABLE_DEPRECATED
#include "ftdi.hpp"
#include "ftdi_i.h"
#include "ftdi.h"
return ret;
}
+int Context::tcflush(int mask)
+{
+ int ret;
+
+ switch (mask & (Input | Output)) {
+ case Input:
+ ret = ftdi_tciflush(d->ftdi);
+ break;
+
+ case Output:
+ ret = ftdi_tcoflush(d->ftdi);
+ break;
+
+ case Input | Output:
+ ret = ftdi_tcioflush(d->ftdi);
+ break;
+
+ default:
+ // Emulate behavior of previous version.
+ ret = 1;
+ break;
+ }
+
+ return ret;
+}
+
int Context::set_interface(enum ftdi_interface interface)
{
return ftdi_set_interface(d->ftdi, interface);
int open(const std::string& description);
int close();
int reset();
- int flush(int mask = Input|Output);
+ int DEPRECATED(flush)(int mask = Input|Output);
+ int tcflush(int mask = Input|Output);
int set_interface(enum ftdi_interface interface);
void set_usb_device(struct libusb_device_handle *dev);
#include <stdlib.h>
#include "ftdi_i.h"
+/* Prevent deprecated messages when building library */
+#define _FTDI_DISABLE_DEPRECATED
#include "ftdi.h"
#include "ftdi_version_i.h"
/**
Clears the read buffer on the chip and the internal read buffer.
+ This is the correct behavior for an RX flush.
\param ftdi pointer to ftdi_context
\retval -1: read buffer purge failed
\retval -2: USB device unavailable
*/
+int ftdi_tciflush(struct ftdi_context *ftdi)
+{
+ if (ftdi == NULL || ftdi->usb_dev == NULL)
+ ftdi_error_return(-2, "USB device unavailable");
+
+ if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
+ SIO_RESET_REQUEST, SIO_TCIFLUSH,
+ ftdi->index, NULL, 0, ftdi->usb_write_timeout) < 0)
+ ftdi_error_return(-1, "FTDI purge of RX buffer failed");
+
+ // Invalidate data in the readbuffer
+ ftdi->readbuffer_offset = 0;
+ ftdi->readbuffer_remaining = 0;
+
+ return 0;
+}
+
+
+/**
+ Clears the write buffer on the chip and the internal read buffer.
+ This is incorrect behavior for an RX flush.
+
+ \param ftdi pointer to ftdi_context
+
+ \retval 0: all fine
+ \retval -1: write buffer purge failed
+ \retval -2: USB device unavailable
+
+ \deprecated Use \ref ftdi_tciflush(struct ftdi_context *ftdi)
+*/
int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi)
{
if (ftdi == NULL || ftdi->usb_dev == NULL)
/**
Clears the write buffer on the chip.
+ This is correct behavior for a TX flush.
\param ftdi pointer to ftdi_context
\retval -1: write buffer purge failed
\retval -2: USB device unavailable
*/
+int ftdi_tcoflush(struct ftdi_context *ftdi)
+{
+ if (ftdi == NULL || ftdi->usb_dev == NULL)
+ ftdi_error_return(-2, "USB device unavailable");
+
+ if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
+ SIO_RESET_REQUEST, SIO_TCOFLUSH,
+ ftdi->index, NULL, 0, ftdi->usb_write_timeout) < 0)
+ ftdi_error_return(-1, "FTDI purge of TX buffer failed");
+
+ return 0;
+}
+
+
+/**
+ Clears the read buffer on the chip.
+ This is incorrect behavior for a TX flush.
+
+ \param ftdi pointer to ftdi_context
+
+ \retval 0: all fine
+ \retval -1: read buffer purge failed
+ \retval -2: USB device unavailable
+
+ \deprecated Use \ref ftdi_tcoflush(struct ftdi_context *ftdi)
+*/
int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi)
{
if (ftdi == NULL || ftdi->usb_dev == NULL)
}
/**
+ Clears the RX and TX FIFOs on the chip and the internal read buffer.
+ This is correct behavior for both RX and TX flush.
+
+ \param ftdi pointer to ftdi_context
+
+ \retval 0: all fine
+ \retval -1: read buffer purge failed
+ \retval -2: write buffer purge failed
+ \retval -3: USB device unavailable
+*/
+int ftdi_tcioflush(struct ftdi_context *ftdi)
+{
+ int result;
+
+ if (ftdi == NULL || ftdi->usb_dev == NULL)
+ ftdi_error_return(-3, "USB device unavailable");
+
+ result = ftdi_tcoflush(ftdi);
+ if (result < 0)
+ return -1;
+
+ result = ftdi_tciflush(ftdi);
+ if (result < 0)
+ return -2;
+
+ return 0;
+}
+
+/**
Clears the buffers on the chip and the internal read buffer.
+ While coded incorrectly, the result is satisfactory.
\param ftdi pointer to ftdi_context
\retval -1: read buffer purge failed
\retval -2: write buffer purge failed
\retval -3: USB device unavailable
+
+ \deprecated Use \ref ftdi_tcioflush(struct ftdi_context *ftdi)
*/
int ftdi_usb_purge_buffers(struct ftdi_context *ftdi)
{
#include <sys/time.h>
#endif
+/* Define _FTDI_DISABLE_DEPRECATED to disable deprecated messages. */
+#ifdef _FTDI_DISABLE_DEPRECATED
+#define _Ftdi_Pragma(_msg)
+#else
+#define _Ftdi_Pragma(_msg) _Pragma(_msg)
+#endif
+
/* 'interface' might be defined as a macro on Windows, so we need to
* undefine it so as not to break the current libftdi API, because
* struct ftdi_context has an 'interface' member
#define SIO_RESET_SIO 0
+
+/* ** WARNING ** SIO_RESET_PURGE_RX or SIO_RESET_PURGE_TX are values used
+ * internally by libftdi to purge the RX and/or TX FIFOs (buffers).
+ * APPLICATION PROGRAMS SHOULD NOT BE USING THESE VALUES. Application
+ * programs should use one of the ftdi_tciflush, ftdi_tcoflush, or
+ * ftdi_tcioflush functions which emulate the Linux serial port tcflush(3)
+ * function.
+ *
+ * History:
+ *
+ * The definitions for these values are with respect to the FTDI chip, not the
+ * CPU. That is, when the FTDI chip receives a USB control transfer request
+ * with the command SIO_RESET_PURGE_RX, the FTDI chip empties the FIFO
+ * containing data received from the CPU awaiting transfer out the serial
+ * port to the connected serial device (e.g., a modem). Likewise, upon
+ * reception of the SIO_RESET_PURGE_TX command, the FTDI chip empties the
+ * FIFO of data received from the attached serial device destined to be
+ * transmitted to the CPU.
+ *
+ * Unfortunately the coding of the previous releases of libfti assumed these
+ * commands had the opposite effect. This resulted in the function
+ * ftdi_usb_purge_tx_buffer clearing data received from the attached serial
+ * device. Similarly, the function ftdi_usb_purge_rx_buffer cleared the
+ * FTDI FIFO containing data to be transmitted to the attached serial
+ * device. More seriously, this latter function clear the libftid's
+ * internal buffer of data received from the serial device, destined
+ * to the application program.
+ */
+#ifdef __GNUC__
+#define SIO_RESET_PURGE_RX _Ftdi_Pragma("GCC warning \"SIO_RESET_PURGE_RX\" deprecated: - use tciflush() method") 1
+#define SIO_RESET_PURGE_TX _Ftdi_Pragma("GCC warning \"SIO_RESET_PURGE_RX\" deprecated: - use tcoflush() method") 2
+#else
+#pragma message("WARNING: You need to implement deprecated #define for this compiler")
#define SIO_RESET_PURGE_RX 1
#define SIO_RESET_PURGE_TX 2
+#endif
+/* New names for the values used internally to flush (purge). */
+#define SIO_TCIFLUSH 2
+#define SIO_TCOFLUSH 1
#define SIO_DISABLE_FLOW_CTRL 0x0
#define SIO_RTS_CTS_HS (0x1 << 8)
(taken from libusb) */
#define FTDI_URB_USERCONTEXT_COOKIE ((void *)0x1)
+#ifdef _FTDI_DISABLE_DEPRECATED
+#define DEPRECATED(func) func
+#else
#ifdef __GNUC__
-#define DEPRECATED(func) func __attribute__ ((deprecated))
+#define DEPRECATED(func) __attribute__ ((deprecated)) func
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func
#endif
+#endif
struct ftdi_transfer_control
{
int ftdi_usb_close(struct ftdi_context *ftdi);
int ftdi_usb_reset(struct ftdi_context *ftdi);
- int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi);
- int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi);
- int ftdi_usb_purge_buffers(struct ftdi_context *ftdi);
+ int ftdi_tciflush(struct ftdi_context *ftdi);
+ int ftdi_tcoflush(struct ftdi_context *ftdi);
+ int ftdi_tcioflush(struct ftdi_context *ftdi);
+ int DEPRECATED(ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi));
+ int DEPRECATED(ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi));
+ int DEPRECATED(ftdi_usb_purge_buffers(struct ftdi_context *ftdi));
int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate);
int ftdi_set_line_property(struct ftdi_context *ftdi, enum ftdi_bits_type bits,
}
/* Purge anything remaining in the buffers*/
- if (ftdi_usb_purge_buffers(ftdi) < 0)
+ if (ftdi_tcioflush(ftdi) < 0)
{
- fprintf(stderr,"Can't Purge\n");
+ fprintf(stderr,"Can't flush FIFOs & buffers\n");
return 1;
}