improve performance by
* using synchronous bitbang mode * handling multi transfers in the jtagkey-driver by combining writes and reads
This commit is contained in:
parent
1dac51954a
commit
b122ac4b01
73
jtagkey.c
73
jtagkey.c
@ -28,22 +28,24 @@ int jtagkey_init(unsigned short vid, unsigned short pid) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = ftdi_write_data_set_chunksize(&ftdic, 1)) != 0) {
|
#if 0
|
||||||
|
if ((ret = ftdi_write_data_set_chunksize(&ftdic, 3)) != 0) {
|
||||||
fprintf(stderr, "unable to set write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
fprintf(stderr, "unable to set write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((ret = ftdi_set_latency_timer(&ftdic, 1)) != 0) {
|
if ((ret = ftdi_set_latency_timer(&ftdic, 1)) != 0) {
|
||||||
fprintf(stderr, "unable to set latency timer: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
fprintf(stderr, "unable to set latency timer: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = ftdi_set_baudrate(&ftdic, 230400)) != 0) {
|
if ((ret = ftdi_set_baudrate(&ftdic, 1000000)) != 0) {
|
||||||
fprintf(stderr, "unable to set baudrate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
fprintf(stderr, "unable to set baudrate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, 1)) != 0) {
|
if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, BITMODE_SYNCBB)) != 0) {
|
||||||
fprintf(stderr, "unable to enable bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
fprintf(stderr, "unable to enable bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -88,9 +90,11 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
int i;
|
int i;
|
||||||
unsigned long port;
|
unsigned long port;
|
||||||
unsigned char val;
|
unsigned char val;
|
||||||
static unsigned char last_write = 0;
|
static unsigned char last_write = 0, last_data = 0;
|
||||||
unsigned char data;
|
unsigned char data;
|
||||||
|
unsigned char writebuf[4096], readbuf[4096], *pos;
|
||||||
|
|
||||||
|
pos = writebuf;
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
|
DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
|
||||||
(unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
|
(unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
|
||||||
@ -104,6 +108,12 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
DPRINTF("write byte: %d\n", val);
|
DPRINTF("write byte: %d\n", val);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Pad writebuf for read-commands in stream */
|
||||||
|
if (tr[i].cmdTrans == 10) {
|
||||||
|
*pos = last_data;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
if (port == ppbase + PP_DATA) {
|
if (port == ppbase + PP_DATA) {
|
||||||
DPRINTF("data port\n");
|
DPRINTF("data port\n");
|
||||||
|
|
||||||
@ -138,15 +148,11 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
} else {
|
} else {
|
||||||
DPRINTF("!CTRL\n");
|
DPRINTF("!CTRL\n");
|
||||||
}
|
}
|
||||||
ftdi_write_data(&ftdic, &data, 1);
|
*pos = data;
|
||||||
|
pos++;
|
||||||
#if 0
|
|
||||||
do {
|
|
||||||
ftdi_read_pins(&ftdic, &tmp);
|
|
||||||
} while ((tmp & (JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_TCK|JTAGKEY_TDI)) != data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
last_write = val;
|
last_write = val;
|
||||||
|
last_data = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -154,11 +160,43 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (port == ppbase + PP_STATUS) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ftdi_usb_purge_buffers(&ftdic);
|
||||||
|
ftdi_write_data(&ftdic, writebuf, pos-writebuf);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
#if 0
|
||||||
|
ftdi_write_data(&ftdic, &last_data, 1);
|
||||||
|
#endif
|
||||||
|
i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf));
|
||||||
|
} while (i < pos-writebuf);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
DPRINTF("write: ");
|
||||||
|
hexdump(writebuf, pos-writebuf);
|
||||||
|
DPRINTF("read: ");
|
||||||
|
hexdump(readbuf, i);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pos = readbuf;
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
|
||||||
|
(unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
|
||||||
|
tr[i].fAutoinc, tr[i].dwOptions);
|
||||||
|
|
||||||
|
port = (unsigned long)tr[i].dwPort;
|
||||||
|
val = tr[i].Data.Byte;
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
if (port == ppbase + PP_STATUS) {
|
||||||
DPRINTF("status port (last write: %d)\n", last_write);
|
DPRINTF("status port (last write: %d)\n", last_write);
|
||||||
switch(tr[i].cmdTrans) {
|
switch(tr[i].cmdTrans) {
|
||||||
case PP_READ:
|
case PP_READ:
|
||||||
ftdi_read_pins(&ftdic, &data);
|
data = *pos;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DPRINTF("READ: 0x%x\n", data);
|
DPRINTF("READ: 0x%x\n", data);
|
||||||
jtagkey_state(data);
|
jtagkey_state(data);
|
||||||
@ -183,16 +221,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (port == ppbase + PP_CONTROL) {
|
|
||||||
DPRINTF("control port\n");
|
|
||||||
} else if ((port == ecpbase + PP_ECP_CFGA) && ecpbase) {
|
|
||||||
DPRINTF("ECP_CFGA port\n");
|
|
||||||
} else if ((port == ecpbase + PP_ECP_CFGB) && ecpbase) {
|
|
||||||
DPRINTF("ECP_CFGB port\n");
|
|
||||||
} else if ((port == ecpbase + PP_ECP_ECR) && ecpbase) {
|
|
||||||
DPRINTF("ECP_ECR port\n");
|
|
||||||
} else {
|
} else {
|
||||||
DPRINTF("access to unsupported address range!\n");
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,6 @@ static pthread_mutex_t int_wait = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
|
|
||||||
#define NO_WINDRVR 1
|
#define NO_WINDRVR 1
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
void hexdump(unsigned char *buf, int len) {
|
void hexdump(unsigned char *buf, int len) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -76,7 +75,6 @@ void hexdump(unsigned char *buf, int len) {
|
|||||||
}
|
}
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
int usb_deviceinfo(unsigned char *buf) {
|
int usb_deviceinfo(unsigned char *buf) {
|
||||||
int i,j,k,l;
|
int i,j,k,l;
|
||||||
@ -351,7 +349,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
|
|||||||
switch(request & ~(0xc0000000)) {
|
switch(request & ~(0xc0000000)) {
|
||||||
case VERSION:
|
case VERSION:
|
||||||
version = (struct version_struct*)(wdheader->data);
|
version = (struct version_struct*)(wdheader->data);
|
||||||
strcpy(version->version, "libusb-driver.so $Revision: 1.63 $");
|
strcpy(version->version, "libusb-driver.so $Revision: 1.64 $");
|
||||||
version->versionul = 802;
|
version->versionul = 802;
|
||||||
DPRINTF("VERSION\n");
|
DPRINTF("VERSION\n");
|
||||||
break;
|
break;
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
#define DPRINTF(format, args...)
|
#define DPRINTF(format, args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void hexdump(unsigned char *buf, int len);
|
||||||
|
|
||||||
#define WDU_GET_MAX_PACKET_SIZE(x) ((unsigned short) (((x) & 0x7ff) * (1 + (((x) & 0x1800) >> 11))))
|
#define WDU_GET_MAX_PACKET_SIZE(x) ((unsigned short) (((x) & 0x7ff) * (1 + (((x) & 0x1800) >> 11))))
|
||||||
|
|
||||||
/* http://www.jungo.com/support/documentation/windriver/811/wdusb_man_mhtml/node78.html#SECTION001734000000000000000 */
|
/* http://www.jungo.com/support/documentation/windriver/811/wdusb_man_mhtml/node78.html#SECTION001734000000000000000 */
|
||||||
|
Reference in New Issue
Block a user