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:45 UTC

[02/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/arm-jtag-ew.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/arm-jtag-ew.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/arm-jtag-ew.c
new file mode 100755
index 0000000..4c4cc6d
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/arm-jtag-ew.c
@@ -0,0 +1,795 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Dimitar Dimitrov <di...@gmail.com>            *
+ *   based on Dominic Rath's and Benedikt Sauter's usbprog.c               *
+ *                                                                         *
+ *   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>
+#include <jtag/commands.h>
+#include <usb.h>
+#include "usb_common.h"
+
+#define USB_VID						0x15ba
+#define USB_PID						0x001e
+
+#define ARMJTAGEW_EPT_BULK_OUT		0x01u
+#define ARMJTAGEW_EPT_BULK_IN		0x82u
+
+#define ARMJTAGEW_USB_TIMEOUT		2000
+
+#define ARMJTAGEW_IN_BUFFER_SIZE	(4*1024)
+#define ARMJTAGEW_OUT_BUFFER_SIZE	(4*1024)
+
+/* USB command request codes. */
+#define CMD_GET_VERSION				0x00
+#define CMD_SELECT_DPIMPL			0x10
+#define CMD_SET_TCK_FREQUENCY		0x11
+#define CMD_GET_TCK_FREQUENCY		0x12
+#define CMD_MEASURE_MAX_TCK_FREQ	0x15
+#define CMD_MEASURE_RTCK_RESPONSE	0x16
+#define CMD_TAP_SHIFT				0x17
+#define CMD_SET_TAPHW_STATE			0x20
+#define CMD_GET_TAPHW_STATE			0x21
+#define CMD_TGPWR_SETUP				0x22
+
+/* Global USB buffers */
+static uint8_t usb_in_buffer[ARMJTAGEW_IN_BUFFER_SIZE];
+static uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE];
+
+/* Queue command functions */
+static void armjtagew_end_state(tap_state_t state);
+static void armjtagew_state_move(void);
+static void armjtagew_path_move(int num_states, tap_state_t *path);
+static void armjtagew_runtest(int num_cycles);
+static void armjtagew_scan(bool ir_scan,
+		enum scan_type type,
+		uint8_t *buffer,
+		int scan_size,
+		struct scan_command *command);
+static void armjtagew_reset(int trst, int srst);
+/* static void armjtagew_simple_command(uint8_t command); */
+static int armjtagew_get_status(void);
+
+/* tap buffer functions */
+static void armjtagew_tap_init(void);
+static int armjtagew_tap_execute(void);
+static void armjtagew_tap_ensure_space(int scans, int bits);
+static void armjtagew_tap_append_step(int tms, int tdi);
+static void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command);
+
+/* ARM-JTAG-EW lowlevel functions */
+struct armjtagew {
+	struct usb_dev_handle *usb_handle;
+};
+
+static struct armjtagew *armjtagew_usb_open(void);
+static void armjtagew_usb_close(struct armjtagew *armjtagew);
+static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length);
+static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length);
+static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length);
+
+/* helper functions */
+static int armjtagew_get_version_info(void);
+
+#ifdef _DEBUG_USB_COMMS_
+static void armjtagew_debug_buffer(uint8_t *buffer, int length);
+#endif
+
+static struct armjtagew *armjtagew_handle;
+
+/**************************************************************************
+ * External interface implementation */
+
+static int armjtagew_execute_queue(void)
+{
+	struct jtag_command *cmd = jtag_command_queue;
+	int scan_size;
+	enum scan_type type;
+	uint8_t *buffer;
+
+	while (cmd != NULL) {
+		switch (cmd->type) {
+			case JTAG_RUNTEST:
+				DEBUG_JTAG_IO("runtest %i cycles, end in %i",
+						cmd->cmd.runtest->num_cycles, \
+						cmd->cmd.runtest->end_state);
+
+				armjtagew_end_state(cmd->cmd.runtest->end_state);
+				armjtagew_runtest(cmd->cmd.runtest->num_cycles);
+				break;
+
+			case JTAG_TLR_RESET:
+				DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
+
+				armjtagew_end_state(cmd->cmd.statemove->end_state);
+				armjtagew_state_move();
+				break;
+
+			case JTAG_PATHMOVE:
+				DEBUG_JTAG_IO("pathmove: %i states, end in %i", \
+						cmd->cmd.pathmove->num_states, \
+						cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+
+				armjtagew_path_move(cmd->cmd.pathmove->num_states,
+						cmd->cmd.pathmove->path);
+				break;
+
+			case JTAG_SCAN:
+				DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state);
+
+				armjtagew_end_state(cmd->cmd.scan->end_state);
+
+				scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
+				DEBUG_JTAG_IO("scan input, length = %d", scan_size);
+
+#ifdef _DEBUG_USB_COMMS_
+				armjtagew_debug_buffer(buffer, (scan_size + 7) / 8);
+#endif
+				type = jtag_scan_type(cmd->cmd.scan);
+				armjtagew_scan(cmd->cmd.scan->ir_scan,
+						type, buffer,
+						scan_size, cmd->cmd.scan);
+				break;
+
+			case JTAG_RESET:
+				DEBUG_JTAG_IO("reset trst: %i srst %i",
+						cmd->cmd.reset->trst,
+						cmd->cmd.reset->srst);
+
+				armjtagew_tap_execute();
+
+				if (cmd->cmd.reset->trst == 1)
+					tap_set_state(TAP_RESET);
+				armjtagew_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+				break;
+
+			case JTAG_SLEEP:
+				DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
+				armjtagew_tap_execute();
+				jtag_sleep(cmd->cmd.sleep->us);
+				break;
+
+			default:
+				LOG_ERROR("BUG: unknown JTAG command type encountered");
+				exit(-1);
+		}
+		cmd = cmd->next;
+	}
+
+	return armjtagew_tap_execute();
+}
+
+/* Sets speed in kHz. */
+static int armjtagew_speed(int speed)
+{
+	int result;
+	int speed_real;
+
+
+	usb_out_buffer[0] = CMD_SET_TCK_FREQUENCY;
+	buf_set_u32(usb_out_buffer + 1, 0, 32, speed*1000);
+
+	result = armjtagew_usb_message(armjtagew_handle, 5, 4);
+
+	if (result < 0) {
+		LOG_ERROR("ARM-JTAG-EW setting speed failed (%d)", result);
+		return ERROR_JTAG_DEVICE_ERROR;
+	}
+
+	usb_out_buffer[0] = CMD_GET_TCK_FREQUENCY;
+	result = armjtagew_usb_message(armjtagew_handle, 1, 4);
+	speed_real = (int)buf_get_u32(usb_in_buffer, 0, 32) / 1000;
+	if (result < 0) {
+		LOG_ERROR("ARM-JTAG-EW getting speed failed (%d)", result);
+		return ERROR_JTAG_DEVICE_ERROR;
+	} else
+		LOG_INFO("Requested speed %dkHz, emulator reported %dkHz.", speed, speed_real);
+
+	return ERROR_OK;
+}
+
+static int armjtagew_khz(int khz, int *jtag_speed)
+{
+	*jtag_speed = khz;
+
+	return ERROR_OK;
+}
+
+static int armjtagew_speed_div(int speed, int *khz)
+{
+	*khz = speed;
+
+	return ERROR_OK;
+}
+
+static int armjtagew_init(void)
+{
+	int check_cnt;
+
+	armjtagew_handle = armjtagew_usb_open();
+
+	if (armjtagew_handle == 0) {
+		LOG_ERROR(
+			"Cannot find ARM-JTAG-EW Interface! Please check connection and permissions.");
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	check_cnt = 0;
+	while (check_cnt < 3) {
+		if (armjtagew_get_version_info() == ERROR_OK) {
+			/* attempt to get status */
+			armjtagew_get_status();
+			break;
+		}
+
+		check_cnt++;
+	}
+
+	if (check_cnt == 3)
+		LOG_INFO("ARM-JTAG-EW initial read failed, don't worry");
+
+	/* Initial JTAG speed (for reset and initialization): 32 kHz */
+	armjtagew_speed(32);
+
+	LOG_INFO("ARM-JTAG-EW JTAG Interface ready");
+
+	armjtagew_reset(0, 0);
+	armjtagew_tap_init();
+
+	return ERROR_OK;
+}
+
+static int armjtagew_quit(void)
+{
+	armjtagew_usb_close(armjtagew_handle);
+	return ERROR_OK;
+}
+
+/**************************************************************************
+ * Queue command implementations */
+
+static void armjtagew_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);
+	}
+}
+
+/* Goes to the end state. */
+static void armjtagew_state_move(void)
+{
+	int i;
+	int tms = 0;
+	uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
+	int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
+
+	for (i = 0; i < tms_count; i++) {
+		tms = (tms_scan >> i) & 1;
+		armjtagew_tap_append_step(tms, 0);
+	}
+
+	tap_set_state(tap_get_end_state());
+}
+
+static void armjtagew_path_move(int num_states, tap_state_t *path)
+{
+	int i;
+
+	for (i = 0; i < num_states; i++) {
+		/*
+		 * TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.
+		 * Either handle that here, or update the documentation with examples
+		 * how to fix that in the configuration files.
+		 */
+		if (path[i] == tap_state_transition(tap_get_state(), false))
+			armjtagew_tap_append_step(0, 0);
+		else if (path[i] == tap_state_transition(tap_get_state(), true))
+			armjtagew_tap_append_step(1, 0);
+		else {
+			LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
+				tap_state_name(tap_get_state()), tap_state_name(path[i]));
+			exit(-1);
+		}
+
+		tap_set_state(path[i]);
+	}
+
+	tap_set_end_state(tap_get_state());
+}
+
+static void armjtagew_runtest(int num_cycles)
+{
+	int i;
+
+	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) {
+		armjtagew_end_state(TAP_IDLE);
+		armjtagew_state_move();
+	}
+
+	/* execute num_cycles */
+	for (i = 0; i < num_cycles; i++)
+		armjtagew_tap_append_step(0, 0);
+
+	/* finish in end_state */
+	armjtagew_end_state(saved_end_state);
+	if (tap_get_state() != tap_get_end_state())
+		armjtagew_state_move();
+}
+
+static void armjtagew_scan(bool ir_scan,
+	enum scan_type type,
+	uint8_t *buffer,
+	int scan_size,
+	struct scan_command *command)
+{
+	tap_state_t saved_end_state;
+
+	armjtagew_tap_ensure_space(1, scan_size + 8);
+
+	saved_end_state = tap_get_end_state();
+
+	/* Move to appropriate scan state */
+	armjtagew_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
+
+	/* Only move if we're not already there */
+	if (tap_get_state() != tap_get_end_state())
+		armjtagew_state_move();
+
+	armjtagew_end_state(saved_end_state);
+
+	/* Scan */
+	armjtagew_tap_append_scan(scan_size, buffer, command);
+
+	/* We are in Exit1, go to Pause */
+	armjtagew_tap_append_step(0, 0);
+
+	tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
+
+	if (tap_get_state() != tap_get_end_state())
+		armjtagew_state_move();
+}
+
+static void armjtagew_reset(int trst, int srst)
+{
+	const uint8_t trst_mask = (1u << 5);
+	const uint8_t srst_mask = (1u << 6);
+	uint8_t val = 0;
+	uint8_t outp_en = 0;
+	uint8_t change_mask = 0;
+	int result;
+
+	LOG_DEBUG("trst: %i, srst: %i", trst, srst);
+
+	if (srst == 0) {
+		val |= srst_mask;
+		outp_en &= ~srst_mask;		/* tristate */
+		change_mask |= srst_mask;
+	} else if (srst == 1) {
+		val &= ~srst_mask;
+		outp_en |= srst_mask;
+		change_mask |= srst_mask;
+	}
+
+	if (trst == 0) {
+		val |= trst_mask;
+		outp_en &= ~trst_mask;		/* tristate */
+		change_mask |= trst_mask;
+	} else if (trst == 1) {
+		val &= ~trst_mask;
+		outp_en |= trst_mask;
+		change_mask |= trst_mask;
+	}
+
+	usb_out_buffer[0] = CMD_SET_TAPHW_STATE;
+	usb_out_buffer[1] = val;
+	usb_out_buffer[2] = outp_en;
+	usb_out_buffer[3] = change_mask;
+	result = armjtagew_usb_write(armjtagew_handle, 4);
+	if (result != 4)
+		LOG_ERROR("ARM-JTAG-EW TRST/SRST pin set failed failed (%d)", result);
+}
+
+static int armjtagew_get_status(void)
+{
+	int result;
+
+	usb_out_buffer[0] = CMD_GET_TAPHW_STATE;
+	result = armjtagew_usb_message(armjtagew_handle, 1, 12);
+
+	if (result == 0) {
+		unsigned int u_tg = buf_get_u32(usb_in_buffer, 0, 16);
+		LOG_INFO(
+			"U_tg = %d mV, U_aux = %d mV, U_tgpwr = %d mV, I_tgpwr = %d mA, D1 = %d, Target power %s %s",
+			(int)(buf_get_u32(usb_in_buffer + 0, 0, 16)),
+			(int)(buf_get_u32(usb_in_buffer + 2, 0, 16)),
+			(int)(buf_get_u32(usb_in_buffer + 4, 0, 16)),
+			(int)(buf_get_u32(usb_in_buffer + 6, 0, 16)),
+			usb_in_buffer[9],
+			usb_in_buffer[11] ? "OVERCURRENT" : "OK",
+			usb_in_buffer[10] ? "enabled" : "disabled");
+
+		if (u_tg < 1500)
+			LOG_ERROR("Vref too low. Check Target Power");
+	} else
+		LOG_ERROR("ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)", result);
+
+	return ERROR_OK;
+}
+
+static int armjtagew_get_version_info(void)
+{
+	int result;
+	char sn[16];
+	char auxinfo[257];
+
+	/* query hardware version */
+	usb_out_buffer[0] = CMD_GET_VERSION;
+	result = armjtagew_usb_message(armjtagew_handle, 1, 4 + 15 + 256);
+
+	if (result != 0) {
+		LOG_ERROR("ARM-JTAG-EW command CMD_GET_VERSION failed (%d)", result);
+		return ERROR_JTAG_DEVICE_ERROR;
+	}
+
+	memcpy(sn, usb_in_buffer + 4, 15);
+	sn[15] = '\0';
+	memcpy(auxinfo, usb_in_buffer + 4+15, 256);
+	auxinfo[256] = '\0';
+
+	LOG_INFO(
+		"ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s",	\
+		usb_in_buffer[1],
+		usb_in_buffer[0], \
+		isgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X', \
+		sn,
+		auxinfo);
+
+	if (1 != usb_in_buffer[1] || 6 != usb_in_buffer[0])
+		LOG_WARNING(
+			"ARM-JTAG-EW firmware version %d.%d is untested with this version of OpenOCD. You might experience unexpected behavior.",
+			usb_in_buffer[1],
+			usb_in_buffer[0]);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(armjtagew_handle_armjtagew_info_command)
+{
+	if (armjtagew_get_version_info() == ERROR_OK) {
+		/* attempt to get status */
+		armjtagew_get_status();
+	}
+
+	return ERROR_OK;
+}
+
+static const struct command_registration armjtagew_command_handlers[] = {
+	{
+		.name = "armjtagew_info",
+		.handler = &armjtagew_handle_armjtagew_info_command,
+		.mode = COMMAND_EXEC,
+		.help = "query armjtagew info",
+	},
+	COMMAND_REGISTRATION_DONE
+};
+
+struct jtag_interface armjtagew_interface = {
+	.name = "arm-jtag-ew",
+	.commands = armjtagew_command_handlers,
+	.transports = jtag_only,
+	.execute_queue = armjtagew_execute_queue,
+	.speed = armjtagew_speed,
+	.speed_div = armjtagew_speed_div,
+	.khz = armjtagew_khz,
+	.init = armjtagew_init,
+	.quit = armjtagew_quit,
+};
+
+/**************************************************************************
+ * ARM-JTAG-EW tap functions */
+
+/* 2048 is the max value we can use here */
+#define ARMJTAGEW_TAP_BUFFER_SIZE 2048
+
+static int tap_length;
+static uint8_t tms_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
+static uint8_t tdi_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
+static uint8_t tdo_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
+
+struct pending_scan_result {
+	int first;	/* First bit position in tdo_buffer to read */
+	int length;	/* Number of bits to read */
+	struct scan_command *command;	/* Corresponding scan command */
+	uint8_t *buffer;
+};
+
+#define MAX_PENDING_SCAN_RESULTS 256
+
+static int pending_scan_results_length;
+static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
+
+static int last_tms;
+
+static void armjtagew_tap_init(void)
+{
+	tap_length = 0;
+	pending_scan_results_length = 0;
+}
+
+static void armjtagew_tap_ensure_space(int scans, int bits)
+{
+	int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
+	int available_bits = ARMJTAGEW_TAP_BUFFER_SIZE * 8 - tap_length;
+
+	if (scans > available_scans || bits > available_bits)
+		armjtagew_tap_execute();
+}
+
+static void armjtagew_tap_append_step(int tms, int tdi)
+{
+	last_tms = tms;
+	int index_local = tap_length / 8;
+
+	if (index_local < ARMJTAGEW_TAP_BUFFER_SIZE) {
+		int bit_index = tap_length % 8;
+		uint8_t bit = 1 << bit_index;
+
+		if (tms)
+			tms_buffer[index_local] |= bit;
+		else
+			tms_buffer[index_local] &= ~bit;
+
+		if (tdi)
+			tdi_buffer[index_local] |= bit;
+		else
+			tdi_buffer[index_local] &= ~bit;
+
+		tap_length++;
+	} else
+		LOG_ERROR("armjtagew_tap_append_step, overflow");
+}
+
+void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)
+{
+	struct pending_scan_result *pending_scan_result =
+		&pending_scan_results_buffer[pending_scan_results_length];
+	int i;
+
+	pending_scan_result->first = tap_length;
+	pending_scan_result->length = length;
+	pending_scan_result->command = command;
+	pending_scan_result->buffer = buffer;
+
+	for (i = 0; i < length; i++)
+		armjtagew_tap_append_step((i < length-1 ? 0 : 1), (buffer[i/8] >> (i%8)) & 1);
+	pending_scan_results_length++;
+}
+
+/* Pad and send a tap sequence to the device, and receive the answer.
+ * For the purpose of padding we assume that we are in idle or pause state. */
+static int armjtagew_tap_execute(void)
+{
+	int byte_length;
+	int tms_offset;
+	int tdi_offset;
+	int i;
+	int result;
+
+	if (tap_length > 0) {
+		/* Pad last byte so that tap_length is divisible by 8 */
+		while (tap_length % 8 != 0) {
+			/* More of the last TMS value keeps us in the same state,
+			 * analogous to free-running JTAG interfaces. */
+			armjtagew_tap_append_step(last_tms, 0);
+		}
+
+		byte_length = tap_length / 8;
+
+		usb_out_buffer[0] = CMD_TAP_SHIFT;
+		buf_set_u32(usb_out_buffer + 1, 0, 16, byte_length);
+
+		tms_offset = 3;
+		for (i = 0; i < byte_length; i++)
+			usb_out_buffer[tms_offset + i] = flip_u32(tms_buffer[i], 8);
+
+		tdi_offset = tms_offset + byte_length;
+		for (i = 0; i < byte_length; i++)
+			usb_out_buffer[tdi_offset + i] = flip_u32(tdi_buffer[i], 8);
+
+		result = armjtagew_usb_message(armjtagew_handle,
+				3 + 2 * byte_length,
+				byte_length + 4);
+
+		if (result == 0) {
+			int stat_local;
+
+			stat_local = (int)buf_get_u32(usb_in_buffer + byte_length, 0, 32);
+			if (stat_local) {
+				LOG_ERROR(
+					"armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command",
+					stat_local);
+				return ERROR_JTAG_QUEUE_FAILED;
+			}
+
+			for (i = 0; i < byte_length; i++)
+				tdo_buffer[i] = flip_u32(usb_in_buffer[i], 8);
+
+			for (i = 0; i < pending_scan_results_length; i++) {
+				struct pending_scan_result *pending_scan_result =
+					&pending_scan_results_buffer[i];
+				uint8_t *buffer = pending_scan_result->buffer;
+				int length = pending_scan_result->length;
+				int first = pending_scan_result->first;
+				struct scan_command *command = pending_scan_result->command;
+
+				/* Copy to buffer */
+				buf_set_buf(tdo_buffer, first, buffer, 0, length);
+
+				DEBUG_JTAG_IO("pending scan result, length = %d", length);
+
+#ifdef _DEBUG_USB_COMMS_
+				armjtagew_debug_buffer(buffer, byte_length);
+#endif
+
+				if (jtag_read_buffer(buffer, command) != ERROR_OK) {
+					armjtagew_tap_init();
+					return ERROR_JTAG_QUEUE_FAILED;
+				}
+
+				if (pending_scan_result->buffer != NULL)
+					free(pending_scan_result->buffer);
+			}
+		} else {
+			LOG_ERROR("armjtagew_tap_execute, wrong result %d, expected %d",
+				result,
+				byte_length);
+			return ERROR_JTAG_QUEUE_FAILED;
+		}
+
+		armjtagew_tap_init();
+	}
+
+	return ERROR_OK;
+}
+
+/****************************************************************************
+ * JLink USB low-level functions */
+
+static struct armjtagew *armjtagew_usb_open()
+{
+	usb_init();
+
+	const uint16_t vids[] = { USB_VID, 0 };
+	const uint16_t pids[] = { USB_PID, 0 };
+	struct usb_dev_handle *dev;
+	if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
+		return NULL;
+
+	struct armjtagew *result = malloc(sizeof(struct armjtagew));
+	result->usb_handle = dev;
+
+#if 0
+	/* usb_set_configuration required under win32 */
+	usb_set_configuration(dev, dev->config[0].bConfigurationValue);
+#endif
+	usb_claim_interface(dev, 0);
+#if 0
+	/*
+	 * This makes problems under Mac OS X. And is not needed
+	 * under Windows. Hopefully this will not break a linux build
+	 */
+	usb_set_altinterface(dev, 0);
+#endif
+	return result;
+}
+
+static void armjtagew_usb_close(struct armjtagew *armjtagew)
+{
+	usb_close(armjtagew->usb_handle);
+	free(armjtagew);
+}
+
+/* Send a message and receive the reply. */
+static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length)
+{
+	int result;
+
+	result = armjtagew_usb_write(armjtagew, out_length);
+	if (result == out_length) {
+		result = armjtagew_usb_read(armjtagew, in_length);
+		if (result != in_length) {
+			LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
+				in_length,
+				result);
+			return -1;
+		}
+	} else {
+		LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
+		return -1;
+	}
+	return 0;
+}
+
+/* Write data from out_buffer to USB. */
+static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length)
+{
+	int result;
+
+	if (out_length > ARMJTAGEW_OUT_BUFFER_SIZE) {
+		LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)",
+			out_length,
+			ARMJTAGEW_OUT_BUFFER_SIZE);
+		return -1;
+	}
+
+	result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT, \
+			(char *)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT);
+
+	DEBUG_JTAG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result);
+
+#ifdef _DEBUG_USB_COMMS_
+	armjtagew_debug_buffer(usb_out_buffer, out_length);
+#endif
+	return result;
+}
+
+/* Read data from USB into in_buffer. */
+static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)
+{
+	int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN, \
+			(char *)usb_in_buffer, exp_in_length, ARMJTAGEW_USB_TIMEOUT);
+
+	DEBUG_JTAG_IO("armjtagew_usb_read, result = %d", result);
+
+#ifdef _DEBUG_USB_COMMS_
+	armjtagew_debug_buffer(usb_in_buffer, result);
+#endif
+	return result;
+}
+
+#ifdef _DEBUG_USB_COMMS_
+#define BYTES_PER_LINE  16
+
+static void armjtagew_debug_buffer(uint8_t *buffer, int length)
+{
+	char line[81];
+	char s[4];
+	int i;
+	int j;
+
+	for (i = 0; i < length; i += BYTES_PER_LINE) {
+		snprintf(line, 5, "%04x", i);
+		for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
+			snprintf(s, 4, " %02x", buffer[j]);
+			strcat(line, s);
+		}
+		LOG_DEBUG("%s", line);
+
+		/* Prevent GDB timeout (writing to log might take some time) */
+		keep_alive();
+	}
+}
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/at91rm9200.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/at91rm9200.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/at91rm9200.c
new file mode 100755
index 0000000..d7e11df
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/at91rm9200.c
@@ -0,0 +1,268 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Anders Larsen                                   *
+ *   al@alarsen.net                                                        *
+ *                                                                         *
+ *   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>
+#include "bitbang.h"
+
+#include <sys/mman.h>
+
+/* AT91RM9200 */
+#define AT91C_BASE_SYS	(0xfffff000)
+
+/* GPIO assignment */
+#define PIOA	(0 << 7)
+#define PIOB	(1 << 7)
+#define PIOC	(2 << 7)
+#define PIOD	(3 << 7)
+
+#define PIO_PER		(0)		/* PIO enable */
+#define PIO_OER		(4)		/* output enable */
+#define PIO_ODR		(5)		/* output disable */
+#define PIO_SODR	(12)		/* set output data */
+#define PIO_CODR	(13)		/* clear output data */
+#define PIO_PDSR	(15)		/* pin data status */
+#define PIO_PPUER	(25)		/* pull-up enable */
+
+#define NC	(0)			/* not connected */
+#define P0	(1 << 0)
+#define P1	(1 << 1)
+#define P2	(1 << 2)
+#define P3	(1 << 3)
+#define P4	(1 << 4)
+#define P5	(1 << 5)
+#define P6	(1 << 6)
+#define P7	(1 << 7)
+#define P8	(1 << 8)
+#define P9	(1 << 9)
+#define P10	(1 << 10)
+#define P11	(1 << 11)
+#define P12	(1 << 12)
+#define P13	(1 << 13)
+#define P14	(1 << 14)
+#define P15	(1 << 15)
+#define P16	(1 << 16)
+#define P17	(1 << 17)
+#define P18	(1 << 18)
+#define P19	(1 << 19)
+#define P20	(1 << 20)
+#define P21	(1 << 21)
+#define P22	(1 << 22)
+#define P23	(1 << 23)
+#define P24	(1 << 24)
+#define P25	(1 << 25)
+#define P26	(1 << 26)
+#define P27	(1 << 27)
+#define P28	(1 << 28)
+#define P29	(1 << 29)
+#define P30	(1 << 30)
+#define P31	(1 << 31)
+
+struct device_t {
+	const char *name;
+	int TDO_PIO;	/* PIO holding TDO */
+	uint32_t TDO_MASK;	/* TDO bitmask */
+	int TRST_PIO;	/* PIO holding TRST */
+	uint32_t TRST_MASK;	/* TRST bitmask */
+	int TMS_PIO;	/* PIO holding TMS */
+	uint32_t TMS_MASK;	/* TMS bitmask */
+	int TCK_PIO;	/* PIO holding TCK */
+	uint32_t TCK_MASK;	/* TCK bitmask */
+	int TDI_PIO;	/* PIO holding TDI */
+	uint32_t TDI_MASK;	/* TDI bitmask */
+	int SRST_PIO;	/* PIO holding SRST */
+	uint32_t SRST_MASK;	/* SRST bitmask */
+};
+
+static const struct device_t devices[] = {
+	{ "rea_ecr", PIOD, P27, PIOA, NC, PIOD, P23, PIOD, P24, PIOD, P26, PIOC, P5 },
+	{ .name = NULL },
+};
+
+/* configuration */
+static char *at91rm9200_device;
+
+/* interface variables
+ */
+static const struct device_t *device;
+static int dev_mem_fd;
+static void *sys_controller;
+static uint32_t *pio_base;
+
+/* low level command set
+ */
+static int at91rm9200_read(void);
+static void at91rm9200_write(int tck, int tms, int tdi);
+static void at91rm9200_reset(int trst, int srst);
+
+static int at91rm9200_init(void);
+static int at91rm9200_quit(void);
+
+static struct bitbang_interface at91rm9200_bitbang = {
+	.read = at91rm9200_read,
+	.write = at91rm9200_write,
+	.reset = at91rm9200_reset,
+	.blink = 0
+};
+
+static int at91rm9200_read(void)
+{
+	return (pio_base[device->TDO_PIO + PIO_PDSR] & device->TDO_MASK) != 0;
+}
+
+static void at91rm9200_write(int tck, int tms, int tdi)
+{
+	if (tck)
+		pio_base[device->TCK_PIO + PIO_SODR] = device->TCK_MASK;
+	else
+		pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;
+
+	if (tms)
+		pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;
+	else
+		pio_base[device->TMS_PIO + PIO_CODR] = device->TMS_MASK;
+
+	if (tdi)
+		pio_base[device->TDI_PIO + PIO_SODR] = device->TDI_MASK;
+	else
+		pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;
+}
+
+/* (1) assert or (0) deassert reset lines */
+static void at91rm9200_reset(int trst, int srst)
+{
+	if (trst == 0)
+		pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;
+	else if (trst == 1)
+		pio_base[device->TRST_PIO + PIO_CODR] = device->TRST_MASK;
+
+	if (srst == 0)
+		pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;
+	else if (srst == 1)
+		pio_base[device->SRST_PIO + PIO_CODR] = device->SRST_MASK;
+}
+
+COMMAND_HANDLER(at91rm9200_handle_device_command)
+{
+	if (CMD_ARGC == 0)
+		return ERROR_COMMAND_SYNTAX_ERROR;
+
+	/* only if the device name wasn't overwritten by cmdline */
+	if (at91rm9200_device == 0) {
+		at91rm9200_device = malloc(strlen(CMD_ARGV[0]) + sizeof(char));
+		strcpy(at91rm9200_device, CMD_ARGV[0]);
+	}
+
+	return ERROR_OK;
+}
+
+static const struct command_registration at91rm9200_command_handlers[] = {
+	{
+		.name = "at91rm9200_device",
+		.handler = &at91rm9200_handle_device_command,
+		.mode = COMMAND_CONFIG,
+		.help = "query armjtagew info",
+	},
+	COMMAND_REGISTRATION_DONE
+};
+
+struct jtag_interface at91rm9200_interface = {
+	.name = "at91rm9200",
+	.execute_queue = bitbang_execute_queue,
+	.commands = at91rm9200_command_handlers,
+	.init = at91rm9200_init,
+	.quit = at91rm9200_quit,
+};
+
+static int at91rm9200_init(void)
+{
+	const struct device_t *cur_device;
+
+	cur_device = devices;
+
+	if (at91rm9200_device == NULL || at91rm9200_device[0] == 0) {
+		at91rm9200_device = "rea_ecr";
+		LOG_WARNING("No at91rm9200 device specified, using default 'rea_ecr'");
+	}
+
+	while (cur_device->name) {
+		if (strcmp(cur_device->name, at91rm9200_device) == 0) {
+			device = cur_device;
+			break;
+		}
+		cur_device++;
+	}
+
+	if (!device) {
+		LOG_ERROR("No matching device found for %s", at91rm9200_device);
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	bitbang_interface = &at91rm9200_bitbang;
+
+	dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
+	if (dev_mem_fd < 0) {
+		perror("open");
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	sys_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
+				MAP_SHARED, dev_mem_fd, AT91C_BASE_SYS);
+	if (sys_controller == MAP_FAILED) {
+		perror("mmap");
+		close(dev_mem_fd);
+		return ERROR_JTAG_INIT_FAILED;
+	}
+	pio_base = (uint32_t *)sys_controller + 0x100;
+
+	/*
+	 * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
+	 * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.
+	 */
+	pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;
+	pio_base[device->TDI_PIO + PIO_OER] = device->TDI_MASK;
+	pio_base[device->TDI_PIO + PIO_PER] = device->TDI_MASK;
+	pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;
+	pio_base[device->TCK_PIO + PIO_OER] = device->TCK_MASK;
+	pio_base[device->TCK_PIO + PIO_PER] = device->TCK_MASK;
+	pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;
+	pio_base[device->TMS_PIO + PIO_OER] = device->TMS_MASK;
+	pio_base[device->TMS_PIO + PIO_PER] = device->TMS_MASK;
+	pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;
+	pio_base[device->TRST_PIO + PIO_OER] = device->TRST_MASK;
+	pio_base[device->TRST_PIO + PIO_PER] = device->TRST_MASK;
+	pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;
+	pio_base[device->SRST_PIO + PIO_OER] = device->SRST_MASK;
+	pio_base[device->SRST_PIO + PIO_PER] = device->SRST_MASK;
+	pio_base[device->TDO_PIO + PIO_ODR] = device->TDO_MASK;
+	pio_base[device->TDO_PIO + PIO_PPUER] = device->TDO_MASK;
+	pio_base[device->TDO_PIO + PIO_PER] = device->TDO_MASK;
+
+	return ERROR_OK;
+}
+
+static int at91rm9200_quit(void)
+{
+
+	return ERROR_OK;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bcm2835gpio.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bcm2835gpio.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bcm2835gpio.c
new file mode 100755
index 0000000..e1cc56c
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bcm2835gpio.c
@@ -0,0 +1,533 @@
+/***************************************************************************
+ *   Copyright (C) 2013 by Paul Fertser, fercerpav@gmail.com               *
+ *                                                                         *
+ *   Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *
+ *   Based on at91rm9200.c (c) Anders Larsen                               *
+ *   and RPi GPIO examples by Gert van Loo & Dom                           *
+ *                                                                         *
+ *   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>
+#include "bitbang.h"
+
+#include <sys/mman.h>
+
+uint32_t bcm2835_peri_base = 0x20000000;
+#define BCM2835_GPIO_BASE	(bcm2835_peri_base + 0x200000) /* GPIO controller */
+
+#define BCM2835_PADS_GPIO_0_27		(bcm2835_peri_base + 0x100000)
+#define BCM2835_PADS_GPIO_0_27_OFFSET	(0x2c / 4)
+
+/* GPIO setup macros */
+#define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7)
+#define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0)
+#define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \
+		INP_GPIO(g);						\
+		*(pio_base+((g)/10)) |=  ((m)<<(((g)%10)*3)); } while (0)
+#define OUT_GPIO(g) SET_MODE_GPIO(g, 1)
+
+#define GPIO_SET (*(pio_base+7))  /* sets   bits which are 1, ignores bits which are 0 */
+#define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */
+#define GPIO_LEV (*(pio_base+13)) /* current level of the pin */
+
+static int dev_mem_fd;
+static volatile uint32_t *pio_base;
+
+static int bcm2835gpio_read(void);
+static void bcm2835gpio_write(int tck, int tms, int tdi);
+static void bcm2835gpio_reset(int trst, int srst);
+
+static int bcm2835_swdio_read(void);
+static void bcm2835_swdio_drive(bool is_output);
+
+static int bcm2835gpio_init(void);
+static int bcm2835gpio_quit(void);
+
+static struct bitbang_interface bcm2835gpio_bitbang = {
+	.read = bcm2835gpio_read,
+	.write = bcm2835gpio_write,
+	.reset = bcm2835gpio_reset,
+	.swdio_read = bcm2835_swdio_read,
+	.swdio_drive = bcm2835_swdio_drive,
+	.blink = NULL
+};
+
+/* GPIO numbers for each signal. Negative values are invalid */
+static int tck_gpio = -1;
+static int tck_gpio_mode;
+static int tms_gpio = -1;
+static int tms_gpio_mode;
+static int tdi_gpio = -1;
+static int tdi_gpio_mode;
+static int tdo_gpio = -1;
+static int tdo_gpio_mode;
+static int trst_gpio = -1;
+static int trst_gpio_mode;
+static int srst_gpio = -1;
+static int srst_gpio_mode;
+static int swclk_gpio = -1;
+static int swclk_gpio_mode;
+static int swdio_gpio = -1;
+static int swdio_gpio_mode;
+
+/* Transition delay coefficients */
+static int speed_coeff = 113714;
+static int speed_offset = 28;
+static unsigned int jtag_delay;
+
+static int bcm2835gpio_read(void)
+{
+	return !!(GPIO_LEV & 1<<tdo_gpio);
+}
+
+static void bcm2835gpio_write(int tck, int tms, int tdi)
+{
+	uint32_t set = tck<<tck_gpio | tms<<tms_gpio | tdi<<tdi_gpio;
+	uint32_t clear = !tck<<tck_gpio | !tms<<tms_gpio | !tdi<<tdi_gpio;
+
+	GPIO_SET = set;
+	GPIO_CLR = clear;
+
+	for (unsigned int i = 0; i < jtag_delay; i++)
+		asm volatile ("");
+}
+
+static void bcm2835gpio_swd_write(int tck, int tms, int tdi)
+{
+	uint32_t set = tck<<swclk_gpio | tdi<<swdio_gpio;
+	uint32_t clear = !tck<<swclk_gpio | !tdi<<swdio_gpio;
+
+	GPIO_SET = set;
+	GPIO_CLR = clear;
+
+	for (unsigned int i = 0; i < jtag_delay; i++)
+		asm volatile ("");
+}
+
+/* (1) assert or (0) deassert reset lines */
+static void bcm2835gpio_reset(int trst, int srst)
+{
+	uint32_t set = 0;
+	uint32_t clear = 0;
+
+	if (trst_gpio > 0) {
+		set |= !trst<<trst_gpio;
+		clear |= trst<<trst_gpio;
+	}
+
+	if (srst_gpio > 0) {
+		set |= !srst<<srst_gpio;
+		clear |= srst<<srst_gpio;
+	}
+
+	GPIO_SET = set;
+	GPIO_CLR = clear;
+}
+
+static void bcm2835_swdio_drive(bool is_output)
+{
+	if (is_output)
+		OUT_GPIO(swdio_gpio);
+	else
+		INP_GPIO(swdio_gpio);
+}
+
+static int bcm2835_swdio_read(void)
+{
+	return !!(GPIO_LEV & 1 << swdio_gpio);
+}
+
+static int bcm2835gpio_khz(int khz, int *jtag_speed)
+{
+	if (!khz) {
+		LOG_DEBUG("RCLK not supported");
+		return ERROR_FAIL;
+	}
+	*jtag_speed = speed_coeff/khz - speed_offset;
+	if (*jtag_speed < 0)
+		*jtag_speed = 0;
+	return ERROR_OK;
+}
+
+static int bcm2835gpio_speed_div(int speed, int *khz)
+{
+	*khz = speed_coeff/(speed + speed_offset);
+	return ERROR_OK;
+}
+
+static int bcm2835gpio_speed(int speed)
+{
+	jtag_delay = speed;
+	return ERROR_OK;
+}
+
+static int is_gpio_valid(int gpio)
+{
+	return gpio >= 0 && gpio <= 53;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums)
+{
+	if (CMD_ARGC == 4) {
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
+	} else if (CMD_ARGC != 0) {
+		return ERROR_COMMAND_SYNTAX_ERROR;
+	}
+
+	command_print(CMD_CTX,
+			"BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
+			tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
+
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
+
+	command_print(CMD_CTX, "BCM2835 GPIO config: tck = %d", tck_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
+
+	command_print(CMD_CTX, "BCM2835 GPIO config: tms = %d", tms_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
+
+	command_print(CMD_CTX, "BCM2835 GPIO config: tdo = %d", tdo_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
+
+	command_print(CMD_CTX, "BCM2835 GPIO config: tdi = %d", tdi_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
+
+	command_print(CMD_CTX, "BCM2835 GPIO config: srst = %d", srst_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
+
+	command_print(CMD_CTX, "BCM2835 GPIO config: trst = %d", trst_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionums)
+{
+	if (CMD_ARGC == 2) {
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);
+	} else if (CMD_ARGC != 0) {
+		return ERROR_COMMAND_SYNTAX_ERROR;
+	}
+
+	command_print(CMD_CTX,
+			"BCM2835 GPIO nums: swclk = %d, swdio = %d",
+			swclk_gpio, swdio_gpio);
+
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swclk)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
+
+	command_print(CMD_CTX, "BCM2835 num: swclk = %d", swclk_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);
+
+	command_print(CMD_CTX, "BCM2835 num: swdio = %d", swdio_gpio);
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)
+{
+	if (CMD_ARGC == 2) {
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], speed_coeff);
+		COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], speed_offset);
+	}
+	return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base)
+{
+	if (CMD_ARGC == 1)
+		COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], bcm2835_peri_base);
+	return ERROR_OK;
+}
+
+static const struct command_registration bcm2835gpio_command_handlers[] = {
+	{
+		.name = "bcm2835gpio_jtag_nums",
+		.handler = &bcm2835gpio_handle_jtag_gpionums,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio numbers for tck, tms, tdi, tdo. (in that order)",
+		.usage = "(tck tms tdi tdo)* ",
+	},
+	{
+		.name = "bcm2835gpio_tck_num",
+		.handler = &bcm2835gpio_handle_jtag_gpionum_tck,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for tck.",
+	},
+	{
+		.name = "bcm2835gpio_tms_num",
+		.handler = &bcm2835gpio_handle_jtag_gpionum_tms,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for tms.",
+	},
+	{
+		.name = "bcm2835gpio_tdo_num",
+		.handler = &bcm2835gpio_handle_jtag_gpionum_tdo,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for tdo.",
+	},
+	{
+		.name = "bcm2835gpio_tdi_num",
+		.handler = &bcm2835gpio_handle_jtag_gpionum_tdi,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for tdi.",
+	},
+	{
+		.name = "bcm2835gpio_swd_nums",
+		.handler = &bcm2835gpio_handle_swd_gpionums,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio numbers for swclk, swdio. (in that order)",
+		.usage = "(swclk swdio)* ",
+	},
+	{
+		.name = "bcm2835gpio_swclk_num",
+		.handler = &bcm2835gpio_handle_swd_gpionum_swclk,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for swclk.",
+	},
+	{
+		.name = "bcm2835gpio_swdio_num",
+		.handler = &bcm2835gpio_handle_swd_gpionum_swdio,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for swdio.",
+	},
+	{
+		.name = "bcm2835gpio_srst_num",
+		.handler = &bcm2835gpio_handle_jtag_gpionum_srst,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for srst.",
+	},
+	{
+		.name = "bcm2835gpio_trst_num",
+		.handler = &bcm2835gpio_handle_jtag_gpionum_trst,
+		.mode = COMMAND_CONFIG,
+		.help = "gpio number for trst.",
+	},
+	{
+		.name = "bcm2835gpio_speed_coeffs",
+		.handler = &bcm2835gpio_handle_speed_coeffs,
+		.mode = COMMAND_CONFIG,
+		.help = "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
+	},
+	{
+		.name = "bcm2835gpio_peripheral_base",
+		.handler = &bcm2835gpio_handle_peripheral_base,
+		.mode = COMMAND_CONFIG,
+		.help = "peripheral base to access GPIOs (RPi1 0x20000000, RPi2 0x3F000000).",
+	},
+
+	COMMAND_REGISTRATION_DONE
+};
+
+static const char * const bcm2835_transports[] = { "jtag", "swd", NULL };
+
+struct jtag_interface bcm2835gpio_interface = {
+	.name = "bcm2835gpio",
+	.supported = DEBUG_CAP_TMS_SEQ,
+	.execute_queue = bitbang_execute_queue,
+	.transports = bcm2835_transports,
+	.swd = &bitbang_swd,
+	.speed = bcm2835gpio_speed,
+	.khz = bcm2835gpio_khz,
+	.speed_div = bcm2835gpio_speed_div,
+	.commands = bcm2835gpio_command_handlers,
+	.init = bcm2835gpio_init,
+	.quit = bcm2835gpio_quit,
+};
+
+static bool bcm2835gpio_jtag_mode_possible(void)
+{
+	if (!is_gpio_valid(tck_gpio))
+		return 0;
+	if (!is_gpio_valid(tms_gpio))
+		return 0;
+	if (!is_gpio_valid(tdi_gpio))
+		return 0;
+	if (!is_gpio_valid(tdo_gpio))
+		return 0;
+	return 1;
+}
+
+static bool bcm2835gpio_swd_mode_possible(void)
+{
+	if (!is_gpio_valid(swclk_gpio))
+		return 0;
+	if (!is_gpio_valid(swdio_gpio))
+		return 0;
+	return 1;
+}
+
+static int bcm2835gpio_init(void)
+{
+	bitbang_interface = &bcm2835gpio_bitbang;
+
+	LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver");
+
+	if (bcm2835gpio_jtag_mode_possible()) {
+		if (bcm2835gpio_swd_mode_possible())
+			LOG_INFO("JTAG and SWD modes enabled");
+		else
+			LOG_INFO("JTAG only mode enabled (specify swclk and swdio gpio to add SWD mode)");
+		if (!is_gpio_valid(trst_gpio) && !is_gpio_valid(srst_gpio)) {
+			LOG_ERROR("Require at least one of trst or srst gpios to be specified");
+			return ERROR_JTAG_INIT_FAILED;
+		}
+	} else if (bcm2835gpio_swd_mode_possible()) {
+		LOG_INFO("SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)");
+	} else {
+		LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode and/or swclk and swdio gpio for SWD mode");
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
+	if (dev_mem_fd < 0) {
+		perror("open");
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	pio_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
+				MAP_SHARED, dev_mem_fd, BCM2835_GPIO_BASE);
+
+	if (pio_base == MAP_FAILED) {
+		perror("mmap");
+		close(dev_mem_fd);
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	static volatile uint32_t *pads_base;
+	pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
+				MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27);
+
+	if (pads_base == MAP_FAILED) {
+		perror("mmap");
+		close(dev_mem_fd);
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	/* set 16mA drive strength */
+	pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000018 + 7;
+
+	tdo_gpio_mode = MODE_GPIO(tdo_gpio);
+	tdi_gpio_mode = MODE_GPIO(tdi_gpio);
+	tck_gpio_mode = MODE_GPIO(tck_gpio);
+	tms_gpio_mode = MODE_GPIO(tms_gpio);
+	swclk_gpio_mode = MODE_GPIO(swclk_gpio);
+	swdio_gpio_mode = MODE_GPIO(swdio_gpio);
+	/*
+	 * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
+	 * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.
+	 */
+	INP_GPIO(tdo_gpio);
+
+	GPIO_CLR = 1<<tdi_gpio | 1<<tck_gpio | 1<<swdio_gpio | 1<<swclk_gpio;
+	GPIO_SET = 1<<tms_gpio;
+
+	OUT_GPIO(tdi_gpio);
+	OUT_GPIO(tck_gpio);
+	OUT_GPIO(tms_gpio);
+	OUT_GPIO(swclk_gpio);
+	OUT_GPIO(swdio_gpio);
+	if (trst_gpio != -1) {
+		trst_gpio_mode = MODE_GPIO(trst_gpio);
+		GPIO_SET = 1 << trst_gpio;
+		OUT_GPIO(trst_gpio);
+	}
+	if (srst_gpio != -1) {
+		srst_gpio_mode = MODE_GPIO(srst_gpio);
+		GPIO_SET = 1 << srst_gpio;
+		OUT_GPIO(srst_gpio);
+	}
+
+	LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d "
+		  "tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode,
+		  tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode);
+
+	if (swd_mode) {
+		bcm2835gpio_bitbang.write = bcm2835gpio_swd_write;
+		bitbang_switch_to_swd();
+	}
+
+	return ERROR_OK;
+}
+
+static int bcm2835gpio_quit(void)
+{
+	SET_MODE_GPIO(tdo_gpio, tdo_gpio_mode);
+	SET_MODE_GPIO(tdi_gpio, tdi_gpio_mode);
+	SET_MODE_GPIO(tck_gpio, tck_gpio_mode);
+	SET_MODE_GPIO(tms_gpio, tms_gpio_mode);
+	SET_MODE_GPIO(swclk_gpio, swclk_gpio_mode);
+	SET_MODE_GPIO(swdio_gpio, swdio_gpio_mode);
+	if (trst_gpio != -1)
+		SET_MODE_GPIO(trst_gpio, trst_gpio_mode);
+	if (srst_gpio != -1)
+		SET_MODE_GPIO(srst_gpio, srst_gpio_mode);
+
+	return ERROR_OK;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.c
new file mode 100755
index 0000000..1a0fa1c
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.c
@@ -0,0 +1,550 @@
+/***************************************************************************
+ *   Copyright (C) 2005 by Dominic Rath                                    *
+ *   Dominic.Rath@gmx.de                                                   *
+ *                                                                         *
+ *   Copyright (C) 2007,2008 �yvind Harboe                                 *
+ *   oyvind.harboe@zylin.com                                               *
+ *                                                                         *
+ *   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.           *
+ ***************************************************************************/
+
+/* 2014-12: Addition of the SWD protocol support is based on the initial work
+ * by Paul Fertser and modifications by Jean-Christian de Rivaz. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "bitbang.h"
+#include <jtag/interface.h>
+#include <jtag/commands.h>
+
+/* YUK! - but this is currently a global.... */
+extern struct jtag_interface *jtag_interface;
+
+/**
+ * Function bitbang_stableclocks
+ * issues a number of clock cycles while staying in a stable state.
+ * Because the TMS value required to stay in the RESET state is a 1, whereas
+ * the TMS value required to stay in any of the other stable states is a 0,
+ * this function checks the current stable state to decide on the value of TMS
+ * to use.
+ */
+static void bitbang_stableclocks(int num_cycles);
+
+static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
+
+struct bitbang_interface *bitbang_interface;
+
+/* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work!
+ *
+ * Set this to 1 and str912 reset halt will fail.
+ *
+ * If someone can submit a patch with an explanation it will be greatly
+ * appreciated, but as far as I can tell (�H) DCLK is generated upon
+ * clk = 0 in TAP_IDLE. Good luck deducing that from the ARM documentation!
+ * The ARM documentation uses the term "DCLK is asserted while in the TAP_IDLE
+ * state". With hardware there is no such thing as *while* in a state. There
+ * are only edges. So clk => 0 is in fact a very subtle state transition that
+ * happens *while* in the TAP_IDLE state. "#&�"#�&"#&"#&
+ *
+ * For "reset halt" the last thing that happens before srst is asserted
+ * is that the breakpoint is set up. If DCLK is not wiggled one last
+ * time before the reset, then the breakpoint is not set up and
+ * "reset halt" will fail to halt.
+ *
+ */
+#define CLOCK_IDLE() 0
+
+/* The bitbang driver leaves the TCK 0 when in idle */
+static void bitbang_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 bitbang_state_move(int skip)
+{
+	int i = 0, tms = 0;
+	uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
+	int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
+
+	for (i = skip; i < tms_count; i++) {
+		tms = (tms_scan >> i) & 1;
+		bitbang_interface->write(0, tms, 0);
+		bitbang_interface->write(1, tms, 0);
+	}
+	bitbang_interface->write(CLOCK_IDLE(), tms, 0);
+
+	tap_set_state(tap_get_end_state());
+}
+
+/**
+ * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG
+ * (or SWD) state machine.
+ */
+static int bitbang_execute_tms(struct jtag_command *cmd)
+{
+	unsigned num_bits = cmd->cmd.tms->num_bits;
+	const uint8_t *bits = cmd->cmd.tms->bits;
+
+	DEBUG_JTAG_IO("TMS: %d bits", num_bits);
+
+	int tms = 0;
+	for (unsigned i = 0; i < num_bits; i++) {
+		tms = ((bits[i/8] >> (i % 8)) & 1);
+		bitbang_interface->write(0, tms, 0);
+		bitbang_interface->write(1, tms, 0);
+	}
+	bitbang_interface->write(CLOCK_IDLE(), tms, 0);
+
+	return ERROR_OK;
+}
+
+static void bitbang_path_move(struct pathmove_command *cmd)
+{
+	int num_states = cmd->num_states;
+	int state_count;
+	int tms = 0;
+
+	state_count = 0;
+	while (num_states) {
+		if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])
+			tms = 0;
+		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",
+				tap_state_name(tap_get_state()),
+				tap_state_name(cmd->path[state_count]));
+			exit(-1);
+		}
+
+		bitbang_interface->write(0, tms, 0);
+		bitbang_interface->write(1, tms, 0);
+
+		tap_set_state(cmd->path[state_count]);
+		state_count++;
+		num_states--;
+	}
+
+	bitbang_interface->write(CLOCK_IDLE(), tms, 0);
+
+	tap_set_end_state(tap_get_state());
+}
+
+static void bitbang_runtest(int num_cycles)
+{
+	int i;
+
+	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) {
+		bitbang_end_state(TAP_IDLE);
+		bitbang_state_move(0);
+	}
+
+	/* execute num_cycles */
+	for (i = 0; i < num_cycles; i++) {
+		bitbang_interface->write(0, 0, 0);
+		bitbang_interface->write(1, 0, 0);
+	}
+	bitbang_interface->write(CLOCK_IDLE(), 0, 0);
+
+	/* finish in end_state */
+	bitbang_end_state(saved_end_state);
+	if (tap_get_state() != tap_get_end_state())
+		bitbang_state_move(0);
+}
+
+static void bitbang_stableclocks(int num_cycles)
+{
+	int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
+	int i;
+
+	/* send num_cycles clocks onto the cable */
+	for (i = 0; i < num_cycles; i++) {
+		bitbang_interface->write(1, tms, 0);
+		bitbang_interface->write(0, tms, 0);
+	}
+}
+
+static void bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
+{
+	tap_state_t saved_end_state = tap_get_end_state();
+	int bit_cnt;
+
+	if (!((!ir_scan &&
+			(tap_get_state() == TAP_DRSHIFT)) ||
+			(ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {
+		if (ir_scan)
+			bitbang_end_state(TAP_IRSHIFT);
+		else
+			bitbang_end_state(TAP_DRSHIFT);
+
+		bitbang_state_move(0);
+		bitbang_end_state(saved_end_state);
+	}
+
+	for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {
+		int val = 0;
+		int tms = (bit_cnt == scan_size-1) ? 1 : 0;
+		int tdi;
+		int bytec = bit_cnt/8;
+		int bcval = 1 << (bit_cnt % 8);
+
+		/* if we're just reading the scan, but don't care about the output
+		 * default to outputting 'low', this also makes valgrind traces more readable,
+		 * as it removes the dependency on an uninitialised value
+		 */
+		tdi = 0;
+		if ((type != SCAN_IN) && (buffer[bytec] & bcval))
+			tdi = 1;
+
+		bitbang_interface->write(0, tms, tdi);
+
+		if (type != SCAN_OUT)
+			val = bitbang_interface->read();
+
+		bitbang_interface->write(1, tms, tdi);
+
+		if (type != SCAN_OUT) {
+			if (val)
+				buffer[bytec] |= bcval;
+			else
+				buffer[bytec] &= ~bcval;
+		}
+	}
+
+	if (tap_get_state() != tap_get_end_state()) {
+		/* we *KNOW* the above loop transitioned out of
+		 * the shift state, so we skip the first state
+		 * and move directly to the end state.
+		 */
+		bitbang_state_move(1);
+	}
+}
+
+int bitbang_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;
+
+	if (!bitbang_interface) {
+		LOG_ERROR("BUG: Bitbang interface called, but not yet initialized");
+		exit(-1);
+	}
+
+	/* 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;
+
+	if (bitbang_interface->blink)
+		bitbang_interface->blink(1);
+
+	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) ||
+						(cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
+					tap_set_state(TAP_RESET);
+				bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+				break;
+			case JTAG_RUNTEST:
+#ifdef _DEBUG_JTAG_IO_
+				LOG_DEBUG("runtest %i cycles, end in %s",
+						cmd->cmd.runtest->num_cycles,
+						tap_state_name(cmd->cmd.runtest->end_state));
+#endif
+				bitbang_end_state(cmd->cmd.runtest->end_state);
+				bitbang_runtest(cmd->cmd.runtest->num_cycles);
+				break;
+
+			case JTAG_STABLECLOCKS:
+				/* this is only allowed while in a stable state.  A check for a stable
+				 * state was done in jtag_add_clocks()
+				 */
+				bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles);
+				break;
+
+			case JTAG_TLR_RESET:
+#ifdef _DEBUG_JTAG_IO_
+				LOG_DEBUG("statemove end in %s",
+						tap_state_name(cmd->cmd.statemove->end_state));
+#endif
+				bitbang_end_state(cmd->cmd.statemove->end_state);
+				bitbang_state_move(0);
+				break;
+			case JTAG_PATHMOVE:
+#ifdef _DEBUG_JTAG_IO_
+				LOG_DEBUG("pathmove: %i states, end in %s",
+						cmd->cmd.pathmove->num_states,
+						tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
+#endif
+				bitbang_path_move(cmd->cmd.pathmove);
+				break;
+			case JTAG_SCAN:
+#ifdef _DEBUG_JTAG_IO_
+				LOG_DEBUG("%s scan end in %s",
+						(cmd->cmd.scan->ir_scan) ? "IR" : "DR",
+					tap_state_name(cmd->cmd.scan->end_state));
+#endif
+				bitbang_end_state(cmd->cmd.scan->end_state);
+				scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
+				type = jtag_scan_type(cmd->cmd.scan);
+				bitbang_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;
+			case JTAG_TMS:
+				retval = bitbang_execute_tms(cmd);
+				break;
+			default:
+				LOG_ERROR("BUG: unknown JTAG command type encountered");
+				exit(-1);
+		}
+		cmd = cmd->next;
+	}
+	if (bitbang_interface->blink)
+		bitbang_interface->blink(0);
+
+	return retval;
+}
+
+
+bool swd_mode;
+static int queued_retval;
+
+static int bitbang_swd_init(void)
+{
+	LOG_DEBUG("bitbang_swd_init");
+	swd_mode = true;
+	return ERROR_OK;
+}
+
+static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt)
+{
+	LOG_DEBUG("bitbang_exchange");
+	int tdi;
+
+	for (unsigned int i = offset; i < bit_cnt + offset; i++) {
+		int bytec = i/8;
+		int bcval = 1 << (i % 8);
+		tdi = !rnw && (buf[bytec] & bcval);
+
+		bitbang_interface->write(0, 0, tdi);
+
+		if (rnw && buf) {
+			if (bitbang_interface->swdio_read())
+				buf[bytec] |= bcval;
+			else
+				buf[bytec] &= ~bcval;
+		}
+
+		bitbang_interface->write(1, 0, tdi);
+	}
+}
+
+int bitbang_swd_switch_seq(enum swd_special_seq seq)
+{
+	LOG_DEBUG("bitbang_swd_switch_seq");
+
+	switch (seq) {
+	case LINE_RESET:
+		LOG_DEBUG("SWD line reset");
+		bitbang_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len);
+		break;
+	case JTAG_TO_SWD:
+		LOG_DEBUG("JTAG-to-SWD");
+		bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
+		break;
+	case SWD_TO_JTAG:
+		LOG_DEBUG("SWD-to-JTAG");
+		bitbang_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len);
+		break;
+	default:
+		LOG_ERROR("Sequence %d not supported", seq);
+		return ERROR_FAIL;
+	}
+
+	return ERROR_OK;
+}
+
+void bitbang_switch_to_swd(void)
+{
+	LOG_DEBUG("bitbang_switch_to_swd");
+	bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
+}
+
+static void swd_clear_sticky_errors(void)
+{
+	bitbang_swd_write_reg(swd_cmd(false,  false, DP_ABORT),
+		STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
+}
+
+static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
+{
+	LOG_DEBUG("bitbang_swd_read_reg");
+	assert(cmd & SWD_CMD_RnW);
+
+	if (queued_retval != ERROR_OK) {
+		LOG_DEBUG("Skip bitbang_swd_read_reg because queued_retval=%d", queued_retval);
+		return;
+	}
+
+	for (;;) {
+		uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];
+
+		cmd |= SWD_CMD_START | (1 << 7);
+		bitbang_exchange(false, &cmd, 0, 8);
+
+		bitbang_interface->swdio_drive(false);
+		bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 1 + 1);
+		bitbang_interface->swdio_drive(true);
+
+		int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
+		uint32_t data = buf_get_u32(trn_ack_data_parity_trn, 1 + 3, 32);
+		int parity = buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 32, 1);
+
+		LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
+			  ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
+			  cmd & SWD_CMD_APnDP ? "AP" : "DP",
+			  cmd & SWD_CMD_RnW ? "read" : "write",
+			  (cmd & SWD_CMD_A32) >> 1,
+			  data);
+
+		switch (ack) {
+		 case SWD_ACK_OK:
+			if (parity != parity_u32(data)) {
+				LOG_DEBUG("Wrong parity detected");
+				queued_retval = ERROR_FAIL;
+				return;
+			}
+			if (value)
+				*value = data;
+			if (cmd & SWD_CMD_APnDP)
+				bitbang_exchange(true, NULL, 0, ap_delay_clk);
+			return;
+		 case SWD_ACK_WAIT:
+			LOG_DEBUG("SWD_ACK_WAIT");
+			swd_clear_sticky_errors();
+			break;
+		 case SWD_ACK_FAULT:
+			LOG_DEBUG("SWD_ACK_FAULT");
+			queued_retval = ack;
+			return;
+		 default:
+			LOG_DEBUG("No valid acknowledge: ack=%d", ack);
+			queued_retval = ack;
+			return;
+		}
+	}
+}
+
+static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
+{
+	LOG_DEBUG("bitbang_swd_write_reg");
+	assert(!(cmd & SWD_CMD_RnW));
+
+	if (queued_retval != ERROR_OK) {
+		LOG_DEBUG("Skip bitbang_swd_write_reg because queued_retval=%d", queued_retval);
+		return;
+	}
+
+	for (;;) {
+		uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];
+		buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32, value);
+		buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(value));
+
+		cmd |= SWD_CMD_START | (1 << 7);
+		bitbang_exchange(false, &cmd, 0, 8);
+
+		bitbang_interface->swdio_drive(false);
+		bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1);
+		bitbang_interface->swdio_drive(true);
+		bitbang_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1);
+
+		int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
+		LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
+			  ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
+			  cmd & SWD_CMD_APnDP ? "AP" : "DP",
+			  cmd & SWD_CMD_RnW ? "read" : "write",
+			  (cmd & SWD_CMD_A32) >> 1,
+			  buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32));
+
+		switch (ack) {
+		 case SWD_ACK_OK:
+			if (cmd & SWD_CMD_APnDP)
+				bitbang_exchange(true, NULL, 0, ap_delay_clk);
+			return;
+		 case SWD_ACK_WAIT:
+			LOG_DEBUG("SWD_ACK_WAIT");
+			swd_clear_sticky_errors();
+			break;
+		 case SWD_ACK_FAULT:
+			LOG_DEBUG("SWD_ACK_FAULT");
+			queued_retval = ack;
+			return;
+		 default:
+			LOG_DEBUG("No valid acknowledge: ack=%d", ack);
+			queued_retval = ack;
+			return;
+		}
+	}
+}
+
+static int bitbang_swd_run_queue(void)
+{
+	LOG_DEBUG("bitbang_swd_run_queue");
+	/* A transaction must be followed by another transaction or at least 8 idle cycles to
+	 * ensure that data is clocked through the AP. */
+	bitbang_exchange(true, NULL, 0, 8);
+
+	int retval = queued_retval;
+	queued_retval = ERROR_OK;
+	LOG_DEBUG("SWD queue return value: %02x", retval);
+	return retval;
+}
+
+const struct swd_driver bitbang_swd = {
+	.init = bitbang_swd_init,
+	.switch_seq = bitbang_swd_switch_seq,
+	.read_reg = bitbang_swd_read_reg,
+	.write_reg = bitbang_swd_write_reg,
+	.run = bitbang_swd_run_queue,
+};

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.h
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.h b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.h
new file mode 100755
index 0000000..1bdb8f5
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitbang.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ *   Copyright (C) 2005 by Dominic Rath                                    *
+ *   Dominic.Rath@gmx.de                                                   *
+ *                                                                         *
+ *   Copyright (C) 2007,2008 �yvind Harboe                                 *
+ *   oyvind.harboe@zylin.com                                               *
+ *                                                                         *
+ *   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.           *
+ ***************************************************************************/
+
+#ifndef BITBANG_H
+#define BITBANG_H
+
+#include <jtag/swd.h>
+
+struct bitbang_interface {
+	/* low level callbacks (for bitbang)
+	 */
+	int (*read)(void);
+	void (*write)(int tck, int tms, int tdi);
+	void (*reset)(int trst, int srst);
+	void (*blink)(int on);
+	int (*swdio_read)(void);
+	void (*swdio_drive)(bool on);
+};
+
+const struct swd_driver bitbang_swd;
+
+extern bool swd_mode;
+
+int bitbang_execute_queue(void);
+
+extern struct bitbang_interface *bitbang_interface;
+void bitbang_switch_to_swd(void);
+int bitbang_swd_switch_seq(enum swd_special_seq seq);
+
+#endif /* BITBANG_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.c
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.c b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.c
new file mode 100755
index 0000000..1d0ff09
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.c
@@ -0,0 +1,317 @@
+/***************************************************************************
+*   Copyright (C) 2007 by Pavel Chromy                                    *
+*   chromy@asix.cz                                                        *
+*                                                                         *
+*   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/jtag.h>
+#include "bitq.h"
+#include <jtag/interface.h>
+
+struct bitq_interface *bitq_interface; /* low level bit queue interface */
+
+/* state of input queue */
+struct bitq_state {
+	struct jtag_command *cmd; /* command currently processed */
+	int field_idx; /* index of field currently being processed */
+	int bit_pos; /* position of bit currently being processed */
+	int status; /* processing status */
+};
+static struct bitq_state bitq_in_state;
+
+/*
+ * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
+ * no parameters, makes use of stored state information
+ */
+static void bitq_in_proc(void)
+{
+	/* loop through the queue */
+	while (bitq_in_state.cmd) {
+		/* only JTAG_SCAN command may return data */
+		if (bitq_in_state.cmd->type == JTAG_SCAN) {
+			/* loop through the fields */
+			while (bitq_in_state.field_idx < bitq_in_state.cmd->cmd.scan->num_fields) {
+				struct scan_field *field;
+				field = &bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
+				if (field->in_value) {
+					/* field scanning */
+					while (bitq_in_state.bit_pos < field->num_bits) {
+						/* index of byte being scanned */
+						int in_idx = bitq_in_state.bit_pos / 8;
+						/* mask of next bit to be scanned */
+						uint8_t in_mask = 1 << (bitq_in_state.bit_pos % 8);
+
+						int tdo = bitq_interface->in();
+						if (tdo < 0) {
+#ifdef _DEBUG_JTAG_IO_
+							LOG_DEBUG("bitq in EOF");
+#endif
+							return;
+						}
+						if (in_mask == 0x01)
+							field->in_value[in_idx] = 0;
+						if (tdo)
+							field->in_value[in_idx] |= in_mask;
+						bitq_in_state.bit_pos++;
+					}
+				}
+
+				bitq_in_state.field_idx++;  /* advance to next field */
+				bitq_in_state.bit_pos = 0;  /* start next field from the first bit */
+			}
+		}
+		bitq_in_state.cmd = bitq_in_state.cmd->next;    /* advance to next command */
+		bitq_in_state.field_idx = 0;                    /* preselect first field */
+	}
+}
+
+static void bitq_io(int tms, int tdi, int tdo_req)
+{
+	bitq_interface->out(tms, tdi, tdo_req);
+	/* check and process the input queue */
+	if (bitq_interface->in_rdy())
+		bitq_in_proc();
+}
+
+static void bitq_end_state(tap_state_t state)
+{
+	if (!tap_is_state_stable(state)) {
+		LOG_ERROR("BUG: %i is not a valid end state", state);
+		exit(-1);
+	}
+	tap_set_end_state(state);
+}
+
+static void bitq_state_move(tap_state_t new_state)
+{
+	int i = 0;
+	uint8_t  tms_scan;
+
+	if (!tap_is_state_stable(tap_get_state()) || !tap_is_state_stable(new_state)) {
+		LOG_ERROR("TAP move from or to unstable state");
+		exit(-1);
+	}
+
+	tms_scan = tap_get_tms_path(tap_get_state(), new_state);
+	int tms_count = tap_get_tms_path_len(tap_get_state(), new_state);
+
+	for (i = 0; i < tms_count; i++) {
+		bitq_io(tms_scan & 1, 0, 0);
+		tms_scan >>= 1;
+	}
+
+	tap_set_state(new_state);
+}
+
+static void bitq_path_move(struct pathmove_command *cmd)
+{
+	int i;
+
+	for (i = 0; i <= cmd->num_states; i++) {
+		if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
+			bitq_io(0, 0, 0);
+		else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
+			bitq_io(1, 0, 0);
+		else {
+			LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
+							 tap_get_state()), tap_state_name(cmd->path[i]));
+			exit(-1);
+		}
+
+		tap_set_state(cmd->path[i]);
+	}
+
+	tap_set_end_state(tap_get_state());
+}
+
+static void bitq_runtest(int num_cycles)
+{
+	int i;
+
+	/* only do a state_move when we're not already in IDLE */
+	if (tap_get_state() != TAP_IDLE)
+		bitq_state_move(TAP_IDLE);
+
+	/* execute num_cycles */
+	for (i = 0; i < num_cycles; i++)
+		bitq_io(0, 0, 0);
+
+	/* finish in end_state */
+	if (tap_get_state() != tap_get_end_state())
+		bitq_state_move(tap_get_end_state());
+}
+
+static void bitq_scan_field(struct scan_field *field, int do_pause)
+{
+	int bit_cnt;
+	int tdo_req;
+
+	const uint8_t *out_ptr;
+	uint8_t  out_mask;
+
+	if (field->in_value)
+		tdo_req = 1;
+	else
+		tdo_req = 0;
+
+	if (field->out_value == NULL) {
+		/* just send zeros and request data from TDO */
+		for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
+			bitq_io(0, 0, tdo_req);
+
+		bitq_io(do_pause, 0, tdo_req);
+	} else {
+		/* send data, and optionally request TDO */
+		out_mask = 0x01;
+		out_ptr  = field->out_value;
+		for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--) {
+			bitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req);
+			if (out_mask == 0x80) {
+				out_mask = 0x01;
+				out_ptr++;
+			} else
+				out_mask <<= 1;
+		}
+
+		bitq_io(do_pause, ((*out_ptr) & out_mask) != 0, tdo_req);
+	}
+
+	if (do_pause) {
+		bitq_io(0, 0, 0);
+		if (tap_get_state() == TAP_IRSHIFT)
+			tap_set_state(TAP_IRPAUSE);
+		else if (tap_get_state() == TAP_DRSHIFT)
+			tap_set_state(TAP_DRPAUSE);
+	}
+}
+
+static void bitq_scan(struct scan_command *cmd)
+{
+	int i;
+
+	if (cmd->ir_scan)
+		bitq_state_move(TAP_IRSHIFT);
+	else
+		bitq_state_move(TAP_DRSHIFT);
+
+	for (i = 0; i < cmd->num_fields - 1; i++)
+		bitq_scan_field(&cmd->fields[i], 0);
+
+	bitq_scan_field(&cmd->fields[i], 1);
+}
+
+int bitq_execute_queue(void)
+{
+	struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
+
+	bitq_in_state.cmd = jtag_command_queue;
+	bitq_in_state.field_idx = 0;
+	bitq_in_state.bit_pos   = 0;
+	bitq_in_state.status    = 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) ||
+					(cmd->cmd.reset->srst &&
+					(jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
+				tap_set_state(TAP_RESET);
+			bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+			if (bitq_interface->in_rdy())
+				bitq_in_proc();
+			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
+			bitq_end_state(cmd->cmd.runtest->end_state);
+			bitq_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
+			bitq_end_state(cmd->cmd.statemove->end_state);
+			bitq_state_move(tap_get_end_state());   /* uncoditional TAP move */
+			break;
+
+		case JTAG_PATHMOVE:
+#ifdef _DEBUG_JTAG_IO_
+			LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
+					cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+#endif
+			bitq_path_move(cmd->cmd.pathmove);
+			break;
+
+		case JTAG_SCAN:
+#ifdef _DEBUG_JTAG_IO_
+			LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
+			if (cmd->cmd.scan->ir_scan)
+				LOG_DEBUG("scan ir");
+			else
+				LOG_DEBUG("scan dr");
+#endif
+			bitq_end_state(cmd->cmd.scan->end_state);
+			bitq_scan(cmd->cmd.scan);
+			if (tap_get_state() != tap_get_end_state())
+				bitq_state_move(tap_get_end_state());
+			break;
+
+		case JTAG_SLEEP:
+#ifdef _DEBUG_JTAG_IO_
+			LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
+#endif
+			bitq_interface->sleep(cmd->cmd.sleep->us);
+			if (bitq_interface->in_rdy())
+				bitq_in_proc();
+			break;
+
+		default:
+			LOG_ERROR("BUG: unknown JTAG command type encountered");
+			exit(-1);
+		}
+
+		cmd = cmd->next;
+	}
+
+	bitq_interface->flush();
+	bitq_in_proc();
+
+	if (bitq_in_state.cmd) {
+		LOG_ERROR("missing data from bitq interface");
+		return ERROR_JTAG_QUEUE_FAILED;
+	}
+	if (bitq_interface->in() >= 0) {
+		LOG_ERROR("extra data from bitq interface");
+		return ERROR_JTAG_QUEUE_FAILED;
+	}
+
+	return bitq_in_state.status;
+}
+
+void bitq_cleanup(void)
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/e302582d/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.h
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.h b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.h
new file mode 100755
index 0000000..f54de95
--- /dev/null
+++ b/docs/os/tutorials/downloads/openocd-code-89bf96ffe6ac66c80407af8383b9d5adc0dc35f4/src/jtag/drivers/bitq.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Pavel Chromy                                    *
+ *   chromy@asix.cz                                                        *
+ *                                                                         *
+ *   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.           *
+ ***************************************************************************/
+
+#ifndef BITQ_H
+#define BITQ_H
+
+#include <jtag/commands.h>
+
+struct bitq_interface {
+	/* function to enqueueing low level IO requests */
+	int (*out)(int tms, int tdi, int tdo_req);
+	int (*flush)(void);
+
+	int (*sleep)(unsigned long us);
+	int (*reset)(int trst, int srst);
+
+	/* delayed read of requested TDO data,
+	 * the input shall be checked after call to any enqueuing function
+	 */
+	int (*in_rdy)(void);
+	int (*in)(void);
+};
+
+extern struct bitq_interface *bitq_interface;
+
+int bitq_execute_queue(void);
+
+void bitq_cleanup(void);
+
+#endif /* BITQ_H */