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 */