From b122ac4b01ada42874d0747f6c7cf67e6e46d43e Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 10:19:40 +0000 Subject: [PATCH] improve performance by * using synchronous bitbang mode * handling multi transfers in the jtagkey-driver by combining writes and reads --- jtagkey.c | 73 ++++++++++++++++++++++++++++++++++++---------------- usb-driver.c | 4 +-- usb-driver.h | 2 ++ 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/jtagkey.c b/jtagkey.c index 0078e47..f8e7158 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -28,22 +28,24 @@ int jtagkey_init(unsigned short vid, unsigned short pid) { 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)); return ret; } +#endif 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)); 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)); 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)); return ret; } @@ -88,9 +90,11 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int i; unsigned long port; unsigned char val; - static unsigned char last_write = 0; + static unsigned char last_write = 0, last_data = 0; unsigned char data; + unsigned char writebuf[4096], readbuf[4096], *pos; + pos = writebuf; 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, @@ -104,6 +108,12 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, DPRINTF("write byte: %d\n", val); #endif + /* Pad writebuf for read-commands in stream */ + if (tr[i].cmdTrans == 10) { + *pos = last_data; + pos++; + } + if (port == ppbase + PP_DATA) { DPRINTF("data port\n"); @@ -138,15 +148,11 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, } else { DPRINTF("!CTRL\n"); } - ftdi_write_data(&ftdic, &data, 1); - -#if 0 - do { - ftdi_read_pins(&ftdic, &tmp); - } while ((tmp & (JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_TCK|JTAGKEY_TDI)) != data); -#endif + *pos = data; + pos++; last_write = val; + last_data = data; break; default: @@ -154,11 +160,43 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, ret = -1; 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); switch(tr[i].cmdTrans) { case PP_READ: - ftdi_read_pins(&ftdic, &data); + data = *pos; #ifdef DEBUG DPRINTF("READ: 0x%x\n", data); jtagkey_state(data); @@ -183,16 +221,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, ret = -1; 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 { - DPRINTF("access to unsupported address range!\n"); ret = 0; } diff --git a/usb-driver.c b/usb-driver.c index b3dd4d8..6b1fb87 100644 --- a/usb-driver.c +++ b/usb-driver.c @@ -65,7 +65,6 @@ static pthread_mutex_t int_wait = PTHREAD_MUTEX_INITIALIZER; #define NO_WINDRVR 1 -#ifdef DEBUG void hexdump(unsigned char *buf, int len) { int i; @@ -76,7 +75,6 @@ void hexdump(unsigned char *buf, int len) { } fprintf(stderr,"\n"); } -#endif int usb_deviceinfo(unsigned char *buf) { int i,j,k,l; @@ -351,7 +349,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { switch(request & ~(0xc0000000)) { case VERSION: 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; DPRINTF("VERSION\n"); break; diff --git a/usb-driver.h b/usb-driver.h index dd93deb..282a5f8 100644 --- a/usb-driver.h +++ b/usb-driver.h @@ -43,6 +43,8 @@ #define DPRINTF(format, args...) #endif +void hexdump(unsigned char *buf, int len); + #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 */ -- 2.39.2