ftdi.c - description
-------------------
begin : Fri Apr 4 2003
- copyright : (C) 2003-2010 by Intra2net AG
+ copyright : (C) 2003-2011 by Intra2net AG and the libftdi developers
email : opensource@intra2net.com
***************************************************************************/
ftdi->writebuffer_chunksize = 4096;
ftdi->max_packet_size = 0;
- ftdi->interface = 0;
- ftdi->index = 0;
- ftdi->in_ep = 0x02;
- ftdi->out_ep = 0x81;
+ ftdi_set_interface(ftdi, INTERFACE_ANY);
ftdi->bitbang_mode = 1; /* when bitbang is enabled this holds the number of the mode */
ftdi->error_str = NULL;
{
case INTERFACE_ANY:
case INTERFACE_A:
- /* ftdi_usb_open_desc cares to set the right index, depending on the found chip */
+ ftdi->interface = 0;
+ ftdi->index = INTERFACE_A;
+ ftdi->in_ep = 0x02;
+ ftdi->out_ep = 0x81;
break;
case INTERFACE_B:
ftdi->interface = 1;
else if (desc.bcdDevice == 0x800)
ftdi->type = TYPE_4232H;
- // Set default interface on dual/quad type chips
- switch (ftdi->type)
- {
- case TYPE_2232C:
- case TYPE_2232H:
- case TYPE_4232H:
- if (!ftdi->index)
- ftdi->index = INTERFACE_A;
- break;
- default:
- break;
- }
-
// Determine maximum packet size
ftdi->max_packet_size = _ftdi_determine_max_packet_size(ftdi, dev);
char string[256];
int i = 0;
- if (libusb_init(&ftdi->usb_ctx) < 0)
- ftdi_error_return(-11, "libusb_init() failed");
-
if (ftdi == NULL)
ftdi_error_return(-11, "ftdi context invalid");
+ if (libusb_init(&ftdi->usb_ctx) < 0)
+ ftdi_error_return(-11, "libusb_init() failed");
+
if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0)
ftdi_error_return(-12, "libusb_get_device_list() failed");
{
if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iProduct, (unsigned char *)string, sizeof(string)) < 0)
{
- libusb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return_free_device_list(-8, "unable to fetch product description", devs);
}
if (strncmp(string, description, sizeof(string)) != 0)
{
- libusb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
continue;
}
}
struct ftdi_transfer_control *ftdi_write_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size)
{
struct ftdi_transfer_control *tc;
- struct libusb_transfer *transfer = libusb_alloc_transfer(0);
+ struct libusb_transfer *transfer;
int write_size, ret;
if (ftdi == NULL || ftdi->usb_dev == NULL)
- {
- libusb_free_transfer(transfer);
return NULL;
- }
tc = (struct ftdi_transfer_control *) malloc (sizeof (*tc));
+ if (!tc)
+ return NULL;
- if (!tc || !transfer)
+ transfer = libusb_alloc_transfer(0);
+ if (!transfer)
+ {
+ free(tc);
return NULL;
+ }
tc->ftdi = ftdi;
tc->completed = 0;
if (ret < 0)
{
libusb_free_transfer(transfer);
- tc->completed = 1;
- tc->transfer = NULL;
+ free(tc);
return NULL;
}
tc->transfer = transfer;
if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, SIO_POLL_MODEM_STATUS_REQUEST, 0, ftdi->index, (unsigned char *)usb_val, 2, ftdi->usb_read_timeout) != 2)
ftdi_error_return(-1, "getting modem status failed");
- *status = (usb_val[1] << 8) | usb_val[0];
+ *status = (usb_val[1] << 8) | (usb_val[0] & 0xFF);
return 0;
}
\retval >=0: size of eeprom user area in bytes
\retval -1: eeprom size (128 bytes) exceeded by custom strings
- \retval -2: Invalid eeprom pointer
- \retval -3: Invalid cbus function setting
- \retval -4: Chip doesn't support invert
- \retval -5: Chip doesn't support high current drive
+ \retval -2: Invalid eeprom or ftdi pointer
+ \retval -3: Invalid cbus function setting (FIXME: Not in the code?)
+ \retval -4: Chip doesn't support invert (FIXME: Not in the code?)
+ \retval -5: Chip doesn't support high current drive (FIXME: Not in the code?)
\retval -6: No connected EEPROM or EEPROM Type unknown
*/
int ftdi_eeprom_build(struct ftdi_context *ftdi)
output = eeprom->buf;
if (eeprom->chip == -1)
- ftdi_error_return(-5,"No connected EEPROM or EEPROM type unknown");
+ ftdi_error_return(-6,"No connected EEPROM or EEPROM type unknown");
if ((eeprom->chip == 0x56) || (eeprom->chip == 0x66))
eeprom->size = 0x100;
case TYPE_4232H:
user_area_size = 86;
break;
+ default:
+ user_area_size = 0;
+ break;
}
user_area_size -= (manufacturer_size + product_size + serial_size) * 2;
"IOMODE","BB_WR","BB_RD"
};
char *cbus_BB[] = {"RXF","TXE","RD", "WR"};
- int i;
if (eeprom->invert)
{
fprintf(stdout,"C%d Function: %s\n", i,
cbus_mux[eeprom->cbus_function[i]]);
else
+ {
+ /* FIXME for Uwe: This results in an access above array bounds.
+ Also I couldn't find documentation about this mode.
fprintf(stdout,"C%d BB Function: %s\n", i,
cbus_BB[i]);
+ */
+ fprintf(stdout, "Unknown CBUS mode. Might be special mode?\n");
+ (void)cbus_BB;
+ }
}
}
}
/**
Get a value from the decoded EEPROM structure
- \\param ftdi pointer to ftdi_context
- \\param value_name Enum of the value to query
- \\param Pointer to store read value
+ \param ftdi pointer to ftdi_context
+ \param value_name Enum of the value to query
+ \param value Pointer to store read value
- \\retval 0: all fine
- \\retval -1: Value doesn't exist
+ \retval 0: all fine
+ \retval -1: Value doesn't exist
*/
int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value value_name, int* value)
{
Set a value in the decoded EEPROM Structure
No parameter checking is performed
- \\param ftdi pointer to ftdi_context
- \\param value_name Enum of the value to query
- \\param Value to set
+ \param ftdi pointer to ftdi_context
+ \param value_name Enum of the value to set
+ \param value to set
- \\retval 0: all fine
- \\retval -1: Value doesn't exist
- \\retval -2: Value not user settable
+ \retval 0: all fine
+ \retval -1: Value doesn't exist
+ \retval -2: Value not user settable
*/
int ftdi_set_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value value_name, int value)
{
/** Get the read-only buffer to the binary EEPROM content
\param ftdi pointer to ftdi_context
- \param ftdi buffer to receive EEPROM content
+ \param buf buffer to receive EEPROM content
\param size Size of receiving buffer
\retval 0: All fine
\retval -1: struct ftdi_contxt or ftdi_eeprom missing
+ \retval -2: Not enough room to store eeprom
*/
int ftdi_get_eeprom_buf(struct ftdi_context *ftdi, unsigned char * buf, int size)
{
if (!ftdi || !(ftdi->eeprom))
ftdi_error_return(-1, "No appropriate structure");
+
+ if (!buf || size < ftdi->eeprom->size)
+ ftdi_error_return(-1, "Not enough room to store eeprom");
+
+ // Only copy up to FTDI_MAX_EEPROM_SIZE bytes
+ if (size > FTDI_MAX_EEPROM_SIZE)
+ size = FTDI_MAX_EEPROM_SIZE;
+
memcpy(buf, ftdi->eeprom->buf, size);
+
return 0;
}