#this is highly experimental patch that adds support for buspirate # use only with openocd-0.3.0-rc0 # to compile: # tar xvf openocd-0.3.0-rc0.tar.bz2 # cd openocd-0.3.0-rc0 # patch -p1 < ../openocd-0.3.0-rc0-buspirate.diff # aclocal # automake # autoconfig # mkdir build # cd build # ../configure --enable-buspirate # make # make install (as root) # create config that contains these lines (without #) : # interface buspirate # buspirate_port /dev/ttyUSB0 # buspirate_speed fast # enjoy ;) diff -Naur openocd-0.3.0-rc0/config.h.in openocd-0.3.0-rc0-BP/config.h.in --- openocd-0.3.0-rc0/config.h.in 2009-10-29 05:23:51.000000000 +0100 +++ openocd-0.3.0-rc0-BP/config.h.in 2010-01-18 17:37:20.000000000 +0100 @@ -69,6 +69,9 @@ /* 0 if you don't want the usbprog JTAG driver. */ #undef BUILD_USBPROG +/* 0 if you don't want the usbprog JTAG driver. */ +#undef BUILD_BUSPIRATE + /* 0 if you don't want the Versaloon-Link JTAG driver. */ #undef BUILD_VSLLINK diff -Naur openocd-0.3.0-rc0/configure.in openocd-0.3.0-rc0-BP/configure.in --- openocd-0.3.0-rc0/configure.in 2009-10-29 05:23:17.000000000 +0100 +++ openocd-0.3.0-rc0-BP/configure.in 2010-01-18 17:37:04.000000000 +0100 @@ -376,6 +376,10 @@ AS_HELP_STRING([--enable-usbprog], [Enable building support for the usbprog JTAG Programmer]), [build_usbprog=$enableval], [build_usbprog=no]) +AC_ARG_ENABLE(buspirate, + AS_HELP_STRING([--enable-buspirate], [Enable building support for the buspirate JTAG Programmer]), + [build_buspirate=$enableval], [build_buspirate=no]) + AC_ARG_ENABLE(oocd_trace, AS_HELP_STRING([--enable-oocd_trace], [Enable building support for some prototype OpenOCD+trace ETM capture hardware]), @@ -632,6 +636,12 @@ AC_DEFINE(BUILD_USBPROG, 0, [0 if you don't want the usbprog JTAG driver.]) fi +if test $build_buspirate = yes; then + AC_DEFINE(BUILD_BUSPIRATE, 1, [1 if you want the buspirate JTAG driver.]) +else + AC_DEFINE(BUILD_BUSPIRATE, 0, [0 if you don't want the buspirate JTAG driver.]) +fi + if test $build_oocd_trace = yes; then AC_DEFINE(BUILD_OOCD_TRACE, 1, [1 if you want the OpenOCD+trace ETM capture driver.]) else @@ -947,6 +957,7 @@ AM_CONDITIONAL(PRESTO_LIBFTDI, test $build_presto_libftdi = yes) AM_CONDITIONAL(PRESTO_DRIVER, test $build_presto_ftd2xx = yes -o $build_presto_libftdi = yes) AM_CONDITIONAL(USBPROG, test $build_usbprog = yes) +AM_CONDITIONAL(BUSPIRATE, test $build_buspirate = yes) AM_CONDITIONAL(OOCD_TRACE, test $build_oocd_trace = yes) AM_CONDITIONAL(JLINK, test $build_jlink = yes) AM_CONDITIONAL(VSLLINK, test $build_vsllink = yes) diff -Naur openocd-0.3.0-rc0/src/jtag/Makefile.am openocd-0.3.0-rc0-BP/src/jtag/Makefile.am --- openocd-0.3.0-rc0/src/jtag/Makefile.am 2009-10-21 13:45:59.000000000 +0200 +++ openocd-0.3.0-rc0-BP/src/jtag/Makefile.am 2010-01-18 17:41:03.000000000 +0100 @@ -68,6 +68,9 @@ if ARMJTAGEW DRIVERFILES += arm-jtag-ew.c endif +if BUSPIRATE +DRIVERFILES += buspirate.c +endif endif # endif // MINIDRIVER diff -Naur openocd-0.3.0-rc0/src/jtag/buspirate.c openocd-0.3.0-rc0-BP/src/jtag/buspirate.c --- openocd-0.3.0-rc0/src/jtag/buspirate.c 1970-01-01 01:00:00.000000000 +0100 +++ openocd-0.3.0-rc0-BP/src/jtag/buspirate.c 2010-01-29 21:46:55.000000000 +0100 @@ -0,0 +1,826 @@ +/*************************************************************************** + * Copyright (C) 2010 by Michal Demin * + * heavily based on Benedikt Sauter's usnprog.c and arm-jtag-ew.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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "interface.h" +#include "commands.h" + +#include +#include + +/* Pins at buspirate */ +#define TDO_BIT 0 +#define TDI_BIT 3 +#define TCK_BIT 2 +#define TMS_BIT 1 + + +#undef DEBUG_SERIAL +static int buspirate_execute_queue(void); +static int buspirate_speed(int speed); +static int buspirate_khz(int khz, int *jtag_speed); +static int buspirate_register_commands(struct command_context_s *cmd_ctx); +static int buspirate_init(void); +static int buspirate_quit(void); + +static void buspirate_end_state(tap_state_t state); +static void buspirate_state_move(void); +static void buspirate_path_move(pathmove_command_t *cmd); +static void buspirate_runtest(int num_cycles); +static void buspirate_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, scan_command_t *command); + +jtag_interface_t buspirate_interface = +{ + .name = "buspirate", + .execute_queue = buspirate_execute_queue, + .speed = buspirate_speed, + .khz = buspirate_khz, + .register_commands = buspirate_register_commands, + .init = buspirate_init, + .quit = buspirate_quit +}; + +#define CMD_UNKOWN 0x00 +#define CMD_PORT_MODE 0x01 +#define CMD_FEATURE 0x02 +#define CMD_READ_ADCS 0x03 +#define CMD_TAP_SHIFT 0x04 +#define CMD_TAP_SHIFT2 0x05 +#define CMD_JTAG_SPEED 0x06 +#define CMD_UART_SPEED 0x07 + +enum { + MODE_HIZ=0, + MODE_JTAG=1 +}; + +enum { + FEATURE_LED=0x01, + FEATURE_VREG=0x02, + FEATURE_TRST=0x04, + FEATURE_SRST=0x08, + FEATURE_PULLUP=0x10 +}; + +enum { + ACTION_DISABLE=0, + ACTION_ENABLE=1 +}; + +enum { + SERIAL_NORMAL=0, + SERIAL_FAST=1 +}; + + +static int buspirate_fd = -1; +static int buspirate_baudrate = SERIAL_NORMAL; +static char* buspirate_port = NULL; + + + +static void buspirate_tap_init(void); +static int buspirate_tap_execute(void); +static void buspirate_tap_append(int tms, int tdi); +static void buspirate_tap_append_scan(int length, uint8_t *buffer, scan_command_t *command); +static void buspirate_tap_make_space(int scan, int bits); + +static void buspirate_reset(int trst, int srst); + +/* low level interface */ +static unsigned char buspirate_jtag_command(int buspirate_fd, char *cmd, int cmdlen); +static void buspirate_jtag_set_speed(int buspirate_fd, char speed); +static void buspirate_jtag_set_mode(int buspirate_fd, char mode); +static void buspirate_jtag_set_feature(int buspirate_fd, char feat, char action); +static void buspirate_jtag_get_adcs(int buspirate_fd); + +/* command interface */ +static int buspirate_handle_adc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +static int buspirate_handle_vreg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +static int buspirate_handle_led_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +static int buspirate_handle_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +static int buspirate_handle_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); + +/* low level HW communication interface */ +static int buspirate_serial_setspeed(int fd, speed_t speed); +static int buspirate_serial_write(int fd, char *buf, int size); +static int buspirate_serial_read(int fd, char *buf, int size); +static void buspirate_print_buffer(char* buf, int size); + +static int buspirate_speed(int speed) +{ + // TODO + LOG_INFO("Want to set speed to %dkHz, but not implemented :(", speed); + return ERROR_OK; +} + +static int buspirate_khz(int khz, int *jtag_speed) { + *jtag_speed = khz; + return ERROR_OK; +} + +static int buspirate_register_commands(struct command_context_s *cmd_ctx) +{ + register_command(cmd_ctx, NULL, "buspirate_adc", buspirate_handle_adc_command, + COMMAND_EXEC, "reads voltages on the buspirate"); + register_command(cmd_ctx, NULL, "buspirate_vreg", buspirate_handle_vreg_command, + COMMAND_EXEC, "changes the state of voltage regulators"); + register_command(cmd_ctx, NULL, "buspirate_led", buspirate_handle_led_command, + COMMAND_EXEC, "changes the state of the led"); + register_command(cmd_ctx, NULL, "buspirate_speed", buspirate_handle_speed_command, + COMMAND_CONFIG, "speed of the interface"); + register_command(cmd_ctx, NULL, "buspirate_port", buspirate_handle_port_command, + COMMAND_CONFIG, "name of the serial port to open"); + return ERROR_OK; +} + +static int buspirate_execute_queue(void) +{ + jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ + int scan_size; + enum scan_type type; + uint8_t *buffer; + + while (cmd) + { + switch (cmd->type) + { + 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 + buspirate_end_state(cmd->cmd.runtest->end_state); + buspirate_runtest(cmd->cmd.runtest->num_cycles); + break; + case JTAG_STATEMOVE: +#ifdef _DEBUG_JTAG_IO_ + LOG_DEBUG("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state)); +#endif + buspirate_end_state(cmd->cmd.statemove->end_state); + buspirate_state_move(); + 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 + buspirate_path_move(cmd->cmd.pathmove); + break; + case JTAG_SCAN: +#ifdef _DEBUG_JTAG_IO_ + LOG_DEBUG("scan end in %s", tap_state_name(cmd->cmd.scan->end_state)); +#endif + + buspirate_end_state(cmd->cmd.scan->end_state); + + scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); + type = jtag_scan_type(cmd->cmd.scan); + buspirate_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan); + + break; + case JTAG_RESET: +#ifdef _DEBUG_JTAG_IO_ + LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); +#endif + // flush buffers, so we can reset + buspirate_tap_execute(); + + if (cmd->cmd.reset->trst == 1) + { + tap_set_state(TAP_RESET); + } + buspirate_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); + break; + case JTAG_SLEEP: +#ifdef _DEBUG_JTAG_IO_ + LOG_DEBUG("sleep %i", cmd->cmd.sleep->us); +#endif + buspirate_tap_execute(); + jtag_sleep(cmd->cmd.sleep->us); + break; + default: + LOG_ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } + + cmd = cmd->next; + } + + return buspirate_tap_execute(); +} + +static int buspirate_init(void) +{ +buspirate_print_buffer(" ", 0); + if (buspirate_port == NULL) { + buspirate_port = "/dev/ttyUSB0"; + } + + + buspirate_fd = open(buspirate_port, O_RDWR | O_NOCTTY); + if (buspirate_fd == -1) + { + LOG_ERROR("Could not open serial port."); + return ERROR_JTAG_INIT_FAILED; + } + + buspirate_serial_setspeed(buspirate_fd, B115200); + + if (buspirate_baudrate != SERIAL_NORMAL) { + buspirate_jtag_set_speed(buspirate_fd, SERIAL_FAST); + } + + LOG_INFO("Buspirate Interface ready!"); + + buspirate_tap_init(); + buspirate_jtag_set_mode(buspirate_fd, MODE_JTAG); + buspirate_reset(0, 0); + + return ERROR_OK; +} + +static int buspirate_quit(void) +{ + if (buspirate_port) { + free(buspirate_port); + buspirate_port = NULL; + } + return ERROR_OK; +} + +/*************** jtag execute commands **********************/ +static void buspirate_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 buspirate_state_move(void) +{ + 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 = 0; i < tms_count; i++) + { + tms = (tms_scan >> i) & 1; + buspirate_tap_append(tms, 0); + } + + tap_set_state(tap_get_end_state()); +} + +static void buspirate_path_move(pathmove_command_t *cmd) +{ + int num_states = cmd->num_states; + int i; + + for (i = 0; i< num_states; i++) + { + if (tap_state_transition(tap_get_state(), false) == cmd->path[i]) + { + /* LOG_INFO("1"); */ + buspirate_tap_append(0, 0); + } + else if (tap_state_transition(tap_get_state(), true) == cmd->path[i]) + { + /* LOG_INFO("2"); */ + buspirate_tap_append(1, 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 buspirate_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) + { + buspirate_end_state(TAP_IDLE); + buspirate_state_move(); + } + + for (i = 0; i < num_cycles; i++) + { + buspirate_tap_append(0, 0); + } + +#ifdef _DEBUG_JTAG_IO_ + LOG_DEBUG("runtest: cur_state %s end_state %s", tap_state_name(tap_get_state()), tap_state_name(tap_get_end_state())); +#endif + + /* finish in end_state */ + buspirate_end_state(saved_end_state); + if (tap_get_state() != tap_get_end_state()) + { + buspirate_state_move(); + } +} + +static void buspirate_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, scan_command_t *command) +{ + tap_state_t saved_end_state; + + buspirate_tap_make_space(1, scan_size+8); // is 8 correct ? (2 moves = 16) + + saved_end_state = tap_get_end_state(); + + buspirate_end_state(ir_scan?TAP_IRSHIFT:TAP_DRSHIFT); + buspirate_state_move(); + + + /* The adapter does the transition to PAUSE internally */ + if (ir_scan) + tap_set_state(TAP_IRPAUSE); + else + tap_set_state(TAP_DRPAUSE); + + buspirate_tap_append_scan(scan_size, buffer, command); + + /* move to PAUSE */ + buspirate_tap_append(0, 0); + + /* restore the saved state */ + buspirate_end_state(saved_end_state); + tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); + + if (tap_get_state() != tap_get_end_state()) + buspirate_state_move(); +} + + +/************************* TAP related stuff **********/ + +#define BUSPIRATE_BUFFER_SIZE 1024 +#define BUSPIRATE_MAX_PENDING_SCANS 32 + +static char tms_chain[BUSPIRATE_BUFFER_SIZE]; // send +static char tdi_chain[BUSPIRATE_BUFFER_SIZE]; // send +//static char tdo_chain[BUSPIRATE_BUFFER_SIZE]; // recv +static int tap_chain_index; + +typedef struct // this was stolen from arm-jtag-ew +{ + int first; /* First bit position in tdo_buffer to read */ + int length; /* Number of bits to read */ + scan_command_t *command; /* Corresponding scan command */ + uint8_t *buffer; +} pending_scan_result_t; + +static pending_scan_result_t tap_pending_scans[BUSPIRATE_MAX_PENDING_SCANS]; +static int tap_pending_scans_num; + +static void buspirate_tap_init(void) { + tap_chain_index = 0; + tap_pending_scans_num = 0; +} + +static int buspirate_tap_execute(void) +{ + char tmp[4096]; + uint8_t *in_buf; + int i; + int fill_index = 0; + int ret; + int bytes_to_send; + + if (tap_chain_index <= 0) + return ERROR_OK; + LOG_DEBUG("executing tap num bits = %i scans = %i", tap_chain_index, tap_pending_scans_num); + + bytes_to_send = (tap_chain_index+7) / 8; + + tmp[0] = CMD_TAP_SHIFT2; // this command expects number of bits + tmp[1] = (char)(tap_chain_index >> 8); /* high */ + tmp[2] = (char)(tap_chain_index); /* low */ + + fill_index = 3; + for (i=0; i> (i%8)) & 1; + buspirate_tap_append(tms, tdi); + } + tap_pending_scans_num++; +} + +/*************** jtag wrapper functions *********************/ + +/* (1) assert or (0) deassert reset lines */ +static void buspirate_reset(int trst, int srst) +{ + LOG_DEBUG("trst: %i, srst: %i", trst, srst); + + if (trst) + buspirate_jtag_set_feature(buspirate_fd, FEATURE_TRST, ACTION_DISABLE); + else + buspirate_jtag_set_feature(buspirate_fd, FEATURE_TRST, ACTION_ENABLE); + + if (srst) + buspirate_jtag_set_feature(buspirate_fd, FEATURE_SRST, ACTION_DISABLE); + else + buspirate_jtag_set_feature(buspirate_fd, FEATURE_SRST, ACTION_ENABLE); +} + +/*************** jtag lowlevel functions ********************/ + +static void buspirate_jtag_set_speed(int fd, char speed) +{ + int ret; + char tmp[2]; + char ack[2]; + speed_t baudrate = B115200; + + ack[0] = 0xAA; + ack[1] = 0x55; + + tmp[0] = CMD_UART_SPEED; + tmp[1] = speed; + buspirate_jtag_command(fd, tmp, 2); + + // here the adapter changes speed, we need follow + if (speed == SERIAL_FAST) { + baudrate = B1000000; + } + buspirate_serial_setspeed(fd, baudrate); + + buspirate_serial_write(fd, ack, 2); + ret = buspirate_serial_read(fd, tmp, 2); + if (ret != 2) { + LOG_ERROR("Buspirate did not respond :(( restart everything"); + exit(-1); + } + if ((tmp[0] != CMD_UART_SPEED) || (tmp[1] != speed)) { + LOG_ERROR("Buspirate didn't reply as expected :(( restart everything"); + exit(-1); + } + LOG_INFO("Running in %s mode", (speed==SERIAL_NORMAL)?"normal":"FAST"); +} + + +static void buspirate_jtag_set_mode(int fd, char mode) +{ + char tmp[2]; + tmp[0] = CMD_PORT_MODE; + tmp[1] = mode; + buspirate_jtag_command(fd, tmp, 2); +} + +static void buspirate_jtag_set_feature(int fd, char feat, char action) +{ + char tmp[3]; + tmp[0] = CMD_FEATURE; + tmp[1] = feat; // what + tmp[2] = action; // action + buspirate_jtag_command(fd, tmp, 3); +} + +static void buspirate_jtag_get_adcs(int fd) +{ + char tmp[10]; + tmp[0] = CMD_READ_ADCS; + buspirate_jtag_command(fd, tmp, 1); + LOG_INFO("ADC: Ch1 = %d Ch2 = %d Ch3 = %d", tmp[1], tmp[2], tmp[3]); +} + +static unsigned char buspirate_jtag_command(int buspirate_fd, char *cmd, int cmdlen) +{ + int res; + int len = 0; + + res = buspirate_serial_write(buspirate_fd, cmd, cmdlen); +#ifdef DEBUG_SERIAL +//LOG_INFO("jtag_message %i",(int)cmd[0]); +LOG_INFO("write cmd = %i bytes %i", cmd[0], res); +buspirate_print_buffer(cmd, cmdlen); +#endif + if ((cmd[0] == CMD_UART_SPEED) || (cmd[0] == CMD_PORT_MODE) || (cmd[0] == CMD_FEATURE) || (cmd[0] == CMD_JTAG_SPEED)) + return 1; + + if (res == cmdlen) + { + // LOG_INFO("waiting jtag_message response %i",(int)msg[0]); + switch (cmd[0]) { + case CMD_READ_ADCS: + len = 4; // 3+1 + break; + case CMD_TAP_SHIFT: + case CMD_TAP_SHIFT2: + len = cmdlen; + break; + default: + LOG_INFO("Wrong !"); + } + res = buspirate_serial_read(buspirate_fd, cmd, len); +#ifdef DEBUG_SERIAL +LOG_INFO("read bytes %i should have read %i", res, len); +buspirate_print_buffer(cmd, len); +#endif + if (res > 0) + return (unsigned char)cmd[1]; + else + return -1; + } + else + return -1; + return 0; +} + +/* openocd command interface */ +static int buspirate_handle_adc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + if (argc != 0) + { + command_print(cmd_ctx, "usage: buspirate_adc"); + return ERROR_OK; + } + + if (buspirate_fd == -1) { + return ERROR_OK; + } + + // send the command + buspirate_jtag_get_adcs(buspirate_fd); + + return ERROR_OK; + +} + +static int buspirate_handle_vreg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + if (argc != 1) + { + command_print(cmd_ctx, "usage: buspirate_vreg <1|0>"); + return ERROR_OK; + } + + if (atoi(args[0]) == 1) { + // enable vreg + buspirate_jtag_set_feature(buspirate_fd, FEATURE_VREG, ACTION_ENABLE); + } else { + // disable vreg + buspirate_jtag_set_feature(buspirate_fd, FEATURE_VREG, ACTION_DISABLE); + } + + return ERROR_OK; + +} + +static int buspirate_handle_led_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + if (argc != 1) + { + command_print(cmd_ctx, "usage: buspirate_led <1|0>"); + return ERROR_OK; + } + + if (atoi(args[0]) == 1) { + // enable led + buspirate_jtag_set_feature(buspirate_fd, FEATURE_LED, ACTION_ENABLE); + } else { + // disable led + buspirate_jtag_set_feature(buspirate_fd, FEATURE_LED, ACTION_DISABLE); + } + + return ERROR_OK; + +} + +static int buspirate_handle_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + if (argc != 1) + { + command_print(cmd_ctx, "usage: buspirate_speed "); + return ERROR_OK; + } + + if (args[0][0] == 'n') { + buspirate_baudrate = SERIAL_NORMAL; + } else if (args[0][0] == 'f') { + buspirate_baudrate = SERIAL_FAST; + } else { + command_print(cmd_ctx, "usage: buspirate_speed "); + } + + return ERROR_OK; + +} + +static int buspirate_handle_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + if (argc != 1) + { + command_print(cmd_ctx, "usage: buspirate_port /dev/ttyUSB0"); + return ERROR_OK; + } + + if (buspirate_port == 0) { + buspirate_port = strdup(args[0]); + } + + return ERROR_OK; + +} + +/* low level serial port */ +static int buspirate_serial_setspeed(int fd, speed_t speed) { + struct termios t_opt; + + /* set the serial port parameters */ + fcntl(buspirate_fd, F_SETFL, 0); + tcgetattr(buspirate_fd, &t_opt); + cfsetispeed(&t_opt, speed); + cfsetospeed(&t_opt, speed); + t_opt.c_cflag |= (CLOCAL | CREAD); + t_opt.c_cflag &= ~PARENB; + t_opt.c_cflag &= ~CSTOPB; + t_opt.c_cflag &= ~CSIZE; + t_opt.c_cflag |= CS8; + t_opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + t_opt.c_iflag &= ~(IXON | IXOFF | IXANY); + t_opt.c_oflag &= ~OPOST; + t_opt.c_cc[VMIN] = 0; + t_opt.c_cc[VTIME] = 10; + tcsetattr(buspirate_fd, TCSANOW, &t_opt); + + return 0; +} + +static int buspirate_serial_write(int fd, char *buf, int size) { + int ret = 0; + + ret = write(fd, buf, size); + + if (ret != size) { + LOG_ERROR("Error sending data"); + } + + return ret; +} + +static int buspirate_serial_read(int fd, char *buf, int size) { + int len = 0; + int ret = 0; + int timeout = 0; + + while (len < size) + { + ret = read(fd, buf+len, size-len); + if (ret == -1) + return -1; + + if (ret == 0) { + timeout ++; + + if (timeout >= 10) + return len; + + continue; + } + + len += ret; + } + + return len; +} + +static void buspirate_print_buffer(char* buf, int size) { + int i; + + for (i = 0 ; i < size; i++) { + fprintf(stderr, "%02X ", ((unsigned char)buf[i]) & 0xff); + } + fprintf(stderr, "\n"); +} diff -Naur openocd-0.3.0-rc0/src/jtag/interfaces.c openocd-0.3.0-rc0-BP/src/jtag/interfaces.c --- openocd-0.3.0-rc0/src/jtag/interfaces.c 2009-10-21 13:45:59.000000000 +0200 +++ openocd-0.3.0-rc0-BP/src/jtag/interfaces.c 2010-01-18 17:41:44.000000000 +0100 @@ -88,6 +88,9 @@ #if BUILD_ARMJTAGEW == 1 extern jtag_interface_t armjtagew_interface; #endif +#if BUILD_BUSPIRATE == 1 +extern jtag_interface_t buspirate_interface; +#endif #endif // standard drivers /** @@ -145,6 +148,9 @@ #if BUILD_ARMJTAGEW == 1 &armjtagew_interface, #endif +#if BUILD_BUSPIRATE == 1 + &buspirate_interface, +#endif #endif // standard drivers NULL, };