#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;
*usb_buffer_p++ = va_arg(ap, int);
length--;
}
-
+
memset(
usb_buffer_p,
0,
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)) {
break;
}
-
+
usb_ret = usb_bulk_read(
pHDev, USB_EP1IN_ADDR,
buffer, length,
if(usb_ret < length) {
break;
}
-
+
addr += length;
buffer += length;
count += length;
sizeof(usb_buffer) - 4 - length
);
- usb_ret = usb_bulk_write(
+ usb_ret = usb_bulk_write(
pHDev, USB_EP1OUT_ADDR,
(char *)usb_buffer, sizeof(usb_buffer),
USB_TIMEOUT_MS
if(usb_ret < sizeof(usb_buffer)) {
break;
}
-
+
addr += length;
buffer += length;
count += length;
LOG_ERROR("Malformed DTC image\n");
exit(1);
}
-
+
header = (struct header_s *)buffer;
buffer += sizeof(*header);
length -= sizeof(*header);
LOG_ERROR("Malformed DTC image\n");
exit(1);
}
-
+
switch(header->type) {
case DTCLOAD_COMMENT:
break;
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,
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
exit(1);
break;
}
-
+
buffer += (header->length + 1);
length -= (header->length + 1);
}
*/
static
int
-dtc_start_download(
-) {
+dtc_start_download(void) {
int usb_err;
u8 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,
usb_err = ep1_generic_commandl(
pHDev, 13,
-
+
EP1_CMD_MEMORY_WRITE, /* preinitialize poll byte */
DTC_STATUS_POLL_BYTE >> 8,
DTC_STATUS_POLL_BYTE,
static
int
-dtc_queue_init(
-) {
+dtc_queue_init(void) {
dtc_queue.rq_head = NULL;
dtc_queue.rq_tail = NULL;
dtc_queue.cmd_index = 0;
static
int
-dtc_queue_run(
-) {
+dtc_queue_run(void) {
dtc_reply_queue_entry_t *rq_p, *rq_next;
int retval;
int usb_err;
usb_err = dtc_run_download(pHDev,
dtc_queue.cmd_buffer, dtc_queue.cmd_index,
NULL, 0
- );
+ );
if(usb_err < 0) {
LOG_ERROR("dtc_run_download: %s\n", usb_strerror());
exit(1);
usb_err = dtc_run_download(pHDev,
dtc_queue.cmd_buffer, dtc_queue.cmd_index,
reply_buffer, dtc_queue.reply_index
- );
+ );
if(usb_err < 0) {
LOG_ERROR("dtc_run_download: %s\n", usb_strerror());
exit(1);
} else {
*tdo_p &=~ tdo_mask;
}
-
+
dtc_mask >>= 1;
if(dtc_mask == 0) {
dtc_p++;
tdo_p++;
tdo_mask = 1;
}
-
+
}
}
static
int
-tap_state_queue_init(
-) {
+tap_state_queue_init(void) {
tap_state_queue.length = 0;
tap_state_queue.buffer = 0;
return(0);
static
int
-tap_state_queue_run(
-) {
+tap_state_queue_run(void) {
int i;
int bits;
u8 byte;
bits = 1;
byte = 0;
for(i = tap_state_queue.length; i--;) {
-
+
byte <<= 1;
if(tap_state_queue.buffer & 1) {
byte |= 1;
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);
void rlink_state_move(void) {
int i=0, tms=0;
- u8 tms_scan = TAP_MOVE(cur_state, end_state);
+ u8 tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
for (i = 0; i < 7; i++)
{
tap_state_queue_append(tms);
}
- cur_state = end_state;
+ tap_set_state(tap_get_end_state());
}
static
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());
}
{
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();
/* 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();
}
u8 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);
+ }
+
+ 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(trst) {
- bitmap &= ~ST7_PA_NJTAG_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, 9,
+ EP1_CMD_MEMORY_WRITE,
+ ST7_PADR >> 8,
+ ST7_PADR,
+ 1,
+ 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_PA_NRLINK_RST;
+ 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_PADR >> 8,
- ST7_PADR,
+ ST7_PBDDR >> 8,
+ ST7_PBDDR,
1,
bitmap,
EP1_CMD_DTC_GET_CACHED_STATUS
);
if(usb_err < 0) {
- LOG_ERROR("%s: %s\n", __func__, usb_strerror());
+ LOG_ERROR("%s", usb_strerror());
exit(1);
}
usb_err = usb_bulk_read(
pHDev, USB_EP1IN_ADDR,
- &bitmap, 1,
+ (char *)&bitmap, 1,
USB_TIMEOUT_MS
);
if(usb_err < 1) {
- LOG_ERROR("%s: %s\n", __func__, usb_strerror());
+ LOG_ERROR("%s", usb_strerror());
exit(1);
}
}
int scan_size
) {
int ir_scan;
- enum tap_state saved_end_state;
+ tap_state_t saved_end_state;
int byte_bits;
int extra_bits;
int chunk_bits;
/* 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))
+ (ir_scan && (tap_get_state() == TAP_IRSHIFT))
)) {
- saved_end_state = end_state;
+ 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);
x = 0;
dtc_mask = 1 << (extra_bits - 1);
-
+
while(extra_bits--) {
if(*tdi_p & tdi_mask) {
x |= dtc_mask;
LOG_ERROR("enqueuing DTC reply entry: %s\n", strerror(errno));
exit(1);
}
-
+
tdi_bit_offset += chunk_bits;
}
if(type != SCAN_IN) {
x = 0;
dtc_mask = 1 << (8 - 1);
-
+
while(chunk_bits--) {
if(*tdi_p & tdi_mask) {
x |= dtc_mask;
}
-
+
dtc_mask >>= 1;
if(dtc_mask == 0) {
dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;
x = 0;
dtc_mask = 1 << (8 - 1);
}
-
+
tdi_mask <<= 1;
if(tdi_mask == 0) {
tdi_p++;
LOG_ERROR("enqueuing DTC reply entry: %s\n", strerror(errno));
exit(1);
}
-
+
tdi_bit_offset += extra_bits;
if(type == SCAN_IN) {
x = 0;
dtc_mask = 1 << (8 - 1);
-
+
while(extra_bits--) {
if(*tdi_p & tdi_mask) {
x |= dtc_mask;
}
-
+
dtc_mask >>= 1;
-
+
tdi_mask <<= 1;
if(tdi_mask == 0) {
tdi_p++;
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++;
/* 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);
}
#endif
if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_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;
LOG_ERROR("An error occurred while trying to load DTC code for speed \"%d\".\n", speed);
exit(1);
}
-
+
if(dtc_start_download() < 0) {
LOG_ERROR("%s, %d: starting DTC: %s",
__FILE__, __LINE__,
/* usb_set_configuration required under win32 */
usb_set_configuration(pHDev, dev->config[0].bConfigurationValue);
-
+
retries = 3;
do
{
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,
ST7_PEDR >> 8,
ST7_PEDR,
3,
- 0x00,
- 0x00,
- 0x00
+ 0x00, /* DR */
+ 0x00, /* DDR */
+ 0x00 /* OR */
);
usb_bulk_read(
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_CMD_LEDUE_NONE,
EP1_CMD_SET_PORTD_LEDS,
~0,
- EP1_CMD_SET_PORTD_UPPER,
+ EP1_CMD_SET_PORTD_VPP,
~0
);