You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ad...@apache.org on 2016/06/15 22:03:46 UTC
[03/51] [partial] incubator-mynewt-site git commit: Fixed broken
Quick Start link and added OpenOCD option for Arduino Primo debugging
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/jtag.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/jtag.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/jtag.c
new file mode 100755
index 0000000..9f45ea7
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/jtag.c
@@ -0,0 +1,723 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Martin Schmoelzer *
+ * <ma...@student.tuwien.ac.at> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "jtag.h"
+
+#include "io.h"
+#include "msgtypes.h"
+#include "common.h"
+
+#include <stdbool.h>
+
+/** Delay value for SCAN_IN operations with less than maximum TCK frequency */
+uint8_t delay_scan_in;
+
+/** Delay value for SCAN_OUT operations with less than maximum TCK frequency */
+uint8_t delay_scan_out;
+
+/** Delay value for SCAN_IO operations with less than maximum TCK frequency */
+uint8_t delay_scan_io;
+
+/** Delay value for CLOCK_TCK operations with less than maximum frequency */
+uint8_t delay_tck;
+
+/** Delay value for CLOCK_TMS operations with less than maximum frequency */
+uint8_t delay_tms;
+
+/**
+ * Perform JTAG SCAN-IN operation at maximum TCK frequency.
+ *
+ * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
+ * stored in the EP2 IN buffer.
+ *
+ * Maximum achievable TCK frequency is 182 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param out_offset offset in OUT2BUF where payload data starts
+ */
+void jtag_scan_in(uint8_t out_offset, uint8_t in_offset)
+{
+ uint8_t scan_size_bytes, bits_last_byte;
+ uint8_t tms_count_start, tms_count_end;
+ uint8_t tms_sequence_start, tms_sequence_end;
+ uint8_t tdo_data, i, j;
+
+ uint8_t outb_buffer;
+
+ /* Get parameters from OUT2BUF */
+ scan_size_bytes = OUT2BUF[out_offset];
+ bits_last_byte = OUT2BUF[out_offset + 1];
+ tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
+ tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
+ tms_sequence_start = OUT2BUF[out_offset + 3];
+ tms_sequence_end = OUT2BUF[out_offset + 4];
+
+ if (tms_count_start > 0)
+ jtag_clock_tms(tms_count_start, tms_sequence_start);
+
+ outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
+
+ /* Shift all bytes except the last byte */
+ for (i = 0; i < scan_size_bytes - 1; i++) {
+ tdo_data = 0;
+
+ for (j = 0; j < 8; j++) {
+ OUTB = outb_buffer; /* TCK changes here */
+ tdo_data = tdo_data >> 1;
+ OUTB = (outb_buffer | PIN_TCK);
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+ }
+
+ tdo_data = 0;
+
+ /* Shift the last byte */
+ for (j = 0; j < bits_last_byte; j++) {
+ /* Assert TMS signal if requested and this is the last bit */
+ if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
+ outb_buffer |= PIN_TMS;
+ tms_count_end--;
+ tms_sequence_end = tms_sequence_end >> 1;
+ }
+
+ OUTB = outb_buffer; /* TCK changes here */
+ tdo_data = tdo_data >> 1;
+ OUTB = (outb_buffer | PIN_TCK);
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+ tdo_data = tdo_data >> (8 - bits_last_byte);
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+
+ /* Move to correct end state */
+ if (tms_count_end > 0)
+ jtag_clock_tms(tms_count_end, tms_sequence_end);
+}
+
+/**
+ * Perform JTAG SCAN-IN operation at variable TCK frequency.
+ *
+ * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
+ * stored in the EP2 IN buffer.
+ *
+ * Maximum achievable TCK frequency is 113 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param out_offset offset in OUT2BUF where payload data starts
+ */
+void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset)
+{
+ uint8_t scan_size_bytes, bits_last_byte;
+ uint8_t tms_count_start, tms_count_end;
+ uint8_t tms_sequence_start, tms_sequence_end;
+ uint8_t tdo_data, i, j, k;
+
+ uint8_t outb_buffer;
+
+ /* Get parameters from OUT2BUF */
+ scan_size_bytes = OUT2BUF[out_offset];
+ bits_last_byte = OUT2BUF[out_offset + 1];
+ tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
+ tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
+ tms_sequence_start = OUT2BUF[out_offset + 3];
+ tms_sequence_end = OUT2BUF[out_offset + 4];
+
+ if (tms_count_start > 0)
+ jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
+
+ outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
+
+ /* Shift all bytes except the last byte */
+ for (i = 0; i < scan_size_bytes - 1; i++) {
+ tdo_data = 0;
+
+ for (j = 0; j < 8; j++) {
+ OUTB = outb_buffer; /* TCK changes here */
+ for (k = 0; k < delay_scan_in; k++)
+ ;
+ tdo_data = tdo_data >> 1;
+
+ OUTB = (outb_buffer | PIN_TCK);
+ for (k = 0; k < delay_scan_in; k++)
+ ;
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+ }
+
+ tdo_data = 0;
+
+ /* Shift the last byte */
+ for (j = 0; j < bits_last_byte; j++) {
+ /* Assert TMS signal if requested and this is the last bit */
+ if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
+ outb_buffer |= PIN_TMS;
+ tms_count_end--;
+ tms_sequence_end = tms_sequence_end >> 1;
+ }
+
+ OUTB = outb_buffer; /* TCK changes here */
+ for (k = 0; k < delay_scan_in; k++)
+ ;
+ tdo_data = tdo_data >> 1;
+
+ OUTB = (outb_buffer | PIN_TCK);
+ for (k = 0; k < delay_scan_in; k++)
+ ;
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+ tdo_data = tdo_data >> (8 - bits_last_byte);
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+
+ /* Move to correct end state */
+ if (tms_count_end > 0)
+ jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
+}
+
+/**
+ * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
+ *
+ * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
+ * data is not sampled.
+ * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
+ *
+ * Maximum achievable TCK frequency is 142 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param out_offset offset in OUT2BUF where payload data starts
+ */
+void jtag_scan_out(uint8_t out_offset)
+{
+ uint8_t scan_size_bytes, bits_last_byte;
+ uint8_t tms_count_start, tms_count_end;
+ uint8_t tms_sequence_start, tms_sequence_end;
+ uint8_t tdi_data, i, j;
+
+ uint8_t outb_buffer;
+
+ /* Get parameters from OUT2BUF */
+ scan_size_bytes = OUT2BUF[out_offset];
+ bits_last_byte = OUT2BUF[out_offset + 1];
+ tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
+ tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
+ tms_sequence_start = OUT2BUF[out_offset + 3];
+ tms_sequence_end = OUT2BUF[out_offset + 4];
+
+ if (tms_count_start > 0)
+ jtag_clock_tms(tms_count_start, tms_sequence_start);
+
+ outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
+
+ /* Shift all bytes except the last byte */
+ for (i = 0; i < scan_size_bytes - 1; i++) {
+ tdi_data = OUT2BUF[i + out_offset + 5];
+
+ for (j = 0; j < 8; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ tdi_data = tdi_data >> 1;
+ OUTB = (outb_buffer | PIN_TCK);
+ }
+ }
+
+ tdi_data = OUT2BUF[i + out_offset + 5];
+
+ /* Shift the last byte */
+ for (j = 0; j < bits_last_byte; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ /* Assert TMS signal if requested and this is the last bit */
+ if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
+ outb_buffer |= PIN_TMS;
+ tms_count_end--;
+ tms_sequence_end = tms_sequence_end >> 1;
+ }
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ tdi_data = tdi_data >> 1;
+ OUTB = (outb_buffer | PIN_TCK);
+ }
+
+ /* Move to correct end state */
+ if (tms_count_end > 0)
+ jtag_clock_tms(tms_count_end, tms_sequence_end);
+}
+
+/**
+ * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
+ *
+ * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
+ * data is not sampled.
+ * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
+ *
+ * Maximum achievable TCK frequency is 97 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param out_offset offset in OUT2BUF where payload data starts
+ */
+void jtag_slow_scan_out(uint8_t out_offset)
+{
+ uint8_t scan_size_bytes, bits_last_byte;
+ uint8_t tms_count_start, tms_count_end;
+ uint8_t tms_sequence_start, tms_sequence_end;
+ uint8_t tdi_data, i, j, k;
+
+ uint8_t outb_buffer;
+
+ /* Get parameters from OUT2BUF */
+ scan_size_bytes = OUT2BUF[out_offset];
+ bits_last_byte = OUT2BUF[out_offset + 1];
+ tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
+ tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
+ tms_sequence_start = OUT2BUF[out_offset + 3];
+ tms_sequence_end = OUT2BUF[out_offset + 4];
+
+ if (tms_count_start > 0)
+ jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
+
+ outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
+
+ /* Shift all bytes except the last byte */
+ for (i = 0; i < scan_size_bytes - 1; i++) {
+ tdi_data = OUT2BUF[i + out_offset + 5];
+
+ for (j = 0; j < 8; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ for (k = 0; k < delay_scan_out; k++)
+ ;
+ tdi_data = tdi_data >> 1;
+
+ OUTB = (outb_buffer | PIN_TCK);
+ for (k = 0; k < delay_scan_out; k++)
+ ;
+ }
+ }
+
+ tdi_data = OUT2BUF[i + out_offset + 5];
+
+ /* Shift the last byte */
+ for (j = 0; j < bits_last_byte; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ /* Assert TMS signal if requested and this is the last bit */
+ if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
+ outb_buffer |= PIN_TMS;
+ tms_count_end--;
+ tms_sequence_end = tms_sequence_end >> 1;
+ }
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ for (k = 0; k < delay_scan_out; k++)
+ ;
+ tdi_data = tdi_data >> 1;
+
+ OUTB = (outb_buffer | PIN_TCK);
+ for (k = 0; k < delay_scan_out; k++)
+ ;
+ }
+
+ /* Move to correct end state */
+ if (tms_count_end > 0)
+ jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
+}
+
+/**
+ * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
+ *
+ * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
+ * data is sampled and stored in the EP2 IN buffer.
+ * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
+ *
+ * Maximum achievable TCK frequency is 100 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param out_offset offset in OUT2BUF where payload data starts
+ */
+void jtag_scan_io(uint8_t out_offset, uint8_t in_offset)
+{
+ uint8_t scan_size_bytes, bits_last_byte;
+ uint8_t tms_count_start, tms_count_end;
+ uint8_t tms_sequence_start, tms_sequence_end;
+ uint8_t tdi_data, tdo_data, i, j;
+
+ uint8_t outb_buffer;
+
+ /* Get parameters from OUT2BUF */
+ scan_size_bytes = OUT2BUF[out_offset];
+ bits_last_byte = OUT2BUF[out_offset + 1];
+ tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
+ tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
+ tms_sequence_start = OUT2BUF[out_offset + 3];
+ tms_sequence_end = OUT2BUF[out_offset + 4];
+
+ if (tms_count_start > 0)
+ jtag_clock_tms(tms_count_start, tms_sequence_start);
+
+ outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
+
+ /* Shift all bytes except the last byte */
+ for (i = 0; i < scan_size_bytes - 1; i++) {
+ tdi_data = OUT2BUF[i + out_offset + 5];
+ tdo_data = 0;
+
+ for (j = 0; j < 8; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ tdi_data = tdi_data >> 1;
+ OUTB = (outb_buffer | PIN_TCK);
+ tdo_data = tdo_data >> 1;
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+ }
+
+ tdi_data = OUT2BUF[i + out_offset + 5];
+ tdo_data = 0;
+
+ /* Shift the last byte */
+ for (j = 0; j < bits_last_byte; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ /* Assert TMS signal if requested and this is the last bit */
+ if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
+ outb_buffer |= PIN_TMS;
+ tms_count_end--;
+ tms_sequence_end = tms_sequence_end >> 1;
+ }
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ tdi_data = tdi_data >> 1;
+ OUTB = (outb_buffer | PIN_TCK);
+ tdo_data = tdo_data >> 1;
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+ tdo_data = tdo_data >> (8 - bits_last_byte);
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+
+ /* Move to correct end state */
+ if (tms_count_end > 0)
+ jtag_clock_tms(tms_count_end, tms_sequence_end);
+}
+
+/**
+ * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
+ *
+ * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
+ * data is sampled and stored in the EP2 IN buffer.
+ * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
+ *
+ * Maximum achievable TCK frequency is 78 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param out_offset offset in OUT2BUF where payload data starts
+ */
+void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset)
+{
+ uint8_t scan_size_bytes, bits_last_byte;
+ uint8_t tms_count_start, tms_count_end;
+ uint8_t tms_sequence_start, tms_sequence_end;
+ uint8_t tdi_data, tdo_data, i, j, k;
+
+ uint8_t outb_buffer;
+
+ /* Get parameters from OUT2BUF */
+ scan_size_bytes = OUT2BUF[out_offset];
+ bits_last_byte = OUT2BUF[out_offset + 1];
+ tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
+ tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
+ tms_sequence_start = OUT2BUF[out_offset + 3];
+ tms_sequence_end = OUT2BUF[out_offset + 4];
+
+ if (tms_count_start > 0)
+ jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
+
+ outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
+
+ /* Shift all bytes except the last byte */
+ for (i = 0; i < scan_size_bytes - 1; i++) {
+ tdi_data = OUT2BUF[i + out_offset + 5];
+ tdo_data = 0;
+
+ for (j = 0; j < 8; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ for (k = 0; k < delay_scan_io; k++)
+ ;
+ tdi_data = tdi_data >> 1;
+
+ OUTB = (outb_buffer | PIN_TCK);
+ for (k = 0; k < delay_scan_io; k++)
+ ;
+ tdo_data = tdo_data >> 1;
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+ }
+
+ tdi_data = OUT2BUF[i + out_offset + 5];
+ tdo_data = 0;
+
+ /* Shift the last byte */
+ for (j = 0; j < bits_last_byte; j++) {
+ if (tdi_data & 0x01)
+ outb_buffer |= PIN_TDI;
+ else
+ outb_buffer &= ~PIN_TDI;
+
+ /* Assert TMS signal if requested and this is the last bit */
+ if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
+ outb_buffer |= PIN_TMS;
+ tms_count_end--;
+ tms_sequence_end = tms_sequence_end >> 1;
+ }
+
+ OUTB = outb_buffer; /* TDI and TCK change here */
+ for (k = 0; k < delay_scan_io; k++)
+ ;
+ tdi_data = tdi_data >> 1;
+
+ OUTB = (outb_buffer | PIN_TCK);
+ for (k = 0; k < delay_scan_io; k++)
+ ;
+ tdo_data = tdo_data >> 1;
+
+ if (GET_TDO())
+ tdo_data |= 0x80;
+ }
+ tdo_data = tdo_data >> (8 - bits_last_byte);
+
+ /* Copy TDO data to IN2BUF */
+ IN2BUF[i + in_offset] = tdo_data;
+
+ /* Move to correct end state */
+ if (tms_count_end > 0)
+ jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
+}
+
+/**
+ * Generate TCK clock cycles.
+ *
+ * Maximum achievable TCK frequency is 375 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param count number of TCK clock cyclces to generate.
+ */
+void jtag_clock_tck(uint16_t count)
+{
+ uint16_t i;
+ uint8_t outb_buffer = OUTB & ~(PIN_TCK);
+
+ for (i = 0; i < count; i++) {
+ OUTB = outb_buffer;
+ OUTB = outb_buffer | PIN_TCK;
+ }
+}
+
+/**
+ * Generate TCK clock cycles at variable frequency.
+ *
+ * Maximum achieveable TCK frequency is 166.6 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param count number of TCK clock cyclces to generate.
+ */
+void jtag_slow_clock_tck(uint16_t count)
+{
+ uint16_t i;
+ uint8_t j;
+ uint8_t outb_buffer = OUTB & ~(PIN_TCK);
+
+ for (i = 0; i < count; i++) {
+ OUTB = outb_buffer;
+ for (j = 0; j < delay_tck; j++)
+ ;
+ OUTB = outb_buffer | PIN_TCK;
+ for (j = 0; j < delay_tck; j++)
+ ;
+ }
+}
+
+/**
+ * Perform TAP FSM state transitions at maximum TCK frequency.
+ *
+ * Maximum achievable TCK frequency is 176 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param count the number of state transitions to perform.
+ * @param sequence the TMS pin levels for each state transition, starting with
+ * the least-significant bit.
+ */
+void jtag_clock_tms(uint8_t count, uint8_t sequence)
+{
+ uint8_t outb_buffer = OUTB & ~(PIN_TCK);
+ uint8_t i;
+
+ for (i = 0; i < count; i++) {
+ /* Set TMS pin according to sequence parameter */
+ if (sequence & 0x1)
+ outb_buffer |= PIN_TMS;
+ else
+ outb_buffer &= ~PIN_TMS;
+
+ OUTB = outb_buffer;
+ sequence = sequence >> 1;
+ OUTB = outb_buffer | PIN_TCK;
+ }
+}
+
+/**
+ * Perform TAP-FSM state transitions at less than maximum TCK frequency.
+ *
+ * Maximum achievable TCK frequency is 117 kHz for ULINK clocked at 24 MHz.
+ *
+ * @param count the number of state transitions to perform.
+ * @param sequence the TMS pin levels for each state transition, starting with
+ * the least-significant bit.
+ */
+void jtag_slow_clock_tms(uint8_t count, uint8_t sequence)
+{
+ uint8_t outb_buffer = OUTB & ~(PIN_TCK);
+ uint8_t i, j;
+
+ for (i = 0; i < count; i++) {
+ /* Set TMS pin according to sequence parameter */
+ if (sequence & 0x1)
+ outb_buffer |= PIN_TMS;
+ else
+ outb_buffer &= ~PIN_TMS;
+
+ OUTB = outb_buffer;
+ for (j = 0; j < delay_tms; j++)
+ ;
+ sequence = sequence >> 1;
+ OUTB = outb_buffer | PIN_TCK;
+ for (j = 0; j < delay_tms; j++)
+ ;
+ }
+}
+
+/**
+ * Get current JTAG signal states.
+ *
+ * @return a 16-bit integer where the most-significant byte contains the state
+ * of the JTAG input signals and the least-significant byte contains the state
+ * of the JTAG output signals.
+ */
+uint16_t jtag_get_signals(void)
+{
+ uint8_t input_signal_state, output_signal_state;
+
+ input_signal_state = 0;
+ output_signal_state = 0;
+
+ /* Get states of input pins */
+ if (GET_TDO())
+ input_signal_state |= SIGNAL_TDO;
+ if (GET_BRKOUT())
+ input_signal_state |= SIGNAL_BRKOUT;
+ if (GET_TRAP())
+ input_signal_state |= SIGNAL_TRAP;
+ if (GET_RTCK()) {
+ /* Using RTCK this way would be extremely slow,
+ * implemented only for the sake of completeness */
+ input_signal_state |= SIGNAL_RTCK;
+ }
+
+ /* Get states of output pins */
+ output_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT;
+
+ return ((uint16_t)input_signal_state << 8) | ((uint16_t)output_signal_state);
+}
+
+/**
+ * Set state of JTAG output signals.
+ *
+ * @param low signals which should be de-asserted.
+ * @param high signals which should be asserted.
+ */
+void jtag_set_signals(uint8_t low, uint8_t high)
+{
+ OUTB &= ~(low & MASK_PORTB_DIRECTION_OUT);
+ OUTB |= (high & MASK_PORTB_DIRECTION_OUT);
+}
+
+/**
+ * Configure TCK delay parameters.
+ *
+ * @param scan_in number of delay cycles in scan_in operations.
+ * @param scan_out number of delay cycles in scan_out operations.
+ * @param scan_io number of delay cycles in scan_io operations.
+ * @param tck number of delay cycles in clock_tck operations.
+ * @param tms number of delay cycles in clock_tms operations.
+ */
+void jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out,
+ uint8_t scan_io, uint8_t tck, uint8_t tms)
+{
+ delay_scan_in = scan_in;
+ delay_scan_out = scan_out;
+ delay_scan_io = scan_io;
+ delay_tck = tck;
+ delay_tms = tms;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/main.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/main.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/main.c
new file mode 100755
index 0000000..e4865f8
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/main.c
@@ -0,0 +1,91 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Martin Schmoelzer *
+ * <ma...@student.tuwien.ac.at> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "main.h"
+
+#include "io.h"
+#include "usb.h"
+#include "protocol.h"
+
+extern void sudav_isr(void) __interrupt SUDAV_ISR;
+extern void sof_isr(void) __interrupt;
+extern void sutok_isr(void) __interrupt;
+extern void suspend_isr(void) __interrupt;
+extern void usbreset_isr(void) __interrupt;
+extern void ibn_isr(void) __interrupt;
+extern void ep0in_isr(void) __interrupt;
+extern void ep0out_isr(void) __interrupt;
+extern void ep1in_isr(void) __interrupt;
+extern void ep1out_isr(void) __interrupt;
+extern void ep2in_isr(void) __interrupt;
+extern void ep2out_isr(void) __interrupt;
+extern void ep3in_isr(void) __interrupt;
+extern void ep3out_isr(void) __interrupt;
+extern void ep4in_isr(void) __interrupt;
+extern void ep4out_isr(void) __interrupt;
+extern void ep5in_isr(void) __interrupt;
+extern void ep5out_isr(void) __interrupt;
+extern void ep6in_isr(void) __interrupt;
+extern void ep6out_isr(void) __interrupt;
+extern void ep7in_isr(void) __interrupt;
+extern void ep7out_isr(void) __interrupt;
+
+void io_init(void)
+{
+ /* PORTxCFG register bits select alternate functions (1 == alternate function,
+ * 0 == standard I/O)
+ * OEx register bits turn on/off output buffer (1 == output, 0 == input)
+ * OUTx register bits determine pin state of output
+ * PINx register bits reflect pin state (high == 1, low == 0) */
+
+ /* PORT A */
+ PORTACFG = PIN_OE;
+ OEA = PIN_U_OE | PIN_OE | PIN_RUN_LED | PIN_COM_LED;
+ OUTA = PIN_RUN_LED | PIN_COM_LED;
+
+ /* PORT B */
+ PORTBCFG = 0x00;
+ OEB = PIN_TDI | PIN_TMS | PIN_TCK | PIN_TRST | PIN_BRKIN | PIN_RESET
+ | PIN_OCDSE;
+
+ /* TRST and RESET signals are low-active but inverted by hardware, so we clear
+ * these signals here! */
+ OUTB = 0x00;
+
+ /* PORT C */
+ PORTCCFG = PIN_WR;
+ OEC = PIN_TXD0 | PIN_WR;
+ OUTC = 0x00;
+}
+
+int main(void)
+{
+ io_init();
+ usb_init();
+
+ /* Enable Interrupts */
+ EA = 1;
+
+ /* Begin executing command(s). This function never returns. */
+ command_loop();
+
+ /* Never reached, but SDCC complains about missing return statement */
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/protocol.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/protocol.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/protocol.c
new file mode 100755
index 0000000..5f7f984
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/protocol.c
@@ -0,0 +1,240 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Martin Schmoelzer *
+ * <ma...@student.tuwien.ac.at> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "protocol.h"
+#include "jtag.h"
+#include "delay.h"
+#include "usb.h"
+#include "io.h"
+#include "msgtypes.h"
+
+#include "reg_ezusb.h"
+
+/**
+ * @file
+ * Implementation of the OpenULINK communication protocol.
+ *
+ * The OpenULINK protocol uses one OUT and one IN endpoint. These two endpoints
+ * are configured to use the maximum packet size for full-speed transfers,
+ * 64 bytes. Commands always start with a command ID (see msgtypes.h for
+ * command ID definitions) and contain zero or more payload data bytes in both
+ * transfer directions (IN and OUT). The payload
+ *
+ * Almost all commands contain a fixed number of payload data bytes. The number
+ * of payload data bytes for the IN and OUT direction does not need to be the
+ * same.
+ *
+ * Multiple commands may be sent in one EP2 Bulk-OUT packet. Because the
+ * OpenULINK firmware does not perform bounds checking for EP2 Bulk-IN packets,
+ * the host MUST ensure that the commands sent in the OUT packet require a
+ * maximum of 64 bytes of IN data.
+ */
+
+/** Index in EP2 Bulk-OUT data buffer that contains the current command ID */
+volatile uint8_t cmd_id_index;
+
+/** Number of data bytes already in EP2 Bulk-IN buffer */
+volatile uint8_t payload_index_in;
+
+/**
+ * Execute a SET_LEDS command.
+ */
+void execute_set_led_command(void)
+{
+ uint8_t led_state = OUT2BUF[cmd_id_index + 1];
+
+ if (led_state & RUN_LED_ON)
+ SET_RUN_LED();
+
+ if (led_state & COM_LED_ON)
+ SET_COM_LED();
+
+ if (led_state & RUN_LED_OFF)
+ CLEAR_RUN_LED();
+
+ if (led_state & COM_LED_OFF)
+ CLEAR_COM_LED();
+}
+
+/**
+ * Executes one command and updates global command indexes.
+ *
+ * @return true if this command was the last command.
+ * @return false if there are more commands within the current contents of the
+ * Bulk EP2-OUT data buffer.
+ */
+bool execute_command(void)
+{
+ uint8_t usb_out_bytecount, usb_in_bytecount;
+ uint16_t signal_state;
+ uint16_t count;
+
+ /* Most commands do not transfer IN data. To save code space, we write 0 to
+ * usb_in_bytecount here, then modify it in the switch statement below where
+ * neccessary */
+ usb_in_bytecount = 0;
+
+ switch (OUT2BUF[cmd_id_index] /* Command ID */) {
+ case CMD_SCAN_IN:
+ usb_out_bytecount = 5;
+ usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
+ jtag_scan_in(cmd_id_index + 1, payload_index_in);
+ break;
+ case CMD_SCAN_OUT:
+ usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5;
+ jtag_scan_out(cmd_id_index + 1);
+ break;
+ case CMD_SCAN_IO:
+ usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
+ usb_out_bytecount = usb_in_bytecount + 5;
+ jtag_scan_io(cmd_id_index + 1, payload_index_in);
+ break;
+ case CMD_CLOCK_TMS:
+ usb_out_bytecount = 2;
+ jtag_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
+ break;
+ case CMD_CLOCK_TCK:
+ usb_out_bytecount = 2;
+ count = (uint16_t)OUT2BUF[cmd_id_index + 1];
+ count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
+ jtag_clock_tck(count);
+ break;
+ case CMD_SLOW_SCAN_IN:
+ usb_out_bytecount = 5;
+ usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
+ jtag_slow_scan_in(cmd_id_index + 1, payload_index_in);
+ break;
+ case CMD_SLOW_SCAN_OUT:
+ usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5;
+ jtag_slow_scan_out(cmd_id_index + 1);
+ break;
+ case CMD_SLOW_SCAN_IO:
+ usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
+ usb_out_bytecount = usb_in_bytecount + 5;
+ jtag_slow_scan_io(cmd_id_index + 1, payload_index_in);
+ break;
+ case CMD_SLOW_CLOCK_TMS:
+ usb_out_bytecount = 2;
+ jtag_slow_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
+ break;
+ case CMD_SLOW_CLOCK_TCK:
+ usb_out_bytecount = 2;
+ count = (uint16_t)OUT2BUF[cmd_id_index + 1];
+ count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
+ jtag_slow_clock_tck(count);
+ break;
+ case CMD_SLEEP_US:
+ usb_out_bytecount = 2;
+ count = (uint16_t)OUT2BUF[cmd_id_index + 1];
+ count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
+ delay_us(count);
+ break;
+ case CMD_SLEEP_MS:
+ usb_out_bytecount = 2;
+ count = (uint16_t)OUT2BUF[cmd_id_index + 1];
+ count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
+ delay_ms(count);
+ break;
+ case CMD_GET_SIGNALS:
+ usb_out_bytecount = 0;
+ usb_in_bytecount = 2;
+ signal_state = jtag_get_signals();
+ IN2BUF[payload_index_in] = (signal_state >> 8) & 0x00FF;
+ IN2BUF[payload_index_in + 1] = signal_state & 0x00FF;
+ break;
+ case CMD_SET_SIGNALS:
+ usb_out_bytecount = 2;
+ jtag_set_signals(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
+ break;
+ case CMD_CONFIGURE_TCK_FREQ:
+ usb_out_bytecount = 5;
+ jtag_configure_tck_delay(
+ OUT2BUF[cmd_id_index + 1], /* scan_in */
+ OUT2BUF[cmd_id_index + 2], /* scan_out */
+ OUT2BUF[cmd_id_index + 3], /* scan_io */
+ OUT2BUF[cmd_id_index + 4], /* clock_tck */
+ OUT2BUF[cmd_id_index + 5]); /* clock_tms */
+ break;
+ case CMD_SET_LEDS:
+ usb_out_bytecount = 1;
+ execute_set_led_command();
+ break;
+ case CMD_TEST:
+ usb_out_bytecount = 1;
+ /* Do nothing... This command is only used to test if the device is ready
+ * to accept new commands */
+ break;
+ default:
+ /* Should never be reached */
+ usb_out_bytecount = 0;
+ break;
+ }
+
+ /* Update EP2 Bulk-IN data byte count */
+ payload_index_in += usb_in_bytecount;
+
+ /* Determine if this was the last command */
+ if ((cmd_id_index + usb_out_bytecount + 1) >= OUT2BC)
+ return true;
+ else {
+ /* Not the last command, update cmd_id_index */
+ cmd_id_index += (usb_out_bytecount + 1);
+ return false;
+ }
+}
+
+/**
+ * Forever wait for commands and execute them as they arrive.
+ */
+void command_loop(void)
+{
+ bool last_command;
+
+ while (1) {
+ cmd_id_index = 0;
+ payload_index_in = 0;
+
+ /* Wait until host sends EP2 Bulk-OUT packet */
+ while (!EP2_out)
+ ;
+ EP2_out = 0;
+
+ /* Turn on COM LED to indicate command execution */
+ SET_COM_LED();
+
+ /* Execute the commands */
+ last_command = false;
+ while (last_command == false)
+ last_command = execute_command();
+
+ CLEAR_COM_LED();
+
+ /* Send back EP2 Bulk-IN packet if required */
+ if (payload_index_in > 0) {
+ IN2BC = payload_index_in;
+ while (!EP2_in)
+ ;
+ EP2_in = 0;
+ }
+
+ /* Re-arm EP2-OUT after command execution */
+ OUT2BC = 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/usb.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/usb.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/usb.c
new file mode 100755
index 0000000..98ae67f
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/src/usb.c
@@ -0,0 +1,564 @@
+/***************************************************************************
+ * Copyright (C) 2011-2013 by Martin Schmoelzer *
+ * <ma...@student.tuwien.ac.at> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+/**
+ * @file
+ * Defines USB descriptors, interrupt routines and helper functions.
+ * To minimize code size, we make the following assumptions:
+ * - The OpenULINK has exactly one configuration
+ * - and exactly one alternate setting
+ *
+ * Therefore, we do not have to support the Set Configuration USB request.
+ */
+
+#include "usb.h"
+#include "delay.h"
+#include "io.h"
+
+/* Also update external declarations in "include/usb.h" if making changes to
+ * these variables! */
+volatile bool EP2_out;
+volatile bool EP2_in;
+
+volatile __xdata __at 0x7FE8 struct setup_data setup_data;
+
+/* Define number of endpoints (except Control Endpoint 0) in a central place.
+ * Be sure to include the neccessary endpoint descriptors! */
+#define NUM_ENDPOINTS 2
+
+__code struct usb_device_descriptor device_descriptor = {
+ .bLength = sizeof(struct usb_device_descriptor),
+ .bDescriptorType = DESCRIPTOR_TYPE_DEVICE,
+ .bcdUSB = 0x0110, /* BCD: 01.00 (Version 1.0 USB spec) */
+ .bDeviceClass = 0xFF, /* 0xFF = vendor-specific */
+ .bDeviceSubClass = 0xFF,
+ .bDeviceProtocol = 0xFF,
+ .bMaxPacketSize0 = 64,
+ .idVendor = 0xC251,
+ .idProduct = 0x2710,
+ .bcdDevice = 0x0100,
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .iSerialNumber = 3,
+ .bNumConfigurations = 1
+};
+
+/* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */
+
+__code struct usb_config_descriptor config_descriptor = {
+ .bLength = sizeof(struct usb_config_descriptor),
+ .bDescriptorType = DESCRIPTOR_TYPE_CONFIGURATION,
+ .wTotalLength = sizeof(struct usb_config_descriptor) +
+ sizeof(struct usb_interface_descriptor) +
+ (NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)),
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 1,
+ .iConfiguration = 4, /* String describing this configuration */
+ .bmAttributes = 0x80, /* Only MSB set according to USB spec */
+ .MaxPower = 50 /* 100 mA */
+};
+
+__code struct usb_interface_descriptor interface_descriptor00 = {
+ .bLength = sizeof(struct usb_interface_descriptor),
+ .bDescriptorType = DESCRIPTOR_TYPE_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = NUM_ENDPOINTS,
+ .bInterfaceClass = 0xFF,
+ .bInterfaceSubclass = 0xFF,
+ .bInterfaceProtocol = 0xFF,
+ .iInterface = 0
+};
+
+__code struct usb_endpoint_descriptor Bulk_EP2_IN_Endpoint_Descriptor = {
+ .bLength = sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = 0x05,
+ .bEndpointAddress = (2 | USB_DIR_IN),
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = 64,
+ .bInterval = 0
+};
+
+__code struct usb_endpoint_descriptor Bulk_EP2_OUT_Endpoint_Descriptor = {
+ .bLength = sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = 0x05,
+ .bEndpointAddress = (2 | USB_DIR_OUT),
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = 64,
+ .bInterval = 0
+};
+
+__code struct usb_language_descriptor language_descriptor = {
+ .bLength = 4,
+ .bDescriptorType = DESCRIPTOR_TYPE_STRING,
+ .wLANGID = {0x0409 /* US English */}
+};
+
+__code struct usb_string_descriptor strManufacturer =
+ STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
+
+__code struct usb_string_descriptor strProduct =
+ STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
+
+__code struct usb_string_descriptor strSerialNumber =
+ STR_DESCR(6, '0', '0', '0', '0', '0', '1');
+
+__code struct usb_string_descriptor strConfigDescr =
+ STR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r');
+
+/* Table containing pointers to string descriptors */
+__code struct usb_string_descriptor *__code en_string_descriptors[4] = {
+ &strManufacturer,
+ &strProduct,
+ &strSerialNumber,
+ &strConfigDescr
+};
+
+void sudav_isr(void) __interrupt SUDAV_ISR
+{
+ CLEAR_IRQ();
+
+ usb_handle_setup_data();
+
+ USBIRQ = SUDAVIR;
+ EP0CS |= HSNAK;
+}
+
+void sof_isr(void) __interrupt SOF_ISR
+{
+}
+void sutok_isr(void) __interrupt SUTOK_ISR
+{
+}
+void suspend_isr(void) __interrupt SUSPEND_ISR
+{
+}
+void usbreset_isr(void) __interrupt USBRESET_ISR
+{
+}
+void ibn_isr(void) __interrupt IBN_ISR
+{
+}
+
+void ep0in_isr(void) __interrupt EP0IN_ISR
+{
+}
+void ep0out_isr(void) __interrupt EP0OUT_ISR
+{
+}
+void ep1in_isr(void) __interrupt EP1IN_ISR
+{
+}
+void ep1out_isr(void) __interrupt EP1OUT_ISR
+{
+}
+
+/**
+ * EP2 IN: called after the transfer from uC->Host has finished: we sent data
+ */
+void ep2in_isr(void) __interrupt EP2IN_ISR
+{
+ EP2_in = 1;
+
+ CLEAR_IRQ();
+ IN07IRQ = IN2IR;/* Clear OUT2 IRQ */
+}
+
+/**
+ * EP2 OUT: called after the transfer from Host->uC has finished: we got data
+ */
+void ep2out_isr(void) __interrupt EP2OUT_ISR
+{
+ EP2_out = 1;
+
+ CLEAR_IRQ();
+ OUT07IRQ = OUT2IR; /* Clear OUT2 IRQ */
+}
+
+void ep3in_isr(void) __interrupt EP3IN_ISR
+{
+}
+void ep3out_isr(void) __interrupt EP3OUT_ISR
+{
+}
+void ep4in_isr(void) __interrupt EP4IN_ISR
+{
+}
+void ep4out_isr(void) __interrupt EP4OUT_ISR
+{
+}
+void ep5in_isr(void) __interrupt EP5IN_ISR
+{
+}
+void ep5out_isr(void) __interrupt EP5OUT_ISR
+{
+}
+void ep6in_isr(void) __interrupt EP6IN_ISR
+{
+}
+void ep6out_isr(void) __interrupt EP6OUT_ISR
+{
+}
+void ep7in_isr(void) __interrupt EP7IN_ISR
+{
+}
+void ep7out_isr(void) __interrupt EP7OUT_ISR
+{
+}
+
+/**
+ * Return the control/status register for an endpoint
+ *
+ * @param ep endpoint address
+ * @return on success: pointer to Control & Status register for endpoint
+ * specified in \a ep
+ * @return on failure: NULL
+ */
+__xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep)
+{
+ /* Mask direction bit */
+ uint8_t ep_num = ep & 0x7F;
+
+ switch (ep_num) {
+ case 0:
+ return &EP0CS;
+ break;
+ case 1:
+ return ep & 0x80 ? &IN1CS : &OUT1CS;
+ break;
+ case 2:
+ return ep & 0x80 ? &IN2CS : &OUT2CS;
+ break;
+ case 3:
+ return ep & 0x80 ? &IN3CS : &OUT3CS;
+ break;
+ case 4:
+ return ep & 0x80 ? &IN4CS : &OUT4CS;
+ break;
+ case 5:
+ return ep & 0x80 ? &IN5CS : &OUT5CS;
+ break;
+ case 6:
+ return ep & 0x80 ? &IN6CS : &OUT6CS;
+ break;
+ case 7:
+ return ep & 0x80 ? &IN7CS : &OUT7CS;
+ break;
+ }
+
+ return NULL;
+}
+
+void usb_reset_data_toggle(uint8_t ep)
+{
+ /* TOGCTL register:
+ +----+-----+-----+------+-----+-------+-------+-------+
+ | Q | S | R | IO | 0 | EP2 | EP1 | EP0 |
+ +----+-----+-----+------+-----+-------+-------+-------+
+
+ To reset data toggle bits, we have to write the endpoint direction (IN/OUT)
+ to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a
+ separate write cycle, the R bit needs to be set.
+ */
+ uint8_t togctl_value = (ep & 0x80 >> 3) | (ep & 0x7);
+
+ /* First step: Write EP number and direction bit */
+ TOGCTL = togctl_value;
+
+ /* Second step: Set R bit */
+ togctl_value |= TOG_R;
+ TOGCTL = togctl_value;
+}
+
+/**
+ * Handle GET_STATUS request.
+ *
+ * @return on success: true
+ * @return on failure: false
+ */
+bool usb_handle_get_status(void)
+{
+ uint8_t *ep_cs;
+
+ switch (setup_data.bmRequestType) {
+ case GS_DEVICE:
+ /* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup.
+ * Byte 1: reserved, reset to zero */
+ IN0BUF[0] = 0;
+ IN0BUF[1] = 0;
+
+ /* Send response */
+ IN0BC = 2;
+ break;
+ case GS_INTERFACE:
+ /* Always return two zero bytes according to USB 1.1 spec, p. 191 */
+ IN0BUF[0] = 0;
+ IN0BUF[1] = 0;
+
+ /* Send response */
+ IN0BC = 2;
+ break;
+ case GS_ENDPOINT:
+ /* Get stall bit for endpoint specified in low byte of wIndex */
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex & 0xff);
+
+ if (*ep_cs & EPSTALL)
+ IN0BUF[0] = 0x01;
+ else
+ IN0BUF[0] = 0x00;
+
+ /* Second byte sent has to be always zero */
+ IN0BUF[1] = 0;
+
+ /* Send response */
+ IN0BC = 2;
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * Handle CLEAR_FEATURE request.
+ *
+ * @return on success: true
+ * @return on failure: false
+ */
+bool usb_handle_clear_feature(void)
+{
+ __xdata uint8_t *ep_cs;
+
+ switch (setup_data.bmRequestType) {
+ case CF_DEVICE:
+ /* Clear remote wakeup not supported: stall EP0 */
+ STALL_EP0();
+ break;
+ case CF_ENDPOINT:
+ if (setup_data.wValue == 0) {
+ /* Unstall the endpoint specified in wIndex */
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
+ if (!ep_cs)
+ return false;
+ *ep_cs &= ~EPSTALL;
+ } else {
+ /* Unsupported feature, stall EP0 */
+ STALL_EP0();
+ }
+ break;
+ default:
+ /* Vendor commands... */
+ }
+
+ return true;
+}
+
+/**
+ * Handle SET_FEATURE request.
+ *
+ * @return on success: true
+ * @return on failure: false
+ */
+bool usb_handle_set_feature(void)
+{
+ __xdata uint8_t *ep_cs;
+
+ switch (setup_data.bmRequestType) {
+ case SF_DEVICE:
+ if (setup_data.wValue == 2)
+ return true;
+ break;
+ case SF_ENDPOINT:
+ if (setup_data.wValue == 0) {
+ /* Stall the endpoint specified in wIndex */
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
+ if (!ep_cs)
+ return false;
+ *ep_cs |= EPSTALL;
+ } else {
+ /* Unsupported endpoint feature */
+ return false;
+ }
+ break;
+ default:
+ /* Vendor commands... */
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * Handle GET_DESCRIPTOR request.
+ *
+ * @return on success: true
+ * @return on failure: false
+ */
+bool usb_handle_get_descriptor(void)
+{
+ __xdata uint8_t descriptor_type;
+ __xdata uint8_t descriptor_index;
+
+ descriptor_type = (setup_data.wValue & 0xff00) >> 8;
+ descriptor_index = setup_data.wValue & 0x00ff;
+
+ switch (descriptor_type) {
+ case DESCRIPTOR_TYPE_DEVICE:
+ SUDPTRH = HI8(&device_descriptor);
+ SUDPTRL = LO8(&device_descriptor);
+ break;
+ case DESCRIPTOR_TYPE_CONFIGURATION:
+ SUDPTRH = HI8(&config_descriptor);
+ SUDPTRL = LO8(&config_descriptor);
+ break;
+ case DESCRIPTOR_TYPE_STRING:
+ if (setup_data.wIndex == 0) {
+ /* Supply language descriptor */
+ SUDPTRH = HI8(&language_descriptor);
+ SUDPTRL = LO8(&language_descriptor);
+ } else if (setup_data.wIndex == 0x0409 /* US English */) {
+ /* Supply string descriptor */
+ SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]);
+ SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]);
+ } else
+ return false;
+ break;
+ default:
+ /* Unsupported descriptor type */
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * Handle SET_INTERFACE request.
+ */
+void usb_handle_set_interface(void)
+{
+ /* Reset Data Toggle */
+ usb_reset_data_toggle(USB_DIR_IN | 2);
+ usb_reset_data_toggle(USB_DIR_OUT | 2);
+
+ /* Unstall & clear busy flag of all valid IN endpoints */
+ IN2CS = 0 | EPBSY;
+
+ /* Unstall all valid OUT endpoints, reset bytecounts */
+ OUT2CS = 0;
+ OUT2BC = 0;
+}
+
+/**
+ * Handle the arrival of a USB Control Setup Packet.
+ */
+void usb_handle_setup_data(void)
+{
+ switch (setup_data.bRequest) {
+ case GET_STATUS:
+ if (!usb_handle_get_status())
+ STALL_EP0();
+ break;
+ case CLEAR_FEATURE:
+ if (!usb_handle_clear_feature())
+ STALL_EP0();
+ break;
+ case 2: case 4:
+ /* Reserved values */
+ STALL_EP0();
+ break;
+ case SET_FEATURE:
+ if (!usb_handle_set_feature())
+ STALL_EP0();
+ break;
+ case SET_ADDRESS:
+ /* Handled by USB core */
+ break;
+ case SET_DESCRIPTOR:
+ /* Set Descriptor not supported. */
+ STALL_EP0();
+ break;
+ case GET_DESCRIPTOR:
+ if (!usb_handle_get_descriptor())
+ STALL_EP0();
+ break;
+ case GET_CONFIGURATION:
+ /* OpenULINK has only one configuration, return its index */
+ IN0BUF[0] = config_descriptor.bConfigurationValue;
+ IN0BC = 1;
+ break;
+ case SET_CONFIGURATION:
+ /* OpenULINK has only one configuration -> nothing to do */
+ break;
+ case GET_INTERFACE:
+ /* OpenULINK only has one interface, return its number */
+ IN0BUF[0] = interface_descriptor00.bInterfaceNumber;
+ IN0BC = 1;
+ break;
+ case SET_INTERFACE:
+ usb_handle_set_interface();
+ break;
+ case SYNCH_FRAME:
+ /* Isochronous endpoints not used -> nothing to do */
+ break;
+ default:
+ /* Any other requests: do nothing */
+ break;
+ }
+}
+
+/**
+ * USB initialization. Configures USB interrupts, endpoints and performs
+ * ReNumeration.
+ */
+void usb_init(void)
+{
+ /* Mark endpoint 2 IN & OUT as valid */
+ IN07VAL = IN2VAL;
+ OUT07VAL = OUT2VAL;
+
+ /* Make sure no isochronous endpoints are marked valid */
+ INISOVAL = 0;
+ OUTISOVAL = 0;
+
+ /* Disable isochronous endpoints. This makes the isochronous data buffers
+ * available as 8051 XDATA memory at address 0x2000 - 0x27FF */
+ ISOCTL = ISODISAB;
+
+ /* Enable USB Autovectoring */
+ USBBAV |= AVEN;
+
+ /* Enable SUDAV interrupt */
+ USBIEN |= SUDAVIE;
+
+ /* Enable EP2 OUT & IN interrupts */
+ OUT07IEN = OUT2IEN;
+ IN07IEN = IN2IEN;
+
+ /* Enable USB interrupt (EIE register) */
+ EUSB = 1;
+
+ /* Perform ReNumeration */
+ USBCS = DISCON | RENUM;
+ delay_ms(200);
+ USBCS = DISCOE | RENUM;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/ulink_firmware.hex
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/ulink_firmware.hex b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/ulink_firmware.hex
new file mode 100755
index 0000000..efaea58
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/OpenULINK/ulink_firmware.hex
@@ -0,0 +1,347 @@
+:040000000200713257
+:01000B0032C2
+:0100130032BA
+:01001B0032B2
+:0100230032AA
+:01002B0032A2
+:01003300329A
+:01003B003292
+:01004300328A
+:01004B003282
+:01005300327A
+:01005B003272
+:01006300326A
+:03006B000201107F
+:0300CA0002006EC3
+:03006E000201018B
+:1000CD00907F937404F0907F9C7495F0907F96745C
+:1000DD0090F0907F94E4F0907F9D747FF0907F97E7
+:1000ED00E4F0907F957440F0907F9E7442F0907F85
+:1000FD0098E4F0221200CD1204ADD2AF1208E090B8
+:10010D00000022C021C0E0C0F0C082C083C007C083
+:10011D0006C005C004C003C002C001C000C0D07538
+:10012D00D000AF9174EF5FF59112040C907FAB741A
+:10013D0001F0907FB4E04402F0D0D0D000D001D0D7
+:10014D0002D003D004D005D006D007D083D082D002
+:10015D00F0D0E0D02132323232323232323232C04D
+:10016D00E0C082C083C007C0D075D000D201AF916E
+:10017D0074EF5FF591907FA97404F0D0D0D007D0C3
+:10018D0083D082D0E032C0E0C082C083C007C0D02F
+:10019D0075D000D200AF9174EF5FF591907FAA7486
+:1001AD0004F0D0D0D007D083D082D0E032323232BA
+:1001BD0032323232323232AF82747F5FFE24F850E7
+:1001CD0003020278EE240A83F582EE240C83F58374
+:1001DD00E473EFF306192C3F52650101020202028E
+:1001ED000202907FB422EF30E7067DB67E7F800459
+:1001FD007DC67E7F8D828E8322EF30E7067DB87EB1
+:10020D007F80047DC87E7F8D828E8322EF30E7064E
+:10021D007DBA7E7F80047DCA7E7F8D828E8322EFA4
+:10022D0030E7067DBC7E7F80047DCC7E7F8D828E07
+:10023D008322EF30E7067DBE7E7F80047DCE7E7FFC
+:10024D008D828E8322EF30E7067DC07E7F80047D18
+:10025D00D07E7F8D828E8322EF30E7067EC27F7F38
+:10026D0080047ED27F7F8E828F832290000022AF0A
+:10027D008274105FFE74075F4206907FD7EEF074B4
+:10028D00204EF022907FE8E0C322907FE8E0FF60EF
+:10029D0005BF0246800A907FB4E0FF4401F0803A2A
+:1002AD00907FEAE0FEA3E0FF4E7027907FECE0FE2A
+:1002BD00A3E08E821201C4AE82AF83EE4F7002C3F3
+:1002CD00228E828F83E0FD5305FE8E828F83EDF0AB
+:1002DD008008907FB4E0FF4401F0D322907FE8E0E6
+:1002ED00FF6005BF02468010907FEAE0FEA3E0FFAD
+:1002FD00BE0239BF0036D322907FEAE0FEA3E0FFB5
+:10030D004E7027907FECE0FEA3E08E821201C4AE0A
+:10031D0082AF83EE4F7002C3228E828F83E0FD4346
+:10032D0005018E828F83EDF08002C322D322907F50
+:10033D00EAE0A3E0FF907FEAE0FDA3E07E00BF01CD
+:10034D0002800DBF02028021BF030280340203EC44
+:10035D007ED37F138F06907FD4EEF07ED37F137FF5
+:10036D0000907FD5EEF00203EE7EE57F138F0690B1
+:10037D007FD4EEF07EE57F137F00907FD5EEF08089
+:10038D0060907FECE0FEA3E0FF4E70187E057F14B9
+:10039D008F06907FD4EEF07E057F147F00907FD581
+:1003AD00EEF0803D907FECE0FEA3E0FFBE092EBF96
+:1003BD00042BED1475F002A42459F582741435F054
+:1003CD00F583E493FEA3E493FF8E048F058D0490D3
+:1003DD007FD4ECF07F00907FD5EEF08004C322C374
+:1003ED0022D32275828212027C75820212027C90C7
+:1003FD007FB87402F0907FC8E4F0907FC9F022902E
+:10040D007FE9E0FF24F3500122EFF5F0240B83F593
+:10041D0082E5F0241183F583E473414F5D655D72D0
+:10042D007B73889899A9AC0404040404040404049F
+:10043D0004040404120291500122907FB4E044019F
+:10044D00F022120297500122907FB4E04401F02275
+:10045D00907FB4E04401F0221202E94042907FB453
+:10046D00E04401F02222907FB4E04401F022120317
+:10047D003B402C907FB4E04401F0229013EAE493CA
+:10048D00907F00F0907FB57401F022229013F0E47C
+:10049D0093907F00F0907FB57401F0221203F0224B
+:1004AD00907FDE7404F0907FDF7404F0907FE0E4C1
+:1004BD00F0907FE1F0907FA17401F0907FAFE04468
+:1004CD0001F0907FAEE04401F0907FAD7404F090A8
+:1004DD007FAC7404F0D2E8907FD6740AF09000C817
+:0A04ED0012137C907FD67406F022F3
+:1013D30012011001FFFFFF4051C21027000101025B
+:1013E3000301090220000101048032090400000204
+:1013F300FFFFFF00070582024000000705020240CD
+:1014030000000403090414034F00700065006E001C
+:1014130055004C0049004E004B0014034F00700070
+:1014230065006E0055004C0049004E004B000E0352
+:101433003000300030003000300031001A034A0021
+:101443005400410047002000410064006100700027
+:0E14530074006500720009141D1431143F145A
+:1004F700E5080424C0F582E4347DF583E0FF30E1AC
+:1005070008907F96E0FE54EFF08F06EE30E00890FB
+:100517007F96E0FE547FF0EF30E308907F96E0FE91
+:100527004410F0EF30E208907F96E0FF4480F0221D
+:100537007F00E50824C0F582E4347DF583E0FE24DE
+:10054700D550030208A6EE240A83F582EE242F83F2
+:10055700F583E473B18AD7B0FAD3A6A6A6A6A6A652
+:10056700A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A624
+:10057700A6A6A6A621FA512A639CD5053493A205FF
+:1005870006050605060808080808080808080808F0
+:1005970008080808080808080808080808080806D6
+:1005A700060607070707080808087E05E508042464
+:1005B700C0F582E4347DF583E0FFE50804F5828524
+:1005C7000927C007C00612091DD006D0070208A8D0
+:1005D700E5080424C0F582E4347DF583E02405FEB4
+:1005E700E50804F582C007C006120BDED006D00767
+:1005F7000208A8E5080424C0F582E4347DF583E009
+:10060700FF2405FEE50804F58285093CC007C006FE
+:10061700120E79D006D0070208A87E02E508042446
+:10062700C0F582E4347DF583E0FD7402250824C01B
+:10063700F582E4347DF583E0F50A8D82C007C006B4
+:1006470012124AD006D0070208A87E02E508042441
+:10065700C0F582E4347DF583E0FC7D007402250853
+:1006670024C0F582E4347DF583E0FAE44204EA42EB
+:10067700058C828D83C007C0061211DDD006D00716
+:100687000208A87E05E5080424C0F582E4347DF558
+:1006970083E0FFE50804F58285092DC007C006122F
+:1006A7000A67D006D0070208A8E5080424C0F58227
+:1006B700E4347DF583E02405FEE50804F582C007F0
+:1006C700C006120D14D006D0070208A8E5080424B6
+:1006D700C0F582E4347DF583E0FF2405FEE50804D8
+:1006E700F582850943C007C006121013D006D0074C
+:1006F7000208A87E02E5080424C0F582E4347DF5EB
+:1007070083E0FB7402250824C0F582E4347DF58379
+:10071700E0F50A8B82C007C006121281D006D00707
+:100727000208A87E02E5080424C0F582E4347DF5BA
+:1007370083E0FC7D007402250824C0F582E4347D43
+:10074700F583E0FAE44204EA42058C828D83C00710
+:10075700C006121207D006D0070208A87E02E508D5
+:100767000424C0F582E4347DF583E0FC7D00740247
+:10077700250824C0F582E4347DF583E0FAE44204D9
+:10078700EA42058C828D83C007C006121349D00642
+:10079700D0070208A87E02E5080424C0F582E434E5
+:1007A7007DF583E0FC7D007402250824C0F582E412
+:1007B700347DF583E0FAE44204EA42058C828D83B6
+:1007C700C007C00612137CD006D0070208A87E0017
+:1007D7007F02C007C0061212CEAC82AD83D006D00E
+:1007E7000785098275837E8D03EBF0E509042400F4
+:1007F700F582E4347EF5837D00ECF00208A87E02E2
+:10080700E5080424C0F582E4347DF583E0FD740235
+:10081700250824C0F582E4347DF583E0F50A8D824E
+:10082700C007C006121311D006D00780747E05E5F5
+:10083700080424C0F582E4347DF583E0FD740225C5
+:100847000824C0F582E4347DF583E0F50A740325B6
+:100857000824C0F582E4347DF583E0F50B740425A4
+:100867000824C0F582E4347DF583E0F50C74052592
+:100877000824C0F582E4347DF583E0F50D8D82C050
+:1008870007C006121329D006D00780157E01C007BE
+:10089700C0061204F7D006D00780067E0180027ECC
+:1008A70000EF2509F509AD087F008E037C00EB2DCD
+:1008B700FDEC3FFF0DBD00010F907FC9E0FC7B0001
+:1008C700C3ED9CEF64808BF063F08095F04002D31A
+:1008D70022EE042508F508C32275080075090010E3
+:1008E700000280FB907F96E0FF547FF0C202200257
+:1008F70007120537920280F6907F96E0FF4480F05A
+:10090700E509600B907FB9E509F010010280FB90C3
+:100917007FC9E4F080C3E582FF24C0F582E4347D1B
+:10092700F583E0F528EF0424C0F582E4347DF583F0
+:10093700E0F52974022FFC24C0F582E4347DF583A9
+:10094700E0C4540FFB53030FEC24C0F582E4347D5D
+:10095700F583E0FC740F5CF52A74032F24C0F5823D
+:10096700E4347DF583E0FA74042F24C0F582E4347F
+:100977007DF583E0F52BEB60078A0A8B8212124A1A
+:10098700907F97E0FB5303F874044BFA7900A8288B
+:100997007C0018B8FF011C89067F00C3EE98EF643E
+:1009A700808CF063F08095F050347F007E00907F5C
+:1009B70097EBF0EFC313FF907F97EAF0907F99E0F2
+:1009C700FC30E5034307800EBE080040E1E5272918
+:1009D7002400F582E4347EF583EFF00980B0892C9A
+:1009E7007F00AC2A7A00C3EA95295040A8297900EC
+:1009F70018B8FF01198A057E00EDB50011EEB501A3
+:100A07000DEC600A4303021CE52BC313F52B907F03
+:100A170097EBF0EFC313FF907F9774044BF0907F31
+:100A270099E0FE30E5034307800A80BAAD297E00CE
+:100A37007408C39DFDE49EFE8DF005F0EF8002C3B0
+:100A470013D5F0FBFFE527252C2400F582E4347E3F
+:100A5700F583EFF0EC6008852B0A8C8202124A229C
+:100A6700E582FF24C0F582E4347DF583E0F52EEFBF
+:100A77000424C0F582E4347DF583E0F52F74022F5A
+:100A8700FC24C0F582E4347DF583E0C4540FFB53A6
+:100A9700030FEC24C0F582E4347DF583E0FC740F8A
+:100AA7005CF53074032F24C0F582E4347DF583E0D0
+:100AB700FA74042F24C0F582E4347DF583E0F53120
+:100AC700EB60078A0A8B82121281907F97E0FB53B3
+:100AD70003F874044BFA753200A82E7C0018B8FF8F
+:100AE700011CA9327E00C3E998EE64808CF063F0A4
+:100AF7008095F0504C7E007C00907F97EBF079005A
+:100B0700C3E9952250030980F7EEC313FE907F9740
+:100B1700EAF07900C3E9952250030980F7907F999D
+:100B2700E0F930E5034306800CBC080040CBE52D17
+:100B370025322400F582E4347EF583EEF005328019
+:100B4700987E00AA307900C3E9952F5056A82F7CCC
+:100B57000018B8FF011C89057F00EDB50011EFB53E
+:100B6700040DEA600A4303021AE531C313F5319015
+:100B77007F97EBF07F00C3EF952250030F80F7EECE
+:100B8700C313FE907F9774044BF07F00C3EF952249
+:100B970050030F80F7907F99E0FF30E5034306800D
+:100BA7000980A4AD2F7F007408C39DFDE49FFF8DCE
+:100BB700F005F0EE8002C313D5F0FBFEE52D2532DC
+:100BC7002400F582E4347EF583EEF0EA600885318F
+:100BD7000A8A8202128122E582FF24C0F582E43468
+:100BE7007DF583E0F533EF0424C0F582E4347DF529
+:100BF70083E0F53474022FFC24C0F582E4347DF5DC
+:100C070083E0C4540FFB53030FEC24C0F582E43494
+:100C17007DF583E0FC740F5CF53574032F24C0F574
+:100C270082E4347DF583E0FA74042F24C0F582E46E
+:100C3700347DF583E0F536EB600B8A0A8B82C007BB
+:100C470012124AD007907F97E0FB5303F97A00A866
+:100C5700337C0018B8FF011C8A017E00C3E998EEB7
+:100C670064808CF063F08095F05039EF2A240524D6
+:100C7700C0F582E4347DF583E0FE7C00EE30E005CC
+:100C870043030180068B0174FE59FB907F97EBF0BD
+:100C9700EEC313FE907F9774044BF00CBC08004022
+:100CA700DB0A80ABEF2A240524C0F582E4347DF506
+:100CB70083E0FEAF357C00C3EC95345044EE30E062
+:100CC7000543030180068B0274FE5AFBA9347A00A0
+:100CD70019B9FF011A8C007D00E8B50111EDB502C5
+:100CE7000DEF600A4303021FE536C313F536907F05
+:100CF70097EBF0EEC313FE907F9774044BF00C80D4
+:100D0700B6EF600885360A8F8202124A22E582F51D
+:100D17003724C0F582E4347DF583E0F538E5370400
+:100D270024C0F582E4347DF583E0F5397402253774
+:100D3700FC24C0F582E4347DF583E0C4540FFB53F3
+:100D4700030FEC24C0F582E4347DF583E0FC740FD7
+:100D57005CF53A7403253724C0F582E4347DF583C6
+:100D6700E0FA7404253724C0F582E4347DF583E086
+:100D7700F53BEB60078A0A8B82121281907F97E01E
+:100D8700FB5303F97A00A8387C0018B8FF011C8AC6
+:100D9700067F00C3EE98EF64808CF063F08095F0D7
+:100DA7005050E5372A240524C0F582E4347DF583C5
+:100DB700E0FF7E00EF30E00543030180068B0474FB
+:100DC700FE5CFB907F97EBF07C00C3EC9523500310
+:100DD7000C80F7EFC313FF907F9774044BF07C00F0
+:100DE700C3EC952350030C80F70EBE080040C50ADC
+:100DF7008094E5372A240524C0F582E4347DF58301
+:100E0700E0FFAE3A7C00C3EC9539505AEF30E0056D
+:100E170043030180068B0274FE5AFBA8397A001837
+:100E2700B8FF011A8C017D00E9B50011EDB5020D7F
+:100E3700EE600A4303021EE53BC313F53B907F9721
+:100E4700EBF07D00C3ED952350030D80F7EFC3133F
+:100E5700FF907F9774044BF07D00C3ED95235003FB
+:100E67000D80F70C80A0EE6008853B0A8E82021287
+:100E77008122E582FF24C0F582E4347DF583E0F525
+:100E87003DEF0424C0F582E4347DF583E0F53E743C
+:100E9700022FFC24C0F582E4347DF583E0C4540FAF
+:100EA700FB53030FEC24C0F582E4347DF583E0FCAB
+:100EB700740F5CF53F74032F24C0F582E4347DF58D
+:100EC70083E0FA74042F24C0F582E4347DF583E0CF
+:100ED700F540EB600B8A0A8B82C00712124AD007D3
+:100EE700907F97E0FB5303F97A00A83D7C0018B880
+:100EF700FF011C8A017E00C3E998EE64808CF063D1
+:100F0700F08095F0505CEF2A240524C0F582E43484
+:100F17007DF583E0F5417C007900E54130E005434C
+:100F2700030180068B0074FE58FB907F97EBF0E57A
+:100F370041C313F541907F9774044BF0ECC313FC46
+:100F4700907F99E0F830E50343048009B908004031
+:100F5700C9E53C2A2400F582E4347EF583ECF00AE7
+:100F670080888A01EF2A240524C0F582E4347DF5C0
+:100F770083E0F5417C00AF3F754200C3E542953EF3
+:100F87005057E54130E00543030180068B0074FEAE
+:100F970058FBA83E7D0018B8FF011DAA427E00EA53
+:100FA700B50011EEB5050DEF600A4303021FE540DA
+:100FB700C313F540907F97EBF0E541C313F54190DC
+:100FC7007F9774044BF0ECC313FC907F99E0FE30DD
+:100FD700E503430480054280A2AD3E7E007408C34A
+:100FE7009DFDE49EFE8DF005F0EC8002C313D5F065
+:100FF700FBFCE53C292400F582E4347EF583ECF024
+:10100700EF600885400A8F8202124A22E582F54482
+:1010170024C0F582E4347DF583E0F545E5440424F6
+:10102700C0F582E4347DF583E0F54674022544FC7F
+:1010370024C0F582E4347DF583E0C4540FFB5303E9
+:101047000FEC24C0F582E4347DF583E0FC740F5C7B
+:10105700F5477403254424C0F582E4347DF583E025
+:10106700FA7404254424C0F582E4347DF583E0F561
+:1010770048EB60078A0A8B82121281907F97E0FB08
+:101087005303F97A00A8457C0018B8FF011C8A06AB
+:101097007F00C3EE98EF64808CF063F08095F0508A
+:1010A70074E5442A240524C0F582E4347DF583E001
+:1010B700F5497E007C00E54930E0054303018006E1
+:1010C7008B0074FE58FB907F97EBF07800C3E89590
+:1010D7002450030880F7E549C313F549907F9774B7
+:1010E700044BF07800C3E8952450030880F7EEC35B
+:1010F70013FE907F99E0F830E5034306800CBC08A7
+:101107000040B3E5432A2400F582E4347EF583EEFC
+:10111700F00A02108C8A04E5442A240524C0F582CB
+:10112700E4347DF583E0F5497E00AA47754A00C39C
+:10113700E54A9546506DE54930E0054303018006D1
+:101147008B0174FE59FBA9467D0019B9FF011DA843
+:101157004A7F00E8B50111EFB5050DEA600A4303C0
+:10116700021AE548C313F548907F97EBF07F00C359
+:10117700EF952450030F80F7E549C313F549907F96
+:101187009774044BF07F00C3EF952450030F80F74B
+:10119700EEC313FE907F99E0FF30E5034306800519
+:1011A7004A808CAD467F007408C39DFDE49FFF8D88
+:1011B700F005F0EE8002C313D5F0FBFEE5432C24C7
+:1011C70000F582E4347EF583EEF0EA600885480A8C
+:1011D7008A8202128122AE82AF83907F97E0FD530D
+:1011E70005FB74044DFC7A007B00C3EA9EEB9F501D
+:1011F7000E907F97EDF0ECF00ABA00EE0B80EB2231
+:10120700AE82AF83907F97E0FD5305FB74044DFCDE
+:101217007A007B00C3EA9EEB9F5027907F97EDF003
+:101227007900C3E9952550030980F7907F97ECF083
+:101237007900C3E9952550030980F70ABA00D50B51
+:1012470080D222AF82907F97E0FE5306FB7D00C3DA
+:10125700ED9F5025E50A30E00543060280068E041F
+:1012670074FD5CFE907F97EEF0E50AC313F50A90D4
+:101277007F9774044EF00D80D622AF82907F97E05F
+:10128700FE5306FB7D00C3ED9F503BE50A30E005AA
+:1012970043060280068E0474FD5CFE907F97EEF095
+:1012A7007C00C3EC952650030C80F7E50AC313F5C1
+:1012B7000A907F9774044EF07C00C3EC9526500388
+:1012C7000C80F70D80C0227F00907F99E0FE30E50B
+:1012D700027F01907F99E0FE30E603430702907F8B
+:1012E7009AE0FE30E703430704907F9BE0FE30E57A
+:1012F70003430708907F9AE0FE53067F8F05E4FFBC
+:10130700FCEE4FF582EC4DF58322E582547FF4FF26
+:10131700907F97E05FF0747F550AFF907F97E04FCB
+:10132700F022858222850A23850B24850C25850DCD
+:10133700262200227E567F021EBEFF011FEE4F703F
+:10134700F722750A05750B001213A6AE82AF837CD0
+:10135700007D00C3EC9EED9F501AC007C006C00574
+:10136700C004121339D004D005D006D0070CBC0036
+:10137700E20D80DF22AE82AF837C007D00C3EC9E4E
+:10138700ED9F501AC007C006C005C00412133BD01A
+:0F13970004D005D006D0070CBC00E20D80DF2289
+:03004300021B009D
+:101B0000020110000201630002016400020165008D
+:101B1000020166000201670002016800020169001B
+:101B200002016A0002016B0002016C0002019300D5
+:101B30000201BA000201BB000201BC000201BD00AB
+:101B40000201BE000201BF000201C0000201C1008B
+:081B50000201C2000201C30002
+:1013A6007A10E4FBFCE58225E0F582E58333F583DC
+:1013B600EB33FBEC33FCEB950AF5F0EC950B4006B2
+:0913C600FCABF0438201DADD22E8
+:0600A000E478FFF6D8FD34
+:10007E007900E94400601B7A009014617800759253
+:10008E0020E493F2A308B800020592D9F4DAF275CF
+:02009E0092FFCF
+:1000A6007800E84400600A7900759220E4F309D8E4
+:1000B600FC7800E84400600C7900902000E4F0A38E
+:0400C600D8FCD9FA8F
+:0D00710075814A1213CFE582600302006E14
+:0413CF007582002201
+:00000001FF
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/amt_jtagaccel.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/amt_jtagaccel.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/amt_jtagaccel.c
new file mode 100755
index 0000000..5aacead
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/amt_jtagaccel.c
@@ -0,0 +1,607 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Dominic Rath *
+ * Dominic.Rath@gmx.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <jtag/interface.h>
+
+#if PARPORT_USE_PPDEV == 1
+#include <linux/parport.h>
+#include <linux/ppdev.h>
+#include <sys/ioctl.h>
+#else /* not PARPORT_USE_PPDEV */
+#ifndef _WIN32
+#include <sys/io.h>
+#endif
+#endif
+
+#if PARPORT_USE_GIVEIO == 1
+#if IS_CYGWIN == 1
+#include <windows.h>
+#endif
+#endif
+
+/**
+ * @file
+ * Support the Amontec Chameleon POD with JTAG Accelerator support.
+ * This is a parallel port JTAG adapter with a CPLD between the
+ * parallel port and the JTAG connection. VHDL code running in the
+ * CPLD significantly accelerates JTAG operations compared to the
+ * bitbanging "Wiggler" style of most parallel port adapters.
+ */
+
+/* configuration */
+static uint16_t amt_jtagaccel_port;
+
+/* interface variables
+ */
+static uint8_t aw_control_rst;
+static uint8_t aw_control_fsm = 0x10;
+static uint8_t aw_control_baudrate = 0x20;
+
+static int rtck_enabled;
+
+#if PARPORT_USE_PPDEV == 1
+static int device_handle;
+
+static const int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR;
+
+/* FIXME do something sane when these ioctl/read/write calls fail. */
+
+#define AMT_AW(val) \
+ do { \
+ int __retval; \
+ \
+ __retval = ioctl(device_handle, PPSETMODE, &addr_mode); \
+ assert(__retval >= 0); \
+ __retval = write(device_handle, &val, 1); \
+ assert(__retval >= 0); \
+ } while (0)
+#define AMT_AR(val) \
+ do { \
+ int __retval; \
+ \
+ __retval = ioctl(device_handle, PPSETMODE, &addr_mode); \
+ assert(__retval >= 0); \
+ __retval = read(device_handle, &val, 1); \
+ assert(__retval >= 0); \
+ } while (0)
+
+static const int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA;
+
+#define AMT_DW(val) \
+ do { \
+ int __retval; \
+ \
+ __retval = ioctl(device_handle, PPSETMODE, &data_mode); \
+ assert(__retval >= 0); \
+ __retval = write(device_handle, &val, 1); \
+ assert(__retval >= 0); \
+ } while (0)
+#define AMT_DR(val) \
+ do { \
+ int __retval; \
+ \
+ __retval = ioctl(device_handle, PPSETMODE, &data_mode); \
+ assert(__retval >= 0); \
+ __retval = read(device_handle, &val, 1); \
+ assert(__retval >= 0); \
+ } while (0)
+
+#else
+
+#define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0)
+#define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0)
+#define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0)
+#define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0)
+
+#endif /* PARPORT_USE_PPDEV */
+
+/* tap_move[i][j]: tap movement command to go from state i to state j
+ * 0: Test-Logic-Reset
+ * 1: Run-Test/Idle
+ * 2: Shift-DR
+ * 3: Pause-DR
+ * 4: Shift-IR
+ * 5: Pause-IR
+ */
+static const uint8_t amt_jtagaccel_tap_move[6][6][2] = {
+ /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
+ { {0x1f, 0x00}, {0x0f, 0x00}, {0x05, 0x00}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00} }, /* RESET */
+ { {0x1f, 0x00}, {0x00, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x0b, 0x00} }, /* IDLE */
+ { {0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01} }, /* DRSHIFT */
+ { {0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01} }, /* DRPAUSE */
+ { {0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00} }, /* IRSHIFT */
+ { {0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00} }, /* IRPAUSE */
+};
+
+static void amt_jtagaccel_reset(int trst, int srst)
+{
+ if (trst == 1)
+ aw_control_rst |= 0x4;
+ else if (trst == 0)
+ aw_control_rst &= ~0x4;
+
+ if (srst == 1)
+ aw_control_rst |= 0x1;
+ else if (srst == 0)
+ aw_control_rst &= ~0x1;
+
+ AMT_AW(aw_control_rst);
+}
+
+static int amt_jtagaccel_speed(int speed)
+{
+ aw_control_baudrate &= 0xf0;
+ aw_control_baudrate |= speed & 0x0f;
+ AMT_AW(aw_control_baudrate);
+
+ return ERROR_OK;
+}
+
+static void amt_jtagaccel_end_state(tap_state_t state)
+{
+ if (tap_is_state_stable(state))
+ tap_set_end_state(state);
+ else {
+ LOG_ERROR("BUG: %i is not a valid end state", state);
+ exit(-1);
+ }
+}
+
+static void amt_wait_scan_busy(void)
+{
+ int timeout = 4096;
+ uint8_t ar_status;
+
+ AMT_AR(ar_status);
+ while (((ar_status) & 0x80) && (timeout-- > 0))
+ AMT_AR(ar_status);
+
+ if (ar_status & 0x80) {
+ LOG_ERROR(
+ "amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x",
+ (rtck_enabled) ? "enabled" : "disabled",
+ ar_status);
+ exit(-1);
+ }
+}
+
+static void amt_jtagaccel_state_move(void)
+{
+ uint8_t aw_scan_tms_5;
+ uint8_t tms_scan[2];
+
+ tap_state_t cur_state = tap_get_state();
+ tap_state_t end_state = tap_get_end_state();
+
+ tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0];
+ tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1];
+
+ aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f);
+ AMT_AW(aw_scan_tms_5);
+ int jtag_speed = 0;
+ int retval = jtag_get_speed(&jtag_speed);
+ assert(retval == ERROR_OK);
+ if (jtag_speed > 3 || rtck_enabled)
+ amt_wait_scan_busy();
+
+ if (tms_scan[0] & 0x80) {
+ aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f);
+ AMT_AW(aw_scan_tms_5);
+ if (jtag_speed > 3 || rtck_enabled)
+ amt_wait_scan_busy();
+ }
+
+ tap_set_state(end_state);
+}
+
+static void amt_jtagaccel_runtest(int num_cycles)
+{
+ int i = 0;
+ uint8_t aw_scan_tms_5;
+ uint8_t aw_scan_tms_1to4;
+
+ tap_state_t saved_end_state = tap_get_end_state();
+
+ /* only do a state_move when we're not already in IDLE */
+ if (tap_get_state() != TAP_IDLE) {
+ amt_jtagaccel_end_state(TAP_IDLE);
+ amt_jtagaccel_state_move();
+ }
+
+ while (num_cycles - i >= 5) {
+ aw_scan_tms_5 = 0x40;
+ AMT_AW(aw_scan_tms_5);
+ i += 5;
+ }
+
+ if (num_cycles - i > 0) {
+ aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4;
+ AMT_AW(aw_scan_tms_1to4);
+ }
+
+ amt_jtagaccel_end_state(saved_end_state);
+ if (tap_get_state() != tap_get_end_state())
+ amt_jtagaccel_state_move();
+}
+
+static void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
+{
+ int bits_left = scan_size;
+ int bit_count = 0;
+ tap_state_t saved_end_state = tap_get_end_state();
+ uint8_t aw_tdi_option;
+ uint8_t dw_tdi_scan;
+ uint8_t dr_tdo;
+ uint8_t aw_tms_scan;
+ uint8_t tms_scan[2];
+ int jtag_speed_var;
+ int retval = jtag_get_speed(&jtag_speed_var);
+ assert(retval == ERROR_OK);
+
+ if (ir_scan)
+ amt_jtagaccel_end_state(TAP_IRSHIFT);
+ else
+ amt_jtagaccel_end_state(TAP_DRSHIFT);
+
+ /* Only move if we're not already there */
+ if (tap_get_state() != tap_get_end_state())
+ amt_jtagaccel_state_move();
+
+ amt_jtagaccel_end_state(saved_end_state);
+
+ /* handle unaligned bits at the beginning */
+ if ((scan_size - 1) % 8) {
+ aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1);
+ AMT_AW(aw_tdi_option);
+
+ dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff;
+ AMT_DW(dw_tdi_scan);
+ if (jtag_speed_var > 3 || rtck_enabled)
+ amt_wait_scan_busy();
+
+ if ((type == SCAN_IN) || (type == SCAN_IO)) {
+ AMT_DR(dr_tdo);
+ dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8));
+ buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo);
+ }
+
+ bit_count += (scan_size - 1) % 8;
+ bits_left -= (scan_size - 1) % 8;
+ }
+
+ while (bits_left - 1 >= 8) {
+ dw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff;
+ AMT_DW(dw_tdi_scan);
+ if (jtag_speed_var > 3 || rtck_enabled)
+ amt_wait_scan_busy();
+
+ if ((type == SCAN_IN) || (type == SCAN_IO)) {
+ AMT_DR(dr_tdo);
+ buf_set_u32(buffer, bit_count, 8, dr_tdo);
+ }
+
+ bit_count += 8;
+ bits_left -= 8;
+ }
+
+ tms_scan[0] =
+ amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
+ tms_scan[1] =
+ amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
+ aw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5);
+ AMT_AW(aw_tms_scan);
+ if (jtag_speed_var > 3 || rtck_enabled)
+ amt_wait_scan_busy();
+
+ if ((type == SCAN_IN) || (type == SCAN_IO)) {
+ AMT_DR(dr_tdo);
+ dr_tdo = dr_tdo >> 7;
+ buf_set_u32(buffer, bit_count, 1, dr_tdo);
+ }
+
+ if (tms_scan[0] & 0x80) {
+ aw_tms_scan = 0x40 | (tms_scan[1] & 0x1f);
+ AMT_AW(aw_tms_scan);
+ if (jtag_speed_var > 3 || rtck_enabled)
+ amt_wait_scan_busy();
+ }
+ tap_set_state(tap_get_end_state());
+}
+
+static int amt_jtagaccel_execute_queue(void)
+{
+ struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
+ int scan_size;
+ enum scan_type type;
+ uint8_t *buffer;
+ int retval;
+
+ /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
+ * that wasn't handled by a caller-provided error handler
+ */
+ retval = ERROR_OK;
+
+ while (cmd) {
+ switch (cmd->type) {
+ 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)
+ tap_set_state(TAP_RESET);
+ amt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+ break;
+ case JTAG_RUNTEST:
+#ifdef _DEBUG_JTAG_IO_
+ LOG_DEBUG("runtest %i cycles, end in %i",
+ cmd->cmd.runtest->num_cycles,
+ cmd->cmd.runtest->end_state);
+#endif
+ amt_jtagaccel_end_state(cmd->cmd.runtest->end_state);
+ amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles);
+ break;
+ case JTAG_TLR_RESET:
+#ifdef _DEBUG_JTAG_IO_
+ LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
+#endif
+ amt_jtagaccel_end_state(cmd->cmd.statemove->end_state);
+ amt_jtagaccel_state_move();
+ break;
+ case JTAG_SCAN:
+#ifdef _DEBUG_JTAG_IO_
+ LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
+#endif
+ amt_jtagaccel_end_state(cmd->cmd.scan->end_state);
+ scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
+ type = jtag_scan_type(cmd->cmd.scan);
+ amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
+ if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ if (buffer)
+ free(buffer);
+ break;
+ case JTAG_SLEEP:
+#ifdef _DEBUG_JTAG_IO_
+ LOG_DEBUG("sleep %" PRIi32, cmd->cmd.sleep->us);
+#endif
+ jtag_sleep(cmd->cmd.sleep->us);
+ break;
+ default:
+ LOG_ERROR("BUG: unknown JTAG command type encountered");
+ exit(-1);
+ }
+ cmd = cmd->next;
+ }
+
+ return retval;
+}
+
+#if PARPORT_USE_GIVEIO == 1
+int amt_jtagaccel_get_giveio_access(void)
+{
+ HANDLE h;
+ OSVERSIONINFO version;
+
+ version.dwOSVersionInfoSize = sizeof version;
+ if (!GetVersionEx(&version)) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ return 0;
+
+ h = CreateFile("\\\\.\\giveio",
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ errno = ENODEV;
+ return -1;
+ }
+
+ CloseHandle(h);
+
+ return 0;
+}
+#endif
+
+static int amt_jtagaccel_init(void)
+{
+#if PARPORT_USE_PPDEV == 1
+ char buffer[256];
+ int i = 0;
+ uint8_t control_port;
+#else
+ uint8_t status_port;
+#endif
+ uint8_t ar_status;
+
+#if PARPORT_USE_PPDEV == 1
+ if (device_handle > 0) {
+ LOG_ERROR("device is already opened");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ snprintf(buffer, 256, "/dev/parport%d", amt_jtagaccel_port);
+ device_handle = open(buffer, O_RDWR);
+
+ if (device_handle < 0) {
+ LOG_ERROR(
+ "cannot open device. check it exists and that user read and write rights are set");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ i = ioctl(device_handle, PPCLAIM);
+ if (i < 0) {
+ LOG_ERROR("cannot claim device");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ i = IEEE1284_MODE_EPP;
+ i = ioctl(device_handle, PPSETMODE, &i);
+ if (i < 0) {
+ LOG_ERROR(" cannot set compatible mode to device");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ control_port = 0x00;
+ i = ioctl(device_handle, PPWCONTROL, &control_port);
+
+ control_port = 0x04;
+ i = ioctl(device_handle, PPWCONTROL, &control_port);
+
+#else
+ if (amt_jtagaccel_port == 0) {
+ amt_jtagaccel_port = 0x378;
+ LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
+ }
+
+#if PARPORT_USE_GIVEIO == 1
+ if (amt_jtagaccel_get_giveio_access() != 0) {
+#else /* PARPORT_USE_GIVEIO */
+ if (ioperm(amt_jtagaccel_port, 5, 1) != 0) {
+#endif /* PARPORT_USE_GIVEIO */
+ LOG_ERROR("missing privileges for direct i/o");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ /* prepare epp port
+ * clear timeout */
+ status_port = inb(amt_jtagaccel_port + 1);
+ outb(status_port | 0x1, amt_jtagaccel_port + 1);
+
+ /* reset epp port */
+ outb(0x00, amt_jtagaccel_port + 2);
+ outb(0x04, amt_jtagaccel_port + 2);
+#endif
+
+ if (rtck_enabled) {
+ /* set RTCK enable bit */
+ aw_control_fsm |= 0x02;
+ }
+
+ /* enable JTAG port */
+ aw_control_fsm |= 0x04;
+ AMT_AW(aw_control_fsm);
+
+ enum reset_types jtag_reset_config = jtag_get_reset_config();
+ if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+ aw_control_rst &= ~0x8;
+ else
+ aw_control_rst |= 0x8;
+
+ if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+ aw_control_rst &= ~0x2;
+ else
+ aw_control_rst |= 0x2;
+
+ amt_jtagaccel_reset(0, 0);
+
+ /* read status register */
+ AMT_AR(ar_status);
+ LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status);
+
+ return ERROR_OK;
+}
+
+static int amt_jtagaccel_quit(void)
+{
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command)
+{
+ if (CMD_ARGC == 1) {
+ /* only if the port wasn't overwritten by cmdline */
+ if (amt_jtagaccel_port == 0) {
+ uint16_t port;
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
+ amt_jtagaccel_port = port;
+ } else {
+ LOG_ERROR("The parport port was already configured!");
+ return ERROR_FAIL;
+ }
+ }
+
+ command_print(CMD_CTX, "parport port = %u", amt_jtagaccel_port);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command)
+{
+ if (CMD_ARGC == 0) {
+ command_print(CMD_CTX,
+ "amt_jtagaccel RTCK feature %s",
+ (rtck_enabled) ? "enabled" : "disabled");
+ return ERROR_OK;
+ } else {
+ if (strcmp(CMD_ARGV[0], "enabled") == 0)
+ rtck_enabled = 1;
+ else
+ rtck_enabled = 0;
+ }
+
+ return ERROR_OK;
+}
+
+static const struct command_registration amtjtagaccel_command_handlers[] = {
+ {
+ .name = "parport_port",
+ .handler = &amt_jtagaccel_handle_parport_port_command,
+ .mode = COMMAND_CONFIG,
+ .help = "configure or display the parallel port to use",
+ .usage = "[port_num]",
+ },
+ {
+ /**
+ * @todo Remove this "rtck" command; just use the standard
+ * mechanism to enable/disable adaptive clocking. First
+ * implement the standard mechanism and deprecate "rtck";
+ * after a year or so, it'll be safe to remove this.
+ */
+ .name = "rtck",
+ .handler = &amt_jtagaccel_handle_rtck_command,
+ .mode = COMMAND_CONFIG,
+ .help = "configure or display RTCK support",
+ .usage = "[enable|disable]",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+struct jtag_interface amt_jtagaccel_interface = {
+ .name = "amt_jtagaccel",
+ .commands = amtjtagaccel_command_handlers,
+
+ .init = amt_jtagaccel_init,
+ .quit = amt_jtagaccel_quit,
+ .speed = amt_jtagaccel_speed,
+ .execute_queue = amt_jtagaccel_execute_queue,
+};