\return a pointer to a new ftdi_context, or NULL on failure
*/
-struct ftdi_context *ftdi_new()
+struct ftdi_context *ftdi_new(void)
{
struct ftdi_context * ftdi = (struct ftdi_context *)malloc(sizeof(struct ftdi_context));
Open selected channels on a chip, otherwise use first channel.
\param ftdi pointer to ftdi_context
- \param interface Interface to use for FT2232C chips.
+ \param interface Interface to use for FT2232C/2232H/4232H chips.
\retval 0: all fine
\retval -1: unknown interface
ftdi->in_ep = 0x04;
ftdi->out_ep = 0x83;
break;
+ case INTERFACE_C:
+ ftdi->interface = 2;
+ ftdi->index = INTERFACE_C;
+ ftdi->in_ep = 0x06;
+ ftdi->out_ep = 0x85;
+ break;
+ case INTERFACE_D:
+ ftdi->interface = 3;
+ ftdi->index = INTERFACE_D;
+ ftdi->in_ep = 0x08;
+ ftdi->out_ep = 0x87;
+ break;
default:
ftdi_error_return(-1, "Unknown interface");
}
else if (dev->descriptor.bcdDevice == 0x200)
ftdi->type = TYPE_AM;
else if (dev->descriptor.bcdDevice == 0x500)
- {
ftdi->type = TYPE_2232C;
- if (!ftdi->index)
- ftdi->index = INTERFACE_A;
- }
else if (dev->descriptor.bcdDevice == 0x600)
ftdi->type = TYPE_R;
+ else if (dev->descriptor.bcdDevice == 0x700)
+ ftdi->type = TYPE_2232H;
+ else if (dev->descriptor.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;
+ }
ftdi_error_return(0, "all fine");
}
int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
{
int offset = 0, ret = 1, i, num_of_chunks, chunk_remains;
+ int packet_size;
+
+ // New hi-speed devices from FTDI use a packet size of 512 bytes
+ if (ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H)
+ packet_size = 512;
+ else
+ packet_size = 64;
// everything we want is still in the readbuffer?
if (size <= ftdi->readbuffer_remaining)
{
// skip FTDI status bytes.
// Maybe stored in the future to enable modem use
- num_of_chunks = ret / 64;
- chunk_remains = ret % 64;
+ num_of_chunks = ret / packet_size;
+ chunk_remains = ret % packet_size;
//printf("ret = %X, num_of_chunks = %X, chunk_remains = %X, readbuffer_offset = %X\n", ret, num_of_chunks, chunk_remains, ftdi->readbuffer_offset);
ftdi->readbuffer_offset += 2;
ret -= 2;
- if (ret > 62)
+ if (ret > packet_size - 2)
{
for (i = 1; i < num_of_chunks; i++)
- memmove (ftdi->readbuffer+ftdi->readbuffer_offset+62*i,
- ftdi->readbuffer+ftdi->readbuffer_offset+64*i,
- 62);
+ memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
+ ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
+ packet_size - 2);
if (chunk_remains > 2)
{
- memmove (ftdi->readbuffer+ftdi->readbuffer_offset+62*i,
- ftdi->readbuffer+ftdi->readbuffer_offset+64*i,
+ memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
+ ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
chunk_remains-2);
ret -= 2*num_of_chunks;
}
// Addr 04: Product ID
eeprom->product_id = buf[0x04] + (buf[0x05] << 8);
- switch (buf[0x06] + (buf[0x07]<<8))
+ value = buf[0x06] + (buf[0x07]<<8);
+ switch (value)
{
case 0x0400:
eeprom->BM_type_chip = 1;