Hello,
find appended a small test program. Compile like
gcc -g -o test main.c -lftdi -l usb
and run if you have a FT2232(H) connected.
Even without anything connected to the low nibble of the low byte, the
programm should terminate and perhaps print 0xffffffff or 0. If the pins are
connected in the MPSSE-Jtag way, the IDs of the devices connected in the
JTAG chain should get printed bit reversed.
However on fast repeated runs, the programm soemtimes doesn't terminate. I
verified on two different machines with two differrent USB Chipsets
(Intel/AMD). If you change the #if 0 to #if 1, it always terminates.
Could people perhaps try to reproduce my observation or point me to
errors/flaws in my code. In short I observe in an strace of the program,
that the program stumbles after sequences like
14389 gettimeofday({1248377804, 892023}, NULL) = 0
14389 ioctl(3, USBDEVFS_SUBMITURB, 0xbf8ad934) = 0
14389 ioctl(3, USBDEVFS_REAPURBNDELAY, 0xbf8ad978) = -1 EAGAIN (Resource
temporarily unavailable)
14389 select(4, NULL, [3], NULL, {0, 1000}) = 1 (out [3], left {0, 1000})
14389 gettimeofday({1248377804, 893493}, NULL) = 0
I also think that libftdi doesn't handle EAGAIN right. It should't return to
the user program, but handle EAGAIN internally.
Thanks
Hello,
find appended a small test program. Compile like
gcc -g -o test main.c -lftdi -l usb
and run if you have a FT2232(H) connected.
Even without anything connected to the low nibble of the low byte, the
programm should terminate and perhaps print 0xffffffff or 0. If the pins are
connected in the MPSSE-Jtag way, the IDs of the devices connected in the
JTAG chain should get printed bit reversed.
However on fast repeated runs, the programm soemtimes doesn't terminate. I
verified on two different machines with two differrent USB Chipsets
(Intel/AMD). If you change the #if 0 to #if 1, it always terminates.
Could people perhaps try to reproduce my observation or point me to
errors/flaws in my code. In short I observe in an strace of the program,
that the program stumbles after sequences like
14389 gettimeofday({1248377804, 892023}, NULL) = 0
14389 ioctl(3, USBDEVFS_SUBMITURB, 0xbf8ad934) = 0
14389 ioctl(3, USBDEVFS_REAPURBNDELAY, 0xbf8ad978) = -1 EAGAIN (Resource
temporarily unavailable)
14389 select(4, NULL, [3], NULL, {0, 1000}) = 1 (out [3], left {0, 1000})
14389 gettimeofday({1248377804, 893493}, NULL) = 0
I also think that libftdi doesn't handle EAGAIN right. It should't return to
the user program, but handle EAGAIN internally.
Thanks
--
Uwe Bonnes bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
#include <ftdi.h>
#include <usb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#define VENDOR 0x0403
#define PRODUCT 0x6010
/* Sampe libftdi code to show the need for a dummy read
Compile like
gcc -g -o test main.c -lftdi -l usb
*/
int main(void)
{
struct ftdi_context ftdi;
unsigned long id;
int i, j, read=0, to_read, last_read, retries = 0;
unsigned char buf[256] = { SET_BITS_LOW, 0x08, 0x0b,
TCK_DIVISOR, 0x01, 0x00 ,
SET_BITS_HIGH, ~0x04, 0x04};
ftdi_init(&ftdi);
ftdi_set_interface(&ftdi, INTERFACE_A);
if (ftdi_usb_open_desc(&ftdi, VENDOR, PRODUCT, 0, 0) < 0)
{
printf("Can't open device\n");
return 1;
}
ftdi_set_latency_timer(&ftdi, 2);
ftdi_set_bitmode(&ftdi, 0xfb, BITMODE_MPSSE);
ftdi_usb_purge_buffers(&ftdi);
ftdi_usb_purge_rx_buffer(&ftdi);
if (ftdi_write_data(&ftdi,buf, 9) != 9)
printf("Write failed\n");
#if 0
while((last_read = ftdi_read_data(&ftdi, buf, 256))>0)
printf("%d dummy bytes readn\n", last_read);
#endif
/* Send 5 Clocks with TMS = 1 to reset the chain*/
buf[0]= MPSSE_WRITE_TMS|MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG;
buf[1]= 5;
buf[2]= 0x9f;
if (ftdi_write_data(&ftdi,buf, 3) != 3)
printf("Write1 failed\n");
usleep(10000);
/* Send 4 Clocks with TMS = 0 1 0 0 to reach SHIFTDR*/
buf[0]= MPSSE_WRITE_TMS|MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG;
buf[1]= 4;
buf[2]= 0x82;
if (ftdi_write_data(&ftdi,buf, 3) != 3)
printf("Write1 failed\n");
/* In SHIFTDR, clock 32 times to get the ID (last device first)*/
j = 0;
do
{
buf[0] = MPSSE_DO_READ|MPSSE_DO_WRITE|MPSSE_LSB|MPSSE_WRITE_NEG;
buf[1] = 3;
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
if (ftdi_write_data(&ftdi,buf, 7) != 7)
printf("Write loop failed\n");
to_read = 4;
read = 0;
while (read <to_read)
{
retries++;
last_read = ftdi_read_data(&ftdi, buf+read, to_read -read);
if (last_read > 0)
read += last_read;
}
id =
(unsigned long) buf[3] <<24 |
(unsigned long) buf[2] <<16 |
(unsigned long) buf[1] << 8 |
(unsigned long) buf[0];
if (id)
{
printf("0x%08lx\n", id);
j++;
}
} while( id !=0 && id!=0xffffffff && j<10);
ftdi_usb_close(&ftdi);
ftdi_deinit(&ftdi);
return 0;
}
--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
|