+ if (type != SCAN_IN)
+ {
+ /* add complete bytes */
+ while (thisrun_bytes-- > 0)
+ {
+ BUFFER_ADD = buffer[cur_byte];
+ cur_byte++;
+ bits_left -= 8;
+ }
+ }
+ else /* (type == SCAN_IN) */
+ {
+ bits_left -= 8 * (thisrun_bytes);
+ }
+
+ if ( ( retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written) ) != ERROR_OK )
+ {
+ LOG_ERROR("couldn't write MPSSE commands to FT2232");
+ exit(-1);
+ }
+ LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);
+ ft2232_buffer_size = 0;
+
+ if (type != SCAN_OUT)
+ {
+ if ( ( retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read) ) != ERROR_OK )
+ {
+ LOG_ERROR("couldn't read from FT2232");
+ exit(-1);
+ }
+ LOG_DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);
+ receive_pointer += bytes_read;
+ }
+ }
+
+ thisrun_read = 0;
+
+ /* the most signifcant bit is scanned during TAP movement */
+ if (type != SCAN_IN)
+ last_bit = ( buffer[cur_byte] >> (bits_left - 1) ) & 0x1;
+ else
+ last_bit = 0;
+
+ /* process remaining bits but the last one */
+ if (bits_left > 1)
+ {
+ if (type == SCAN_IO)
+ {
+ /* Clock Data Bits In and Out LSB First */
+ BUFFER_ADD = 0x3b;
+ /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
+ }
+ else if (type == SCAN_OUT)
+ {
+ /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
+ BUFFER_ADD = 0x1b;
+ /* LOG_DEBUG("added TDI bits (o)"); */
+ }
+ else if (type == SCAN_IN)
+ {
+ /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
+ BUFFER_ADD = 0x2a;
+ /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
+ }
+ BUFFER_ADD = bits_left - 2;
+ if (type != SCAN_IN)
+ BUFFER_ADD = buffer[cur_byte];
+
+ if (type != SCAN_OUT)
+ thisrun_read += 2;
+ }
+
+ if (tap_get_end_state() == TAP_DRSHIFT)
+ {
+ if (type == SCAN_IO)
+ {
+ /* Clock Data Bits In and Out LSB First */
+ BUFFER_ADD = 0x3b;
+ /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
+ }
+ else if (type == SCAN_OUT)
+ {
+ /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
+ BUFFER_ADD = 0x1b;
+ /* LOG_DEBUG("added TDI bits (o)"); */
+ }
+ else if (type == SCAN_IN)
+ {
+ /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
+ BUFFER_ADD = 0x2a;
+ /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
+ }
+ BUFFER_ADD = 0x0;
+ BUFFER_ADD = last_bit;
+ }
+ else
+ {
+ /* move from Shift-IR/DR to end state */
+ if (type != SCAN_OUT)
+ {
+ /* Clock Data to TMS/CS Pin with Read */
+ BUFFER_ADD = 0x6b;
+ /* LOG_DEBUG("added TMS scan (read)"); */
+ }
+ else
+ {
+ /* Clock Data to TMS/CS Pin (no Read) */
+ BUFFER_ADD = 0x4b;
+ /* LOG_DEBUG("added TMS scan (no read)"); */
+ }
+ BUFFER_ADD = 0x6;
+ BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() ) | (last_bit << 7);
+ tap_set_state( tap_get_end_state() );
+ }
+
+ if (type != SCAN_OUT)
+ thisrun_read += 1;
+
+ if ( ( retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written) ) != ERROR_OK )
+ {
+ LOG_ERROR("couldn't write MPSSE commands to FT2232");
+ exit(-1);
+ }
+ LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);
+ ft2232_buffer_size = 0;
+
+ if (type != SCAN_OUT)
+ {
+ if ( ( retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read) ) != ERROR_OK )
+ {
+ LOG_ERROR("couldn't read from FT2232");
+ exit(-1);
+ }
+ LOG_DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);
+ receive_pointer += bytes_read;
+ }
+
+ return ERROR_OK;
+}
+
+
+static int ft2232_predict_scan_out(int scan_size, enum scan_type type)
+{
+ int predicted_size = 3;
+ int num_bytes = (scan_size - 1) / 8;
+
+ if (tap_get_state() != TAP_DRSHIFT)
+ predicted_size += 3;
+
+ if (type == SCAN_IN) /* only from device to host */
+ {
+ /* complete bytes */
+ predicted_size += CEIL(num_bytes, 65536) * 3;
+ /* remaining bits - 1 (up to 7) */
+ predicted_size += ( (scan_size - 1) % 8 ) ? 2 : 0;
+ }
+ else /* host to device, or bidirectional */
+ {
+ /* complete bytes */
+ predicted_size += num_bytes + CEIL(num_bytes, 65536) * 3;
+ /* remaining bits -1 (up to 7) */
+ predicted_size += ( (scan_size - 1) % 8 ) ? 3 : 0;
+ }
+
+ return predicted_size;
+}
+
+
+static int ft2232_predict_scan_in(int scan_size, enum scan_type type)
+{
+ int predicted_size = 0;
+
+ if (type != SCAN_OUT)
+ {
+ /* complete bytes */
+ predicted_size += (CEIL(scan_size, 8) > 1) ? (CEIL(scan_size, 8) - 1) : 0;
+
+ /* remaining bits - 1 */
+ predicted_size += ( (scan_size - 1) % 8 ) ? 1 : 0;
+
+ /* last bit (from TMS scan) */
+ predicted_size += 1;
+ }
+
+ /* LOG_DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size); */
+
+ return predicted_size;
+}
+
+
+static void usbjtag_reset(int trst, int srst)
+{
+ if (trst == 1)
+ {
+ if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+ low_direction |= nTRSTnOE; /* switch to output pin (output is low) */
+ else
+ low_output &= ~nTRST; /* switch output low */
+ }
+ else if (trst == 0)
+ {
+ if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+ low_direction &= ~nTRSTnOE; /* switch to input pin (high-Z + internal and external pullup) */
+ else
+ low_output |= nTRST; /* switch output high */
+ }
+
+ if (srst == 1)
+ {
+ if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+ low_output &= ~nSRST; /* switch output low */
+ else
+ low_direction |= nSRSTnOE; /* switch to output pin (output is low) */
+ }
+ else if (srst == 0)
+ {
+ if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+ low_output |= nSRST; /* switch output high */
+ else
+ low_direction &= ~nSRSTnOE; /* switch to input pin (high-Z) */
+ }
+
+ /* command "set data bits low byte" */
+ BUFFER_ADD = 0x80;
+ BUFFER_ADD = low_output;
+ BUFFER_ADD = low_direction;
+}
+
+
+static void jtagkey_reset(int trst, int srst)
+{
+ if (trst == 1)
+ {
+ if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+ high_output &= ~nTRSTnOE;
+ else
+ high_output &= ~nTRST;
+ }
+ else if (trst == 0)
+ {
+ if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+ high_output |= nTRSTnOE;
+ else
+ high_output |= nTRST;
+ }
+
+ if (srst == 1)
+ {