pathmove_command_t -> struct pathmove_command
[openocd.git] / src / jtag / rlink / rlink.c
index dc75bdef5926fad639a232e50eb53cb71f928a74..bc354575b67b89af54d8d1f6cc3bda441f9c96e6 100644 (file)
@@ -2,7 +2,7 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
- *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
+ *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   Copyright (C) 2008 Rob Brown, Lou Deluxe                              *
 #include "config.h"
 #endif
 
-/* system includes */
-#include <errno.h>
-#include <string.h>
-#include <usb.h>
-#include <stdint.h>
-
 /* project specific includes */
-#include "log.h"
-#include "types.h"
-#include "jtag.h"
-#include "configuration.h"
+#include "interface.h"
+#include "commands.h"
 #include "rlink.h"
 #include "st7.h"
 #include "ep1_cmd.h"
 #include "dtc_cmd.h"
 
+/* system includes */
+#include <usb.h>
+
 
 /* This feature is made useless by running the DTC all the time.  When automatic, the LED is on whenever the DTC is running.  Otherwise, USB messages are sent to turn it on and off. */
 #undef AUTOMATIC_BUSY_LED
 #define DTC_STATUS_POLL_BYTE   (ST7_USB_BUF_EP0OUT + 0xff)
 
 
-/* Symbolic names for some pins */
-#define ST7_PA_NJTAG_TRST              ST7_PA1
-#define ST7_PA_NRLINK_RST              ST7_PA3
-#define ST7_PA_NLINE_DRIVER_ENABLE     ST7_PA5
-
-/* mask for negative-logic pins */
-#define ST7_PA_NUNASSERTED     (0      \
-       | ST7_PA_NJTAG_TRST     \
-       | ST7_PA_NRLINK_RST     \
-       | ST7_PA_NLINE_DRIVER_ENABLE    \
-)
-
 #define ST7_PD_NBUSY_LED               ST7_PD0
-#define ST7_PD_NERROR_LED              ST7_PD1
-#define ST7_PD_NRUN_LED                        ST7_PD7
+#define ST7_PD_NRUN_LED                        ST7_PD1
+/* low enables VPP at adapter header, high connects it to GND instead */
+#define ST7_PD_VPP_SEL                 ST7_PD6
+/* low: VPP = 12v, high: VPP <= 5v */
+#define ST7_PD_VPP_SHDN                        ST7_PD7
 
+/* These pins are connected together */
 #define ST7_PE_ADAPTER_SENSE_IN                ST7_PE3
 #define ST7_PE_ADAPTER_SENSE_OUT       ST7_PE4
 
+/* Symbolic mapping between port pins and numbered IO lines */
+#define ST7_PA_IO1     ST7_PA1
+#define ST7_PA_IO2     ST7_PA2
+#define ST7_PA_IO4     ST7_PA4
+#define ST7_PA_IO8     ST7_PA6
+#define ST7_PA_IO10    ST7_PA7
+#define ST7_PB_IO5     ST7_PB5
+#define ST7_PC_IO9     ST7_PC1
+#define ST7_PC_IO3     ST7_PC2
+#define ST7_PC_IO7     ST7_PC3
+#define ST7_PE_IO6     ST7_PE5
+
+/* Symbolic mapping between numbered IO lines and adapter signals */
+#define ST7_PA_RTCK    ST7_PA_IO0
+#define ST7_PA_NTRST   ST7_PA_IO1
+#define ST7_PC_TDI     ST7_PC_IO3
+#define ST7_PA_DBGRQ   ST7_PA_IO4
+#define ST7_PB_NSRST   ST7_PB_IO5
+#define ST7_PE_TMS     ST7_PE_IO6
+#define ST7_PC_TCK     ST7_PC_IO7
+#define ST7_PC_TDO     ST7_PC_IO9
+#define ST7_PA_DBGACK  ST7_PA_IO10
+
 static usb_dev_handle *pHDev;
 
 
@@ -111,30 +121,30 @@ ep1_generic_commandl(
        va_list         ap;
        int             usb_ret;
 
-       if(length > sizeof(usb_buffer)) {
+       if (length > sizeof(usb_buffer)) {
                length = sizeof(usb_buffer);
        }
 
        usb_buffer_p = usb_buffer;
 
        va_start(ap, length);
-       while(length > 0) {
+       while (length > 0) {
                *usb_buffer_p++ = va_arg(ap, int);
                length--;
        }
-       
+
        memset(
                usb_buffer_p,
                0,
                sizeof(usb_buffer) - (usb_buffer_p - usb_buffer)
-       );
+);
 
        usb_ret = usb_bulk_write(
                pHDev,
                USB_EP1OUT_ADDR,
-               usb_buffer, sizeof(usb_buffer),
+               (char *)usb_buffer, sizeof(usb_buffer),
                USB_TIMEOUT_MS
-       );
+);
 
        return(usb_ret);
 }
@@ -160,13 +170,13 @@ ep1_memory_read(
                usb_buffer + 4,
                0,
                sizeof(usb_buffer) - 4
-       );
+);
 
        remain = length;
        count = 0;
 
-       while(remain) {
-               if(remain > sizeof(usb_buffer)) {
+       while (remain) {
+               if (remain > sizeof(usb_buffer)) {
                        length = sizeof(usb_buffer);
                } else {
                        length = remain;
@@ -176,26 +186,26 @@ ep1_memory_read(
                usb_buffer[2] = addr;
                usb_buffer[3] = length;
 
-               usb_ret = usb_bulk_write(
+                       usb_ret = usb_bulk_write(
                        pHDev, USB_EP1OUT_ADDR,
                        usb_buffer, sizeof(usb_buffer),
                        USB_TIMEOUT_MS
-               );
+);
 
-               if(usb_ret < sizeof(usb_buffer)) {
+               if (usb_ret < sizeof(usb_buffer)) {
                        break;
                }
-               
+
                usb_ret = usb_bulk_read(
                        pHDev, USB_EP1IN_ADDR,
                        buffer, length,
                        USB_TIMEOUT_MS
-               );
+);
 
-               if(usb_ret < length) {
+               if (usb_ret < length) {
                        break;
                }
-               
+
                addr += length;
                buffer += length;
                count += length;
@@ -226,8 +236,8 @@ ep1_memory_write(
        remain = length;
        count = 0;
 
-       while(remain) {
-               if(remain > (sizeof(usb_buffer) - 4)) {
+       while (remain) {
+               if (remain > (sizeof(usb_buffer) - 4)) {
                        length = (sizeof(usb_buffer) - 4);
                } else {
                        length = remain;
@@ -240,23 +250,23 @@ ep1_memory_write(
                        usb_buffer + 4,
                        buffer,
                        length
-               );
+);
                memset(
                        usb_buffer + 4 + length,
                        0,
                        sizeof(usb_buffer) - 4 - length
-               );
+);
 
-               usb_ret = usb_bulk_write(
+                       usb_ret = usb_bulk_write(
                        pHDev, USB_EP1OUT_ADDR,
-                       usb_buffer, sizeof(usb_buffer),
+                       (char *)usb_buffer, sizeof(usb_buffer),
                        USB_TIMEOUT_MS
-               );
+);
 
-               if(usb_ret < sizeof(usb_buffer)) {
+               if ((size_t)usb_ret < sizeof(usb_buffer)) {
                        break;
                }
-               
+
                addr += length;
                buffer += length;
                count += length;
@@ -281,7 +291,7 @@ ep1_memory_writel(
        va_list         ap;
        size_t          remain;
 
-       if(length > sizeof(buffer)) {
+       if (length > sizeof(buffer)) {
                length = sizeof(buffer);
        }
 
@@ -289,7 +299,7 @@ ep1_memory_writel(
        buffer_p = buffer;
 
        va_start(ap, length);
-       while(remain > 0) {
+       while (remain > 0) {
                *buffer_p++ = va_arg(ap, int);
                remain--;
        }
@@ -317,17 +327,17 @@ static
 int
 dtc_load_from_buffer(
        usb_dev_handle  *pHDev,
-       const u8                *buffer,
+       const uint8_t           *buffer,
        size_t                  length
 ) {
        struct header_s {
-               u8      type;
-               u8      length;
+               uint8_t type;
+               uint8_t length;
        };
 
        int                             usb_err;
        struct header_s *header;
-       u8                              lut_start = 0xc0;
+       uint8_t                         lut_start = 0xc0;
 
        dtc_entry_download = 0;
 
@@ -335,43 +345,43 @@ dtc_load_from_buffer(
        usb_err = ep1_generic_commandl(
                pHDev, 1,
                EP1_CMD_DTC_STOP
-       );
-       if(usb_err < 0) return(usb_err);
+);
+       if (usb_err < 0) return(usb_err);
 
-       while(length) {
-               if(length < sizeof(*header)) {
+       while (length) {
+               if (length < sizeof(*header)) {
                        LOG_ERROR("Malformed DTC image\n");
                        exit(1);
                }
-               
+
                header = (struct header_s *)buffer;
                buffer += sizeof(*header);
                length -= sizeof(*header);
 
-               if(length < header->length + 1) {
+               if (length < (size_t)header->length + 1) {
                        LOG_ERROR("Malformed DTC image\n");
                        exit(1);
                }
-               
-               switch(header->type) {
+
+               switch (header->type) {
                        case DTCLOAD_COMMENT:
                                break;
 
                        case DTCLOAD_ENTRY:
                                /* store entry addresses somewhere */
-                               if(!strncmp("download", buffer + 1, 8)) {
+                               if (!strncmp("download", (char *)buffer + 1, 8)) {
                                        dtc_entry_download = buffer[0];
                                }
                                break;
 
                        case DTCLOAD_LOAD:
-                               /* Send the DTC program to ST7 RAM. */
+                               /* Send the DTC program to ST7 RAM. */
                                usb_err = ep1_memory_write(
                                        pHDev,
                                        DTC_LOAD_BUFFER,
                                        header->length + 1, buffer
-                               );
-                               if(usb_err < 0) return(usb_err);
+);
+                               if (usb_err < 0) return(usb_err);
 
                                /* Load it into the DTC. */
                                usb_err = ep1_generic_commandl(
@@ -379,8 +389,8 @@ dtc_load_from_buffer(
                                        EP1_CMD_DTC_LOAD,
                                                (DTC_LOAD_BUFFER >> 8),
                                                DTC_LOAD_BUFFER
-                               );
-                               if(usb_err < 0) return(usb_err);
+);
+                               if (usb_err < 0) return(usb_err);
 
                                break;
 
@@ -390,22 +400,22 @@ dtc_load_from_buffer(
                                        EP1_CMD_DTC_CALL,
                                                buffer[0],
                                        EP1_CMD_DTC_WAIT
-                               );
-                               if(usb_err < 0) return(usb_err);
+);
+                               if (usb_err < 0) return(usb_err);
 
                                break;
 
                        case DTCLOAD_LUT_START:
                                lut_start = buffer[0];
                                break;
-               
+
                        case DTCLOAD_LUT:
-                               usb_err = ep1_memory_write(
+                               usb_err = ep1_memory_write(
                                        pHDev,
                                        ST7_USB_BUF_EP0OUT + lut_start,
                                        header->length + 1, buffer
-                               );
-                               if(usb_err < 0) return(usb_err);
+);
+                               if (usb_err < 0) return(usb_err);
                                break;
 
                        default:
@@ -413,7 +423,7 @@ dtc_load_from_buffer(
                                exit(1);
                                break;
                }
-               
+
                buffer += (header->length + 1);
                length -= (header->length + 1);
        }
@@ -427,15 +437,14 @@ dtc_load_from_buffer(
  */
 static
 int
-dtc_start_download(
-) {
+dtc_start_download(void) {
        int     usb_err;
-       u8      ep2txr;
+       uint8_t ep2txr;
 
        /* set up for download mode and make sure EP2 is set up to transmit */
        usb_err = ep1_generic_commandl(
                pHDev, 7,
-                
+
                EP1_CMD_DTC_STOP,
                EP1_CMD_SET_UPLOAD,
                EP1_CMD_SET_DOWNLOAD,
@@ -443,20 +452,20 @@ dtc_start_download(
                        ST7_EP2TXR >> 8,
                        ST7_EP2TXR,
                        1
-       );
-       if(usb_err < 0) return(usb_err);
+);
+       if (usb_err < 0) return(usb_err);
 
        /* read back ep2txr */
        usb_err = usb_bulk_read(
                pHDev, USB_EP1IN_ADDR,
-               &ep2txr, 1,
+               (char *)&ep2txr, 1,
                USB_TIMEOUT_MS
-       );
-       if(usb_err < 0) return(usb_err);
+);
+       if (usb_err < 0) return(usb_err);
 
        usb_err = ep1_generic_commandl(
                pHDev, 13,
-                
+
                EP1_CMD_MEMORY_WRITE,   /* preinitialize poll byte */
                        DTC_STATUS_POLL_BYTE >> 8,
                        DTC_STATUS_POLL_BYTE,
@@ -470,15 +479,15 @@ dtc_start_download(
                EP1_CMD_DTC_CALL,       /* start running the DTC */
                        dtc_entry_download,
                EP1_CMD_DTC_GET_CACHED_STATUS
-       );
-       if(usb_err < 0) return(usb_err);
+);
+       if (usb_err < 0) return(usb_err);
 
        /* wait for completion */
        usb_err = usb_bulk_read(
                pHDev, USB_EP1IN_ADDR,
-               &ep2txr, 1,
+               (char *)&ep2txr, 1,
                USB_TIMEOUT_MS
-       );
+);
 
        return(usb_err);
 }
@@ -488,12 +497,12 @@ static
 int
 dtc_run_download(
        usb_dev_handle  *pHDev,
-       u8      *command_buffer,
+       uint8_t *command_buffer,
        int     command_buffer_size,
-       u8      *reply_buffer,
+       uint8_t *reply_buffer,
        int     reply_buffer_size
 ) {
-       u8      ep2_buffer[USB_EP2IN_SIZE];
+       uint8_t ep2_buffer[USB_EP2IN_SIZE];
        int     usb_err;
        int     i;
 
@@ -502,14 +511,14 @@ dtc_run_download(
        usb_err = usb_bulk_write(
                pHDev,
                USB_EP2OUT_ADDR,
-               command_buffer, USB_EP2BANK_SIZE,
+               (char *)command_buffer, USB_EP2BANK_SIZE,
                USB_TIMEOUT_MS
-       );
-       if(usb_err < 0) return(usb_err);
+);
+       if (usb_err < 0) return(usb_err);
 
 
        /* Wait for DTC to finish running command buffer */
-       for(i = 5;;) {
+       for (i = 10;;) {
                usb_err = ep1_generic_commandl(
                        pHDev, 4,
 
@@ -517,41 +526,41 @@ dtc_run_download(
                                DTC_STATUS_POLL_BYTE >> 8,
                                DTC_STATUS_POLL_BYTE,
                                1
-               );
-               if(usb_err < 0) return(usb_err);
+);
+               if (usb_err < 0) return(usb_err);
 
                usb_err = usb_bulk_read(
                        pHDev,
                        USB_EP1IN_ADDR,
-                       ep2_buffer, 1,
+                       (char *)ep2_buffer, 1,
                        USB_TIMEOUT_MS
-               );
-               if(usb_err < 0) return(usb_err);
+);
+               if (usb_err < 0) return(usb_err);
 
-               if(ep2_buffer[0] & 0x01) break;
+               if (ep2_buffer[0] & 0x01) break;
 
-               if(!--i) {
+               if (!--i) {
                        LOG_ERROR("%s, %d: too many retries waiting for DTC status\n",
                                __FILE__, __LINE__
-                       );
+);
                        return(-ETIMEDOUT);
                }
        }
 
 
-       if(!reply_buffer) reply_buffer_size = 0;
-       if(reply_buffer_size) {
+       if (!reply_buffer) reply_buffer_size = 0;
+       if (reply_buffer_size) {
                usb_err = usb_bulk_read(
                        pHDev,
                        USB_EP2IN_ADDR,
-                       ep2_buffer, sizeof(ep2_buffer),
+                       (char *)ep2_buffer, sizeof(ep2_buffer),
                        USB_TIMEOUT_MS
-               );
+);
 
-               if(usb_err < (int)sizeof(ep2_buffer)) {
+               if (usb_err < (int)sizeof(ep2_buffer)) {
                        LOG_ERROR("%s, %d: Read of endpoint 2 returned %d\n",
                                __FILE__, __LINE__, usb_err
-                       );
+);
                        return(usb_err);
                }
 
@@ -573,7 +582,7 @@ struct dtc_reply_queue_entry_s {
        jtag_command_t  *cmd;   /* the command that resulted in this entry */
 
        struct {
-               u8              *buffer;        /* the scan buffer */
+               uint8_t         *buffer;        /* the scan buffer */
                int             size;           /* size of the scan buffer in bits */
                int             offset;         /* how many bits were already done before this? */
                int             length;         /* how many bits are processed in this operation? */
@@ -591,9 +600,9 @@ static
 struct {
        dtc_reply_queue_entry_t *rq_head;
        dtc_reply_queue_entry_t *rq_tail;
-       int                     cmd_index;
-       int                     reply_index;
-       u8                      cmd_buffer[USB_EP2BANK_SIZE];
+       uint32_t                        cmd_index;
+       uint32_t                        reply_index;
+       uint8_t                 cmd_buffer[USB_EP2BANK_SIZE];
 } dtc_queue;
 
 
@@ -603,16 +612,15 @@ struct {
 
 static
 struct {
-       int     length;
-       u32     buffer;
+       uint32_t        length;
+       uint32_t        buffer;
 } tap_state_queue;
 
 
 
 static
 int
-dtc_queue_init(
-) {
+dtc_queue_init(void) {
        dtc_queue.rq_head = NULL;
        dtc_queue.rq_tail = NULL;
        dtc_queue.cmd_index = 0;
@@ -626,7 +634,7 @@ inline
 dtc_reply_queue_entry_t *
 dtc_queue_enqueue_reply(
        enum scan_type  type,
-       u8                              *buffer,
+       uint8_t                         *buffer,
        int                             size,
        int                             offset,
        int                             length,
@@ -635,7 +643,7 @@ dtc_queue_enqueue_reply(
        dtc_reply_queue_entry_t *rq_entry;
 
        rq_entry = malloc(sizeof(dtc_reply_queue_entry_t));
-       if(rq_entry != NULL) {
+       if (rq_entry != NULL) {
                rq_entry->scan.type = type;
                rq_entry->scan.buffer = buffer;
                rq_entry->scan.size = size;
@@ -644,7 +652,7 @@ dtc_queue_enqueue_reply(
                rq_entry->cmd = cmd;
                rq_entry->next = NULL;
 
-               if(dtc_queue.rq_head == NULL)
+               if (dtc_queue.rq_head == NULL)
                        dtc_queue.rq_head = rq_entry;
                else
                        dtc_queue.rq_tail->next = rq_entry;
@@ -663,30 +671,29 @@ dtc_queue_enqueue_reply(
 
 static
 int
-dtc_queue_run(
-) {
+dtc_queue_run(void) {
        dtc_reply_queue_entry_t *rq_p, *rq_next;
        int                     retval;
        int                     usb_err;
        int                     bit_cnt;
        int                     x;
-       u8                      *dtc_p, *tdo_p;
-       u8                      dtc_mask, tdo_mask;
-       u8                      reply_buffer[USB_EP2IN_SIZE];
+       uint8_t                 *dtc_p, *tdo_p;
+       uint8_t                 dtc_mask, tdo_mask;
+       uint8_t                 reply_buffer[USB_EP2IN_SIZE];
 
        retval = ERROR_OK;
 
-       if(dtc_queue.cmd_index < 1) return(retval);
+       if (dtc_queue.cmd_index < 1) return(retval);
 
        dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = DTC_CMD_STOP;
 
        /* run the cmd */
-       if(dtc_queue.rq_head == NULL) {
+       if (dtc_queue.rq_head == NULL) {
                usb_err = dtc_run_download(pHDev,
                        dtc_queue.cmd_buffer, dtc_queue.cmd_index,
                        NULL, 0
-               );      
-               if(usb_err < 0) {
+);
+               if (usb_err < 0) {
                        LOG_ERROR("dtc_run_download: %s\n", usb_strerror());
                        exit(1);
                }
@@ -694,8 +701,8 @@ dtc_queue_run(
                usb_err = dtc_run_download(pHDev,
                        dtc_queue.cmd_buffer, dtc_queue.cmd_index,
                        reply_buffer, dtc_queue.reply_index
-               );      
-               if(usb_err < 0) {
+);
+               if (usb_err < 0) {
                        LOG_ERROR("dtc_run_download: %s\n", usb_strerror());
                        exit(1);
                } else {
@@ -704,40 +711,40 @@ dtc_queue_run(
 
                        /* The rigamarole with the masks and doing it bit-by-bit is due to the fact that the scan buffer is LSb-first and the DTC code is MSb-first for hardware reasons.   It was that or craft a function to do the reversal, and that wouldn't work with bit-stuffing (supplying extra bits to use mostly byte operations), or any other scheme which would throw the byte alignment off. */
 
-                       for(
+                       for (
                                rq_p = dtc_queue.rq_head;
                                rq_p != NULL;
                                rq_p = rq_next
-                       ) {
+) {
                                tdo_p = rq_p->scan.buffer + (rq_p->scan.offset / 8);
                                tdo_mask = 1 << (rq_p->scan.offset % 8);
 
 
                                bit_cnt = rq_p->scan.length;
-                               if(bit_cnt >= 8) {
+                               if (bit_cnt >= 8) {
                                        /* bytes */
 
                                        dtc_mask = 1 << (8 - 1);
 
-                                       for(
+                                       for (
                                                ;
                                                bit_cnt;
                                                bit_cnt--
-                                       ) {
-                                               if(*dtc_p & dtc_mask) {
+) {
+                                               if (*dtc_p & dtc_mask) {
                                                        *tdo_p |= tdo_mask;
                                                } else {
                                                        *tdo_p &=~ tdo_mask;
                                                }
-                                               
+
                                                dtc_mask >>= 1;
-                                               if(dtc_mask == 0) {
+                                               if (dtc_mask == 0) {
                                                        dtc_p++;
                                                        dtc_mask = 1 << (8 - 1);
                                                }
 
                                                tdo_mask <<= 1;
-                                               if(tdo_mask == 0) {
+                                               if (tdo_mask == 0) {
                                                        tdo_p++;
                                                        tdo_mask = 1;
                                                }
@@ -746,23 +753,23 @@ dtc_queue_run(
                                        /*  extra bits or last bit */
 
                                        x = *dtc_p++;
-                                       if((
+                                       if ((
                                                rq_p->scan.type == SCAN_IN
-                                       ) && (
+) && (
                                                rq_p->scan.offset != rq_p->scan.size - 1
-                                       )) {
+)) {
                                                /* extra bits were sent as a full byte with padding on the end */
                                                dtc_mask = 1 << (8 - 1);
                                        } else {
                                                dtc_mask = 1 << (bit_cnt - 1);
                                        }
 
-                                       for(
+                                       for (
                                                ;
                                                bit_cnt;
                                                bit_cnt--
-                                       ) {
-                                               if(x & dtc_mask) {
+) {
+                                               if (x & dtc_mask) {
                                                        *tdo_p |= tdo_mask;
                                                } else {
                                                        *tdo_p &=~ tdo_mask;
@@ -771,17 +778,17 @@ dtc_queue_run(
                                                dtc_mask >>= 1;
 
                                                tdo_mask <<= 1;
-                                               if(tdo_mask == 0) {
+                                               if (tdo_mask == 0) {
                                                        tdo_p++;
                                                        tdo_mask = 1;
                                                }
-                                                               
+
                                        }
                                }
 
-                               if((rq_p->scan.offset + rq_p->scan.length) >= rq_p->scan.size) {
+                               if ((rq_p->scan.offset + rq_p->scan.length) >= rq_p->scan.size) {
                                        /* feed scan buffer back into openocd and free it */
-                                       if(jtag_read_buffer(rq_p->scan.buffer, rq_p->cmd->cmd.scan) != ERROR_OK) {
+                                       if (jtag_read_buffer(rq_p->scan.buffer, rq_p->cmd->cmd.scan) != ERROR_OK) {
                                                 retval = ERROR_JTAG_QUEUE_FAILED;
                                        }
                                        free(rq_p->scan.buffer);
@@ -808,8 +815,7 @@ dtc_queue_run(
 
 static
 int
-tap_state_queue_init(
-) {
+tap_state_queue_init(void) {
        tap_state_queue.length = 0;
        tap_state_queue.buffer = 0;
        return(0);
@@ -818,35 +824,34 @@ tap_state_queue_init(
 
 static
 int
-tap_state_queue_run(
-) {
+tap_state_queue_run(void) {
        int     i;
        int     bits;
-       u8      byte;
+       uint8_t byte;
        int     retval;
 
        retval = 0;
-       if(!tap_state_queue.length) return(retval);
+       if (!tap_state_queue.length) return(retval);
        bits = 1;
        byte = 0;
-       for(i = tap_state_queue.length; i--;) {
-               
+       for (i = tap_state_queue.length; i--;) {
+
                byte <<= 1;
-               if(tap_state_queue.buffer & 1) {
+               if (tap_state_queue.buffer & 1) {
                        byte |= 1;
                }
-               if((bits >= 8) || !i) {
+               if ((bits >= 8) || !i) {
                        byte <<= (8 - bits);
 
                        /* make sure there's room for stop, byte op, and one byte */
-                       if(dtc_queue.cmd_index >= (sizeof(dtc_queue.cmd_buffer) - (1 + 1 + 1))) {
+                       if (dtc_queue.cmd_index >= (sizeof(dtc_queue.cmd_buffer) - (1 + 1 + 1))) {
                                dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
                                        DTC_CMD_STOP;
                                dtc_queue_run();
                        }
 
 #ifdef USE_HARDWARE_SHIFTER_FOR_TMS
-                       if(bits == 8) {
+                       if (bits == 8) {
                                dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
                                        DTC_CMD_SHIFT_TMS_BYTES(1);
                        } else {
@@ -876,16 +881,16 @@ tap_state_queue_run(
 static
 int
 tap_state_queue_append(
-       u8      tms
+       uint8_t tms
 ) {
        int     retval;
 
-       if(tap_state_queue.length >= sizeof(tap_state_queue.buffer) * 8) {
+       if (tap_state_queue.length >= sizeof(tap_state_queue.buffer) * 8) {
                retval = tap_state_queue_run();
-               if(retval != 0) return(retval);
+               if (retval != 0) return(retval);
        }
 
-       if(tms) {
+       if (tms) {
                tap_state_queue.buffer |= (1 << tap_state_queue.length);
        }
        tap_state_queue.length++;
@@ -895,10 +900,10 @@ tap_state_queue_append(
 
 
 static
-void rlink_end_state(enum tap_state state)
+void rlink_end_state(tap_state_t state)
 {
-       if (tap_move_map[state] != -1)
-               end_state = state;
+       if (tap_is_state_stable(state))
+               tap_set_end_state(state);
        else
        {
                LOG_ERROR("BUG: %i is not a valid end state", state);
@@ -910,20 +915,21 @@ void rlink_end_state(enum tap_state state)
 static
 void rlink_state_move(void) {
 
-       int i=0, tms=0;
-       u8 tms_scan = TAP_MOVE(cur_state, end_state);
+       int i = 0, tms = 0;
+       uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
+       int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
 
-       for (i = 0; i < 7; i++)
+       for (i = 0; i < tms_count; i++)
        {
                tms = (tms_scan >> i) & 1;
                tap_state_queue_append(tms);
        }
 
-       cur_state = end_state;
+       tap_set_state(tap_get_end_state());
 }
 
 static
-void rlink_path_move(pathmove_command_t *cmd)
+void rlink_path_move(struct pathmove_command *cmd)
 {
        int num_states = cmd->num_states;
        int state_count;
@@ -932,28 +938,28 @@ void rlink_path_move(pathmove_command_t *cmd)
        state_count = 0;
        while (num_states)
        {
-               if (tap_transitions[cur_state].low == cmd->path[state_count])
+               if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])
                {
                        tms = 0;
                }
-               else if (tap_transitions[cur_state].high == cmd->path[state_count])
+               else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])
                {
                        tms = 1;
                }
                else
                {
-                       LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", jtag_state_name(cur_state), jtag_state_name(cmd->path[state_count]));
+                       LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(cmd->path[state_count]));
                        exit(-1);
                }
 
                tap_state_queue_append(tms);
 
-               cur_state = cmd->path[state_count];
+               tap_set_state(cmd->path[state_count]);
                state_count++;
                num_states--;
        }
 
-       end_state = cur_state;
+       tap_set_end_state(tap_get_state());
 }
 
 
@@ -962,10 +968,10 @@ void rlink_runtest(int num_cycles)
 {
        int i;
 
-       enum tap_state saved_end_state = end_state;
+       tap_state_t saved_end_state = tap_get_end_state();
 
        /* only do a state_move when we're not already in RTI */
-       if (cur_state != TAP_IDLE)
+       if (tap_get_state() != TAP_IDLE)
        {
                rlink_end_state(TAP_IDLE);
                rlink_state_move();
@@ -979,7 +985,7 @@ void rlink_runtest(int num_cycles)
 
        /* finish in end_state */
        rlink_end_state(saved_end_state);
-       if (cur_state != end_state)
+       if (tap_get_state() != tap_get_end_state())
                rlink_state_move();
 }
 
@@ -988,29 +994,95 @@ void rlink_runtest(int num_cycles)
 static
 void rlink_reset(int trst, int srst)
 {
-       u8                      bitmap;
+       uint8_t                 bitmap;
        int                     usb_err;
 
-       bitmap = ((~(ST7_PA_NLINE_DRIVER_ENABLE)) & ST7_PA_NUNASSERTED);
+       /* Read port A for bit op */
+       usb_err = ep1_generic_commandl(
+               pHDev, 4,
+               EP1_CMD_MEMORY_READ,
+                       ST7_PADR >> 8,
+                       ST7_PADR,
+                       1
+);
+       if (usb_err < 0) {
+               LOG_ERROR("%s", usb_strerror());
+               exit(1);
+       }
 
-       if(trst) {
-               bitmap &= ~ST7_PA_NJTAG_TRST;
+       usb_err = usb_bulk_read(
+               pHDev, USB_EP1IN_ADDR,
+               (char *)&bitmap, 1,
+               USB_TIMEOUT_MS
+);
+       if (usb_err < 1) {
+               LOG_ERROR("%s", usb_strerror());
+               exit(1);
        }
-       if(srst) {
-               bitmap &= ~ST7_PA_NRLINK_RST;
+
+       if (trst) {
+               bitmap &= ~ST7_PA_NTRST;
+       } else {
+               bitmap |= ST7_PA_NTRST;
        }
 
+       /* Write port A and read port B for bit op */
+       /* port B has no OR, and we want to emulate open drain on NSRST, so we initialize DR to 0 and assert NSRST by setting DDR to 1. */
        usb_err = ep1_generic_commandl(
-               pHDev, 5,
-                
+               pHDev, 9,
                EP1_CMD_MEMORY_WRITE,
                        ST7_PADR >> 8,
                        ST7_PADR,
                        1,
-                       bitmap
-       );
-       if(usb_err < 0) {
-               LOG_ERROR("%s: %s\n", __func__, usb_strerror());
+                       bitmap,
+               EP1_CMD_MEMORY_READ,
+                       ST7_PBDDR >> 8,
+                       ST7_PBDDR,
+                       1
+);
+       if (usb_err < 0) {
+               LOG_ERROR("%s", usb_strerror());
+               exit(1);
+       }
+
+       usb_err = usb_bulk_read(
+               pHDev, USB_EP1IN_ADDR,
+               (char *)&bitmap, 1,
+               USB_TIMEOUT_MS
+);
+       if (usb_err < 1) {
+               LOG_ERROR("%s", usb_strerror());
+               exit(1);
+       }
+
+       if (srst) {
+               bitmap |= ST7_PB_NSRST;
+       } else {
+               bitmap &= ~ST7_PB_NSRST;
+       }
+
+       /* write port B and read dummy to ensure completion before returning */
+       usb_err = ep1_generic_commandl(
+               pHDev, 6,
+               EP1_CMD_MEMORY_WRITE,
+                       ST7_PBDDR >> 8,
+                       ST7_PBDDR,
+                       1,
+                       bitmap,
+               EP1_CMD_DTC_GET_CACHED_STATUS
+);
+       if (usb_err < 0) {
+               LOG_ERROR("%s", usb_strerror());
+               exit(1);
+       }
+
+       usb_err = usb_bulk_read(
+               pHDev, USB_EP1IN_ADDR,
+               (char *)&bitmap, 1,
+               USB_TIMEOUT_MS
+);
+       if (usb_err < 1) {
+               LOG_ERROR("%s", usb_strerror());
                exit(1);
        }
 }
@@ -1021,11 +1093,11 @@ int
 rlink_scan(
        jtag_command_t  *cmd,
        enum scan_type  type,
-       u8                      *buffer,
+       uint8_t                 *buffer,
        int                     scan_size
 ) {
-       int                     ir_scan;
-       enum tap_state  saved_end_state;
+       bool            ir_scan;
+       tap_state_t     saved_end_state;
        int                     byte_bits;
        int                     extra_bits;
        int                     chunk_bits;
@@ -1033,10 +1105,10 @@ rlink_scan(
        int                     x;
 
        int                     tdi_bit_offset;
-       u8                      tdi_mask, *tdi_p;
-       u8                      dtc_mask;
+       uint8_t                 tdi_mask, *tdi_p;
+       uint8_t                 dtc_mask;
 
-       if(scan_size < 1) {
+       if (scan_size < 1) {
                LOG_ERROR("scan_size cannot be less than 1 bit\n");
                exit(1);
        }
@@ -1045,11 +1117,11 @@ rlink_scan(
 
        /* Move to the proper state before starting to shift TDI/TDO. */
        if (!(
-               (!ir_scan && (cur_state == TAP_DRSHIFT))
+               (!ir_scan && (tap_get_state() == TAP_DRSHIFT))
                ||
-               (ir_scan && (cur_state == TAP_IRSHIFT))
-       )) {
-               saved_end_state = end_state;
+               (ir_scan && (tap_get_state() == TAP_IRSHIFT))
+)) {
+               saved_end_state = tap_get_end_state();
                rlink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
                rlink_state_move();
                rlink_end_state(saved_end_state);
@@ -1059,7 +1131,7 @@ rlink_scan(
 
 
 #if 0
-       printf("scan_size = %d, type=0x%x\n", scan_size, type);
+       printf("scan_size = %d, type = 0x%x\n", scan_size, type);
        {
                int   i;
 
@@ -1068,7 +1140,7 @@ rlink_scan(
                buffer[scan_size / 8] &= ((1 << ((scan_size - 1) % 8) + 1) - 1);
 
                printf("before scan:");
-               for(i = 0; i < (scan_size + 7) / 8; i++) {
+               for (i = 0; i < (scan_size + 7) / 8; i++) {
                        printf(" %02x", buffer[i]);
                }
                printf("\n");
@@ -1084,28 +1156,28 @@ rlink_scan(
        tdi_p = buffer;
        tdi_mask = 1;
 
-       if(extra_bits && (type == SCAN_OUT)) {
+       if (extra_bits && (type == SCAN_OUT)) {
                /* Schedule any extra bits into the DTC command buffer, padding as needed */
                /* For SCAN_OUT, this comes before the full bytes so the (leading) padding bits will fall off the end */
                /* make sure there's room for stop, byte op, and one byte */
-               if(
+               if (
                        (dtc_queue.cmd_index >= sizeof(dtc_queue.cmd_buffer) - (1 + 1 + 1))
-               ) {
+) {
                        dtc_queue_run();
                }
 
                x = 0;
                dtc_mask = 1 << (extra_bits - 1);
-       
-               while(extra_bits--) {
-                       if(*tdi_p & tdi_mask) {
+
+               while (extra_bits--) {
+                       if (*tdi_p & tdi_mask) {
                                x |= dtc_mask;
                        }
 
                        dtc_mask >>= 1;
 
                        tdi_mask <<= 1;
-                       if(tdi_mask == 0) {
+                       if (tdi_mask == 0) {
                                tdi_p++;
                                tdi_mask = 1;
                        }
@@ -1118,8 +1190,8 @@ rlink_scan(
        }
 
        /* Loop scheduling full bytes into the DTC command buffer */
-       while(byte_bits) {
-               if(type == SCAN_IN) {
+       while (byte_bits) {
+               if (type == SCAN_IN) {
                        /* make sure there's room for stop and byte op */
                        x = (dtc_queue.cmd_index >= sizeof(dtc_queue.cmd_buffer) - (1 + 1));
                } else {
@@ -1127,51 +1199,51 @@ rlink_scan(
                        x = (dtc_queue.cmd_index >= sizeof(dtc_queue.cmd_buffer) - (1 + 1 + 1));
                }
 
-               if(type != SCAN_OUT) {
+               if (type != SCAN_OUT) {
                        /* make sure there's room for at least one reply byte */
                        x |= (dtc_queue.reply_index >= USB_EP2IN_SIZE - (1));
                }
 
-               if(x) {
+               if (x) {
                        dtc_queue_run();
                }
 
                chunk_bits = byte_bits;
                /* we can only use up to 16 bytes at a time */
-               if(chunk_bits > (16 * 8)) chunk_bits = (16 * 8);
+               if (chunk_bits > (16 * 8)) chunk_bits = (16 * 8);
 
-               if(type != SCAN_IN) {
+               if (type != SCAN_IN) {
                        /* how much is there room for, considering stop and byte op? */
                        x = (sizeof(dtc_queue.cmd_buffer) - (dtc_queue.cmd_index + 1 + 1)) * 8;
-                       if(chunk_bits > x) chunk_bits = x;
+                       if (chunk_bits > x) chunk_bits = x;
                }
 
-               if(type != SCAN_OUT) {
+               if (type != SCAN_OUT) {
                        /* how much is there room for in the reply buffer? */
                        x = (USB_EP2IN_SIZE - dtc_queue.reply_index) * 8;
-                       if(chunk_bits > x) chunk_bits = x;
+                       if (chunk_bits > x) chunk_bits = x;
                }
 
                /* so the loop will end */
                byte_bits -= chunk_bits;
 
-               if(type != SCAN_OUT) {
-                       if(dtc_queue_enqueue_reply(
+               if (type != SCAN_OUT) {
+                       if (dtc_queue_enqueue_reply(
                                type, buffer, scan_size, tdi_bit_offset,
                                chunk_bits,
                                cmd
-                       ) == NULL) {
+) == NULL) {
                                LOG_ERROR("enqueuing DTC reply entry: %s\n", strerror(errno));
                                exit(1);
                        }
-                       
+
                        tdi_bit_offset += chunk_bits;
                }
 
                /* chunk_bits is a multiple of 8, so there are no rounding issues. */
                chunk_bytes = chunk_bits / 8;
 
-               switch(type) {
+               switch (type) {
                        case SCAN_IN:
                                x = DTC_CMD_SHIFT_TDO_BYTES(chunk_bytes);
                                break;
@@ -1184,25 +1256,25 @@ rlink_scan(
                }
                dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;
 
-               if(type != SCAN_IN) {
+               if (type != SCAN_IN) {
                        x = 0;
                        dtc_mask = 1 << (8 - 1);
-               
-                       while(chunk_bits--) {
-                               if(*tdi_p & tdi_mask) {
+
+                       while (chunk_bits--) {
+                               if (*tdi_p & tdi_mask) {
                                        x |= dtc_mask;
                                }
-       
+
                                dtc_mask >>= 1;
-                               if(dtc_mask == 0) {
+                               if (dtc_mask == 0) {
                                        dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;
                                        dtc_queue.reply_index++;
                                        x = 0;
                                        dtc_mask = 1 << (8 - 1);
                                }
-       
+
                                tdi_mask <<= 1;
-                               if(tdi_mask == 0) {
+                               if (tdi_mask == 0) {
                                        tdi_p++;
                                        tdi_mask = 1;
                                }
@@ -1210,29 +1282,29 @@ rlink_scan(
                }
        }
 
-       if(extra_bits && (type != SCAN_OUT)) {
+       if (extra_bits && (type != SCAN_OUT)) {
                /* Schedule any extra bits into the DTC command buffer */
                /* make sure there's room for stop, byte op, and one byte */
-               if(
+               if (
                        (dtc_queue.cmd_index >= sizeof(dtc_queue.cmd_buffer) - (1 + 1 + 1))
                        ||
                        (dtc_queue.reply_index >= USB_EP2IN_SIZE - (1))
-               ) {
+) {
                        dtc_queue_run();
                }
 
-               if(dtc_queue_enqueue_reply(
+               if (dtc_queue_enqueue_reply(
                        type, buffer, scan_size, tdi_bit_offset,
                        extra_bits,
                        cmd
-               ) == NULL) {
+) == NULL) {
                        LOG_ERROR("enqueuing DTC reply entry: %s\n", strerror(errno));
                        exit(1);
                }
-                       
+
                tdi_bit_offset += extra_bits;
 
-               if(type == SCAN_IN) {
+               if (type == SCAN_IN) {
                        dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
                                DTC_CMD_SHIFT_TDO_BYTES(1);
 
@@ -1242,16 +1314,16 @@ rlink_scan(
 
                        x = 0;
                        dtc_mask = 1 << (8 - 1);
-               
-                       while(extra_bits--) {
-                               if(*tdi_p & tdi_mask) {
+
+                       while (extra_bits--) {
+                               if (*tdi_p & tdi_mask) {
                                        x |= dtc_mask;
                                }
-       
+
                                dtc_mask >>= 1;
-       
+
                                tdi_mask <<= 1;
-                               if(tdi_mask == 0) {
+                               if (tdi_mask == 0) {
                                        tdi_p++;
                                        tdi_mask = 1;
                                }
@@ -1266,29 +1338,29 @@ rlink_scan(
        /* Schedule the last bit into the DTC command buffer */
        {
                /* make sure there's room for stop, and bit pair command */
-               if(
+               if (
                        (dtc_queue.cmd_index >= sizeof(dtc_queue.cmd_buffer) - (1 + 1))
                        ||
                        (dtc_queue.reply_index >= USB_EP2IN_SIZE - (1))
-               ) {
+) {
                        dtc_queue_run();
                }
 
-               if(type == SCAN_OUT) {
+               if (type == SCAN_OUT) {
                        dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
                                DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 0);
 
                } else {
-                       if(dtc_queue_enqueue_reply(
+                       if (dtc_queue_enqueue_reply(
                                type, buffer, scan_size, tdi_bit_offset,
                                1,
                                cmd
-                       ) == NULL) {
+) == NULL) {
                                LOG_ERROR("enqueuing DTC reply entry: %s\n", strerror(errno));
                                exit(1);
                        }
-                       
-                       dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = 
+
+                       dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
                                DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 1);
 
                        dtc_queue.reply_index++;
@@ -1297,8 +1369,8 @@ rlink_scan(
 
        /* Move to pause state */
        tap_state_queue_append(0);
-       cur_state = ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE;
-       if (cur_state != end_state) rlink_state_move();
+       tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
+       if (tap_get_state() != tap_get_end_state()) rlink_state_move();
 
        return(0);
 }
@@ -1310,7 +1382,7 @@ int rlink_execute_queue(void)
        jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
        int scan_size;
        enum scan_type type;
-       u8 *buffer;
+       uint8_t *buffer;
        int retval, tmp_retval;
 
        /* return ERROR_OK, unless something goes wrong */
@@ -1321,14 +1393,13 @@ int rlink_execute_queue(void)
        ep1_generic_commandl(pHDev, 2,
                EP1_CMD_SET_PORTD_LEDS,
                ~(ST7_PD_NBUSY_LED)
-       );
+);
 #endif
 
        while (cmd)
        {
                switch (cmd->type)
                {
-                       case JTAG_END_STATE:
                        case JTAG_RUNTEST:
                        case JTAG_STATEMOVE:
                        case JTAG_PATHMOVE:
@@ -1344,20 +1415,13 @@ int rlink_execute_queue(void)
 
                switch (cmd->type)
                {
-                       case JTAG_END_STATE:
-#ifdef _DEBUG_JTAG_IO_
-                               LOG_DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
-#endif
-                               if (cmd->cmd.end_state->end_state != -1)
-                                       rlink_end_state(cmd->cmd.end_state->end_state);
-                               break;
                        case JTAG_RESET:
 #ifdef _DEBUG_JTAG_IO_
                                LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
 #endif
-                               if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST)))
+                               if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
                                {
-                                       cur_state = TAP_RESET;
+                                       tap_set_state(TAP_RESET);
                                }
                                rlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
                                break;
@@ -1391,7 +1455,7 @@ int rlink_execute_queue(void)
                                        rlink_end_state(cmd->cmd.scan->end_state);
                                scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
                                type = jtag_scan_type(cmd->cmd.scan);
-                               if(rlink_scan(cmd, type, buffer, scan_size) != ERROR_OK) {
+                               if (rlink_scan(cmd, type, buffer, scan_size) != ERROR_OK) {
                                        retval = ERROR_FAIL;
                                }
                                break;
@@ -1411,7 +1475,7 @@ int rlink_execute_queue(void)
        /* Flush the DTC queue to make sure any pending reads have been done before exiting this function */
        tap_state_queue_run();
        tmp_retval = dtc_queue_run();
-       if(tmp_retval != ERROR_OK) {
+       if (tmp_retval != ERROR_OK) {
                retval = tmp_retval;
        }
 
@@ -1420,7 +1484,7 @@ int rlink_execute_queue(void)
        ep1_generic_commandl(pHDev, 2,
                EP1_CMD_SET_PORTD_LEDS,
                ~0
-       );
+);
 #endif
 
        return retval;
@@ -1434,23 +1498,23 @@ int rlink_speed(int speed)
 {
        int             i;
 
-       if(speed == 0) {
+       if (speed == 0) {
                /* fastest speed */
                speed = rlink_speed_table[rlink_speed_table_size - 1].prescaler;
        }
 
-       for(i = rlink_speed_table_size; i--; ) {
-               if(rlink_speed_table[i].prescaler == speed) {
-                       if(dtc_load_from_buffer(pHDev, rlink_speed_table[i].dtc, rlink_speed_table[i].dtc_size) != 0) {
+       for (i = rlink_speed_table_size; i--;) {
+               if (rlink_speed_table[i].prescaler == speed) {
+                       if (dtc_load_from_buffer(pHDev, rlink_speed_table[i].dtc, rlink_speed_table[i].dtc_size) != 0) {
                                LOG_ERROR("An error occurred while trying to load DTC code for speed \"%d\".\n", speed);
                                exit(1);
                        }
-       
-                       if(dtc_start_download() < 0) {
+
+                       if (dtc_start_download() < 0) {
                                LOG_ERROR("%s, %d: starting DTC: %s",
                                        __FILE__, __LINE__,
                                        usb_strerror()
-                               );
+);
                                exit(1);
                        }
 
@@ -1470,8 +1534,8 @@ int rlink_speed_div(
 ) {
        int     i;
 
-       for(i = rlink_speed_table_size; i--; ) {
-               if(rlink_speed_table[i].prescaler == speed) {
+       for (i = rlink_speed_table_size; i--;) {
+               if (rlink_speed_table[i].prescaler == speed) {
                        *khz = rlink_speed_table[i].khz;
                        return(ERROR_OK);
                }
@@ -1489,13 +1553,13 @@ int rlink_khz(
 ) {
        int     i;
 
-       if(khz == 0) {
+       if (khz == 0) {
                LOG_ERROR("RCLK not supported");
                return ERROR_FAIL;
        }
 
-       for(i = rlink_speed_table_size; i--; ) {
-               if(rlink_speed_table[i].khz <= khz) {
+       for (i = rlink_speed_table_size; i--;) {
+               if (rlink_speed_table[i].khz <= khz) {
                        *speed = rlink_speed_table[i].prescaler;
                        return(ERROR_OK);
                }
@@ -1516,7 +1580,7 @@ handle_dtc_directory_command(
        char **args,
        int argc
 ) {
-       if(argc != 1) {
+       if (argc != 1) {
                LOG_ERROR("expected exactly one argument to rlink_dtc_directory <directory-path>");
                return(ERROR_INVALID_ARGUMENTS);
        }
@@ -1543,7 +1607,7 @@ int rlink_register_commands(struct command_context_s *cmd_ctx)
                handle_dtc_directory_command,
                COMMAND_CONFIG,
                "The directory in which to search for DTC load images"
-       );
+);
 #endif
 
        return ERROR_OK;
@@ -1556,9 +1620,9 @@ int rlink_init(void)
        struct usb_bus *busses;
        struct usb_bus *bus;
        int i, j, retries;
-       int found=0;
-       int success=0;
-       u8 reply_buffer[USB_EP1IN_SIZE];
+       int found = 0;
+       int success = 0;
+       uint8_t reply_buffer[USB_EP1IN_SIZE];
 
        usb_init();
        usb_find_busses();
@@ -1566,32 +1630,32 @@ int rlink_init(void)
 
        busses = usb_get_busses();
 
-       for(bus = busses; bus; bus = bus->next)
+       for (bus = busses; bus; bus = bus->next)
        {
                struct usb_device *dev;
 
-               for(dev = bus->devices; dev; dev = dev->next)
+               for (dev = bus->devices; dev; dev = dev->next)
                {
-                       if( (dev->descriptor.idVendor == USB_IDVENDOR) && (dev->descriptor.idProduct == USB_IDPRODUCT) )
+                       if ((dev->descriptor.idVendor == USB_IDVENDOR) && (dev->descriptor.idProduct == USB_IDPRODUCT))
                        {
                                found = 1;
                                LOG_DEBUG("Found device on bus.\n");
 
                                do
                                {
-                                       if( dev->descriptor.bNumConfigurations > 1 )
+                                       if (dev->descriptor.bNumConfigurations > 1)
                                        {
                                                LOG_ERROR("Whoops! NumConfigurations is not 1, don't know what to do...\n");
                                                break;
                                        }
-                                       if( dev->config->bNumInterfaces > 1 )
+                                       if (dev->config->bNumInterfaces > 1)
                                        {
                                                LOG_ERROR("Whoops! NumInterfaces is not 1, don't know what to do...\n");
                                                break;
                                        }
 
-                                       pHDev=usb_open(dev);
-                                       if( !pHDev )
+                                       pHDev = usb_open(dev);
+                                       if (!pHDev)
                                                LOG_ERROR ("Failed to open device.\n");
                                        else
                                        {
@@ -1599,17 +1663,17 @@ int rlink_init(void)
 
                                                /* usb_set_configuration required under win32 */
                                                usb_set_configuration(pHDev, dev->config[0].bConfigurationValue);
-                                               
+
                                                retries = 3;
                                                do
                                                {
                                                        i = usb_claim_interface(pHDev,0);
-                                                       if(i)
+                                                       if (i)
                                                        {
                                                                LOG_ERROR("usb_claim_interface: %s", usb_strerror());
 #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
                                                                j = usb_detach_kernel_driver_np(pHDev, 0);
-                                                               if(j)
+                                                               if (j)
                                                                        LOG_ERROR("detach kernel driver: %s", usb_strerror());
 #endif
                                                        }
@@ -1618,31 +1682,31 @@ int rlink_init(void)
                                                                LOG_DEBUG("interface claimed!\n");
                                                                break;
                                                        }
-                                               } while(--retries);
+                                               } while (--retries);
 
-                                               if(!i)
+                                               if (!i)
                                                {
-                                                       if( usb_set_altinterface(pHDev,0) )
+                                                       if (usb_set_altinterface(pHDev,0))
                                                        {
                                                                LOG_ERROR("Failed to set interface.\n");
                                                                break;
                                                        }
                                                        else
-                                                               success=1;
+                                                               success = 1;
                                                }
                                        }
-                               } while(0);
+                               } while (0);
                        }
                }
        }
 
-       if( !found )
+       if (!found)
        {
                LOG_ERROR("No device found on bus.\n");
                exit(1);
        }
 
-       if( !success )
+       if (!success)
        {
                LOG_ERROR("Initialisation failed.");
                exit(1);
@@ -1651,30 +1715,30 @@ int rlink_init(void)
 
        /* The device starts out in an unknown state on open.  As such, result reads time out, and it's not even known whether the command was accepted.  So, for this first command, we issue it repeatedly until its response doesn't time out.  Also, if sending a command is going to time out, we'll find that out here. */
        /* It must be possible to open the device in such a way that this special magic isn't needed, but, so far, it escapes us. */
-       for(i = 0; i < 5; i++) {
+       for (i = 0; i < 5; i++) {
                j = ep1_generic_commandl(
                        pHDev, 1,
                        EP1_CMD_GET_FWREV
-               );
-               if(j < USB_EP1OUT_SIZE) {
+);
+               if (j < USB_EP1OUT_SIZE) {
                        LOG_ERROR("USB write error: %s", usb_strerror());
                        return(ERROR_FAIL);
                }
                j = usb_bulk_read(
                        pHDev, USB_EP1IN_ADDR,
-                       reply_buffer, sizeof(reply_buffer),
+                       (char *)reply_buffer, sizeof(reply_buffer),
                        200
-               );
-               if(j != -ETIMEDOUT) break;
+);
+               if (j != -ETIMEDOUT) break;
        }
 
-       if(j < (int)sizeof(reply_buffer)) {
+       if (j < (int)sizeof(reply_buffer)) {
                LOG_ERROR("USB read error: %s", usb_strerror());
                return(ERROR_FAIL);
        }
        LOG_DEBUG(INTERFACE_NAME" firmware version: %d.%d.%d\n", reply_buffer[0], reply_buffer[1], reply_buffer[2]);
 
-       if((reply_buffer[0] != 0) || (reply_buffer[1] != 0) || (reply_buffer[2] != 3)) {
+       if ((reply_buffer[0] != 0) || (reply_buffer[1] != 0) || (reply_buffer[2] != 3)) {
                LOG_WARNING("The rlink device is not of the version that the developers have played with.  It may or may not work.\n");
        }
 
@@ -1685,9 +1749,9 @@ int rlink_init(void)
                        ST7_PEDR >> 8,
                        ST7_PEDR,
                        3,
-                       0x00,
-                       ST7_PE_ADAPTER_SENSE_OUT,
-                       ST7_PE_ADAPTER_SENSE_OUT,
+                       0x00,                                           /* DR */
+                       ST7_PE_ADAPTER_SENSE_OUT,       /* DDR */
+                       ST7_PE_ADAPTER_SENSE_OUT,       /* OR */
                EP1_CMD_MEMORY_READ,    /* Read back */
                        ST7_PEDR >> 8,
                        ST7_PEDR,
@@ -1697,15 +1761,15 @@ int rlink_init(void)
                        ST7_PEDR,
                        1,
                        ST7_PE_ADAPTER_SENSE_OUT
-       );
+);
 
        usb_bulk_read(
                pHDev, USB_EP1IN_ADDR,
-               reply_buffer, 1,
+               (char *)reply_buffer, 1,
                USB_TIMEOUT_MS
-       );
+);
 
-       if((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) != 0) {
+       if ((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) != 0) {
                LOG_WARNING("target detection problem\n");
        }
 
@@ -1719,41 +1783,57 @@ int rlink_init(void)
                        ST7_PEDR >> 8,
                        ST7_PEDR,
                        3,
-                       0x00,
-                       0x00,
-                       0x00
-       );
+                       0x00,   /* DR */
+                       0x00,   /* DDR */
+                       0x00    /* OR */
+);
 
        usb_bulk_read(
                pHDev, USB_EP1IN_ADDR,
-               reply_buffer, 1,
+               (char *)reply_buffer, 1,
                USB_TIMEOUT_MS
-       );
+);
 
 
-       if((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) == 0) {
+       if ((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) == 0) {
                LOG_WARNING("target not plugged in\n");
        }
 
-       /* float port A, make sure DTC is stopped, set upper 2 bits of port D, and set up port A */
+       /* float ports A and B */
        ep1_generic_commandl(
-               pHDev, 15,
+               pHDev, 11,
                EP1_CMD_MEMORY_WRITE,
                        ST7_PADDR >> 8,
                        ST7_PADDR,
                        2,
                        0x00,
                        0x00,
+               EP1_CMD_MEMORY_WRITE,
+                       ST7_PBDDR >> 8,
+                       ST7_PBDDR,
+                       1,
+                       0x00
+);
+
+       /* make sure DTC is stopped, set VPP control, set up ports A and B */
+       ep1_generic_commandl(
+               pHDev, 14,
                EP1_CMD_DTC_STOP,
-               EP1_CMD_SET_PORTD_UPPER,
-                       ~(ST7_PD_NRUN_LED),
+               EP1_CMD_SET_PORTD_VPP,
+                       ~(ST7_PD_VPP_SHDN),
                EP1_CMD_MEMORY_WRITE,
                        ST7_PADR >> 8,
                        ST7_PADR,
                        2,
-                       ((~(ST7_PA_NLINE_DRIVER_ENABLE)) & ST7_PA_NUNASSERTED),
-                       (ST7_PA_NLINE_DRIVER_ENABLE | ST7_PA_NRLINK_RST | ST7_PA_NJTAG_TRST)
-       );
+                       ((~(0)) & (ST7_PA_NTRST)),
+                       (ST7_PA_NTRST),
+       /* port B has no OR, and we want to emulate open drain on NSRST, so we set DR to 0 here and later assert NSRST by setting DDR bit to 1. */
+               EP1_CMD_MEMORY_WRITE,
+                       ST7_PBDR >> 8,
+                       ST7_PBDR,
+                       1,
+                       0x00
+);
 
        /* set LED updating mode and make sure they're unlit */
        ep1_generic_commandl(
@@ -1765,11 +1845,11 @@ int rlink_init(void)
 #endif
                EP1_CMD_SET_PORTD_LEDS,
                        ~0
-       );
+);
 
        tap_state_queue_init();
        dtc_queue_init();
-       rlink_speed(jtag_speed);
+       rlink_speed(jtag_get_speed());
        rlink_reset(0, 0);
 
        return ERROR_OK;
@@ -1786,9 +1866,9 @@ int rlink_quit(void)
                EP1_CMD_LEDUE_NONE,
                EP1_CMD_SET_PORTD_LEDS,
                        ~0,
-               EP1_CMD_SET_PORTD_UPPER,
+               EP1_CMD_SET_PORTD_VPP,
                        ~0
-       );
+);
 
        usb_release_interface(pHDev,0);
        usb_close(pHDev);
@@ -1798,7 +1878,7 @@ int rlink_quit(void)
 }
 
 
-jtag_interface_t rlink_interface =
+struct jtag_interface rlink_interface =
 {
        .name = "rlink",
        .init = rlink_init,

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)