buspirate: Serial port was not correctly closed.
[openocd.git] / src / jtag / drivers / buspirate.c
1 /***************************************************************************
2 * Copyright (C) 2010 by Michal Demin *
3 * based on usbprog.c and arm-jtag-ew.c *
4 * *
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. *
9 * *
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. *
14 * *
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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <jtag/interface.h>
26 #include <jtag/commands.h>
27
28 #include <termios.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31
32 #undef DEBUG_SERIAL
33 /*#define DEBUG_SERIAL */
34 static int buspirate_execute_queue(void);
35 static int buspirate_speed(int speed);
36 static int buspirate_khz(int khz, int *jtag_speed);
37 static int buspirate_init(void);
38 static int buspirate_quit(void);
39
40 static void buspirate_end_state(tap_state_t state);
41 static void buspirate_state_move(void);
42 static void buspirate_path_move(int num_states, tap_state_t *path);
43 static void buspirate_runtest(int num_cycles);
44 static void buspirate_scan(bool ir_scan, enum scan_type type,
45 uint8_t *buffer, int scan_size, struct scan_command *command);
46
47
48 #define CMD_UNKOWN 0x00
49 #define CMD_PORT_MODE 0x01
50 #define CMD_FEATURE 0x02
51 #define CMD_READ_ADCS 0x03
52 /*#define CMD_TAP_SHIFT 0x04 // old protocol */
53 #define CMD_TAP_SHIFT 0x05
54 #define CMD_ENTER_OOCD 0x06
55 #define CMD_UART_SPEED 0x07
56 #define CMD_JTAG_SPEED 0x08
57
58 enum {
59 MODE_HIZ = 0,
60 MODE_JTAG = 1, /* push-pull outputs */
61 MODE_JTAG_OD = 2, /* open-drain outputs */
62 };
63
64 enum {
65 FEATURE_LED = 0x01,
66 FEATURE_VREG = 0x02,
67 FEATURE_TRST = 0x04,
68 FEATURE_SRST = 0x08,
69 FEATURE_PULLUP = 0x10
70 };
71
72 enum {
73 ACTION_DISABLE = 0,
74 ACTION_ENABLE = 1
75 };
76
77 enum {
78 SERIAL_NORMAL = 0,
79 SERIAL_FAST = 1
80 };
81
82
83 static int buspirate_fd = -1;
84 static int buspirate_pinmode = MODE_JTAG_OD;
85 static int buspirate_baudrate = SERIAL_NORMAL;
86 static int buspirate_vreg;
87 static int buspirate_pullup;
88 static char *buspirate_port;
89
90
91 /* TAP interface */
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);
98
99 static void buspirate_reset(int trst, int srst);
100
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);
109
110 /* low level HW communication interface */
111 static int buspirate_serial_setspeed(int fd, speed_t speed);
112 static int buspirate_serial_write(int fd, char *buf, int size);
113 static int buspirate_serial_read(int fd, char *buf, int size);
114 static void buspirate_serial_close(int fd);
115 static void buspirate_print_buffer(char *buf, int size);
116
117 static int buspirate_speed(int speed)
118 {
119 /* TODO */
120 LOG_INFO("Want to set speed to %dkHz, but not implemented yet", speed);
121 return ERROR_OK;
122 }
123
124 static int buspirate_khz(int khz, int *jtag_speed)
125 {
126 *jtag_speed = khz;
127 return ERROR_OK;
128 }
129
130 static int buspirate_execute_queue(void)
131 {
132 /* currently processed command */
133 struct jtag_command *cmd = jtag_command_queue;
134 int scan_size;
135 enum scan_type type;
136 uint8_t *buffer;
137
138 while (cmd) {
139 switch (cmd->type) {
140 case JTAG_RUNTEST:
141 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
142 cmd->cmd.runtest->num_cycles,
143 tap_state_name(cmd->cmd.runtest
144 ->end_state));
145 buspirate_end_state(cmd->cmd.runtest
146 ->end_state);
147 buspirate_runtest(cmd->cmd.runtest
148 ->num_cycles);
149 break;
150 case JTAG_TLR_RESET:
151 DEBUG_JTAG_IO("statemove end in %s",
152 tap_state_name(cmd->cmd.statemove
153 ->end_state));
154 buspirate_end_state(cmd->cmd.statemove
155 ->end_state);
156 buspirate_state_move();
157 break;
158 case JTAG_PATHMOVE:
159 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
160 cmd->cmd.pathmove->num_states,
161 tap_state_name(cmd->cmd.pathmove
162 ->path[cmd->cmd.pathmove
163 ->num_states - 1]));
164 buspirate_path_move(cmd->cmd.pathmove
165 ->num_states,
166 cmd->cmd.pathmove->path);
167 break;
168 case JTAG_SCAN:
169 DEBUG_JTAG_IO("scan end in %s",
170 tap_state_name(cmd->cmd.scan
171 ->end_state));
172
173 buspirate_end_state(cmd->cmd.scan
174 ->end_state);
175
176 scan_size = jtag_build_buffer(cmd->cmd.scan,
177 &buffer);
178 type = jtag_scan_type(cmd->cmd.scan);
179 buspirate_scan(cmd->cmd.scan->ir_scan, type,
180 buffer, scan_size, cmd->cmd.scan);
181
182 break;
183 case JTAG_RESET:
184 DEBUG_JTAG_IO("reset trst: %i srst %i",
185 cmd->cmd.reset->trst, cmd->cmd.reset->srst);
186
187 /* flush buffers, so we can reset */
188 buspirate_tap_execute();
189
190 if (cmd->cmd.reset->trst == 1)
191 tap_set_state(TAP_RESET);
192 buspirate_reset(cmd->cmd.reset->trst,
193 cmd->cmd.reset->srst);
194 break;
195 case JTAG_SLEEP:
196 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
197 buspirate_tap_execute();
198 jtag_sleep(cmd->cmd.sleep->us);
199 break;
200 default:
201 LOG_ERROR("BUG: unknown JTAG command type encountered");
202 exit(-1);
203 }
204
205 cmd = cmd->next;
206 }
207
208 return buspirate_tap_execute();
209 }
210
211 static int buspirate_init(void)
212 {
213 if (buspirate_port == NULL) {
214 LOG_ERROR("You need to specify port !");
215 return ERROR_JTAG_INIT_FAILED;
216 }
217
218 buspirate_fd = open(buspirate_port, O_RDWR | O_NOCTTY);
219 if (buspirate_fd == -1) {
220 LOG_ERROR("Could not open serial port.");
221 return ERROR_JTAG_INIT_FAILED;
222 }
223
224 buspirate_serial_setspeed(buspirate_fd, B115200);
225
226 buspirate_jtag_enable(buspirate_fd);
227
228 if (buspirate_baudrate != SERIAL_NORMAL)
229 buspirate_jtag_set_speed(buspirate_fd, SERIAL_FAST);
230
231 LOG_INFO("Buspirate Interface ready!");
232
233 buspirate_tap_init();
234 buspirate_jtag_set_mode(buspirate_fd, buspirate_pinmode);
235 buspirate_jtag_set_feature(buspirate_fd, FEATURE_VREG,
236 (buspirate_vreg == 1) ? ACTION_ENABLE : ACTION_DISABLE);
237 buspirate_jtag_set_feature(buspirate_fd, FEATURE_PULLUP,
238 (buspirate_pullup == 1) ? ACTION_ENABLE : ACTION_DISABLE);
239 buspirate_reset(0, 0);
240
241 return ERROR_OK;
242 }
243
244 static int buspirate_quit(void)
245 {
246 LOG_INFO("Shuting down buspirate ");
247 buspirate_jtag_set_mode(buspirate_fd, MODE_HIZ);
248
249 buspirate_jtag_set_speed(buspirate_fd, SERIAL_NORMAL);
250 buspirate_jtag_reset(buspirate_fd);
251
252 buspirate_serial_close(buspirate_fd);
253
254 if (buspirate_port) {
255 free(buspirate_port);
256 buspirate_port = NULL;
257 }
258 return ERROR_OK;
259 }
260
261 /* openocd command interface */
262 COMMAND_HANDLER(buspirate_handle_adc_command)
263 {
264 if (CMD_ARGC != 0) {
265 LOG_ERROR("usage: buspirate_adc");
266 return ERROR_OK;
267 }
268
269 if (buspirate_fd == -1)
270 return ERROR_OK;
271
272 /* send the command */
273 buspirate_jtag_get_adcs(buspirate_fd);
274
275 return ERROR_OK;
276
277 }
278
279 COMMAND_HANDLER(buspirate_handle_vreg_command)
280 {
281 if (CMD_ARGC != 1) {
282 LOG_ERROR("usage: buspirate_vreg <1|0>");
283 return ERROR_OK;
284 }
285
286 if (atoi(CMD_ARGV[0]) == 1)
287 buspirate_vreg = 1;
288 else
289 buspirate_vreg = 0;
290
291 return ERROR_OK;
292
293 }
294
295 COMMAND_HANDLER(buspirate_handle_pullup_command)
296 {
297 if (CMD_ARGC != 1) {
298 LOG_ERROR("usage: buspirate_pullup <1|0>");
299 return ERROR_OK;
300 }
301
302 if (atoi(CMD_ARGV[0]) == 1)
303 buspirate_pullup = 1;
304 else
305 buspirate_pullup = 0;
306
307 return ERROR_OK;
308
309 }
310
311 COMMAND_HANDLER(buspirate_handle_led_command)
312 {
313 if (CMD_ARGC != 1) {
314 LOG_ERROR("usage: buspirate_led <1|0>");
315 return ERROR_OK;
316 }
317
318 if (atoi(CMD_ARGV[0]) == 1) {
319 /* enable led */
320 buspirate_jtag_set_feature(buspirate_fd, FEATURE_LED,
321 ACTION_ENABLE);
322 } else {
323 /* disable led */
324 buspirate_jtag_set_feature(buspirate_fd, FEATURE_LED,
325 ACTION_DISABLE);
326 }
327
328 return ERROR_OK;
329
330 }
331
332 COMMAND_HANDLER(buspirate_handle_mode_command)
333 {
334 if (CMD_ARGC != 1) {
335 LOG_ERROR("usage: buspirate_mode <normal|open-drain>");
336 return ERROR_OK;
337 }
338
339 if (CMD_ARGV[0][0] == 'n')
340 buspirate_pinmode = MODE_JTAG;
341 else if (CMD_ARGV[0][0] == 'o')
342 buspirate_pinmode = MODE_JTAG_OD;
343 else
344 LOG_ERROR("usage: buspirate_mode <normal|open-drain>");
345
346 return ERROR_OK;
347
348 }
349
350 COMMAND_HANDLER(buspirate_handle_speed_command)
351 {
352 if (CMD_ARGC != 1) {
353 LOG_ERROR("usage: buspirate_speed <normal|fast>");
354 return ERROR_OK;
355 }
356
357 if (CMD_ARGV[0][0] == 'n')
358 buspirate_baudrate = SERIAL_NORMAL;
359 else if (CMD_ARGV[0][0] == 'f')
360 buspirate_baudrate = SERIAL_FAST;
361 else
362 LOG_ERROR("usage: buspirate_speed <normal|fast>");
363
364 return ERROR_OK;
365
366 }
367
368 COMMAND_HANDLER(buspirate_handle_port_command)
369 {
370 if (CMD_ARGC != 1) {
371 LOG_ERROR("usage: buspirate_port /dev/ttyUSB0");
372 return ERROR_OK;
373 }
374
375 if (buspirate_port == 0)
376 buspirate_port = strdup(CMD_ARGV[0]);
377
378 return ERROR_OK;
379
380 }
381
382 static const struct command_registration buspirate_command_handlers[] = {
383 {
384 .name = "buspirate_adc",
385 .handler = &buspirate_handle_adc_command,
386 .mode = COMMAND_EXEC,
387 .help = "reads voltages on adc pins",
388 },
389 {
390 .name = "buspirate_vreg",
391 .handler = &buspirate_handle_vreg_command,
392 .mode = COMMAND_CONFIG,
393 .help = "changes the state of voltage regulators",
394 },
395 {
396 .name = "buspirate_pullup",
397 .handler = &buspirate_handle_pullup_command,
398 .mode = COMMAND_CONFIG,
399 .help = "changes the state of pullup",
400 },
401 {
402 .name = "buspirate_led",
403 .handler = &buspirate_handle_led_command,
404 .mode = COMMAND_EXEC,
405 .help = "changes the state of led",
406 },
407 {
408 .name = "buspirate_speed",
409 .handler = &buspirate_handle_speed_command,
410 .mode = COMMAND_CONFIG,
411 .help = "speed of the interface",
412 },
413 {
414 .name = "buspirate_mode",
415 .handler = &buspirate_handle_mode_command,
416 .mode = COMMAND_CONFIG,
417 .help = "pin mode of the interface",
418 },
419 {
420 .name = "buspirate_port",
421 .handler = &buspirate_handle_port_command,
422 .mode = COMMAND_CONFIG,
423 .help = "name of the serial port to open",
424 },
425 COMMAND_REGISTRATION_DONE
426 };
427
428 struct jtag_interface buspirate_interface = {
429 .name = "buspirate",
430 .execute_queue = buspirate_execute_queue,
431 .speed = buspirate_speed,
432 .khz = buspirate_khz,
433 .commands = buspirate_command_handlers,
434 .init = buspirate_init,
435 .quit = buspirate_quit
436 };
437
438 /*************** jtag execute commands **********************/
439 static void buspirate_end_state(tap_state_t state)
440 {
441 if (tap_is_state_stable(state))
442 tap_set_end_state(state);
443 else {
444 LOG_ERROR("BUG: %i is not a valid end state", state);
445 exit(-1);
446 }
447 }
448
449 static void buspirate_state_move(void)
450 {
451 int i = 0, tms = 0;
452 uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
453 tap_get_end_state());
454 int tms_count = tap_get_tms_path_len(tap_get_state(),
455 tap_get_end_state());
456
457 for (i = 0; i < tms_count; i++) {
458 tms = (tms_scan >> i) & 1;
459 buspirate_tap_append(tms, 0);
460 }
461
462 tap_set_state(tap_get_end_state());
463 }
464
465 static void buspirate_path_move(int num_states, tap_state_t *path)
466 {
467 int i;
468
469 for (i = 0; i < num_states; i++) {
470 if (tap_state_transition(tap_get_state(), false) == path[i]) {
471 buspirate_tap_append(0, 0);
472 } else if (tap_state_transition(tap_get_state(), true)
473 == path[i]) {
474 buspirate_tap_append(1, 0);
475 } else {
476 LOG_ERROR("BUG: %s -> %s isn't a valid "
477 "TAP transition",
478 tap_state_name(tap_get_state()),
479 tap_state_name(path[i]));
480 exit(-1);
481 }
482
483 tap_set_state(path[i]);
484 }
485
486 tap_set_end_state(tap_get_state());
487 }
488
489 static void buspirate_runtest(int num_cycles)
490 {
491 int i;
492
493 tap_state_t saved_end_state = tap_get_end_state();
494
495 /* only do a state_move when we're not already in IDLE */
496 if (tap_get_state() != TAP_IDLE) {
497 buspirate_end_state(TAP_IDLE);
498 buspirate_state_move();
499 }
500
501 for (i = 0; i < num_cycles; i++)
502 buspirate_tap_append(0, 0);
503
504 DEBUG_JTAG_IO("runtest: cur_state %s end_state %s",
505 tap_state_name(tap_get_state()),
506 tap_state_name(tap_get_end_state()));
507
508 /* finish in end_state */
509 buspirate_end_state(saved_end_state);
510 if (tap_get_state() != tap_get_end_state())
511 buspirate_state_move();
512 }
513
514 static void buspirate_scan(bool ir_scan, enum scan_type type,
515 uint8_t *buffer, int scan_size, struct scan_command *command)
516 {
517 tap_state_t saved_end_state;
518
519 buspirate_tap_make_space(1, scan_size+8);
520 /* is 8 correct ? (2 moves = 16) */
521
522 saved_end_state = tap_get_end_state();
523
524 buspirate_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
525 buspirate_state_move();
526
527 buspirate_tap_append_scan(scan_size, buffer, command);
528
529 /* move to PAUSE */
530 buspirate_tap_append(0, 0);
531
532 /* restore the saved state */
533 buspirate_end_state(saved_end_state);
534 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
535
536 if (tap_get_state() != tap_get_end_state())
537 buspirate_state_move();
538 }
539
540
541 /************************* TAP related stuff **********/
542
543 #define BUSPIRATE_BUFFER_SIZE 1024
544 #define BUSPIRATE_MAX_PENDING_SCANS 32
545
546 static char tms_chain[BUSPIRATE_BUFFER_SIZE]; /* send */
547 static char tdi_chain[BUSPIRATE_BUFFER_SIZE]; /* send */
548 static int tap_chain_index;
549
550 struct pending_scan_result /* this was stolen from arm-jtag-ew */
551 {
552 int first; /* First bit position in tdo_buffer to read */
553 int length; /* Number of bits to read */
554 struct scan_command *command; /* Corresponding scan command */
555 uint8_t *buffer;
556 };
557
558 static struct pending_scan_result
559 tap_pending_scans[BUSPIRATE_MAX_PENDING_SCANS];
560 static int tap_pending_scans_num;
561
562 static void buspirate_tap_init(void)
563 {
564 tap_chain_index = 0;
565 tap_pending_scans_num = 0;
566 }
567
568 static int buspirate_tap_execute(void)
569 {
570 char tmp[4096];
571 uint8_t *in_buf;
572 int i;
573 int fill_index = 0;
574 int ret;
575 int bytes_to_send;
576
577 if (tap_chain_index <= 0)
578 return ERROR_OK;
579
580 LOG_DEBUG("executing tap num bits = %i scans = %i",
581 tap_chain_index, tap_pending_scans_num);
582
583 bytes_to_send = (tap_chain_index+7) / 8;
584
585 tmp[0] = CMD_TAP_SHIFT; /* this command expects number of bits */
586 tmp[1] = (char)(tap_chain_index >> 8); /* high */
587 tmp[2] = (char)(tap_chain_index); /* low */
588
589 fill_index = 3;
590 for (i = 0; i < bytes_to_send; i++) {
591 tmp[fill_index] = tdi_chain[i];
592 fill_index++;
593 tmp[fill_index] = tms_chain[i];
594 fill_index++;
595 }
596
597 ret = buspirate_serial_write(buspirate_fd, tmp, 3 + bytes_to_send*2);
598 if (ret != bytes_to_send*2+3) {
599 LOG_ERROR("error writing :(");
600 return ERROR_JTAG_DEVICE_ERROR;
601 }
602
603 ret = buspirate_serial_read(buspirate_fd, tmp, bytes_to_send + 3);
604 in_buf = (uint8_t *)(&tmp[3]);
605
606 /* parse the scans */
607 for (i = 0; i < tap_pending_scans_num; i++) {
608 uint8_t *buffer = tap_pending_scans[i].buffer;
609 int length = tap_pending_scans[i].length;
610 int first = tap_pending_scans[i].first;
611 struct scan_command *command = tap_pending_scans[i].command;
612
613 /* copy bits from buffer */
614 buf_set_buf(in_buf, first, buffer, 0, length);
615
616 /* return buffer to higher level */
617 if (jtag_read_buffer(buffer, command) != ERROR_OK) {
618 buspirate_tap_init();
619 return ERROR_JTAG_QUEUE_FAILED;
620 }
621
622 free(buffer);
623 }
624 tap_pending_scans_num = 0;
625 tap_chain_index = 0;
626 return ERROR_OK;
627 }
628
629 static void buspirate_tap_make_space(int scans, int bits)
630 {
631 int have_scans = BUSPIRATE_MAX_PENDING_SCANS - tap_pending_scans_num;
632 int have_bits = BUSPIRATE_BUFFER_SIZE * 8 - tap_chain_index;
633
634 if ((have_scans < scans) || (have_bits < bits))
635 buspirate_tap_execute();
636 }
637
638 static void buspirate_tap_append(int tms, int tdi)
639 {
640 int chain_index;
641
642 buspirate_tap_make_space(0, 1);
643 chain_index = tap_chain_index / 8;
644
645 if (chain_index < BUSPIRATE_BUFFER_SIZE) {
646 int bit_index = tap_chain_index % 8;
647 uint8_t bit = 1 << bit_index;
648
649 if (tms)
650 tms_chain[chain_index] |= bit;
651 else
652 tms_chain[chain_index] &= ~bit;
653
654 if (tdi)
655 tdi_chain[chain_index] |= bit;
656 else
657 tdi_chain[chain_index] &= ~bit;
658
659 tap_chain_index++;
660 } else
661 LOG_ERROR("tap_chain overflow, Bad things will happen");
662
663 }
664
665 static void buspirate_tap_append_scan(int length, uint8_t *buffer,
666 struct scan_command *command)
667 {
668 int i;
669 tap_pending_scans[tap_pending_scans_num].length = length;
670 tap_pending_scans[tap_pending_scans_num].buffer = buffer;
671 tap_pending_scans[tap_pending_scans_num].command = command;
672 tap_pending_scans[tap_pending_scans_num].first = tap_chain_index;
673
674 for (i = 0; i < length; i++) {
675 int tms = (i < length-1 ? 0 : 1);
676 int tdi = (buffer[i/8] >> (i%8)) & 1;
677 buspirate_tap_append(tms, tdi);
678 }
679 tap_pending_scans_num++;
680 }
681
682 /*************** jtag wrapper functions *********************/
683
684 /* (1) assert or (0) deassert reset lines */
685 static void buspirate_reset(int trst, int srst)
686 {
687 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
688
689 if (trst)
690 buspirate_jtag_set_feature(buspirate_fd,
691 FEATURE_TRST, ACTION_DISABLE);
692 else
693 buspirate_jtag_set_feature(buspirate_fd,
694 FEATURE_TRST, ACTION_ENABLE);
695
696 if (srst)
697 buspirate_jtag_set_feature(buspirate_fd,
698 FEATURE_SRST, ACTION_DISABLE);
699 else
700 buspirate_jtag_set_feature(buspirate_fd,
701 FEATURE_SRST, ACTION_ENABLE);
702 }
703
704 /*************** jtag lowlevel functions ********************/
705 static void buspirate_jtag_enable(int fd)
706 {
707 int ret;
708 char tmp[21] = { [0 ... 20] = 0x00 };
709 int done = 0;
710 int cmd_sent = 0;
711
712 LOG_DEBUG("Entering binary mode");
713 buspirate_serial_write(fd, tmp, 20);
714 usleep(10000);
715
716 /* reads 1 to n "BBIO1"s and one "OCD1" */
717 while (!done) {
718 ret = buspirate_serial_read(fd, tmp, 4);
719 if (ret != 4) {
720 LOG_ERROR("Buspirate did not respond :"
721 "( restart everything");
722 exit(-1);
723 }
724 LOG_DEBUG("TUI");
725 if (strncmp(tmp, "BBIO", 4) == 0) {
726 ret = buspirate_serial_read(fd, tmp, 1);
727 if (ret != 1) {
728 LOG_ERROR("Buspirate did not respond well :"
729 "( restart everything");
730 exit(-1);
731 }
732 if (tmp[0] != '1') {
733 LOG_ERROR("Unsupported binary protocol ");
734 exit(-1);
735 }
736 if (cmd_sent == 0) {
737 cmd_sent = 1;
738 tmp[0] = CMD_ENTER_OOCD;
739 ret = buspirate_serial_write(fd, tmp, 1);
740 }
741 } else if (strncmp(tmp, "OCD1", 4) == 0)
742 done = 1;
743 else {
744 LOG_ERROR("Buspirate did not respond :"
745 "( restart everything");
746 exit(-1);
747 }
748 }
749
750 }
751
752 static void buspirate_jtag_reset(int fd)
753 {
754 int ret;
755 char tmp[5];
756
757 tmp[0] = 0x00; /* exit OCD1 mode */
758 buspirate_serial_write(fd, tmp, 1);
759 usleep(10000);
760 ret = buspirate_serial_read(fd, tmp, 5);
761 if (strncmp(tmp, "BBIO1", 5) == 0) {
762 tmp[0] = 0x0F; /* reset BP */
763 buspirate_serial_write(fd, tmp, 1);
764 } else
765 LOG_ERROR("Bad reply :( Please restart manually");
766 }
767
768 static void buspirate_jtag_set_speed(int fd, char speed)
769 {
770 int ret;
771 char tmp[2];
772 char ack[2];
773 speed_t baudrate = B115200;
774
775 ack[0] = 0xAA;
776 ack[1] = 0x55;
777
778 tmp[0] = CMD_UART_SPEED;
779 tmp[1] = speed;
780 buspirate_jtag_command(fd, tmp, 2);
781
782 /* here the adapter changes speed, we need follow */
783 if (speed == SERIAL_FAST)
784 baudrate = B1000000;
785
786 buspirate_serial_setspeed(fd, baudrate);
787
788 buspirate_serial_write(fd, ack, 2);
789 ret = buspirate_serial_read(fd, tmp, 2);
790 if (ret != 2) {
791 LOG_ERROR("Buspirate did not respond :"
792 "( restart everything");
793 exit(-1);
794 }
795 if ((tmp[0] != CMD_UART_SPEED) || (tmp[1] != speed)) {
796 LOG_ERROR("Buspirate didn't reply as expected :"
797 "( restart everything");
798 exit(-1);
799 }
800 LOG_INFO("Buspirate switched to %s mode",
801 (speed == SERIAL_NORMAL) ? "normal" : "FAST");
802 }
803
804
805 static void buspirate_jtag_set_mode(int fd, char mode)
806 {
807 char tmp[2];
808 tmp[0] = CMD_PORT_MODE;
809 tmp[1] = mode;
810 buspirate_jtag_command(fd, tmp, 2);
811 }
812
813 static void buspirate_jtag_set_feature(int fd, char feat, char action)
814 {
815 char tmp[3];
816 tmp[0] = CMD_FEATURE;
817 tmp[1] = feat; /* what */
818 tmp[2] = action; /* action */
819 buspirate_jtag_command(fd, tmp, 3);
820 }
821
822 static void buspirate_jtag_get_adcs(int fd)
823 {
824 uint8_t tmp[10];
825 uint16_t a, b, c, d;
826 tmp[0] = CMD_READ_ADCS;
827 buspirate_jtag_command(fd, (char *)tmp, 1);
828 a = tmp[2] << 8 | tmp[3];
829 b = tmp[4] << 8 | tmp[5];
830 c = tmp[6] << 8 | tmp[7];
831 d = tmp[8] << 8 | tmp[9];
832
833 LOG_INFO("ADC: ADC_Pin = %.02f VPullup = %.02f V33 = %.02f "
834 "V50 = %.02f",
835 ((float)a)/155.1515, ((float)b)/155.1515,
836 ((float)c)/155.1515, ((float)d)/155.1515);
837 }
838
839 static unsigned char buspirate_jtag_command(int fd,
840 char *cmd, int cmdlen)
841 {
842 int res;
843 int len = 0;
844
845 res = buspirate_serial_write(fd, cmd, cmdlen);
846
847 if ((cmd[0] == CMD_UART_SPEED)
848 || (cmd[0] == CMD_PORT_MODE)
849 || (cmd[0] == CMD_FEATURE)
850 || (cmd[0] == CMD_JTAG_SPEED))
851 return 1;
852
853 if (res == cmdlen) {
854 switch (cmd[0]) {
855 case CMD_READ_ADCS:
856 len = 10; /* 2*sizeof(char)+4*sizeof(uint16_t) */
857 break;
858 case CMD_TAP_SHIFT:
859 len = cmdlen;
860 break;
861 default:
862 LOG_INFO("Wrong !");
863 }
864 res = buspirate_serial_read(fd, cmd, len);
865 if (res > 0)
866 return (unsigned char)cmd[1];
867 else
868 return -1;
869 } else
870 return -1;
871 return 0;
872 }
873
874 /* low level serial port */
875 /* TODO add support for WIN32 and others ! */
876 static int buspirate_serial_setspeed(int fd, speed_t speed)
877 {
878 struct termios t_opt;
879
880 /* set the serial port parameters */
881 fcntl(fd, F_SETFL, 0);
882 tcgetattr(fd, &t_opt);
883 cfsetispeed(&t_opt, speed);
884 cfsetospeed(&t_opt, speed);
885 t_opt.c_cflag |= (CLOCAL | CREAD);
886 t_opt.c_cflag &= ~PARENB;
887 t_opt.c_cflag &= ~CSTOPB;
888 t_opt.c_cflag &= ~CSIZE;
889 t_opt.c_cflag |= CS8;
890 t_opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
891 t_opt.c_iflag &= ~(IXON | IXOFF | IXANY);
892 t_opt.c_oflag &= ~OPOST;
893 t_opt.c_cc[VMIN] = 0;
894 t_opt.c_cc[VTIME] = 10;
895 tcflush(fd, TCIFLUSH);
896 tcsetattr(fd, TCSANOW, &t_opt);
897
898 return 0;
899 }
900
901 static int buspirate_serial_write(int fd, char *buf, int size)
902 {
903 int ret = 0;
904
905 ret = write(fd, buf, size);
906
907 LOG_DEBUG("size = %d ret = %d", size, ret);
908 buspirate_print_buffer(buf, size);
909
910 if (ret != size)
911 LOG_ERROR("Error sending data");
912
913 return ret;
914 }
915
916 static int buspirate_serial_read(int fd, char *buf, int size)
917 {
918 int len = 0;
919 int ret = 0;
920 int timeout = 0;
921
922 while (len < size) {
923 ret = read(fd, buf+len, size-len);
924 if (ret == -1)
925 return -1;
926
927 if (ret == 0) {
928 timeout++;
929
930 if (timeout >= 10)
931 break;
932
933 continue;
934 }
935
936 len += ret;
937 }
938
939 LOG_DEBUG("should have read = %d actual size = %d", size, len);
940 buspirate_print_buffer(buf, len);
941
942 if (len != size)
943 LOG_ERROR("Error sending data");
944
945 return len;
946 }
947
948 static void buspirate_serial_close(int fd)
949 {
950 close(fd);
951 }
952
953 #define LINE_SIZE 81
954 #define BYTES_PER_LINE 16
955 static void buspirate_print_buffer(char *buf, int size)
956 {
957 char line[LINE_SIZE];
958 char tmp[10];
959 int offset = 0;
960
961 line[0] = 0;
962 while (offset < size) {
963 snprintf(tmp, 5, "%02x ", (uint8_t)buf[offset]);
964 offset++;
965
966 strcat(line, tmp);
967
968 if (offset % BYTES_PER_LINE == 0) {
969 LOG_DEBUG("%s", line);
970 line[0] = 0;
971 }
972 }
973
974 if (line[0] != 0) {
975 LOG_DEBUG("%s", line);
976 }
977 }
978

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)