Implement the Atmel EDBG/CMSIS-DAP driver protocol for JTAGICE3
(running firmware 3.x) and XplainedPro boards. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1278 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
7f2079731b
commit
e59df50eeb
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2014-02-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* jtag3_private.h: Add EDBG/CMSIS-DAP specific constants.
|
||||||
|
* jtag3.c: Add EDBG/CMSIS-DAP protocol implementation.
|
||||||
|
* serial.h: (Dito.)
|
||||||
|
* usbdevs.h: (Dito.)
|
||||||
|
* usb_libusb.c: (Dito.)
|
||||||
|
* configure.ac: (Dito.)
|
||||||
|
* avrdude.conf.in: Add JTAGICE3 and XplainedPro entries using
|
||||||
|
EDBG.
|
||||||
|
* configure.ac: Bump version date.
|
||||||
|
|
||||||
2014-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
2014-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
* usb_libusb.c (usbdev_recv_frame): Fix a bug where a new recv
|
* usb_libusb.c (usbdev_recv_frame): Fix a bug where a new recv
|
||||||
|
|
2
NEWS
2
NEWS
|
@ -8,7 +8,7 @@ Approximate change log for AVRDUDE by version.
|
||||||
Current:
|
Current:
|
||||||
|
|
||||||
* Major changes compared to the previous version:
|
* Major changes compared to the previous version:
|
||||||
- ...
|
- Atmel EDBG protocol support added (JTAGICE3, XplainedPro)
|
||||||
|
|
||||||
* New devices supported:
|
* New devices supported:
|
||||||
- ...
|
- ...
|
||||||
|
|
|
@ -994,6 +994,7 @@ programmer
|
||||||
desc = "Atmel AVR JTAGICE3 in JTAG mode";
|
desc = "Atmel AVR JTAGICE3 in JTAG mode";
|
||||||
type = "jtagice3";
|
type = "jtagice3";
|
||||||
connection_type = usb;
|
connection_type = usb;
|
||||||
|
usbpid = 0x2110;
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -1001,6 +1002,7 @@ programmer
|
||||||
desc = "Atmel AVR JTAGICE3 in PDI mode";
|
desc = "Atmel AVR JTAGICE3 in PDI mode";
|
||||||
type = "jtagice3_pdi";
|
type = "jtagice3_pdi";
|
||||||
connection_type = usb;
|
connection_type = usb;
|
||||||
|
usbpid = 0x2110;
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -1008,6 +1010,7 @@ programmer
|
||||||
desc = "Atmel AVR JTAGICE3 in debugWIRE mode";
|
desc = "Atmel AVR JTAGICE3 in debugWIRE mode";
|
||||||
type = "jtagice3_dw";
|
type = "jtagice3_dw";
|
||||||
connection_type = usb;
|
connection_type = usb;
|
||||||
|
usbpid = 0x2110;
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -1015,6 +1018,47 @@ programmer
|
||||||
desc = "Atmel AVR JTAGICE3 in ISP mode";
|
desc = "Atmel AVR JTAGICE3 in ISP mode";
|
||||||
type = "jtagice3_isp";
|
type = "jtagice3_isp";
|
||||||
connection_type = usb;
|
connection_type = usb;
|
||||||
|
usbpid = 0x2110;
|
||||||
|
;
|
||||||
|
|
||||||
|
programmer
|
||||||
|
id = "jtag3edbg";
|
||||||
|
desc = "Atmel AVR JTAGICE3 in JTAG mode, EDBG protocol";
|
||||||
|
type = "jtagice3";
|
||||||
|
connection_type = usb;
|
||||||
|
usbpid = 0x2140;
|
||||||
|
;
|
||||||
|
|
||||||
|
programmer
|
||||||
|
id = "jtag3pdi_edbg";
|
||||||
|
desc = "Atmel AVR JTAGICE3 in PDI mode, EDBG protocol";
|
||||||
|
type = "jtagice3_pdi";
|
||||||
|
connection_type = usb;
|
||||||
|
usbpid = 0x2140;
|
||||||
|
;
|
||||||
|
|
||||||
|
programmer
|
||||||
|
id = "jtag3dw_edbg";
|
||||||
|
desc = "Atmel AVR JTAGICE3 in debugWIRE mode, EDBG protocol";
|
||||||
|
type = "jtagice3_dw";
|
||||||
|
connection_type = usb;
|
||||||
|
usbpid = 0x2140;
|
||||||
|
;
|
||||||
|
|
||||||
|
programmer
|
||||||
|
id = "jtag3isp_edbg";
|
||||||
|
desc = "Atmel AVR JTAGICE3 in ISP mode, EDBG protocol";
|
||||||
|
type = "jtagice3_isp";
|
||||||
|
connection_type = usb;
|
||||||
|
usbpid = 0x2140;
|
||||||
|
;
|
||||||
|
|
||||||
|
programmer
|
||||||
|
id = "xplainedpro";
|
||||||
|
desc = "Atmel AVR XplainedPro in JTAG mode";
|
||||||
|
type = "jtagice3";
|
||||||
|
connection_type = usb;
|
||||||
|
usbpid = 0x2111;
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ(2.60)
|
AC_PREREQ(2.60)
|
||||||
AC_INIT(avrdude, 6.1-svn-20131205, avrdude-dev@nongnu.org)
|
AC_INIT(avrdude, 6.1-svn-20140226, avrdude-dev@nongnu.org)
|
||||||
|
|
||||||
AC_CANONICAL_BUILD
|
AC_CANONICAL_BUILD
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
|
329
jtag3.c
329
jtag3.c
|
@ -84,8 +84,13 @@ struct pdata
|
||||||
#define PGM_FL_IS_DW (0x0001)
|
#define PGM_FL_IS_DW (0x0001)
|
||||||
#define PGM_FL_IS_PDI (0x0002)
|
#define PGM_FL_IS_PDI (0x0002)
|
||||||
#define PGM_FL_IS_JTAG (0x0004)
|
#define PGM_FL_IS_JTAG (0x0004)
|
||||||
|
#define PGM_FL_IS_EDBG (0x0008)
|
||||||
|
|
||||||
static int jtag3_open(PROGRAMMER * pgm, char * port);
|
static int jtag3_open(PROGRAMMER * pgm, char * port);
|
||||||
|
static int jtag3_edbg_prepare(PROGRAMMER * pgm);
|
||||||
|
static int jtag3_edbg_signoff(PROGRAMMER * pgm);
|
||||||
|
static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
|
||||||
|
static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg);
|
||||||
|
|
||||||
static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p);
|
static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p);
|
||||||
static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
||||||
|
@ -399,6 +404,9 @@ int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||||
{
|
{
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
|
if (pgm->flag & PGM_FL_IS_EDBG)
|
||||||
|
return jtag3_edbg_send(pgm, data, len);
|
||||||
|
|
||||||
if (verbose >= 3)
|
if (verbose >= 3)
|
||||||
fprintf(stderr, "\n%s: jtag3_send(): sending %lu bytes\n",
|
fprintf(stderr, "\n%s: jtag3_send(): sending %lu bytes\n",
|
||||||
progname, (unsigned long)len);
|
progname, (unsigned long)len);
|
||||||
|
@ -419,7 +427,7 @@ int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: jtag3_send(): failed to send command to serial port\n",
|
"%s: jtag3_send(): failed to send command to serial port\n",
|
||||||
progname);
|
progname);
|
||||||
exit(1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -427,6 +435,193 @@ int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||||
|
{
|
||||||
|
unsigned char buf[USBDEV_MAX_XFER_3];
|
||||||
|
unsigned char status[USBDEV_MAX_XFER_3];
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (verbose >= 4)
|
||||||
|
{
|
||||||
|
memset(buf, 0, pgm->fd.usb.max_xfer);
|
||||||
|
memset(status, 0, pgm->fd.usb.max_xfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose >= 3)
|
||||||
|
fprintf(stderr, "\n%s: jtag3_edbg_send(): sending %lu bytes\n",
|
||||||
|
progname, (unsigned long)len);
|
||||||
|
|
||||||
|
if (len + 8 > pgm->fd.usb.max_xfer)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_send(): Fragmentation not (yet) implemented!\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buf[0] = EDBG_VENDOR_AVR_CMD;
|
||||||
|
buf[1] = (1 << 4) | 1; /* first out of a total of 1 fragments */
|
||||||
|
buf[2] = (len + 4) >> 8;
|
||||||
|
buf[3] = (len + 4) & 0xff;
|
||||||
|
buf[4] = TOKEN;
|
||||||
|
buf[5] = 0; /* dummy */
|
||||||
|
u16_to_b2(buf + 6, PDATA(pgm)->command_sequence);
|
||||||
|
memcpy(buf + 8, data, len);
|
||||||
|
|
||||||
|
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_send(): failed to send command to serial port\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
|
||||||
|
|
||||||
|
if (rv < 0) {
|
||||||
|
/* timeout in receive */
|
||||||
|
if (verbose > 1)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_send(): Timeout receiving packet\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (status[0] != EDBG_VENDOR_AVR_CMD || status[1] != 0x01)
|
||||||
|
{
|
||||||
|
/* what to do in this case? */
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
|
||||||
|
progname, status[0], status[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send out all the CMSIS-DAP stuff needed to prepare the ICE.
|
||||||
|
*/
|
||||||
|
static int jtag3_edbg_prepare(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
unsigned char buf[USBDEV_MAX_XFER_3];
|
||||||
|
unsigned char status[USBDEV_MAX_XFER_3];
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (verbose >= 3)
|
||||||
|
fprintf(stderr, "\n%s: jtag3_edbg_prepare()\n",
|
||||||
|
progname);
|
||||||
|
|
||||||
|
if (verbose >= 4)
|
||||||
|
memset(buf, 0, USBDEV_MAX_XFER_3);
|
||||||
|
|
||||||
|
buf[0] = CMSISDAP_CMD_CONNECT;
|
||||||
|
buf[1] = CMSISDAP_CONN_SWD;
|
||||||
|
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||||
|
if (rv != USBDEV_MAX_XFER_3) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_prepare(): failed to read from serial port (%d)\n",
|
||||||
|
progname, rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (status[0] != CMSISDAP_CMD_CONNECT ||
|
||||||
|
status[1] == 0)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_prepare(): unexpected response 0x%02x, 0x%02x\n",
|
||||||
|
progname, status[0], status[1]);
|
||||||
|
if (verbose >= 2)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_prepare(): connection status 0x%02x\n",
|
||||||
|
progname, status[1]);
|
||||||
|
|
||||||
|
buf[0] = CMSISDAP_CMD_LED;
|
||||||
|
buf[1] = CMSISDAP_LED_CONNECT;
|
||||||
|
buf[2] = 1;
|
||||||
|
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||||
|
if (rv != USBDEV_MAX_XFER_3) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_prepare(): failed to read from serial port (%d)\n",
|
||||||
|
progname, rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (status[0] != CMSISDAP_CMD_LED ||
|
||||||
|
status[1] != 0)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_prepare(): unexpected response 0x%02x, 0x%02x\n",
|
||||||
|
progname, status[0], status[1]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send out all the CMSIS-DAP stuff when signing off.
|
||||||
|
*/
|
||||||
|
static int jtag3_edbg_signoff(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
unsigned char buf[USBDEV_MAX_XFER_3];
|
||||||
|
unsigned char status[USBDEV_MAX_XFER_3];
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (verbose >= 3)
|
||||||
|
fprintf(stderr, "\n%s: jtag3_edbg_signoff()\n",
|
||||||
|
progname);
|
||||||
|
|
||||||
|
if (verbose >= 4)
|
||||||
|
memset(buf, 0, USBDEV_MAX_XFER_3);
|
||||||
|
|
||||||
|
buf[0] = CMSISDAP_CMD_LED;
|
||||||
|
buf[1] = CMSISDAP_LED_CONNECT;
|
||||||
|
buf[2] = 0;
|
||||||
|
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||||
|
if (rv != USBDEV_MAX_XFER_3) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||||
|
progname, rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (status[0] != CMSISDAP_CMD_LED ||
|
||||||
|
status[1] != 0)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
|
||||||
|
progname, status[0], status[1]);
|
||||||
|
|
||||||
|
buf[0] = CMSISDAP_CMD_DISCONNECT;
|
||||||
|
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||||
|
if (rv != USBDEV_MAX_XFER_3) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||||
|
progname, rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (status[0] != CMSISDAP_CMD_DISCONNECT ||
|
||||||
|
status[1] != 0)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
|
||||||
|
progname, status[0], status[1]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int jtag3_drain(PROGRAMMER * pgm, int display)
|
static int jtag3_drain(PROGRAMMER * pgm, int display)
|
||||||
{
|
{
|
||||||
|
@ -446,6 +641,9 @@ static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||||
int rv;
|
int rv;
|
||||||
unsigned char *buf = NULL;
|
unsigned char *buf = NULL;
|
||||||
|
|
||||||
|
if (pgm->flag & PGM_FL_IS_EDBG)
|
||||||
|
return jtag3_edbg_recv_frame(pgm, msg);
|
||||||
|
|
||||||
if (verbose >= 4)
|
if (verbose >= 4)
|
||||||
fprintf(stderr, "%s: jtag3_recv():\n", progname);
|
fprintf(stderr, "%s: jtag3_recv():\n", progname);
|
||||||
|
|
||||||
|
@ -454,6 +652,8 @@ static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||||
progname);
|
progname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (verbose >= 4)
|
||||||
|
memset(buf, 0, pgm->fd.usb.max_xfer);
|
||||||
|
|
||||||
rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer);
|
rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer);
|
||||||
|
|
||||||
|
@ -472,6 +672,62 @@ static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||||
|
int rv, len;
|
||||||
|
unsigned char *buf = NULL;
|
||||||
|
|
||||||
|
if (verbose >= 4)
|
||||||
|
fprintf(stderr, "%s: jtag3_edbg_recv():\n", progname);
|
||||||
|
|
||||||
|
if ((buf = malloc(pgm->fd.usb.max_xfer)) == NULL) {
|
||||||
|
fprintf(stderr, "%s: jtag3_edbg_recv(): out of memory\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = EDBG_VENDOR_AVR_RSP;
|
||||||
|
|
||||||
|
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
|
||||||
|
progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer);
|
||||||
|
|
||||||
|
if (rv < 0) {
|
||||||
|
/* timeout in receive */
|
||||||
|
if (verbose > 1)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_recv(): Timeout receiving packet\n",
|
||||||
|
progname);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf[0] != EDBG_VENDOR_AVR_RSP ||
|
||||||
|
buf[1] != ((1 << 4) | 1)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_recv(): Unexpected response 0x%02x, 0x%02x\n",
|
||||||
|
progname, buf[0], buf[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* calculate length from response; CMSIS-DAP response might be larger */
|
||||||
|
len = (buf[2] << 8) | buf[3];
|
||||||
|
if (len > rv + 4) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
|
||||||
|
progname, len, rv + 4);
|
||||||
|
len = rv + 4;
|
||||||
|
}
|
||||||
|
memmove(buf, buf + 4, len);
|
||||||
|
|
||||||
|
*msg = buf;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
|
int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
|
||||||
unsigned short r_seqno;
|
unsigned short r_seqno;
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -562,6 +818,11 @@ int jtag3_getsync(PROGRAMMER * pgm, int mode) {
|
||||||
if (verbose >= 3)
|
if (verbose >= 3)
|
||||||
fprintf(stderr, "%s: jtag3_getsync()\n", progname);
|
fprintf(stderr, "%s: jtag3_getsync()\n", progname);
|
||||||
|
|
||||||
|
if (pgm->flag & PGM_FL_IS_EDBG) {
|
||||||
|
if (jtag3_edbg_prepare(pgm) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the sign-on information. */
|
/* Get the sign-on information. */
|
||||||
buf[0] = SCOPE_GENERAL;
|
buf[0] = SCOPE_GENERAL;
|
||||||
buf[1] = CMD3_SIGN_ON;
|
buf[1] = CMD3_SIGN_ON;
|
||||||
|
@ -1034,9 +1295,15 @@ static int jtag3_open(PROGRAMMER * pgm, char * port)
|
||||||
if (strncmp(port, "usb", 3) == 0) {
|
if (strncmp(port, "usb", 3) == 0) {
|
||||||
#if defined(HAVE_LIBUSB)
|
#if defined(HAVE_LIBUSB)
|
||||||
serdev = &usb_serdev_frame;
|
serdev = &usb_serdev_frame;
|
||||||
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
if (pgm->usbvid)
|
||||||
|
pinfo.usbinfo.vid = pgm->usbvid;
|
||||||
|
else
|
||||||
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
||||||
pinfo.usbinfo.flags = 0;
|
pinfo.usbinfo.flags = 0;
|
||||||
pinfo.usbinfo.pid = USB_DEVICE_JTAGICE3;
|
if (pgm->usbpid)
|
||||||
|
pinfo.usbinfo.pid = pgm->usbpid;
|
||||||
|
else
|
||||||
|
pinfo.usbinfo.pid = USB_DEVICE_JTAGICE3;
|
||||||
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
||||||
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
||||||
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
||||||
|
@ -1052,6 +1319,17 @@ static int jtag3_open(PROGRAMMER * pgm, char * port)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pgm->fd.usb.eep == 0)
|
||||||
|
{
|
||||||
|
/* The event EP has been deleted by usb_open(), so we are
|
||||||
|
running on a CMSIS-DAP device, using EDBG protocol */
|
||||||
|
pgm->flag |= PGM_FL_IS_EDBG;
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: Found CMSIS-DAP compliant device, using EDBG protocol\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drain any extraneous input
|
* drain any extraneous input
|
||||||
*/
|
*/
|
||||||
|
@ -1078,9 +1356,15 @@ static int jtag3_open_dw(PROGRAMMER * pgm, char * port)
|
||||||
if (strncmp(port, "usb", 3) == 0) {
|
if (strncmp(port, "usb", 3) == 0) {
|
||||||
#if defined(HAVE_LIBUSB)
|
#if defined(HAVE_LIBUSB)
|
||||||
serdev = &usb_serdev_frame;
|
serdev = &usb_serdev_frame;
|
||||||
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
if (pgm->usbvid)
|
||||||
|
pinfo.usbinfo.vid = pgm->usbvid;
|
||||||
|
else
|
||||||
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
||||||
pinfo.usbinfo.flags = 0;
|
pinfo.usbinfo.flags = 0;
|
||||||
pinfo.usbinfo.pid = USB_DEVICE_JTAGICE3;
|
if (pgm->usbpid)
|
||||||
|
pinfo.usbinfo.pid = pgm->usbpid;
|
||||||
|
else
|
||||||
|
pinfo.usbinfo.pid = USB_DEVICE_JTAGICE3;
|
||||||
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
||||||
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
||||||
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
||||||
|
@ -1096,6 +1380,17 @@ static int jtag3_open_dw(PROGRAMMER * pgm, char * port)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pgm->fd.usb.eep == 0)
|
||||||
|
{
|
||||||
|
/* The event EP has been deleted by usb_open(), so we are
|
||||||
|
running on a CMSIS-DAP device, using EDBG protocol */
|
||||||
|
pgm->flag |= PGM_FL_IS_EDBG;
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: Found CMSIS-DAP compliant device, using EDBG protocol\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drain any extraneous input
|
* drain any extraneous input
|
||||||
*/
|
*/
|
||||||
|
@ -1122,9 +1417,15 @@ static int jtag3_open_pdi(PROGRAMMER * pgm, char * port)
|
||||||
if (strncmp(port, "usb", 3) == 0) {
|
if (strncmp(port, "usb", 3) == 0) {
|
||||||
#if defined(HAVE_LIBUSB)
|
#if defined(HAVE_LIBUSB)
|
||||||
serdev = &usb_serdev_frame;
|
serdev = &usb_serdev_frame;
|
||||||
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
if (pgm->usbvid)
|
||||||
|
pinfo.usbinfo.vid = pgm->usbvid;
|
||||||
|
else
|
||||||
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
||||||
pinfo.usbinfo.flags = 0;
|
pinfo.usbinfo.flags = 0;
|
||||||
pinfo.usbinfo.pid = USB_DEVICE_JTAGICE3;
|
if (pgm->usbpid)
|
||||||
|
pinfo.usbinfo.pid = pgm->usbpid;
|
||||||
|
else
|
||||||
|
pinfo.usbinfo.pid = USB_DEVICE_JTAGICE3;
|
||||||
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
||||||
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
||||||
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
||||||
|
@ -1140,6 +1441,17 @@ static int jtag3_open_pdi(PROGRAMMER * pgm, char * port)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pgm->fd.usb.eep == 0)
|
||||||
|
{
|
||||||
|
/* The event EP has been deleted by usb_open(), so we are
|
||||||
|
running on a CMSIS-DAP device, using EDBG protocol */
|
||||||
|
pgm->flag |= PGM_FL_IS_EDBG;
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: Found CMSIS-DAP compliant device, using EDBG protocol\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drain any extraneous input
|
* drain any extraneous input
|
||||||
*/
|
*/
|
||||||
|
@ -1172,6 +1484,9 @@ void jtag3_close(PROGRAMMER * pgm)
|
||||||
if (jtag3_command(pgm, buf, 4, &resp, "sign-off") >= 0)
|
if (jtag3_command(pgm, buf, 4, &resp, "sign-off") >= 0)
|
||||||
free(resp);
|
free(resp);
|
||||||
|
|
||||||
|
if (pgm->flag & PGM_FL_IS_EDBG)
|
||||||
|
jtag3_edbg_signoff(pgm);
|
||||||
|
|
||||||
serial_close(&pgm->fd);
|
serial_close(&pgm->fd);
|
||||||
pgm->fd.ifd = -1;
|
pgm->fd.ifd = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,6 +222,47 @@
|
||||||
#define XMEGA_ERASE_EEPROM_PAGE 0x06
|
#define XMEGA_ERASE_EEPROM_PAGE 0x06
|
||||||
#define XMEGA_ERASE_USERSIG 0x07
|
#define XMEGA_ERASE_USERSIG 0x07
|
||||||
|
|
||||||
|
/* EDBG vendor commands */
|
||||||
|
#define EDBG_VENDOR_AVR_CMD 0x80
|
||||||
|
#define EDBG_VENDOR_AVR_RSP 0x81
|
||||||
|
#define EDBG_VENDOR_AVR_EVT 0x82
|
||||||
|
|
||||||
|
/* CMSIS-DAP commands */
|
||||||
|
#define CMSISDAP_CMD_INFO 0x00 /* get info, followed by INFO byte */
|
||||||
|
# define CMSISDAP_INFO_VID 0x01 /* vendor ID (string) */
|
||||||
|
# define CMSISDAP_INFO_PID 0x02 /* product ID (string) */
|
||||||
|
# define CMSISDAP_INFO_SERIAL 0x03 /* serial number (string) */
|
||||||
|
# define CMSISDAP_INFO_FIRMWARE 0x04 /* firmware version (string) */
|
||||||
|
# define CMSISDAP_INFO_TARGET_VENDOR 0x05 /* target device vendor (string) */
|
||||||
|
# define CMSISDAP_INFO_TARGET_NAME 0x06 /* target device name (string) */
|
||||||
|
# define CMSISDAP_INFO_CAPABILITIES 0xF0 /* debug unit capabilities (byte) */
|
||||||
|
# define CMSISDAP_INFO_PACKET_COUNT 0xFE /* packet count (byte) (which packets, anyway?) */
|
||||||
|
# define CMSISDAP_INFO_PACKET_SIZE 0xFF /* packet size (short) */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_LED 0x01 /* LED control, followed by LED number and on/off byte */
|
||||||
|
# define CMSISDAP_LED_CONNECT 0x00 /* connect LED */
|
||||||
|
# define CMSISDAP_LED_RUNNING 0x01 /* running LED */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_CONNECT 0x02 /* connect to target, followed by DAP mode */
|
||||||
|
# define CMSISDAP_CONN_DEFAULT 0x00
|
||||||
|
# define CMSISDAP_CONN_SWD 0x01 /* serial wire debug */
|
||||||
|
# define CMSISDAP_CONN_JTAG 0x02 /* JTAG mode */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_DISCONNECT 0x03 /* disconnect from target */
|
||||||
|
|
||||||
|
#define CMSISDAP_XFR_CONFIGURE 0x04 /* configure transfers; idle cycles (byte);
|
||||||
|
wait retry (short); match retry (short) */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_WRITEAPBORT 0x08 /* write to CoreSight ABORT register of target */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_DELAY 0x09 /* delay for number of microseconds (short) */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_RESET 0x0A /* reset target */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_SWJ_CLOCK 0x11 /* SWD/JTAG clock, (word) */
|
||||||
|
|
||||||
|
#define CMSISDAP_CMD_SWD_CONFIGURE 0x13 /* configure SWD protocol; (byte) */
|
||||||
|
|
||||||
#if !defined(JTAG3_PRIVATE_EXPORTED)
|
#if !defined(JTAG3_PRIVATE_EXPORTED)
|
||||||
|
|
||||||
struct mega_device_desc {
|
struct mega_device_desc {
|
||||||
|
|
2
serial.h
2
serial.h
|
@ -41,6 +41,7 @@ union filedescriptor
|
||||||
int wep; /* bulk write endpoint */
|
int wep; /* bulk write endpoint */
|
||||||
int eep; /* event read endpoint */
|
int eep; /* event read endpoint */
|
||||||
int max_xfer; /* max transfer size */
|
int max_xfer; /* max transfer size */
|
||||||
|
int use_interrupt_xfer; /* device uses interrupt transfers */
|
||||||
} usb;
|
} usb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ union pinfo
|
||||||
unsigned short vid;
|
unsigned short vid;
|
||||||
unsigned short pid;
|
unsigned short pid;
|
||||||
unsigned short flags;
|
unsigned short flags;
|
||||||
|
#define PINFO_FL_USEHID 0x0001
|
||||||
} usbinfo;
|
} usbinfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
157
usb_libusb.c
157
usb_libusb.c
|
@ -70,6 +70,7 @@ static int usbdev_open(char * port, union pinfo pinfo, union filedescriptor *fd)
|
||||||
usb_dev_handle *udev;
|
usb_dev_handle *udev;
|
||||||
char *serno, *cp2;
|
char *serno, *cp2;
|
||||||
int i;
|
int i;
|
||||||
|
int iface;
|
||||||
size_t x;
|
size_t x;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -151,6 +152,21 @@ static int usbdev_open(char * port, union pinfo pinfo, union filedescriptor *fd)
|
||||||
progname, usb_strerror());
|
progname, usb_strerror());
|
||||||
strcpy(product, "[unnamed product]");
|
strcpy(product, "[unnamed product]");
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* The CMSIS-DAP specification mandates the string
|
||||||
|
* "CMSIS-DAP" must be present somewhere in the
|
||||||
|
* product name string for a device compliant to
|
||||||
|
* that protocol. Use this for the decisision
|
||||||
|
* whether we have to search for a HID interface
|
||||||
|
* below.
|
||||||
|
*/
|
||||||
|
if(strstr(product, "CMSIS-DAP") != NULL)
|
||||||
|
{
|
||||||
|
pinfo.usbinfo.flags |= PINFO_FL_USEHID;
|
||||||
|
/* The JTAGICE3 running the CMSIS-DAP firmware doesn't
|
||||||
|
* use a separate endpoint for event reception. */
|
||||||
|
fd->usb.eep = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -186,66 +202,102 @@ static int usbdev_open(char * port, union pinfo pinfo, union filedescriptor *fd)
|
||||||
if (usb_set_configuration(udev, dev->config[0].bConfigurationValue))
|
if (usb_set_configuration(udev, dev->config[0].bConfigurationValue))
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: usbdev_open(): error setting configuration %d: %s\n",
|
"%s: usbdev_open(): WARNING: failed to set configuration %d: %s\n",
|
||||||
progname, dev->config[0].bConfigurationValue,
|
progname, dev->config[0].bConfigurationValue,
|
||||||
usb_strerror());
|
usb_strerror());
|
||||||
goto trynext;
|
/* let's hope it has already been configured */
|
||||||
|
// goto trynext;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_interface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
|
for (iface = 0; iface < dev->config[0].bNumInterfaces; iface++)
|
||||||
if (usb_claim_interface(udev, usb_interface))
|
{
|
||||||
|
usb_interface = dev->config[0].interface[iface].altsetting[0].bInterfaceNumber;
|
||||||
|
#ifdef LIBUSB_HAS_GET_DRIVER_NP
|
||||||
|
/*
|
||||||
|
* Many Linux systems attach the usbhid driver
|
||||||
|
* by default to any HID-class device. On
|
||||||
|
* those, the driver needs to be detached before
|
||||||
|
* we can claim the interface.
|
||||||
|
*/
|
||||||
|
(void)usb_detach_kernel_driver_np(udev, usb_interface);
|
||||||
|
#endif
|
||||||
|
if (usb_claim_interface(udev, usb_interface))
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: usbdev_open(): error claiming interface %d: %s\n",
|
||||||
|
progname, usb_interface, usb_strerror());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pinfo.usbinfo.flags & PINFO_FL_USEHID)
|
||||||
|
{
|
||||||
|
/* only consider an interface that is of class HID */
|
||||||
|
if (dev->config[0].interface[iface].altsetting[0].bInterfaceClass !=
|
||||||
|
USB_CLASS_HID)
|
||||||
|
continue;
|
||||||
|
fd->usb.use_interrupt_xfer = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iface == dev->config[0].bNumInterfaces)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: usbdev_open(): error claiming interface %d: %s\n",
|
"%s: usbdev_open(): no usable interface found\n",
|
||||||
progname, usb_interface, usb_strerror());
|
progname);
|
||||||
goto trynext;
|
goto trynext;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd->usb.handle = udev;
|
fd->usb.handle = udev;
|
||||||
if (fd->usb.rep == 0)
|
if (fd->usb.rep == 0)
|
||||||
{
|
|
||||||
/* Try finding out what our read endpoint is. */
|
|
||||||
for (i = 0; i < dev->config[0].interface[0].altsetting[0].bNumEndpoints; i++)
|
|
||||||
{
|
{
|
||||||
int possible_ep = dev->config[0].interface[0].altsetting[0].
|
/* Try finding out what our read endpoint is. */
|
||||||
endpoint[i].bEndpointAddress;
|
for (i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++)
|
||||||
|
{
|
||||||
|
int possible_ep = dev->config[0].interface[iface].altsetting[0].
|
||||||
|
endpoint[i].bEndpointAddress;
|
||||||
|
|
||||||
if ((possible_ep & USB_ENDPOINT_DIR_MASK) != 0)
|
if ((possible_ep & USB_ENDPOINT_DIR_MASK) != 0)
|
||||||
{
|
{
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: usbdev_open(): using read endpoint 0x%02x\n",
|
||||||
|
progname, possible_ep);
|
||||||
|
}
|
||||||
|
fd->usb.rep = possible_ep;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fd->usb.rep == 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: usbdev_open(): using read endpoint 0x%02x\n",
|
"%s: usbdev_open(): cannot find a read endpoint, using 0x%02x\n",
|
||||||
progname, possible_ep);
|
progname, USBDEV_BULK_EP_READ_MKII);
|
||||||
|
fd->usb.rep = USBDEV_BULK_EP_READ_MKII;
|
||||||
}
|
}
|
||||||
fd->usb.rep = possible_ep;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (fd->usb.rep == 0)
|
for (i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
if ((dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.rep ||
|
||||||
"%s: usbdev_open(): cannot find a read endpoint, using 0x%02x\n",
|
dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.wep) &&
|
||||||
progname, USBDEV_BULK_EP_READ_MKII);
|
dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize < fd->usb.max_xfer)
|
||||||
fd->usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < dev->config[0].interface[0].altsetting[0].bNumEndpoints; i++)
|
|
||||||
{
|
|
||||||
if ((dev->config[0].interface[0].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.rep ||
|
|
||||||
dev->config[0].interface[0].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.wep) &&
|
|
||||||
dev->config[0].interface[0].altsetting[0].endpoint[i].wMaxPacketSize < fd->usb.max_xfer)
|
|
||||||
{
|
{
|
||||||
if (verbose != 0)
|
if (verbose != 0)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: max packet size expected %d, but found %d due to EP 0x%02x's wMaxPacketSize\n",
|
"%s: max packet size expected %d, but found %d due to EP 0x%02x's wMaxPacketSize\n",
|
||||||
progname,
|
progname,
|
||||||
fd->usb.max_xfer,
|
fd->usb.max_xfer,
|
||||||
dev->config[0].interface[0].altsetting[0].endpoint[i].wMaxPacketSize,
|
dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize,
|
||||||
dev->config[0].interface[0].altsetting[0].endpoint[i].bEndpointAddress);
|
dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress);
|
||||||
fd->usb.max_xfer = dev->config[0].interface[0].altsetting[0].endpoint[i].wMaxPacketSize;
|
fd->usb.max_xfer = dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pinfo.usbinfo.flags & PINFO_FL_USEHID)
|
||||||
|
{
|
||||||
|
if (usb_control_msg(udev, 0x21, 0x0a /* SET_IDLE */, 0, 0, NULL, 0, 100) < 0)
|
||||||
|
fprintf(stderr, "%s: usbdev_open(): SET_IDLE failed\n", progname);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
trynext:
|
trynext:
|
||||||
usb_close(udev);
|
usb_close(udev);
|
||||||
|
@ -299,7 +351,10 @@ static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
tx_size = (mlen < fd->usb.max_xfer)? mlen: fd->usb.max_xfer;
|
tx_size = (mlen < fd->usb.max_xfer)? mlen: fd->usb.max_xfer;
|
||||||
rv = usb_bulk_write(udev, fd->usb.wep, (char *)bp, tx_size, 10000);
|
if (fd->usb.use_interrupt_xfer)
|
||||||
|
rv = usb_interrupt_write(udev, fd->usb.wep, (char *)bp, tx_size, 10000);
|
||||||
|
else
|
||||||
|
rv = usb_bulk_write(udev, fd->usb.wep, (char *)bp, tx_size, 10000);
|
||||||
if (rv != tx_size)
|
if (rv != tx_size)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: usbdev_send(): wrote %d out of %d bytes, err = %s\n",
|
fprintf(stderr, "%s: usbdev_send(): wrote %d out of %d bytes, err = %s\n",
|
||||||
|
@ -341,16 +396,20 @@ static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
|
||||||
* empty and more data are requested.
|
* empty and more data are requested.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
usb_fill_buf(usb_dev_handle *udev, int maxsize, int ep)
|
usb_fill_buf(usb_dev_handle *udev, int maxsize, int ep, int use_interrupt_xfer)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = usb_bulk_read(udev, ep, usbbuf, maxsize, 10000);
|
if (use_interrupt_xfer)
|
||||||
|
rv = usb_interrupt_read(udev, ep, usbbuf, maxsize, 10000);
|
||||||
|
else
|
||||||
|
rv = usb_bulk_read(udev, ep, usbbuf, maxsize, 10000);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
{
|
{
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
fprintf(stderr, "%s: usb_fill_buf(): usb_bulk_read() error %s\n",
|
fprintf(stderr, "%s: usb_fill_buf(): usb_%s_read() error %s\n",
|
||||||
progname, usb_strerror());
|
progname, (use_interrupt_xfer? "interrupt": "bulk"),
|
||||||
|
usb_strerror());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +429,7 @@ static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
|
||||||
{
|
{
|
||||||
if (buflen <= bufptr)
|
if (buflen <= bufptr)
|
||||||
{
|
{
|
||||||
if (usb_fill_buf(udev, fd->usb.max_xfer, fd->usb.rep) < 0)
|
if (usb_fill_buf(udev, fd->usb.max_xfer, fd->usb.rep, fd->usb.use_interrupt_xfer) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
amnt = buflen - bufptr > nbytes? nbytes: buflen - bufptr;
|
amnt = buflen - bufptr > nbytes? nbytes: buflen - bufptr;
|
||||||
|
@ -441,13 +500,18 @@ static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_
|
||||||
n = 0;
|
n = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
rv = usb_bulk_read(udev, fd->usb.rep, usbbuf,
|
if (fd->usb.use_interrupt_xfer)
|
||||||
fd->usb.max_xfer, 10000);
|
rv = usb_interrupt_read(udev, fd->usb.rep, usbbuf,
|
||||||
|
fd->usb.max_xfer, 10000);
|
||||||
|
else
|
||||||
|
rv = usb_bulk_read(udev, fd->usb.rep, usbbuf,
|
||||||
|
fd->usb.max_xfer, 10000);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
{
|
{
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
fprintf(stderr, "%s: usbdev_recv_frame(): usb_bulk_read(): %s\n",
|
fprintf(stderr, "%s: usbdev_recv_frame(): usb_%s_read(): %s\n",
|
||||||
progname, usb_strerror());
|
progname, (fd->usb.use_interrupt_xfer? "interrupt": "bulk"),
|
||||||
|
usb_strerror());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +559,10 @@ static int usbdev_drain(union filedescriptor *fd, int display)
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rv = usb_bulk_read(udev, fd->usb.rep, usbbuf, fd->usb.max_xfer, 100);
|
if (fd->usb.use_interrupt_xfer)
|
||||||
|
rv = usb_interrupt_read(udev, fd->usb.rep, usbbuf, fd->usb.max_xfer, 100);
|
||||||
|
else
|
||||||
|
rv = usb_bulk_read(udev, fd->usb.rep, usbbuf, fd->usb.max_xfer, 100);
|
||||||
if (rv > 0 && verbose >= 4)
|
if (rv > 0 && verbose >= 4)
|
||||||
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
|
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
|
||||||
progname, rv);
|
progname, rv);
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#define USB_DEVICE_STK600 0x2106
|
#define USB_DEVICE_STK600 0x2106
|
||||||
#define USB_DEVICE_AVRDRAGON 0x2107
|
#define USB_DEVICE_AVRDRAGON 0x2107
|
||||||
#define USB_DEVICE_JTAGICE3 0x2110
|
#define USB_DEVICE_JTAGICE3 0x2110
|
||||||
|
#define USB_DEVICE_XPLAINEDPRO 0x2111
|
||||||
|
#define USB_DEVICE_JTAG3_EDBG 0x2140
|
||||||
|
|
||||||
/* JTAGICEmkII, AVRISPmkII */
|
/* JTAGICEmkII, AVRISPmkII */
|
||||||
#define USBDEV_BULK_EP_WRITE_MKII 0x02
|
#define USBDEV_BULK_EP_WRITE_MKII 0x02
|
||||||
|
|
Loading…
Reference in New Issue