From bccac33bca3c9d97bc148d41975f49a4f1fa5938 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 00:47:44 +0000 Subject: [PATCH 01/16] some cleanups --- usb-driver.c | 79 ++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/usb-driver.c b/usb-driver.c index d1d5930..9395016 100644 --- a/usb-driver.c +++ b/usb-driver.c @@ -361,7 +361,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.61 $"); + strcpy(version->version, "libusb-driver.so $Revision: 1.62 $"); version->versionul = 802; DPRINTF("VERSION\n"); break; @@ -394,53 +394,54 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { /* FIXME: Ugly hack which maps amontec JtagKey to 4. parallel port */ #ifdef JTAGKEY - if ((unsigned long)cr->Card.Item[0].I.IO.dwAddr != 0x30) + if ((unsigned long)cr->Card.Item[0].I.IO.dwAddr == 0x30) { + ret=jtagkey_init(0x0403, 0xcff8); /* I need a config file... */ + cr->hCard = 0xff; + ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; + if (ret < 0) + cr->hCard = 0; + + break; + } #endif - { - if (parportfd < 0) { - snprintf(ppdev, sizeof(ppdev), "/dev/parport%lu", - (unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); - DPRINTF("opening %s\n", ppdev); - parportfd = open(ppdev, O_RDWR|O_EXCL); - - if (parportfd < 0) - fprintf(stderr,"Can't open %s: %s\n", ppdev, strerror(errno)); - } + if (parportfd < 0) { + snprintf(ppdev, sizeof(ppdev), "/dev/parport%lu", + (unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); + DPRINTF("opening %s\n", ppdev); + parportfd = open(ppdev, O_RDWR|O_EXCL); + + if (parportfd < 0) + fprintf(stderr,"Can't open %s: %s\n", ppdev, strerror(errno)); + } - if (parportfd >= 0) { - int pmode; + if (parportfd >= 0) { + int pmode; - if (ioctl(parportfd, PPCLAIM) == -1) - return ret; + if (ioctl(parportfd, PPCLAIM) == -1) + return ret; - ecpbase = 0; - pmode = IEEE1284_MODE_COMPAT; - if (ioctl(parportfd, PPNEGOT, &pmode) == -1) - return ret; + ecpbase = 0; + pmode = IEEE1284_MODE_COMPAT; + if (ioctl(parportfd, PPNEGOT, &pmode) == -1) + return ret; - if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr) { - DPRINTF("ECP mode requested\n"); - ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr; - /* TODO: Implement ECP mode */ + if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr) { + DPRINTF("ECP mode requested\n"); + ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr; + /* TODO: Implement ECP mode */ #if 0 - pmode = IEEE1284_MODE_ECP; + pmode = IEEE1284_MODE_ECP; - if (ioctl(parportfd, PPNEGOT, &pmode) == -1) { - ecpbase = 0; - pmode = IEEE1284_MODE_COMPAT; - if (ioctl(parportfd, PPNEGOT, &pmode) == -1) - return ret; - } -#endif + if (ioctl(parportfd, PPNEGOT, &pmode) == -1) { + ecpbase = 0; + pmode = IEEE1284_MODE_COMPAT; + if (ioctl(parportfd, PPNEGOT, &pmode) == -1) + return ret; } - - cr->hCard = parportfd; - } -#ifdef JTAGKEY - } else { - ret=jtagkey_init(0x0403, 0xcff8); /* I need a config file... */ - cr->hCard = 0xff; #endif + } + + cr->hCard = parportfd; } ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; -- 2.39.2 From 1dac51954a4ae30f94b76422a292a348b02fe441 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 00:58:10 +0000 Subject: [PATCH 02/16] pass MULTI_TRANSFER to jtagkey_transfer, so it can be optimized there (which will hopefully increase performance by much) --- usb-driver.c | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/usb-driver.c b/usb-driver.c index 9395016..b3dd4d8 100644 --- a/usb-driver.c +++ b/usb-driver.c @@ -238,18 +238,12 @@ int usb_deviceinfo(unsigned char *buf) { return len; } -int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request, unsigned char *wdioctl) { +int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request) { int ret = 0; unsigned long port = (unsigned long)tr->dwPort; unsigned char val; static unsigned char last_pp_write = 0; -#ifdef JTAGKEY - /* FIXME: Config file and mor intelligent mapping! */ - if (ppbase == 0x30) - return jtagkey_transfer(tr, fd, request, ppbase, ecpbase, 1); -#endif - DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes, tr->fAutoinc, tr->dwOptions); @@ -261,9 +255,6 @@ int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request, unsigned char *wd DPRINTF("write byte: %d\n", val); #endif -#ifndef NO_WINDRVR - ret = (*ioctl_func) (fd, request, wdioctl); -#else if (parportfd < 0) return ret; @@ -335,7 +326,6 @@ int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request, unsigned char *wd } tr->Data.Byte = val; -#endif DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes, @@ -361,7 +351,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.62 $"); + strcpy(version->version, "libusb-driver.so $Revision: 1.63 $"); version->versionul = 802; DPRINTF("VERSION\n"); break; @@ -715,7 +705,18 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { { WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data); - ret = pp_transfer(tr, fd, request, wdioctl); +#ifndef NO_WINDRVR + ret = (*ioctl_func) (fd, request, wdioctl); +#else + +#ifdef JTAGKEY + if (ppbase == 0x30) { + ret = jtagkey_transfer(tr, fd, request, ppbase, ecpbase, 1); + break; + } +#endif /* JTAGKEY */ + ret = pp_transfer(tr, fd, request); +#endif } break; @@ -726,22 +727,23 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data); unsigned long num = wdheader->size/sizeof(WD_TRANSFER); int i; +#ifndef NO_WINDRVR + ret = (*ioctl_func) (fd, request, wdioctl); +#else + +#ifdef JTAGKEY + /* FIXME: Config file and mor intelligent mapping! */ + if (ppbase == 0x30) { + ret = jtagkey_transfer(tr, fd, request, ppbase, ecpbase, num); + break; + } +#endif /* JTAGKEY */ for (i = 0; i < num; i++) { DPRINTF("Transfer %d:\n", i+1); -#ifndef NO_WINDRVR - wdheader->size = sizeof(WD_TRANSFER); - request = TRANSFER; - wdheader->data = tr + i; -#endif - ret = pp_transfer(tr + i, fd, request, wdioctl); + ret = pp_transfer(tr + i, fd, request); } - -#ifndef NO_WINDRVR - wdheader->data = tr; #endif - - return ret; } break; -- 2.39.2 From b122ac4b01ada42874d0747f6c7cf67e6e46d43e Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 10:19:40 +0000 Subject: [PATCH 03/16] 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 From d0e2002d3acb644380d6250cc73927ce1d698f76 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 13:49:13 +0000 Subject: [PATCH 04/16] much faster programming via FTDI2232 now. programs a xc3s200 in 22 seconds --- jtagkey.c | 109 ++++++++++++++++++++++++++++++++++++--------------- usb-driver.c | 7 +++- usb-driver.h | 1 + 3 files changed, 84 insertions(+), 33 deletions(-) diff --git a/jtagkey.c b/jtagkey.c index f8e7158..4266959 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -3,10 +3,13 @@ #include "usb-driver.h" #include "jtagkey.h" +#define USBBUFSIZE 384 + static struct ftdi_context ftdic; int jtagkey_init(unsigned short vid, unsigned short pid) { int ret = 0; + unsigned char c; if ((ret = ftdi_init(&ftdic)) != 0) { fprintf(stderr, "unable to initialise libftdi: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); @@ -29,7 +32,7 @@ int jtagkey_init(unsigned short vid, unsigned short pid) { } #if 0 - if ((ret = ftdi_write_data_set_chunksize(&ftdic, 3)) != 0) { + if ((ret = ftdi_write_data_set_chunksize(&ftdic, 1)) != 0) { fprintf(stderr, "unable to set write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return ret; } @@ -40,11 +43,14 @@ int jtagkey_init(unsigned short vid, unsigned short pid) { return ret; } - if ((ret = ftdi_set_baudrate(&ftdic, 1000000)) != 0) { + if ((ret = ftdi_set_baudrate(&ftdic, 500000)) != 0) { fprintf(stderr, "unable to set baudrate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return ret; } + c = 0x00; + ftdi_write_data(&ftdic, &c, 1); + 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,13 +94,34 @@ void jtagkey_state(unsigned char data) { int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num) { int ret = 0; int i; + int nread = 0; unsigned long port; unsigned char val; - static unsigned char last_write = 0, last_data = 0; + static unsigned char last_data = 0; + static unsigned char writebuf[USBBUFSIZE], *writepos = writebuf; + static unsigned char readbuf[USBBUFSIZE], *readpos; unsigned char data; - unsigned char writebuf[4096], readbuf[4096], *pos; + static unsigned char last_write = 0x00; + + /* Count writes */ + for (i = 0; i < num; i++) + if (tr[i].cmdTrans == 10) + nread++; + + /* Write combining */ + if ((writepos-writebuf > sizeof(writebuf)-num) || (nread && writepos-writebuf)) { + DPRINTF("writing %d bytes due to %d following reads in %d chunks or full buffer\n", writepos-writebuf, nread, num); + + ftdi_write_data(&ftdic, writebuf, writepos-writebuf); + + i = 0; + while (i < writepos-writebuf) { + i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf)); + }; + DPRINTF("read %d/%d bytes\n", i, writepos-writebuf); + writepos = writebuf; + } - 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, @@ -109,10 +136,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, #endif /* Pad writebuf for read-commands in stream */ - if (tr[i].cmdTrans == 10) { - *pos = last_data; - pos++; - } + *writepos = last_data; if (port == ppbase + PP_DATA) { DPRINTF("data port\n"); @@ -143,16 +167,22 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, DPRINTF("!TMS\n"); } if (val & PP_CTRL) { - data |= JTAGKEY_OEn; + data = JTAGKEY_OEn; DPRINTF("CTRL\n"); } else { DPRINTF("!CTRL\n"); } - *pos = data; - pos++; - last_write = val; + if (val & PP_PROG) { + DPRINTF("PROG\n"); + } else { + DPRINTF("!PROG\n"); + } + + *writepos = data; + last_data = data; + last_write = val; break; default: @@ -161,27 +191,35 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, break; } } + writepos++; } - ftdi_usb_purge_buffers(&ftdic); - ftdi_write_data(&ftdic, writebuf, pos-writebuf); + if (nread) + { + DPRINTF("writing %d bytes\n", writepos-writebuf); + ftdi_write_data(&ftdic, writebuf, writepos-writebuf); + DPRINTF("reading %d bytes\n", writepos-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); + i = 0; + while (i < writepos-writebuf) { + i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf)); + } + DPRINTF("read %d bytes\n", i); #ifdef DEBUG - DPRINTF("write: "); - hexdump(writebuf, pos-writebuf); - DPRINTF("read: "); - hexdump(readbuf, i); + DPRINTF("write: "); + hexdump(writebuf, writepos-writebuf); + DPRINTF("read: "); + hexdump(readbuf, i); #endif - pos = readbuf; + writepos = writebuf; + } else { + return ret; + } + + readpos = readbuf; + readpos += 0; for (i = 0; i < num; i++) { DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", @@ -190,22 +228,29 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, port = (unsigned long)tr[i].dwPort; val = tr[i].Data.Byte; - pos++; + readpos++; - if (port == ppbase + PP_STATUS) { - DPRINTF("status port (last write: %d)\n", last_write); + if (port == ppbase + PP_DATA) { + if (tr[i].cmdTrans == PP_WRITE) { + last_write = val; + } + } else if (port == ppbase + PP_STATUS) { + DPRINTF("status port (last write: 0x%x)\n", last_write); switch(tr[i].cmdTrans) { case PP_READ: - data = *pos; + data = *readpos; #ifdef DEBUG DPRINTF("READ: 0x%x\n", data); jtagkey_state(data); #endif val = 0x00; - if (data & JTAGKEY_TDO) + if ((data & JTAGKEY_TDO) && (last_write & PP_PROG)) val |= PP_TDO; + if (!(last_write & PP_PROG)) + val |= 0x08; + if (last_write & 0x40) val |= 0x20; else diff --git a/usb-driver.c b/usb-driver.c index 6b1fb87..9599200 100644 --- a/usb-driver.c +++ b/usb-driver.c @@ -349,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.64 $"); + strcpy(version->version, "libusb-driver.so $Revision: 1.65 $"); version->versionul = 802; DPRINTF("VERSION\n"); break; @@ -800,6 +800,11 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else +#ifdef JTAGKEY + if (cr->hCard == 0xff) + jtagkey_close(); +#endif + if (parportfd == cr->hCard && parportfd >= 0) { ioctl(parportfd, PPRELEASE); close(parportfd); diff --git a/usb-driver.h b/usb-driver.h index 282a5f8..baddf4a 100644 --- a/usb-driver.h +++ b/usb-driver.h @@ -33,6 +33,7 @@ #define PP_TDI 0x01 #define PP_TDO 0x10 +#define PP_PROG 0x10 #define PP_TCK 0x02 #define PP_TMS 0x04 #define PP_CTRL 0x08 -- 2.39.2 From e81047b8157f32990ff39fa08f4b58ae614ccd06 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 14:40:03 +0000 Subject: [PATCH 05/16] ignore no-ops --- jtagkey.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/jtagkey.c b/jtagkey.c index 4266959..9891f4b 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -98,14 +98,14 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, unsigned long port; unsigned char val; static unsigned char last_data = 0; + static unsigned char last_write = 0x00; static unsigned char writebuf[USBBUFSIZE], *writepos = writebuf; static unsigned char readbuf[USBBUFSIZE], *readpos; - unsigned char data; - static unsigned char last_write = 0x00; + unsigned char data, prev_data; - /* Count writes */ + /* Count reads */ for (i = 0; i < num; i++) - if (tr[i].cmdTrans == 10) + if (tr[i].cmdTrans == PP_READ) nread++; /* Write combining */ @@ -117,7 +117,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, i = 0; while (i < writepos-writebuf) { i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf)); - }; + } DPRINTF("read %d/%d bytes\n", i, writepos-writebuf); writepos = writebuf; } @@ -137,6 +137,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, /* Pad writebuf for read-commands in stream */ *writepos = last_data; + prev_data = last_data; if (port == ppbase + PP_DATA) { DPRINTF("data port\n"); @@ -191,7 +192,9 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, break; } } - writepos++; + + if (nread || (*writepos != prev_data)) + writepos++; } if (nread) -- 2.39.2 From 3e670223fd5f2f0cf098c8c5ad611679a7c752c3 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 15:18:42 +0000 Subject: [PATCH 06/16] start of configuration infrastructure --- Makefile | 8 +++--- config.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ config.h | 11 ++++++++ usb-driver.c | 54 +++++++++++++++++++------------------ 4 files changed, 119 insertions(+), 29 deletions(-) create mode 100644 config.c create mode 100644 config.h diff --git a/Makefile b/Makefile index 8f1f94a..cc2de3e 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,11 @@ SOBJECTS=libusb-driver.so libusb-driver-DEBUG.so all: $(SOBJECTS) -libusb-driver.so: usb-driver.c jtagkey.c usb-driver.h jtagkey.h Makefile - gcc $(CFLAGS) usb-driver.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared +libusb-driver.so: usb-driver.c jtagkey.c config.c usb-driver.h jtagkey.h config.h Makefile + gcc $(CFLAGS) usb-driver.c config.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared -libusb-driver-DEBUG.so: usb-driver.c jtagkey.c usb-driver.h jtagkey.h Makefile - gcc -DDEBUG $(CFLAGS) usb-driver.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared +libusb-driver-DEBUG.so: usb-driver.c jtagkey.c config.c usb-driver.h jtagkey.h config.h Makefile + gcc -DDEBUG $(CFLAGS) usb-driver.c config.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared clean: rm -f $(SOBJECTS) diff --git a/config.c b/config.c new file mode 100644 index 0000000..9b085d6 --- /dev/null +++ b/config.c @@ -0,0 +1,75 @@ +#include +#include +#include "config.h" + +static struct parport_config pp_config[4]; + +static void read_config() { + int i; + static int config_read = 0; + + if (config_read) + return; + + config_read = 1; + + for (i=0; i #include #include "usb-driver.h" +#include "config.h" #ifdef JTAGKEY #include "jtagkey.h" #endif @@ -349,7 +350,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.65 $"); + strcpy(version->version, "libusb-driver.so $Revision: 1.66 $"); version->versionul = 802; DPRINTF("VERSION\n"); break; @@ -380,10 +381,11 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { ret = (*ioctl_func) (fd, request, wdioctl); #else - /* FIXME: Ugly hack which maps amontec JtagKey to 4. parallel port */ #ifdef JTAGKEY - if ((unsigned long)cr->Card.Item[0].I.IO.dwAddr == 0x30) { - ret=jtagkey_init(0x0403, 0xcff8); /* I need a config file... */ + if (!config_is_real_pport((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10)) { + int num = (unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10; + + ret=jtagkey_init(config_usb_vid(num), config_usb_pid(num)); cr->hCard = 0xff; ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; if (ret < 0) @@ -392,6 +394,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { break; } #endif + if (parportfd < 0) { snprintf(ppdev, sizeof(ppdev), "/dev/parport%lu", (unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); @@ -708,7 +711,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { #else #ifdef JTAGKEY - if (ppbase == 0x30) { + if (!config_is_real_pport(ppbase / 0x10)) { ret = jtagkey_transfer(tr, fd, request, ppbase, ecpbase, 1); break; } @@ -730,8 +733,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { #else #ifdef JTAGKEY - /* FIXME: Config file and mor intelligent mapping! */ - if (ppbase == 0x30) { + if (!config_is_real_pport(ppbase / 0x10)) { ret = jtagkey_transfer(tr, fd, request, ppbase, ecpbase, num); break; } @@ -981,13 +983,26 @@ FILE *fopen(const char *path, const char *mode) { if (!func) func = (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT, "fopen"); -#ifdef JTAGKEY - /* FIXME: Hack for parport mapping */ - if (!strcmp(path, "/proc/sys/dev/parport/parport3/base-addr")) { - ret = (*func) ("/dev/null", mode); - } else -#endif - ret = (*func) (path, mode); + for (i = 0; i < 4; i++) { + snprintf(buf, sizeof(buf), "/proc/sys/dev/parport/parport%d/base-addr", i); + if (!strcmp(path, buf)) { + DPRINTF("open base-addr of parport%d\n", i); + if (config_is_real_pport(i)) { + ret = (*func) (path, mode); + } else { + ret = (*func) ("/dev/null", mode); + } + + if (ret) { + baseaddrfp = ret; + baseaddrnum = i; + } + + return ret; + } + } + + ret = (*func) (path, mode); if (!strcmp(path, "/proc/modules")) { DPRINTF("opening /proc/modules\n"); @@ -996,17 +1011,6 @@ FILE *fopen(const char *path, const char *mode) { modules_read = 0; #endif } - - if (ret) { - for (i = 0; i < 4; i++) { - snprintf(buf, sizeof(buf), "/proc/sys/dev/parport/parport%d/base-addr", i); - if (!strcmp(path, buf)) { - DPRINTF("open base-addr of parport%d\n", i); - baseaddrfp = ret; - baseaddrnum = i; - } - } - } return ret; } -- 2.39.2 From 4af4753dc42ce756e91d803da1824478e11695f0 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 15:57:34 +0000 Subject: [PATCH 07/16] increase programming speed by a factor of 4. it now takes 5 seconds to program a xc3s400, which is the same time it takes to program this chip with a parallel cable. --- jtagkey.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/jtagkey.c b/jtagkey.c index 9891f4b..2be1954 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -3,9 +3,10 @@ #include "usb-driver.h" #include "jtagkey.h" -#define USBBUFSIZE 384 +#define USBBUFSIZE 4096 static struct ftdi_context ftdic; +static unsigned int usb_maxlen = 0; int jtagkey_init(unsigned short vid, unsigned short pid) { int ret = 0; @@ -31,12 +32,11 @@ int jtagkey_init(unsigned short vid, unsigned short pid) { return ret; } -#if 0 - if ((ret = ftdi_write_data_set_chunksize(&ftdic, 1)) != 0) { - fprintf(stderr, "unable to set write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); + + if ((ret = ftdi_write_data_get_chunksize(&ftdic, &usb_maxlen)) != 0) { + fprintf(stderr, "unable to get 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)); @@ -51,7 +51,7 @@ int jtagkey_init(unsigned short vid, unsigned short pid) { c = 0x00; ftdi_write_data(&ftdic, &c, 1); - if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, BITMODE_SYNCBB)) != 0) { + if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, BITMODE_BITBANG)) != 0) { fprintf(stderr, "unable to enable bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return ret; } @@ -110,14 +110,21 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, /* Write combining */ if ((writepos-writebuf > sizeof(writebuf)-num) || (nread && writepos-writebuf)) { + unsigned char *pos = writebuf; + int len; DPRINTF("writing %d bytes due to %d following reads in %d chunks or full buffer\n", writepos-writebuf, nread, num); - ftdi_write_data(&ftdic, writebuf, writepos-writebuf); + len = writepos-pos; + + while (pos < writepos) { + if (len > usb_maxlen) + len = usb_maxlen; - i = 0; - while (i < writepos-writebuf) { - i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf)); + DPRINTF("combined write of %d/%d\n",len,writepos-pos); + ftdi_write_data(&ftdic, pos, len); + pos += len; } + DPRINTF("read %d/%d bytes\n", i, writepos-writebuf); writepos = writebuf; } @@ -200,14 +207,10 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, if (nread) { DPRINTF("writing %d bytes\n", writepos-writebuf); - ftdi_write_data(&ftdic, writebuf, writepos-writebuf); - DPRINTF("reading %d bytes\n", writepos-writebuf); - - i = 0; - while (i < writepos-writebuf) { - i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf)); + for (i=0; i Date: Sun, 29 Apr 2007 16:00:49 +0000 Subject: [PATCH 08/16] correctly handle cases where the usb chunksize is smaller than the combined write --- jtagkey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jtagkey.c b/jtagkey.c index 2be1954..b06b6b4 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -114,9 +114,9 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int len; DPRINTF("writing %d bytes due to %d following reads in %d chunks or full buffer\n", writepos-writebuf, nread, num); - len = writepos-pos; - while (pos < writepos) { + len = writepos-pos; + if (len > usb_maxlen) len = usb_maxlen; -- 2.39.2 From 397d1c368eb948ccabdd711bd20a92461bf60799 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 17:06:01 +0000 Subject: [PATCH 09/16] remove useless code --- jtagkey.c | 1 - 1 file changed, 1 deletion(-) diff --git a/jtagkey.c b/jtagkey.c index b06b6b4..c12e235 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -225,7 +225,6 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, } readpos = readbuf; - readpos += 0; for (i = 0; i < num; i++) { DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", -- 2.39.2 From a270f1e37a49ae072740de471bfe98658dea3b5e Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 17:51:28 +0000 Subject: [PATCH 10/16] only read pins when needed, now it's a bit faster than a parallel cable --- jtagkey.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jtagkey.c b/jtagkey.c index c12e235..bf1cded 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -209,7 +209,9 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, DPRINTF("writing %d bytes\n", writepos-writebuf); for (i=0; i 0 && tr[i].cmdTrans == PP_WRITE && tr[i-1].cmdTrans == PP_READ) + ftdi_read_pins(&ftdic, readbuf+i); } #ifdef DEBUG -- 2.39.2 From 3f5287b7f725b0e90b8a29b4ed3e16cfdc8d6fbe Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 18:48:10 +0000 Subject: [PATCH 11/16] some more performance improvements --- jtagkey.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/jtagkey.c b/jtagkey.c index bf1cded..04cfb4c 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -208,10 +208,35 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, { DPRINTF("writing %d bytes\n", writepos-writebuf); for (i=0; i 0 && + tr[combine-1].cmdTrans == PP_READ) { + break; + } else { + combine++; + } + } while (combine < writepos-writebuf); + + DPRINTF("combined writes before read: %d\n", combine); + + if ((combine-i)-1 > 0) { + ftdi_write_data(&ftdic, writebuf+i, (combine-i)-1); + i = combine-1; + } +#endif + ftdi_write_data(&ftdic, writebuf+i, 1); if (i > 0 && tr[i].cmdTrans == PP_WRITE && tr[i-1].cmdTrans == PP_READ) ftdi_read_pins(&ftdic, readbuf+i); + + if (i == (writepos-writebuf)-1 && tr[i].cmdTrans == PP_READ) { + ftdi_write_data(&ftdic, writebuf+i, 1); + ftdi_read_pins(&ftdic, readbuf+i+1); + } } #ifdef DEBUG -- 2.39.2 From 9640dec9c74e42c63bd63b1df6e660de7a395a30 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 21:32:59 +0000 Subject: [PATCH 12/16] use the right tool for the job! use BITMODE_BITBANG for bulk transfers and BITMODE_BBSYNC for transfers with interleaved reads --- jtagkey.c | 63 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/jtagkey.c b/jtagkey.c index 04cfb4c..249e9d9 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -1,5 +1,6 @@ #include #include +#include #include "usb-driver.h" #include "jtagkey.h" @@ -7,6 +8,7 @@ static struct ftdi_context ftdic; static unsigned int usb_maxlen = 0; +static unsigned char bitbang_mode; int jtagkey_init(unsigned short vid, unsigned short pid) { int ret = 0; @@ -56,6 +58,8 @@ int jtagkey_init(unsigned short vid, unsigned short pid) { return ret; } + bitbang_mode = BITMODE_BITBANG; + if ((ret = ftdi_usb_purge_buffers(&ftdic)) != 0) { fprintf(stderr, "unable to purge buffers: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return ret; @@ -70,6 +74,30 @@ void jtagkey_close() { ftdi_deinit(&ftdic); } +static int jtagkey_set_bbmode(unsigned char mode) { + int ret = 0; + + if (bitbang_mode != mode) { + DPRINTF("switching bitbang-mode!\n"); + /* Wait for the latency-timer to kick in */ + usleep(2); + if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, mode)) != 0) { + fprintf(stderr, "unable to enable bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); + return ret; + } + if ((ret = ftdi_usb_purge_buffers(&ftdic)) != 0) { + fprintf(stderr, "unable to purge buffers: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); + return ret; + } + /* Wait for the FTDI2232 to settle */ + usleep(2); + + bitbang_mode = mode; + } + + return ret; +} + void jtagkey_state(unsigned char data) { fprintf(stderr,"Pins high: "); @@ -114,6 +142,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int len; DPRINTF("writing %d bytes due to %d following reads in %d chunks or full buffer\n", writepos-writebuf, nread, num); + jtagkey_set_bbmode(BITMODE_BITBANG); while (pos < writepos) { len = writepos-pos; @@ -207,36 +236,12 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, if (nread) { DPRINTF("writing %d bytes\n", writepos-writebuf); - for (i=0; i 0 && - tr[combine-1].cmdTrans == PP_READ) { - break; - } else { - combine++; - } - } while (combine < writepos-writebuf); - - DPRINTF("combined writes before read: %d\n", combine); + jtagkey_set_bbmode(BITMODE_SYNCBB); + ftdi_write_data(&ftdic, writebuf, writepos-writebuf); - if ((combine-i)-1 > 0) { - ftdi_write_data(&ftdic, writebuf+i, (combine-i)-1); - i = combine-1; - } -#endif - - ftdi_write_data(&ftdic, writebuf+i, 1); - - if (i > 0 && tr[i].cmdTrans == PP_WRITE && tr[i-1].cmdTrans == PP_READ) - ftdi_read_pins(&ftdic, readbuf+i); - - if (i == (writepos-writebuf)-1 && tr[i].cmdTrans == PP_READ) { - ftdi_write_data(&ftdic, writebuf+i, 1); - ftdi_read_pins(&ftdic, readbuf+i+1); - } + i = 0; + while (i < writepos-writebuf) { + i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf)); } #ifdef DEBUG -- 2.39.2 From 59b06a85e237c6e1ec74c22eac16ee010f07c630 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 21:50:09 +0000 Subject: [PATCH 13/16] make sure that there is valid data if the last command in a transfer is a read --- jtagkey.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jtagkey.c b/jtagkey.c index 249e9d9..7707ae0 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -79,6 +79,7 @@ static int jtagkey_set_bbmode(unsigned char mode) { if (bitbang_mode != mode) { DPRINTF("switching bitbang-mode!\n"); + /* Wait for the latency-timer to kick in */ usleep(2); if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, mode)) != 0) { @@ -236,6 +237,10 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, if (nread) { DPRINTF("writing %d bytes\n", writepos-writebuf); + + *writepos = last_data; + writepos++; + jtagkey_set_bbmode(BITMODE_SYNCBB); ftdi_write_data(&ftdic, writebuf, writepos-writebuf); @@ -276,6 +281,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, switch(tr[i].cmdTrans) { case PP_READ: data = *readpos; + #ifdef DEBUG DPRINTF("READ: 0x%x\n", data); jtagkey_state(data); -- 2.39.2 From 7cd012c138eac61de5325a6950b8dabd3162615c Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 29 Apr 2007 22:15:34 +0000 Subject: [PATCH 14/16] remove old debug message --- jtagkey.c | 1 - 1 file changed, 1 deletion(-) diff --git a/jtagkey.c b/jtagkey.c index 7707ae0..2490b31 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -155,7 +155,6 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, pos += len; } - DPRINTF("read %d/%d bytes\n", i, writepos-writebuf); writepos = writebuf; } -- 2.39.2 From 185be93e9d53875901248462ca1ea6bc5ccb3605 Mon Sep 17 00:00:00 2001 From: michael Date: Mon, 30 Apr 2007 08:02:08 +0000 Subject: [PATCH 15/16] some todos --- config.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config.c b/config.c index 9b085d6..c41590f 100644 --- a/config.c +++ b/config.c @@ -73,3 +73,8 @@ unsigned short config_usb_pid(int num) { return ret; } + +/* TODO: +int config_init_port(int num) {} +config_get_transfer_fn(int num) {} +*/ -- 2.39.2 From 5e3d963bcb6112d798f674b876b167c633ff6b59 Mon Sep 17 00:00:00 2001 From: michael Date: Mon, 30 Apr 2007 09:23:32 +0000 Subject: [PATCH 16/16] unify parallel and jtagkey interface --- Makefile | 8 +-- config.h | 1 + jtagkey.c | 24 +++++-- jtagkey.h | 4 +- parport.c | 168 ++++++++++++++++++++++++++++++++++++++++++++ parport.h | 3 + usb-driver.c | 193 ++++++--------------------------------------------- 7 files changed, 217 insertions(+), 184 deletions(-) create mode 100644 parport.c create mode 100644 parport.h diff --git a/Makefile b/Makefile index cc2de3e..21cb565 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,11 @@ SOBJECTS=libusb-driver.so libusb-driver-DEBUG.so all: $(SOBJECTS) -libusb-driver.so: usb-driver.c jtagkey.c config.c usb-driver.h jtagkey.h config.h Makefile - gcc $(CFLAGS) usb-driver.c config.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared +libusb-driver.so: usb-driver.c parport.c jtagkey.c config.c usb-driver.h parport.h jtagkey.h config.h Makefile + gcc $(CFLAGS) usb-driver.c parport.c config.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared -libusb-driver-DEBUG.so: usb-driver.c jtagkey.c config.c usb-driver.h jtagkey.h config.h Makefile - gcc -DDEBUG $(CFLAGS) usb-driver.c config.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared +libusb-driver-DEBUG.so: usb-driver.c parport.c jtagkey.c config.c usb-driver.h parport.h jtagkey.h config.h Makefile + gcc -DDEBUG $(CFLAGS) usb-driver.c parport.c config.c $(JTAGKEYSRC) -o $@ -ldl -lusb -lpthread $(FTDI) -shared clean: rm -f $(SOBJECTS) diff --git a/config.h b/config.h index 1cacd06..f238e3b 100644 --- a/config.h +++ b/config.h @@ -4,6 +4,7 @@ struct parport_config { unsigned char real; unsigned short usb_vid; unsigned short usb_pid; + /* TODO: function pointer */ }; unsigned char config_is_real_pport(int num); diff --git a/jtagkey.c b/jtagkey.c index 2490b31..dec0b81 100644 --- a/jtagkey.c +++ b/jtagkey.c @@ -2,6 +2,7 @@ #include #include #include "usb-driver.h" +#include "config.h" #include "jtagkey.h" #define USBBUFSIZE 4096 @@ -10,7 +11,7 @@ static struct ftdi_context ftdic; static unsigned int usb_maxlen = 0; static unsigned char bitbang_mode; -int jtagkey_init(unsigned short vid, unsigned short pid) { +static int jtagkey_init(unsigned short vid, unsigned short pid) { int ret = 0; unsigned char c; @@ -68,10 +69,23 @@ int jtagkey_init(unsigned short vid, unsigned short pid) { return ret; } -void jtagkey_close() { - ftdi_disable_bitbang(&ftdic); - ftdi_usb_close(&ftdic); - ftdi_deinit(&ftdic); +int jtagkey_open(int num) { + int ret; + + ret = jtagkey_init(config_usb_vid(num), config_usb_pid(num)); + + if (ret >= 0) + ret = 0xff; + + return ret; +} + +void jtagkey_close(int handle) { + if (handle == 0xff) { + ftdi_disable_bitbang(&ftdic); + ftdi_usb_close(&ftdic); + ftdi_deinit(&ftdic); + } } static int jtagkey_set_bbmode(unsigned char mode) { diff --git a/jtagkey.h b/jtagkey.h index 59a32e2..2c13260 100644 --- a/jtagkey.h +++ b/jtagkey.h @@ -5,6 +5,6 @@ #define JTAGKEY_VREF 0x20 #define JTAGKEY_OEn 0x10 -int jtagkey_init(unsigned short vid, unsigned short pid); -void jtagkey_close(); int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num); +int jtagkey_open(int num); +void jtagkey_close(int handle); diff --git a/parport.c b/parport.c new file mode 100644 index 0000000..9cf35cd --- /dev/null +++ b/parport.c @@ -0,0 +1,168 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "usb-driver.h" +#include "parport.h" + +static int parportfd = -1; + +int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num) { + int ret = 0; + int i; + unsigned long port; + unsigned char val; + static unsigned char last_pp_write = 0; + + 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; + +#ifdef DEBUG + if (tr[i].cmdTrans == 13) + DPRINTF("write byte: %d\n", val); +#endif + + if (parportfd < 0) + return ret; + + if (port == ppbase + PP_DATA) { + DPRINTF("data port\n"); + switch(tr[i].cmdTrans) { + case PP_READ: + ret = 0; /* We don't support reading of the data port */ + break; + + case PP_WRITE: + ret = ioctl(parportfd, PPWDATA, &val); + last_pp_write = val; + break; + + default: + fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr[i].cmdTrans); + ret = -1; + break; + } + } else if (port == ppbase + PP_STATUS) { + DPRINTF("status port (last write: %d)\n", last_pp_write); + switch(tr[i].cmdTrans) { + case PP_READ: + ret = ioctl(parportfd, PPRSTATUS, &val); +#ifdef FORCE_PC3_IDENT + val &= 0x5f; + if (last_pp_write & 0x40) + val |= 0x20; + else + val |= 0x80; +#endif + break; + + case PP_WRITE: + ret = 0; /* Status Port is readonly */ + break; + + default: + fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr[i].cmdTrans); + ret = -1; + break; + } + } else if (port == ppbase + PP_CONTROL) { + DPRINTF("control port\n"); + switch(tr[i].cmdTrans) { + case PP_READ: + ret = ioctl(parportfd, PPRCONTROL, &val); + break; + + case PP_WRITE: + ret = ioctl(parportfd, PPWCONTROL, &val); + break; + + default: + fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr[i].cmdTrans); + ret = -1; + break; + } + } 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; + } + + tr[i].Data.Byte = val; + + DPRINTF("dwPortReturn: 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); +#ifdef DEBUG + if (tr[i].cmdTrans == 10) + DPRINTF("read byte: %d\n", tr[i].Data.Byte); +#endif + } + + return ret; +} + +int parport_open(int num) { + char ppdev[32]; + + if (parportfd < 0) { + snprintf(ppdev, sizeof(ppdev), "/dev/parport%u", num); + DPRINTF("opening %s\n", ppdev); + parportfd = open(ppdev, O_RDWR|O_EXCL); + + if (parportfd < 0) + fprintf(stderr,"Can't open %s: %s\n", ppdev, strerror(errno)); + } + + if (parportfd >= 0) { + int pmode; + + if (ioctl(parportfd, PPCLAIM) == -1) + return -1; + + pmode = IEEE1284_MODE_COMPAT; + if (ioctl(parportfd, PPNEGOT, &pmode) == -1) + return -1; + +#if 0 + if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr) { + DPRINTF("ECP mode requested\n"); + ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr; + /* TODO: Implement ECP mode */ + pmode = IEEE1284_MODE_ECP; + + if (ioctl(parportfd, PPNEGOT, &pmode) == -1) { + ecpbase = 0; + pmode = IEEE1284_MODE_COMPAT; + if (ioctl(parportfd, PPNEGOT, &pmode) == -1) + return ret; + } + } +#endif + } + + return parportfd; +} + +void parport_close(int handle) { + if (parportfd == handle && parportfd >= 0) { + ioctl(parportfd, PPRELEASE); + close(parportfd); + parportfd = -1; + } +} diff --git a/parport.h b/parport.h new file mode 100644 index 0000000..d4fbaa2 --- /dev/null +++ b/parport.h @@ -0,0 +1,3 @@ +int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num); +int parport_open(int num); +void parport_close(int handle); diff --git a/usb-driver.c b/usb-driver.c index b39c4fc..f2f8477 100644 --- a/usb-driver.c +++ b/usb-driver.c @@ -39,17 +39,15 @@ #include #include #include -#include -#include #include "usb-driver.h" #include "config.h" +#include "parport.h" #ifdef JTAGKEY #include "jtagkey.h" #endif static int (*ioctl_func) (int, int, void *) = NULL; static int windrvrfd = -1; -static int parportfd = -1; static unsigned long ppbase = 0; static unsigned long ecpbase = 0; FILE *modulesfp = NULL; @@ -237,106 +235,6 @@ int usb_deviceinfo(unsigned char *buf) { return len; } -int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request) { - int ret = 0; - unsigned long port = (unsigned long)tr->dwPort; - unsigned char val; - static unsigned char last_pp_write = 0; - - DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", - (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes, - tr->fAutoinc, tr->dwOptions); - - val = tr->Data.Byte; - -#ifdef DEBUG - if (tr->cmdTrans == 13) - DPRINTF("write byte: %d\n", val); -#endif - - if (parportfd < 0) - return ret; - - if (port == ppbase + PP_DATA) { - DPRINTF("data port\n"); - switch(tr->cmdTrans) { - case PP_READ: - ret = 0; /* We don't support reading of the data port */ - break; - - case PP_WRITE: - ret = ioctl(parportfd, PPWDATA, &val); - last_pp_write = val; - break; - - default: - fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr->cmdTrans); - ret = -1; - break; - } - } else if (port == ppbase + PP_STATUS) { - DPRINTF("status port (last write: %d)\n", last_pp_write); - switch(tr->cmdTrans) { - case PP_READ: - ret = ioctl(parportfd, PPRSTATUS, &val); -#ifdef FORCE_PC3_IDENT - val &= 0x5f; - if (last_pp_write & 0x40) - val |= 0x20; - else - val |= 0x80; -#endif - break; - - case PP_WRITE: - ret = 0; /* Status Port is readonly */ - break; - - default: - fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr->cmdTrans); - ret = -1; - break; - } - } else if (port == ppbase + PP_CONTROL) { - DPRINTF("control port\n"); - switch(tr->cmdTrans) { - case PP_READ: - ret = ioctl(parportfd, PPRCONTROL, &val); - break; - - case PP_WRITE: - ret = ioctl(parportfd, PPWCONTROL, &val); - break; - - default: - fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr->cmdTrans); - ret = -1; - break; - } - } 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; - } - - tr->Data.Byte = val; - - DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", - (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes, - tr->fAutoinc, tr->dwOptions); -#ifdef DEBUG - if (tr->cmdTrans == 10) - DPRINTF("read byte: %d\n", tr->Data.Byte); -#endif - - return ret; -} - int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { struct header_struct* wdheader = (struct header_struct*)wdioctl; struct version_struct *version; @@ -350,7 +248,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.66 $"); + strcpy(version->version, "libusb-driver.so $Revision: 1.67 $"); version->versionul = 802; DPRINTF("VERSION\n"); break; @@ -364,7 +262,6 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { DPRINTF("CARD_REGISTER\n"); { struct card_register* cr = (struct card_register*)(wdheader->data); - char ppdev[32]; DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", cr->Card.dwItems, @@ -380,64 +277,24 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else - -#ifdef JTAGKEY - if (!config_is_real_pport((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10)) { - int num = (unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10; - - ret=jtagkey_init(config_usb_vid(num), config_usb_pid(num)); - cr->hCard = 0xff; - ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; - if (ret < 0) - cr->hCard = 0; - break; - } +#ifdef JTAGKEY + if (!config_is_real_pport((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10)) + ret = jtagkey_open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); + else #endif + ret = parport_open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); - if (parportfd < 0) { - snprintf(ppdev, sizeof(ppdev), "/dev/parport%lu", - (unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); - DPRINTF("opening %s\n", ppdev); - parportfd = open(ppdev, O_RDWR|O_EXCL); - - if (parportfd < 0) - fprintf(stderr,"Can't open %s: %s\n", ppdev, strerror(errno)); - } + ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; - if (parportfd >= 0) { - int pmode; - - if (ioctl(parportfd, PPCLAIM) == -1) - return ret; - - ecpbase = 0; - pmode = IEEE1284_MODE_COMPAT; - if (ioctl(parportfd, PPNEGOT, &pmode) == -1) - return ret; - - if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr) { - DPRINTF("ECP mode requested\n"); - ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr; - /* TODO: Implement ECP mode */ -#if 0 - pmode = IEEE1284_MODE_ECP; - - if (ioctl(parportfd, PPNEGOT, &pmode) == -1) { - ecpbase = 0; - pmode = IEEE1284_MODE_COMPAT; - if (ioctl(parportfd, PPNEGOT, &pmode) == -1) - return ret; - } -#endif - } + if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr) + ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr; - cr->hCard = parportfd; - } - - ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; - if (ret < 0) + if (ret >= 0) { + cr->hCard = ret; + } else { cr->hCard = 0; + } #endif DPRINTF("hCard: %lu\n", cr->hCard); } @@ -716,7 +573,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { break; } #endif /* JTAGKEY */ - ret = pp_transfer(tr, fd, request); + ret = pp_transfer(tr, fd, request, ppbase, ecpbase, 1); #endif } break; @@ -727,7 +584,6 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { { WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data); unsigned long num = wdheader->size/sizeof(WD_TRANSFER); - int i; #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else @@ -735,14 +591,9 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { #ifdef JTAGKEY if (!config_is_real_pport(ppbase / 0x10)) { ret = jtagkey_transfer(tr, fd, request, ppbase, ecpbase, num); - break; - } + } else #endif /* JTAGKEY */ - - for (i = 0; i < num; i++) { - DPRINTF("Transfer %d:\n", i+1); - ret = pp_transfer(tr + i, fd, request); - } + ret = pp_transfer(tr, fd, request, ppbase, ecpbase, num); #endif } break; @@ -804,14 +655,10 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { #else #ifdef JTAGKEY if (cr->hCard == 0xff) - jtagkey_close(); + jtagkey_close(cr->hCard); + else #endif - - if (parportfd == cr->hCard && parportfd >= 0) { - ioctl(parportfd, PPRELEASE); - close(parportfd); - parportfd = -1; - } + parport_close(cr->hCard); #endif } break; -- 2.39.2