static int buspirate_execute_queue(void);
static int buspirate_init(void);
static int buspirate_quit(void);
+static int buspirate_reset(int trst, int srst);
static void buspirate_end_state(tap_state_t state);
static void buspirate_state_move(void);
#define CMD_RAW_SPEED 0x60
#define CMD_RAW_MODE 0x80
+#define CMD_TAP_SHIFT_HEADER_LEN 3
+
/* raw-wire mode configuration */
#define CMD_RAW_CONFIG_HIZ 0x00
#define CMD_RAW_CONFIG_3V3 0x08
#define B1000000 0010010
#endif
+#define SHORT_TIMEOUT 1 /* Must be at least 1. */
+#define NORMAL_TIMEOUT 10
+
enum {
MODE_HIZ = 0,
MODE_JTAG = 1, /* push-pull outputs */
static int queued_retval;
static char swd_features;
-static const cc_t SHORT_TIMEOUT = 1; /* Must be at least 1. */
-static const cc_t NORMAL_TIMEOUT = 10;
-
static int buspirate_fd = -1;
static int buspirate_pinmode = MODE_JTAG_OD;
static int buspirate_baudrate = SERIAL_NORMAL;
struct scan_command *command);
static void buspirate_tap_make_space(int scan, int bits);
-static void buspirate_reset(int trst, int srst);
static void buspirate_set_feature(int, char, char);
static void buspirate_set_mode(int, char);
static void buspirate_set_speed(int, char);
/* low level interface */
static void buspirate_bbio_enable(int);
static void buspirate_jtag_reset(int);
-static unsigned char buspirate_jtag_command(int, char *, int);
+static unsigned char buspirate_jtag_command(int, uint8_t *, int);
static void buspirate_jtag_set_speed(int, char);
static void buspirate_jtag_set_mode(int, char);
static void buspirate_jtag_set_feature(int, char, char);
/* low level HW communication interface */
static int buspirate_serial_open(char *port);
static int buspirate_serial_setspeed(int fd, char speed, cc_t timeout);
-static int buspirate_serial_write(int fd, char *buf, int size);
-static int buspirate_serial_read(int fd, char *buf, int size);
+static int buspirate_serial_write(int fd, uint8_t *buf, int size);
+static int buspirate_serial_read(int fd, uint8_t *buf, int size);
static void buspirate_serial_close(int fd);
-static void buspirate_print_buffer(char *buf, int size);
+static void buspirate_print_buffer(uint8_t *buf, int size);
static int buspirate_execute_queue(void)
{
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- DEBUG_JTAG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %i cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest
->end_state));
->num_cycles);
break;
case JTAG_TLR_RESET:
- DEBUG_JTAG_IO("statemove end in %s",
+ LOG_DEBUG_IO("statemove end in %s",
tap_state_name(cmd->cmd.statemove
->end_state));
buspirate_end_state(cmd->cmd.statemove
buspirate_state_move();
break;
case JTAG_PATHMOVE:
- DEBUG_JTAG_IO("pathmove: %i states, end in %s",
+ LOG_DEBUG_IO("pathmove: %i states, end in %s",
cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove
->path[cmd->cmd.pathmove
cmd->cmd.pathmove->path);
break;
case JTAG_SCAN:
- DEBUG_JTAG_IO("scan end in %s",
+ LOG_DEBUG_IO("scan end in %s",
tap_state_name(cmd->cmd.scan
->end_state));
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);
-
- /* 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:
- DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
+ LOG_DEBUG_IO("sleep %" PRIu32, cmd->cmd.sleep->us);
buspirate_tap_execute();
jtag_sleep(cmd->cmd.sleep->us);
break;
case JTAG_STABLECLOCKS:
- DEBUG_JTAG_IO("stable clock %i cycles", cmd->cmd.stableclocks->num_cycles);
+ LOG_DEBUG_IO("stable clock %i cycles", cmd->cmd.stableclocks->num_cycles);
buspirate_stableclocks(cmd->cmd.stableclocks->num_cycles);
break;
default:
bool was_msg_already_printed = false;
for ( ; ; ) {
- char buffer[1024]; /* Any size will do, it's a trade-off between stack size and performance. */
+ uint8_t buffer[1024]; /* Any size will do, it's a trade-off between stack size and performance. */
const ssize_t read_count = read(fd, buffer, sizeof(buffer));
static int buspirate_init(void)
{
- if (buspirate_port == NULL) {
+ if (!buspirate_port) {
LOG_ERROR("You need to specify the serial port!");
return ERROR_JTAG_INIT_FAILED;
}
buspirate_serial_close(buspirate_fd);
- if (buspirate_port) {
- free(buspirate_port);
- buspirate_port = NULL;
- }
+ free(buspirate_port);
+ buspirate_port = NULL;
return ERROR_OK;
}
if (CMD_ARGC < 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- if (buspirate_port == NULL)
+ if (!buspirate_port)
buspirate_port = strdup(CMD_ARGV[0]);
return ERROR_OK;
}
-static const struct command_registration buspirate_command_handlers[] = {
+static const struct command_registration buspirate_subcommand_handlers[] = {
{
- .name = "buspirate_adc",
+ .name = "adc",
.handler = &buspirate_handle_adc_command,
.mode = COMMAND_EXEC,
.help = "reads voltages on adc pins",
+ .usage = "",
},
{
- .name = "buspirate_vreg",
+ .name = "vreg",
.usage = "<1|0>",
.handler = &buspirate_handle_vreg_command,
.mode = COMMAND_CONFIG,
.help = "changes the state of voltage regulators",
},
{
- .name = "buspirate_pullup",
+ .name = "pullup",
.usage = "<1|0>",
.handler = &buspirate_handle_pullup_command,
.mode = COMMAND_CONFIG,
.help = "changes the state of pullup",
},
{
- .name = "buspirate_led",
+ .name = "led",
.usage = "<1|0>",
.handler = &buspirate_handle_led_command,
.mode = COMMAND_EXEC,
.help = "changes the state of led",
},
{
- .name = "buspirate_speed",
+ .name = "speed",
.usage = "<normal|fast>",
.handler = &buspirate_handle_speed_command,
.mode = COMMAND_CONFIG,
.help = "speed of the interface",
},
{
- .name = "buspirate_mode",
+ .name = "mode",
.usage = "<normal|open-drain>",
.handler = &buspirate_handle_mode_command,
.mode = COMMAND_CONFIG,
.help = "pin mode of the interface",
},
{
- .name = "buspirate_port",
+ .name = "port",
.usage = "/dev/ttyUSB0",
.handler = &buspirate_handle_port_command,
.mode = COMMAND_CONFIG,
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration buspirate_command_handlers[] = {
+ {
+ .name = "buspirate",
+ .mode = COMMAND_ANY,
+ .help = "perform buspirate management",
+ .chain = buspirate_subcommand_handlers,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
static const struct swd_driver buspirate_swd = {
.init = buspirate_swd_init,
.switch_seq = buspirate_swd_switch_seq,
static const char * const buspirate_transports[] = { "jtag", "swd", NULL };
-struct jtag_interface buspirate_interface = {
- .name = "buspirate",
+static struct jtag_interface buspirate_interface = {
.execute_queue = buspirate_execute_queue,
- .commands = buspirate_command_handlers,
+};
+
+struct adapter_driver buspirate_adapter_driver = {
+ .name = "buspirate",
.transports = buspirate_transports,
- .swd = &buspirate_swd,
+ .commands = buspirate_command_handlers,
+
.init = buspirate_init,
- .quit = buspirate_quit
+ .quit = buspirate_quit,
+ .reset = buspirate_reset,
+
+ .jtag_ops = &buspirate_interface,
+ .swd_ops = &buspirate_swd,
};
/*************** jtag execute commands **********************/
for (i = 0; i < num_cycles; i++)
buspirate_tap_append(0, 0);
- DEBUG_JTAG_IO("runtest: cur_state %s end_state %s",
+ LOG_DEBUG_IO("runtest: cur_state %s end_state %s",
tap_state_name(tap_get_state()),
tap_state_name(tap_get_end_state()));
make it incompatible with the Bus Pirate firmware. */
#define BUSPIRATE_MAX_PENDING_SCANS 128
-static char tms_chain[BUSPIRATE_BUFFER_SIZE]; /* send */
-static char tdi_chain[BUSPIRATE_BUFFER_SIZE]; /* send */
+static uint8_t tms_chain[BUSPIRATE_BUFFER_SIZE]; /* send */
+static uint8_t tdi_chain[BUSPIRATE_BUFFER_SIZE]; /* send */
static int tap_chain_index;
struct pending_scan_result /* this was stolen from arm-jtag-ew */
static int buspirate_tap_execute(void)
{
- static const int CMD_TAP_SHIFT_HEADER_LEN = 3;
-
- char tmp[4096];
+ uint8_t tmp[4096];
uint8_t *in_buf;
int i;
int fill_index = 0;
bytes_to_send = DIV_ROUND_UP(tap_chain_index, 8);
tmp[0] = CMD_TAP_SHIFT; /* this command expects number of bits */
- tmp[1] = (char)(tap_chain_index >> 8); /* high */
- tmp[2] = (char)(tap_chain_index); /* low */
+ tmp[1] = tap_chain_index >> 8; /* high */
+ tmp[2] = tap_chain_index; /* low */
fill_index = CMD_TAP_SHIFT_HEADER_LEN;
for (i = 0; i < bytes_to_send; i++) {
int bit_index = tap_chain_index % 8;
uint8_t bit = 1 << bit_index;
- if (0 == bit_index) {
+ if (bit_index == 0) {
/* Let's say that the TAP shift operation wants to shift 9 bits,
so we will be sending to the Bus Pirate a bit count of 9 but still
full 16 bits (2 bytes) of shift data.
/*************** wrapper functions *********************/
/* (1) assert or (0) deassert reset lines */
-static void buspirate_reset(int trst, int srst)
+static int buspirate_reset(int trst, int srst)
{
LOG_DEBUG("trst: %i, srst: %i", trst, srst);
buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_DISABLE);
else
buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_ENABLE);
+
+ return ERROR_OK;
}
static void buspirate_set_feature(int fd, char feat, char action)
static void buspirate_swd_set_speed(int fd, char speed)
{
int ret;
- char tmp[1];
+ uint8_t tmp[1];
LOG_DEBUG("Buspirate speed setting in SWD mode defaults to 400 kHz");
static void buspirate_swd_set_mode(int fd, char mode)
{
int ret;
- char tmp[1];
+ uint8_t tmp[1];
/* raw-wire mode configuration */
if (mode == MODE_HIZ)
static void buspirate_swd_set_feature(int fd, char feat, char action)
{
int ret;
- char tmp[1];
+ uint8_t tmp[1];
switch (feat) {
case FEATURE_TRST:
char command;
const char *mode_answers[2] = { "OCD1", "RAW1" };
const char *correct_ans = NULL;
- char tmp[21] = { [0 ... 20] = 0x00 };
+ uint8_t tmp[21] = { [0 ... 20] = 0x00 };
int done = 0;
int cmd_sent = 0;
"/OpenOCD support enabled?");
exit(-1);
}
- if (strncmp(tmp, "BBIO", 4) == 0) {
+ if (strncmp((char *)tmp, "BBIO", 4) == 0) {
ret = buspirate_serial_read(fd, tmp, 1);
if (ret != 1) {
LOG_ERROR("Buspirate did not answer correctly! "
exit(-1);
}
}
- } else if (strncmp(tmp, correct_ans, 4) == 0)
+ } else if (strncmp((char *)tmp, correct_ans, 4) == 0)
done = 1;
else {
LOG_ERROR("Buspirate did not answer correctly! "
static void buspirate_jtag_reset(int fd)
{
- char tmp[5];
+ uint8_t tmp[5];
tmp[0] = 0x00; /* exit OCD1 mode */
buspirate_serial_write(fd, tmp, 1);
usleep(10000);
- /* We ignore the return value here purposly, nothing we can do */
+ /* We ignore the return value here on purpose, nothing we can do */
buspirate_serial_read(fd, tmp, 5);
- if (strncmp(tmp, "BBIO1", 5) == 0) {
+ if (strncmp((char *)tmp, "BBIO1", 5) == 0) {
tmp[0] = 0x0F; /* reset BP */
buspirate_serial_write(fd, tmp, 1);
} else
static void buspirate_jtag_set_speed(int fd, char speed)
{
int ret;
- char tmp[2];
- char ack[2];
+ uint8_t tmp[2];
+ uint8_t ack[2];
ack[0] = 0xAA;
ack[1] = 0x55;
static void buspirate_jtag_set_mode(int fd, char mode)
{
- char tmp[2];
+ uint8_t 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];
+ uint8_t tmp[3];
tmp[0] = CMD_FEATURE;
tmp[1] = feat; /* what */
tmp[2] = action; /* action */
uint8_t tmp[10];
uint16_t a, b, c, d;
tmp[0] = CMD_READ_ADCS;
- buspirate_jtag_command(fd, (char *)tmp, 1);
+ buspirate_jtag_command(fd, tmp, 1);
a = tmp[2] << 8 | tmp[3];
b = tmp[4] << 8 | tmp[5];
c = tmp[6] << 8 | tmp[7];
}
static unsigned char buspirate_jtag_command(int fd,
- char *cmd, int cmdlen)
+ uint8_t *cmd, int cmdlen)
{
int res;
int len = 0;
/* set the serial port parameters */
fcntl(fd, F_SETFL, 0);
- if (0 != tcgetattr(fd, &t_opt))
+ if (tcgetattr(fd, &t_opt) != 0)
return -1;
- if (0 != cfsetispeed(&t_opt, baud))
+ if (cfsetispeed(&t_opt, baud) != 0)
return -1;
- if (0 != cfsetospeed(&t_opt, baud))
+ if (cfsetospeed(&t_opt, baud) != 0)
return -1;
t_opt.c_cflag |= (CLOCAL | CREAD);
/* Note that, in the past, TCSANOW was used below instead of TCSADRAIN,
and CMD_UART_SPEED did not work properly then, at least with
the Bus Pirate v3.5 (USB). */
- if (0 != tcsetattr(fd, TCSADRAIN, &t_opt)) {
+ if (tcsetattr(fd, TCSADRAIN, &t_opt) != 0) {
/* According to the Linux documentation, this is actually not enough
to detect errors, you need to call tcgetattr() and check that
all changes have been performed successfully. */
return 0;
}
-static int buspirate_serial_write(int fd, char *buf, int size)
+static int buspirate_serial_write(int fd, uint8_t *buf, int size)
{
int ret = 0;
return ret;
}
-static int buspirate_serial_read(int fd, char *buf, int size)
+static int buspirate_serial_read(int fd, uint8_t *buf, int size)
{
int len = 0;
int ret = 0;
#define LINE_SIZE 81
#define BYTES_PER_LINE 16
-static void buspirate_print_buffer(char *buf, int size)
+static void buspirate_print_buffer(uint8_t *buf, int size)
{
char line[LINE_SIZE];
char tmp[10];
{
const uint8_t *sequence;
int sequence_len;
- char tmp[64];
+ uint32_t no_bytes, sequence_offset;
switch (seq) {
case LINE_RESET:
return ERROR_FAIL;
}
- /* FIXME: all above sequences fit into one pirate command for now
- * but it may cause trouble later
- */
+ no_bytes = sequence_len;
+ sequence_offset = 0;
- tmp[0] = 0x10 + ((sequence_len - 1) & 0x0F);
- memcpy(tmp + 1, sequence, sequence_len);
+ while (no_bytes) {
+ uint8_t tmp[17];
+ uint32_t to_send;
- buspirate_serial_write(buspirate_fd, tmp, sequence_len + 1);
- buspirate_serial_read(buspirate_fd, tmp, sequence_len + 1);
+ to_send = no_bytes > 16 ? 16 : no_bytes;
+
+ tmp[0] = 0x10 + ((to_send - 1) & 0x0F);
+ memcpy(tmp + 1, &sequence[sequence_offset], to_send);
+
+ buspirate_serial_write(buspirate_fd, tmp, to_send + 1);
+ buspirate_serial_read(buspirate_fd, tmp, to_send + 1);
+
+ no_bytes -= to_send;
+ sequence_offset += to_send;
+ }
return ERROR_OK;
}
static uint8_t buspirate_swd_write_header(uint8_t cmd)
{
- char tmp[8];
+ uint8_t tmp[8];
int to_send;
tmp[0] = 0x10; /* bus pirate: send 1 byte */
tmp[5] = 0x07; /* write mode trn_1 */
tmp[6] = 0x07; /* write mode trn_2 */
- to_send = ((cmd & SWD_CMD_RnW) == 0) ? 7 : 5;
+ to_send = ((cmd & SWD_CMD_RNW) == 0) ? 7 : 5;
buspirate_serial_write(buspirate_fd, tmp, to_send);
/* read ack */
static void buspirate_swd_idle_clocks(uint32_t no_bits)
{
uint32_t no_bytes;
- char tmp[20];
+ uint8_t tmp[20];
no_bytes = (no_bits + 7) / 8;
memset(tmp + 1, 0x00, sizeof(tmp) - 1);
static void buspirate_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
- char tmp[16];
+ uint8_t tmp[16];
LOG_DEBUG("buspirate_swd_read_reg");
- assert(cmd & SWD_CMD_RnW);
+ assert(cmd & SWD_CMD_RNW);
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skip buspirate_swd_read_reg because queued_retval=%d", queued_retval);
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_APNDP ? "AP" : "DP",
+ cmd & SWD_CMD_RNW ? "read" : "write",
(cmd & SWD_CMD_A32) >> 1,
data);
}
if (value)
*value = data;
- if (cmd & SWD_CMD_APnDP)
+ if (cmd & SWD_CMD_APNDP)
buspirate_swd_idle_clocks(ap_delay_clk);
return;
case SWD_ACK_WAIT:
static void buspirate_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
- char tmp[16];
+ uint8_t tmp[16];
LOG_DEBUG("buspirate_swd_write_reg");
- assert(!(cmd & SWD_CMD_RnW));
+ assert(!(cmd & SWD_CMD_RNW));
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skip buspirate_swd_write_reg because queued_retval=%d", queued_retval);
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_APNDP ? "AP" : "DP",
+ cmd & SWD_CMD_RNW ? "read" : "write",
(cmd & SWD_CMD_A32) >> 1,
value);
switch (ack) {
case SWD_ACK_OK:
- if (cmd & SWD_CMD_APnDP)
+ if (cmd & SWD_CMD_APNDP)
buspirate_swd_idle_clocks(ap_delay_clk);
return;
case SWD_ACK_WAIT:
LOG_DEBUG("SWD queue return value: %02x", retval);
return retval;
}
-
-