> Good work! Maybe the attached patch will help you.
>
> Cheers,
> Thomas
Thomas,
The line in the patch:
else if (dev->descriptor.bcdDevice == 0x800)
ftdi->type = TYPE_2232H;
for the FT2232H should be:
else if (dev->descriptor.bcdDevice == 0x700)
ftdi->type = TYPE_2232H;
With your patch applied, my proposed new ftdi_read_data() is:
/**
Reads data in chunks (see ftdi_read_data_set_chunksize()) from the chip.
Automatically strips the two modem status bytes transfered during every
read.
\param ftdi pointer to ftdi_context
\param buf Buffer to store data in
\param size Size of the buffer
\retval <0: error code from usb_bulk_read()
\retval 0: no data was available
\retval >0: number of bytes read
\remark This function is not useful in bitbang mode.
Use ftdi_read_pins() to get the current state of the pins.
*/
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;
switch (ftdi->type)
{
case TYPE_2232H:
packet_size = 512;
break;
default:
packet_size = 64;
}
// everything we want is still in the readbuffer?
if (size <= ftdi->readbuffer_remaining) {
memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
// Fix offsets
ftdi->readbuffer_remaining -= size;
ftdi->readbuffer_offset += size;
return size;
}
// something still in the readbuffer, but not enough to satisfy 'size'?
if (ftdi->readbuffer_remaining != 0) {
memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset,
ftdi->readbuffer_remaining);
// Fix offset
offset += ftdi->readbuffer_remaining;
}
// do the actual USB read
while (offset < size && ret > 0) {
ftdi->readbuffer_remaining = 0;
ftdi->readbuffer_offset = 0;
/* returns how much received */
ret = usb_bulk_read (ftdi->usb_dev, ftdi->out_ep, ftdi->readbuffer,
ftdi->readbuffer_chunksize, ftdi->usb_read_timeout);
if (ret < 0)
ftdi_error_return(ret, "usb bulk read failed\n");
if (ret > 2) {
// skip FTDI status bytes.
// Maybe stored in the future to enable modem use
num_of_chunks = ret / packet_size;
chunk_remains = ret % packet_size;
ftdi->readbuffer_offset += 2;
ret -= 2;
if (ret > packet_size - 2) {
for (i = 1; i < num_of_chunks; i++)
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+(packet_size - 2)*i,
ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i, chunk_remains-2);
ret -= 2*num_of_chunks;
}
else
ret -= 2*(num_of_chunks-1)+chunk_remains;
}
}
else if (ret <= 2) {
// no more data to read?
return offset;
}
if (ret > 0) {
// data still fits in buf?
if (offset+ret <= size) {
memcpy (buf+offset,
ftdi->readbuffer+ftdi->readbuffer_offset, ret);
offset += ret;
/* Did we read exactly the right amount of bytes? */
if (offset == size) {
//printf("read_data exact readdata->rem %d offset %d\n",
ftdi->readbuffer_remaining, offset);
}
return offset;
}
else {
// only copy part of the data or size <=
readbuffer_chunksize
int part_size = size-offset;
memcpy (buf+offset,
ftdi->readbuffer+ftdi->readbuffer_offset, part_size);
ftdi->readbuffer_offset += part_size;
ftdi->readbuffer_remaining = ret-part_size;
offset += part_size;
return offset;
}
}
}
// never reached
return -127;
}
--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
|