begin : Fri Apr 4 2003
copyright : (C) 2003-2017 by Intra2net AG and the libftdi developers
email : opensource@intra2net.com
+ SPDX-License-Identifier: LGPL-2.1-only
***************************************************************************/
/***************************************************************************
#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)
{
/**
Reads data in chunks (see ftdi_read_data_set_chunksize()) from the chip.
- Automatically strips the two modem status bytes transfered during every read.
+ Automatically strips the two modem status bytes transferred during every read.
\param ftdi pointer to ftdi_context
\param buf Buffer to store data in
return 0;
}
-int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer,
- char * product, char * serial)
+int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, const char * manufacturer,
+ const char * product, const char * serial)
{
struct ftdi_eeprom *eeprom;
case TYPE_2232C:
output[0x00] = type2bit(eeprom->channel_a_type, TYPE_2232C);
- if ( eeprom->channel_a_driver == DRIVER_VCP)
+ if (eeprom->channel_a_driver == DRIVER_VCP)
output[0x00] |= DRIVER_VCP;
else
output[0x00] &= ~DRIVER_VCP;
- if ( eeprom->high_current_a == HIGH_CURRENT_DRIVE)
+ if (eeprom->high_current_a)
output[0x00] |= HIGH_CURRENT_DRIVE;
else
output[0x00] &= ~HIGH_CURRENT_DRIVE;
output[0x01] = type2bit(eeprom->channel_b_type, TYPE_2232C);
- if ( eeprom->channel_b_driver == DRIVER_VCP)
+ if (eeprom->channel_b_driver == DRIVER_VCP)
output[0x01] |= DRIVER_VCP;
else
output[0x01] &= ~DRIVER_VCP;
- if ( eeprom->high_current_b == HIGH_CURRENT_DRIVE)
+ if (eeprom->high_current_b)
output[0x01] |= HIGH_CURRENT_DRIVE;
else
output[0x01] &= ~HIGH_CURRENT_DRIVE;
break;
case TYPE_R:
output[0x00] = type2bit(eeprom->channel_a_type, TYPE_R);
- if (eeprom->high_current == HIGH_CURRENT_DRIVE_R)
+ if (eeprom->high_current)
output[0x00] |= HIGH_CURRENT_DRIVE_R;
+ if (eeprom->channel_a_driver == DRIVER_VCP)
+ output[0x00] |= DRIVER_VCP;
if (eeprom->external_oscillator)
output[0x00] |= 0x02;
output[0x01] = 0x40; /* Hard coded Endpoint Size*/