1 /***************************************************************************
2 * Copyright (C) 2010 by Michal Demin *
3 * based on usbprog.c and arm-jtag-ew.c *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
25 #include <jtag/interface.h>
26 #include <jtag/commands.h>
30 #include <sys/ioctl.h>
33 /*#define DEBUG_SERIAL */
34 static int buspirate_execute_queue(void);
35 static int buspirate_init(void);
36 static int buspirate_quit(void);
38 static void buspirate_end_state(tap_state_t state
);
39 static void buspirate_state_move(void);
40 static void buspirate_path_move(int num_states
, tap_state_t
*path
);
41 static void buspirate_runtest(int num_cycles
);
42 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
43 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
45 #define CMD_UNKNOWN 0x00
46 #define CMD_PORT_MODE 0x01
47 #define CMD_FEATURE 0x02
48 #define CMD_READ_ADCS 0x03
49 /*#define CMD_TAP_SHIFT 0x04 // old protocol */
50 #define CMD_TAP_SHIFT 0x05
51 #define CMD_ENTER_OOCD 0x06
52 #define CMD_UART_SPEED 0x07
53 #define CMD_JTAG_SPEED 0x08
55 /* Not all OSes have this speed defined */
56 #if !defined(B1000000)
57 #define B1000000 0010010
62 MODE_JTAG
= 1, /* push-pull outputs */
63 MODE_JTAG_OD
= 2, /* open-drain outputs */
84 static int buspirate_fd
= -1;
85 static int buspirate_pinmode
= MODE_JTAG_OD
;
86 static int buspirate_baudrate
= SERIAL_NORMAL
;
87 static int buspirate_vreg
;
88 static int buspirate_pullup
;
89 static char *buspirate_port
;
92 static void buspirate_tap_init(void);
93 static int buspirate_tap_execute(void);
94 static void buspirate_tap_append(int tms
, int tdi
);
95 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
96 struct scan_command
*command
);
97 static void buspirate_tap_make_space(int scan
, int bits
);
99 static void buspirate_reset(int trst
, int srst
);
101 /* low level interface */
102 static void buspirate_jtag_reset(int);
103 static void buspirate_jtag_enable(int);
104 static unsigned char buspirate_jtag_command(int, char *, int);
105 static void buspirate_jtag_set_speed(int, char);
106 static void buspirate_jtag_set_mode(int, char);
107 static void buspirate_jtag_set_feature(int, char, char);
108 static void buspirate_jtag_get_adcs(int);
110 /* low level HW communication interface */
111 static int buspirate_serial_open(char *port
);
112 static int buspirate_serial_setspeed(int fd
, char speed
);
113 static int buspirate_serial_write(int fd
, char *buf
, int size
);
114 static int buspirate_serial_read(int fd
, char *buf
, int size
);
115 static void buspirate_serial_close(int fd
);
116 static void buspirate_print_buffer(char *buf
, int size
);
118 static int buspirate_execute_queue(void)
120 /* currently processed command */
121 struct jtag_command
*cmd
= jtag_command_queue
;
129 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
130 cmd
->cmd
.runtest
->num_cycles
,
131 tap_state_name(cmd
->cmd
.runtest
133 buspirate_end_state(cmd
->cmd
.runtest
135 buspirate_runtest(cmd
->cmd
.runtest
139 DEBUG_JTAG_IO("statemove end in %s",
140 tap_state_name(cmd
->cmd
.statemove
142 buspirate_end_state(cmd
->cmd
.statemove
144 buspirate_state_move();
147 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
148 cmd
->cmd
.pathmove
->num_states
,
149 tap_state_name(cmd
->cmd
.pathmove
150 ->path
[cmd
->cmd
.pathmove
152 buspirate_path_move(cmd
->cmd
.pathmove
154 cmd
->cmd
.pathmove
->path
);
157 DEBUG_JTAG_IO("scan end in %s",
158 tap_state_name(cmd
->cmd
.scan
161 buspirate_end_state(cmd
->cmd
.scan
164 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
,
166 type
= jtag_scan_type(cmd
->cmd
.scan
);
167 buspirate_scan(cmd
->cmd
.scan
->ir_scan
, type
,
168 buffer
, scan_size
, cmd
->cmd
.scan
);
172 DEBUG_JTAG_IO("reset trst: %i srst %i",
173 cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
175 /* flush buffers, so we can reset */
176 buspirate_tap_execute();
178 if (cmd
->cmd
.reset
->trst
== 1)
179 tap_set_state(TAP_RESET
);
180 buspirate_reset(cmd
->cmd
.reset
->trst
,
181 cmd
->cmd
.reset
->srst
);
184 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
185 buspirate_tap_execute();
186 jtag_sleep(cmd
->cmd
.sleep
->us
);
189 LOG_ERROR("BUG: unknown JTAG command type encountered");
196 return buspirate_tap_execute();
199 static int buspirate_init(void)
201 if (buspirate_port
== NULL
) {
202 LOG_ERROR("You need to specify the serial port!");
203 return ERROR_JTAG_INIT_FAILED
;
206 buspirate_fd
= buspirate_serial_open(buspirate_port
);
207 if (buspirate_fd
== -1) {
208 LOG_ERROR("Could not open serial port");
209 return ERROR_JTAG_INIT_FAILED
;
212 buspirate_serial_setspeed(buspirate_fd
, SERIAL_NORMAL
);
214 buspirate_jtag_enable(buspirate_fd
);
216 if (buspirate_baudrate
!= SERIAL_NORMAL
)
217 buspirate_jtag_set_speed(buspirate_fd
, SERIAL_FAST
);
219 LOG_INFO("Buspirate Interface ready!");
221 buspirate_tap_init();
222 buspirate_jtag_set_mode(buspirate_fd
, buspirate_pinmode
);
223 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_VREG
,
224 (buspirate_vreg
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
225 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_PULLUP
,
226 (buspirate_pullup
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
227 buspirate_reset(0, 0);
232 static int buspirate_quit(void)
234 LOG_INFO("Shutting down buspirate.");
235 buspirate_jtag_set_mode(buspirate_fd
, MODE_HIZ
);
237 buspirate_jtag_set_speed(buspirate_fd
, SERIAL_NORMAL
);
238 buspirate_jtag_reset(buspirate_fd
);
240 buspirate_serial_close(buspirate_fd
);
242 if (buspirate_port
) {
243 free(buspirate_port
);
244 buspirate_port
= NULL
;
249 /* openocd command interface */
250 COMMAND_HANDLER(buspirate_handle_adc_command
)
252 if (buspirate_fd
== -1)
255 /* send the command */
256 buspirate_jtag_get_adcs(buspirate_fd
);
262 COMMAND_HANDLER(buspirate_handle_vreg_command
)
265 return ERROR_COMMAND_SYNTAX_ERROR
;
267 if (atoi(CMD_ARGV
[0]) == 1)
269 else if (atoi(CMD_ARGV
[0]) == 0)
272 LOG_ERROR("usage: buspirate_vreg <1|0>");
278 COMMAND_HANDLER(buspirate_handle_pullup_command
)
281 return ERROR_COMMAND_SYNTAX_ERROR
;
283 if (atoi(CMD_ARGV
[0]) == 1)
284 buspirate_pullup
= 1;
285 else if (atoi(CMD_ARGV
[0]) == 0)
286 buspirate_pullup
= 0;
288 LOG_ERROR("usage: buspirate_pullup <1|0>");
294 COMMAND_HANDLER(buspirate_handle_led_command
)
297 return ERROR_COMMAND_SYNTAX_ERROR
;
299 if (atoi(CMD_ARGV
[0]) == 1) {
301 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_LED
,
303 } else if (atoi(CMD_ARGV
[0]) == 0) {
305 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_LED
,
308 LOG_ERROR("usage: buspirate_led <1|0>");
315 COMMAND_HANDLER(buspirate_handle_mode_command
)
318 return ERROR_COMMAND_SYNTAX_ERROR
;
320 if (CMD_ARGV
[0][0] == 'n')
321 buspirate_pinmode
= MODE_JTAG
;
322 else if (CMD_ARGV
[0][0] == 'o')
323 buspirate_pinmode
= MODE_JTAG_OD
;
325 LOG_ERROR("usage: buspirate_mode <normal|open-drain>");
331 COMMAND_HANDLER(buspirate_handle_speed_command
)
334 return ERROR_COMMAND_SYNTAX_ERROR
;
336 if (CMD_ARGV
[0][0] == 'n')
337 buspirate_baudrate
= SERIAL_NORMAL
;
338 else if (CMD_ARGV
[0][0] == 'f')
339 buspirate_baudrate
= SERIAL_FAST
;
341 LOG_ERROR("usage: buspirate_speed <normal|fast>");
347 COMMAND_HANDLER(buspirate_handle_port_command
)
350 return ERROR_COMMAND_SYNTAX_ERROR
;
352 if (buspirate_port
== NULL
)
353 buspirate_port
= strdup(CMD_ARGV
[0]);
359 static const struct command_registration buspirate_command_handlers
[] = {
361 .name
= "buspirate_adc",
362 .handler
= &buspirate_handle_adc_command
,
363 .mode
= COMMAND_EXEC
,
364 .help
= "reads voltages on adc pins",
367 .name
= "buspirate_vreg",
369 .handler
= &buspirate_handle_vreg_command
,
370 .mode
= COMMAND_CONFIG
,
371 .help
= "changes the state of voltage regulators",
374 .name
= "buspirate_pullup",
376 .handler
= &buspirate_handle_pullup_command
,
377 .mode
= COMMAND_CONFIG
,
378 .help
= "changes the state of pullup",
381 .name
= "buspirate_led",
383 .handler
= &buspirate_handle_led_command
,
384 .mode
= COMMAND_EXEC
,
385 .help
= "changes the state of led",
388 .name
= "buspirate_speed",
389 .usage
= "<normal|fast>",
390 .handler
= &buspirate_handle_speed_command
,
391 .mode
= COMMAND_CONFIG
,
392 .help
= "speed of the interface",
395 .name
= "buspirate_mode",
396 .usage
= "<normal|open-drain>",
397 .handler
= &buspirate_handle_mode_command
,
398 .mode
= COMMAND_CONFIG
,
399 .help
= "pin mode of the interface",
402 .name
= "buspirate_port",
403 .usage
= "/dev/ttyUSB0",
404 .handler
= &buspirate_handle_port_command
,
405 .mode
= COMMAND_CONFIG
,
406 .help
= "name of the serial port to open",
408 COMMAND_REGISTRATION_DONE
411 struct jtag_interface buspirate_interface
= {
413 .execute_queue
= buspirate_execute_queue
,
414 .commands
= buspirate_command_handlers
,
415 .init
= buspirate_init
,
416 .quit
= buspirate_quit
419 /*************** jtag execute commands **********************/
420 static void buspirate_end_state(tap_state_t state
)
422 if (tap_is_state_stable(state
))
423 tap_set_end_state(state
);
425 LOG_ERROR("BUG: %i is not a valid end state", state
);
430 static void buspirate_state_move(void)
433 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
434 tap_get_end_state());
435 int tms_count
= tap_get_tms_path_len(tap_get_state(),
436 tap_get_end_state());
438 for (i
= 0; i
< tms_count
; i
++) {
439 tms
= (tms_scan
>> i
) & 1;
440 buspirate_tap_append(tms
, 0);
443 tap_set_state(tap_get_end_state());
446 static void buspirate_path_move(int num_states
, tap_state_t
*path
)
450 for (i
= 0; i
< num_states
; i
++) {
451 if (tap_state_transition(tap_get_state(), false) == path
[i
]) {
452 buspirate_tap_append(0, 0);
453 } else if (tap_state_transition(tap_get_state(), true)
455 buspirate_tap_append(1, 0);
457 LOG_ERROR("BUG: %s -> %s isn't a valid "
459 tap_state_name(tap_get_state()),
460 tap_state_name(path
[i
]));
464 tap_set_state(path
[i
]);
467 tap_set_end_state(tap_get_state());
470 static void buspirate_runtest(int num_cycles
)
474 tap_state_t saved_end_state
= tap_get_end_state();
476 /* only do a state_move when we're not already in IDLE */
477 if (tap_get_state() != TAP_IDLE
) {
478 buspirate_end_state(TAP_IDLE
);
479 buspirate_state_move();
482 for (i
= 0; i
< num_cycles
; i
++)
483 buspirate_tap_append(0, 0);
485 DEBUG_JTAG_IO("runtest: cur_state %s end_state %s",
486 tap_state_name(tap_get_state()),
487 tap_state_name(tap_get_end_state()));
489 /* finish in end_state */
490 buspirate_end_state(saved_end_state
);
491 if (tap_get_state() != tap_get_end_state())
492 buspirate_state_move();
495 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
496 uint8_t *buffer
, int scan_size
, struct scan_command
*command
)
498 tap_state_t saved_end_state
;
500 buspirate_tap_make_space(1, scan_size
+8);
501 /* is 8 correct ? (2 moves = 16) */
503 saved_end_state
= tap_get_end_state();
505 buspirate_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
507 /* Only move if we're not already there */
508 if (tap_get_state() != tap_get_end_state())
509 buspirate_state_move();
511 buspirate_tap_append_scan(scan_size
, buffer
, command
);
514 buspirate_tap_append(0, 0);
516 /* restore the saved state */
517 buspirate_end_state(saved_end_state
);
518 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
520 if (tap_get_state() != tap_get_end_state())
521 buspirate_state_move();
525 /************************* TAP related stuff **********/
527 #define BUSPIRATE_BUFFER_SIZE 1024
528 #define BUSPIRATE_MAX_PENDING_SCANS 32
530 static char tms_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
531 static char tdi_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
532 static int tap_chain_index
;
534 struct pending_scan_result
/* this was stolen from arm-jtag-ew */
536 int first
; /* First bit position in tdo_buffer to read */
537 int length
; /* Number of bits to read */
538 struct scan_command
*command
; /* Corresponding scan command */
542 static struct pending_scan_result
543 tap_pending_scans
[BUSPIRATE_MAX_PENDING_SCANS
];
544 static int tap_pending_scans_num
;
546 static void buspirate_tap_init(void)
549 tap_pending_scans_num
= 0;
552 static int buspirate_tap_execute(void)
561 if (tap_chain_index
<= 0)
564 LOG_DEBUG("executing tap num bits = %i scans = %i",
565 tap_chain_index
, tap_pending_scans_num
);
567 bytes_to_send
= (tap_chain_index
+7) / 8;
569 tmp
[0] = CMD_TAP_SHIFT
; /* this command expects number of bits */
570 tmp
[1] = (char)(tap_chain_index
>> 8); /* high */
571 tmp
[2] = (char)(tap_chain_index
); /* low */
574 for (i
= 0; i
< bytes_to_send
; i
++) {
575 tmp
[fill_index
] = tdi_chain
[i
];
577 tmp
[fill_index
] = tms_chain
[i
];
581 ret
= buspirate_serial_write(buspirate_fd
, tmp
, 3 + bytes_to_send
*2);
582 if (ret
!= bytes_to_send
*2+3) {
583 LOG_ERROR("error writing :(");
584 return ERROR_JTAG_DEVICE_ERROR
;
587 ret
= buspirate_serial_read(buspirate_fd
, tmp
, bytes_to_send
+ 3);
588 if (ret
!= bytes_to_send
+ 3) {
589 LOG_ERROR("error reading");
592 in_buf
= (uint8_t *)(&tmp
[3]);
594 /* parse the scans */
595 for (i
= 0; i
< tap_pending_scans_num
; i
++) {
596 uint8_t *buffer
= tap_pending_scans
[i
].buffer
;
597 int length
= tap_pending_scans
[i
].length
;
598 int first
= tap_pending_scans
[i
].first
;
599 struct scan_command
*command
= tap_pending_scans
[i
].command
;
601 /* copy bits from buffer */
602 buf_set_buf(in_buf
, first
, buffer
, 0, length
);
604 /* return buffer to higher level */
605 if (jtag_read_buffer(buffer
, command
) != ERROR_OK
) {
606 buspirate_tap_init();
607 return ERROR_JTAG_QUEUE_FAILED
;
612 tap_pending_scans_num
= 0;
617 static void buspirate_tap_make_space(int scans
, int bits
)
619 int have_scans
= BUSPIRATE_MAX_PENDING_SCANS
- tap_pending_scans_num
;
620 int have_bits
= BUSPIRATE_BUFFER_SIZE
* 8 - tap_chain_index
;
622 if ((have_scans
< scans
) || (have_bits
< bits
))
623 buspirate_tap_execute();
626 static void buspirate_tap_append(int tms
, int tdi
)
630 buspirate_tap_make_space(0, 1);
631 chain_index
= tap_chain_index
/ 8;
633 if (chain_index
< BUSPIRATE_BUFFER_SIZE
) {
634 int bit_index
= tap_chain_index
% 8;
635 uint8_t bit
= 1 << bit_index
;
638 tms_chain
[chain_index
] |= bit
;
640 tms_chain
[chain_index
] &= ~bit
;
643 tdi_chain
[chain_index
] |= bit
;
645 tdi_chain
[chain_index
] &= ~bit
;
649 LOG_ERROR("tap_chain overflow, bad things will happen");
653 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
654 struct scan_command
*command
)
657 tap_pending_scans
[tap_pending_scans_num
].length
= length
;
658 tap_pending_scans
[tap_pending_scans_num
].buffer
= buffer
;
659 tap_pending_scans
[tap_pending_scans_num
].command
= command
;
660 tap_pending_scans
[tap_pending_scans_num
].first
= tap_chain_index
;
662 for (i
= 0; i
< length
; i
++) {
663 int tms
= (i
< length
-1 ? 0 : 1);
664 int tdi
= (buffer
[i
/8] >> (i
%8)) & 1;
665 buspirate_tap_append(tms
, tdi
);
667 tap_pending_scans_num
++;
670 /*************** jtag wrapper functions *********************/
672 /* (1) assert or (0) deassert reset lines */
673 static void buspirate_reset(int trst
, int srst
)
675 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
678 buspirate_jtag_set_feature(buspirate_fd
,
679 FEATURE_TRST
, ACTION_DISABLE
);
681 buspirate_jtag_set_feature(buspirate_fd
,
682 FEATURE_TRST
, ACTION_ENABLE
);
685 buspirate_jtag_set_feature(buspirate_fd
,
686 FEATURE_SRST
, ACTION_DISABLE
);
688 buspirate_jtag_set_feature(buspirate_fd
,
689 FEATURE_SRST
, ACTION_ENABLE
);
692 /*************** jtag lowlevel functions ********************/
693 static void buspirate_jtag_enable(int fd
)
696 char tmp
[21] = { [0 ... 20] = 0x00 };
700 LOG_DEBUG("Entering binary mode");
701 buspirate_serial_write(fd
, tmp
, 20);
704 /* reads 1 to n "BBIO1"s and one "OCD1" */
706 ret
= buspirate_serial_read(fd
, tmp
, 4);
708 LOG_ERROR("Buspirate error. Is binary"
709 "/OpenOCD support enabled?");
712 if (strncmp(tmp
, "BBIO", 4) == 0) {
713 ret
= buspirate_serial_read(fd
, tmp
, 1);
715 LOG_ERROR("Buspirate did not answer correctly! "
716 "Do you have correct firmware?");
720 LOG_ERROR("Unsupported binary protocol");
725 tmp
[0] = CMD_ENTER_OOCD
;
726 ret
= buspirate_serial_write(fd
, tmp
, 1);
728 LOG_ERROR("error reading");
732 } else if (strncmp(tmp
, "OCD1", 4) == 0)
735 LOG_ERROR("Buspirate did not answer correctly! "
736 "Do you have correct firmware?");
743 static void buspirate_jtag_reset(int fd
)
747 tmp
[0] = 0x00; /* exit OCD1 mode */
748 buspirate_serial_write(fd
, tmp
, 1);
750 /* We ignore the return value here purposly, nothing we can do */
751 buspirate_serial_read(fd
, tmp
, 5);
752 if (strncmp(tmp
, "BBIO1", 5) == 0) {
753 tmp
[0] = 0x0F; /* reset BP */
754 buspirate_serial_write(fd
, tmp
, 1);
756 LOG_ERROR("Unable to restart buspirate!");
759 static void buspirate_jtag_set_speed(int fd
, char speed
)
768 tmp
[0] = CMD_UART_SPEED
;
770 buspirate_jtag_command(fd
, tmp
, 2);
772 /* here the adapter changes speed, we need follow */
773 buspirate_serial_setspeed(fd
, speed
);
775 buspirate_serial_write(fd
, ack
, 2);
776 ret
= buspirate_serial_read(fd
, tmp
, 2);
778 LOG_ERROR("Buspirate did not ack speed change");
781 if ((tmp
[0] != CMD_UART_SPEED
) || (tmp
[1] != speed
)) {
782 LOG_ERROR("Buspirate did not reply as expected");
785 LOG_INFO("Buspirate switched to %s mode",
786 (speed
== SERIAL_NORMAL
) ? "normal" : "FAST");
790 static void buspirate_jtag_set_mode(int fd
, char mode
)
793 tmp
[0] = CMD_PORT_MODE
;
795 buspirate_jtag_command(fd
, tmp
, 2);
798 static void buspirate_jtag_set_feature(int fd
, char feat
, char action
)
801 tmp
[0] = CMD_FEATURE
;
802 tmp
[1] = feat
; /* what */
803 tmp
[2] = action
; /* action */
804 buspirate_jtag_command(fd
, tmp
, 3);
807 static void buspirate_jtag_get_adcs(int fd
)
811 tmp
[0] = CMD_READ_ADCS
;
812 buspirate_jtag_command(fd
, (char *)tmp
, 1);
813 a
= tmp
[2] << 8 | tmp
[3];
814 b
= tmp
[4] << 8 | tmp
[5];
815 c
= tmp
[6] << 8 | tmp
[7];
816 d
= tmp
[8] << 8 | tmp
[9];
818 LOG_INFO("ADC: ADC_Pin = %.02f VPullup = %.02f V33 = %.02f "
820 ((float)a
)/155.1515, ((float)b
)/155.1515,
821 ((float)c
)/155.1515, ((float)d
)/155.1515);
824 static unsigned char buspirate_jtag_command(int fd
,
825 char *cmd
, int cmdlen
)
830 res
= buspirate_serial_write(fd
, cmd
, cmdlen
);
832 if ((cmd
[0] == CMD_UART_SPEED
)
833 || (cmd
[0] == CMD_PORT_MODE
)
834 || (cmd
[0] == CMD_FEATURE
)
835 || (cmd
[0] == CMD_JTAG_SPEED
))
841 len
= 10; /* 2*sizeof(char)+4*sizeof(uint16_t) */
849 res
= buspirate_serial_read(fd
, cmd
, len
);
851 return (unsigned char)cmd
[1];
859 /* low level serial port */
860 /* TODO add support for WIN32 and others ! */
861 static int buspirate_serial_open(char *port
)
864 fd
= open(buspirate_port
, O_RDWR
| O_NOCTTY
| O_NDELAY
);
868 static int buspirate_serial_setspeed(int fd
, char speed
)
870 struct termios t_opt
;
871 speed_t baud
= (speed
== SERIAL_FAST
) ? B1000000
: B115200
;
873 /* set the serial port parameters */
874 fcntl(fd
, F_SETFL
, 0);
875 tcgetattr(fd
, &t_opt
);
876 cfsetispeed(&t_opt
, baud
);
877 cfsetospeed(&t_opt
, baud
);
878 t_opt
.c_cflag
|= (CLOCAL
| CREAD
);
879 t_opt
.c_cflag
&= ~PARENB
;
880 t_opt
.c_cflag
&= ~CSTOPB
;
881 t_opt
.c_cflag
&= ~CSIZE
;
882 t_opt
.c_cflag
|= CS8
;
883 t_opt
.c_lflag
&= ~(ICANON
| ECHO
| ECHOE
| ISIG
);
884 t_opt
.c_iflag
&= ~(IXON
| IXOFF
| IXANY
);
885 t_opt
.c_oflag
&= ~OPOST
;
886 t_opt
.c_cc
[VMIN
] = 0;
887 t_opt
.c_cc
[VTIME
] = 10;
888 tcflush(fd
, TCIFLUSH
);
889 tcsetattr(fd
, TCSANOW
, &t_opt
);
894 static int buspirate_serial_write(int fd
, char *buf
, int size
)
898 ret
= write(fd
, buf
, size
);
900 LOG_DEBUG("size = %d ret = %d", size
, ret
);
901 buspirate_print_buffer(buf
, size
);
904 LOG_ERROR("Error sending data");
909 static int buspirate_serial_read(int fd
, char *buf
, int size
)
916 ret
= read(fd
, buf
+len
, size
-len
);
932 LOG_DEBUG("should have read = %d actual size = %d", size
, len
);
933 buspirate_print_buffer(buf
, len
);
936 LOG_ERROR("Error reading data");
941 static void buspirate_serial_close(int fd
)
947 #define BYTES_PER_LINE 16
948 static void buspirate_print_buffer(char *buf
, int size
)
950 char line
[LINE_SIZE
];
955 while (offset
< size
) {
956 snprintf(tmp
, 5, "%02x ", (uint8_t)buf
[offset
]);
961 if (offset
% BYTES_PER_LINE
== 0) {
962 LOG_DEBUG("%s", line
);
968 LOG_DEBUG("%s", line
);
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)