Zach Welch <zw@superlucidity.net> fix -Wformat-security warnings (1 of 4)
[openocd.git] / src / jtag / vsllink.c
1 /***************************************************************************
2 * Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 /* Versaloon is a programming tool for multiple MCUs.
21 * OpenOCD and MSP430 supports are distributed under GPLv2.
22 * You can find it at http://www.SimonQian.com/en/Versaloon.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "replacements.h"
30
31 #include "jtag.h"
32
33 #include <usb.h>
34 #include <string.h>
35
36 #include "log.h"
37
38 //#define _VSLLINK_IN_DEBUG_MODE_
39
40 /* enable this to view USB communication
41 */
42 #if 0
43 #define _DEBUG_USB_COMMS_
44 #endif
45
46 #ifdef _DEBUG_JTAG_IO_
47 #define DEBUG_JTAG_IO(expr ...) LOG_DEBUG(expr)
48 #else
49 #define DEBUG_JTAG_IO(expr ...)
50 #endif
51
52 static u16 vsllink_vid;
53 static u16 vsllink_pid;
54 static u8 vsllink_bulkout;
55 static u8 vsllink_bulkin;
56
57 #define VSLLINK_USB_TIMEOUT 10000
58
59 static int VSLLINK_BufferSize = 1024;
60
61 /* Global USB buffers */
62 static int vsllink_usb_out_buffer_idx;
63 static int vsllink_usb_in_want_length;
64 static u8* vsllink_usb_in_buffer = NULL;
65 static u8* vsllink_usb_out_buffer = NULL;
66
67 /* Constants for VSLLink command */
68 #define VSLLINK_CMD_CONN 0x80
69 #define VSLLINK_CMD_DISCONN 0x81
70 #define VSLLINK_CMD_SET_SPEED 0x82
71 #define VSLLINK_CMD_SET_PORT 0x90
72 #define VSLLINK_CMD_GET_PORT 0x91
73 #define VSLLINK_CMD_SET_PORTDIR 0x92
74 #define VSLLINK_CMD_HW_JTAGSEQCMD 0xA0
75 #define VSLLINK_CMD_HW_JTAGHLCMD 0xA1
76 #define VSLLINK_CMD_HW_SWDCMD 0xA2
77
78 #define VSLLINK_CMDJTAGSEQ_TMSBYTE 0x00
79 #define VSLLINK_CMDJTAGSEQ_TMSCLOCK 0x40
80 #define VSLLINK_CMDJTAGSEQ_SCAN 0x80
81
82 #define VSLLINK_CMDJTAGSEQ_CMDMSK 0xC0
83 #define VSLLINK_CMDJTAGSEQ_LENMSK 0x3F
84
85 #define JTAG_PINMSK_SRST (1 << 0)
86 #define JTAG_PINMSK_TRST (1 << 1)
87 #define JTAG_PINMSK_USR1 (1 << 2)
88 #define JTAG_PINMSK_USR2 (1 << 3)
89 #define JTAG_PINMSK_TCK (1 << 4)
90 #define JTAG_PINMSK_TMS (1 << 5)
91 #define JTAG_PINMSK_TDI (1 << 6)
92 #define JTAG_PINMSK_TDO (1 << 7)
93
94
95 #define VSLLINK_TAP_MOVE(from, to) VSLLINK_tap_move[tap_move_ndx(from)][tap_move_ndx(to)]
96
97 /* VSLLINK_tap_move[i][j]: tap movement command to go from state i to state j
98 * 0: Test-Logic-Reset
99 * 1: Run-Test/Idle
100 * 2: Shift-DR
101 * 3: Pause-DR
102 * 4: Shift-IR
103 * 5: Pause-IR
104 *
105 * SD->SD and SI->SI have to be caught in interface specific code
106 */
107 static u8 VSLLINK_tap_move[6][6] =
108 {
109 /* TLR RTI SD PD SI PI */
110 {0xff, 0x7f, 0x2f, 0x0a, 0x37, 0x16}, /* TLR */
111 {0xff, 0x00, 0x45, 0x05, 0x4b, 0x0b}, /* RTI */
112 {0xff, 0x61, 0x00, 0x01, 0x0f, 0x2f}, /* SD */
113 {0xff, 0x60, 0x40, 0x5c, 0x3c, 0x5e}, /* PD */
114 {0xff, 0x61, 0x07, 0x17, 0x00, 0x01}, /* SI */
115 {0xff, 0x60, 0x38, 0x5c, 0x40, 0x5e} /* PI */
116 };
117
118 typedef struct insert_insignificant_operation
119 {
120 unsigned char insert_value;
121 unsigned char insert_position;
122 }insert_insignificant_operation_t;
123
124 static insert_insignificant_operation_t VSLLINK_TAP_MOVE_INSERT_INSIGNIFICANT[6][6] =
125 {
126 /* stuff offset */
127 {/* TLR */
128 {1, 0,}, /* TLR */
129 {1, 0,}, /* RTI */
130 {1, 0,}, /* SD */
131 {1, 0,}, /* PD */
132 {1, 0,}, /* SI */
133 {1, 0,}}, /* PI */
134 {/* RTI */
135 {1, 0,}, /* TLR */
136 {0, 0,}, /* RTI */
137 {0, 4,}, /* SD */
138 {0, 7,}, /* PD */
139 {0, 5,}, /* SI */
140 {0, 7,}}, /* PI */
141 {/* SD */
142 {0, 0,}, /* TLR */
143 {0, 0,}, /* RTI */
144 {0, 0,}, /* SD */
145 {0, 0,}, /* PD */
146 {0, 0,}, /* SI */
147 {0, 0,}}, /* PI */
148 {/* PD */
149 {0, 0,}, /* TLR */
150 {0, 0,}, /* RTI */
151 {0, 0,}, /* SD */
152 {0, 0,}, /* PD */
153 {0, 0,}, /* SI */
154 {0, 0,}}, /* PI */
155 {/* SI */
156 {0, 0,}, /* TLR */
157 {0, 0,}, /* RTI */
158 {0, 0,}, /* SD */
159 {0, 0,}, /* PD */
160 {0, 0,}, /* SI */
161 {0, 0,}}, /* PI */
162 {/* PI */
163 {0, 0,}, /* TLR */
164 {0, 0,}, /* RTI */
165 {0, 0,}, /* SD */
166 {0, 0,}, /* PD */
167 {0, 0,}, /* SI */
168 {0, 0,}}, /* PI */
169 };
170
171 static u8 VSLLINK_BIT_MSK[8] =
172 {
173 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f
174 };
175
176 typedef struct
177 {
178 int length; /* Number of bits to read */
179 int offset;
180 scan_command_t *command; /* Corresponding scan command */
181 u8 *buffer;
182 } pending_scan_result_t;
183
184 #define MAX_PENDING_SCAN_RESULTS 256
185
186 static int pending_scan_results_length;
187 static pending_scan_result_t pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
188
189 /* External interface functions */
190 static int vsllink_execute_queue(void);
191 static int vsllink_speed(int speed);
192 static int vsllink_khz(int khz, int *jtag_speed);
193 static int vsllink_speed_div(int jtag_speed, int *khz);
194 static int vsllink_register_commands(struct command_context_s *cmd_ctx);
195 static int vsllink_init(void);
196 static int vsllink_quit(void);
197
198 /* CLI command handler functions */
199 static int vsllink_handle_usb_vid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
200 static int vsllink_handle_usb_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
201 static int vsllink_handle_usb_bulkin_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
202 static int vsllink_handle_usb_bulkout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
203
204 /* Queue command functions */
205 static void vsllink_end_state(tap_state_t state);
206 static void vsllink_state_move(void);
207 static void vsllink_path_move(int num_states, tap_state_t *path);
208 static void vsllink_runtest(int num_cycles);
209 static void vsllink_stableclocks(int num_cycles, int tms);
210 static void vsllink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command);
211 static void vsllink_reset(int trst, int srst);
212 static void vsllink_simple_command(u8 command);
213
214 /* VSLLink tap buffer functions */
215 static void vsllink_tap_init(void);
216 static int vsllink_tap_execute(void);
217 static void vsllink_tap_ensure_space(int scans, int bytes);
218 static void vsllink_tap_append_scan(int length, u8 *buffer, scan_command_t *command, int offset);
219
220 /* VSLLink lowlevel functions */
221 typedef struct vsllink_jtag
222 {
223 struct usb_dev_handle* usb_handle;
224 } vsllink_jtag_t;
225
226 static vsllink_jtag_t *vsllink_usb_open(void);
227 static void vsllink_usb_close(vsllink_jtag_t *vsllink_jtag);
228 static int vsllink_usb_message(vsllink_jtag_t *vsllink_jtag, int out_length, int in_length);
229 static int vsllink_usb_write(vsllink_jtag_t *vsllink_jtag, int out_length);
230 static int vsllink_usb_read(vsllink_jtag_t *vsllink_jtag);
231
232 #ifdef _DEBUG_USB_COMMS_
233 static void vsllink_debug_buffer(u8 *buffer, int length);
234 #endif
235
236 static int vsllink_tms_data_len = 0;
237 static u8* vsllink_tms_cmd_pos;
238
239 static vsllink_jtag_t* vsllink_jtag_handle;
240
241 /***************************************************************************/
242 /* External interface implementation */
243
244 jtag_interface_t vsllink_interface =
245 {
246 .name = "vsllink",
247 .execute_queue = vsllink_execute_queue,
248 .speed = vsllink_speed,
249 .khz = vsllink_khz,
250 .speed_div = vsllink_speed_div,
251 .register_commands = vsllink_register_commands,
252 .init = vsllink_init,
253 .quit = vsllink_quit
254 };
255
256 static int vsllink_execute_queue(void)
257 {
258 jtag_command_t *cmd = jtag_command_queue;
259 int scan_size;
260 enum scan_type type;
261 u8 *buffer;
262
263 DEBUG_JTAG_IO("--------------------------------- vsllink -------------------------------------");
264
265 vsllink_usb_out_buffer[0] = VSLLINK_CMD_HW_JTAGSEQCMD;
266 vsllink_usb_out_buffer_idx = 3;
267 while (cmd != NULL)
268 {
269 switch (cmd->type)
270 {
271 case JTAG_END_STATE:
272 DEBUG_JTAG_IO("end_state: %s", tap_state_name(cmd->cmd.end_state->end_state));
273
274 if (cmd->cmd.end_state->end_state != TAP_INVALID)
275 {
276 vsllink_end_state(cmd->cmd.end_state->end_state);
277 }
278 break;
279
280 case JTAG_RUNTEST:
281 DEBUG_JTAG_IO( "runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, \
282 tap_state_name(cmd->cmd.runtest->end_state));
283
284 if (cmd->cmd.runtest->end_state != TAP_INVALID)
285 {
286 vsllink_end_state(cmd->cmd.runtest->end_state);
287 }
288 vsllink_runtest(cmd->cmd.runtest->num_cycles);
289 break;
290
291 case JTAG_STATEMOVE:
292 DEBUG_JTAG_IO("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state));
293
294 if (cmd->cmd.statemove->end_state != TAP_INVALID)
295 {
296 vsllink_end_state(cmd->cmd.statemove->end_state);
297 }
298 vsllink_state_move();
299 break;
300
301 case JTAG_PATHMOVE:
302 DEBUG_JTAG_IO("pathmove: %i states, end in %s", \
303 cmd->cmd.pathmove->num_states, \
304 tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
305
306 vsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
307 break;
308
309 case JTAG_SCAN:
310 if (cmd->cmd.scan->end_state != TAP_INVALID)
311 {
312 vsllink_end_state(cmd->cmd.scan->end_state);
313 }
314
315 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
316 if (cmd->cmd.scan->ir_scan)
317 {
318 DEBUG_JTAG_IO("JTAG Scan write IR(%d bits), end in %s:", scan_size, tap_state_name(cmd->cmd.scan->end_state));
319 }
320 else
321 {
322 DEBUG_JTAG_IO("JTAG Scan write DR(%d bits), end in %s:", scan_size, tap_state_name(cmd->cmd.scan->end_state));
323 }
324
325 #ifdef _DEBUG_JTAG_IO_
326 vsllink_debug_buffer(buffer, (scan_size + 7) >> 3);
327 #endif
328
329 type = jtag_scan_type(cmd->cmd.scan);
330
331 vsllink_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);
332 break;
333
334 case JTAG_RESET:
335 DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
336
337 vsllink_tap_execute();
338
339 if (cmd->cmd.reset->trst == 1)
340 {
341 tap_set_state(TAP_RESET);
342 }
343 vsllink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
344
345 vsllink_usb_out_buffer[0] = VSLLINK_CMD_HW_JTAGSEQCMD;
346 vsllink_usb_out_buffer_idx = 3;
347 break;
348
349 case JTAG_SLEEP:
350 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
351 vsllink_tap_execute();
352 jtag_sleep(cmd->cmd.sleep->us);
353 break;
354
355 case JTAG_STABLECLOCKS:
356 DEBUG_JTAG_IO("add %d clocks", cmd->cmd.stableclocks->num_cycles);
357 switch(tap_get_state())
358 {
359 case TAP_RESET:
360 // tms should be '1' to stay in TAP_RESET mode
361 scan_size = 1;
362 break;
363 case TAP_DRSHIFT:
364 case TAP_IDLE:
365 case TAP_DRPAUSE:
366 case TAP_IRSHIFT:
367 case TAP_IRPAUSE:
368 // in other mode, tms should be '0'
369 scan_size = 0;
370 break; /* above stable states are OK */
371 default:
372 LOG_ERROR( "jtag_add_clocks() was called with TAP in non-stable state \"%s\"",
373 tap_state_name(tap_get_state()) );
374 exit(-1);
375 }
376 vsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size);
377 break;
378
379 default:
380 LOG_ERROR("BUG: unknown JTAG command type encountered: %d", cmd->type);
381 exit(-1);
382 }
383 cmd = cmd->next;
384 }
385
386 return vsllink_tap_execute();
387 }
388
389 static int vsllink_speed(int speed)
390 {
391 int result;
392
393 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_SPEED;
394 vsllink_usb_out_buffer[1] = (speed >> 0) & 0xff;
395 vsllink_usb_out_buffer[2] = (speed >> 8) & 0xFF;
396
397 result = vsllink_usb_write(vsllink_jtag_handle, 3);
398
399 if (result == 3)
400 {
401 return ERROR_OK;
402 }
403 else
404 {
405 LOG_ERROR("VSLLink setting speed failed (%d)", result);
406 return ERROR_JTAG_DEVICE_ERROR;
407 }
408
409 return ERROR_OK;
410 }
411
412 static int vsllink_khz(int khz, int *jtag_speed)
413 {
414 *jtag_speed = khz;
415
416 return ERROR_OK;
417 }
418
419 static int vsllink_speed_div(int jtag_speed, int *khz)
420 {
421 *khz = jtag_speed;
422
423 return ERROR_OK;
424 }
425
426 static int vsllink_register_commands(struct command_context_s *cmd_ctx)
427 {
428 register_command(cmd_ctx, NULL, "vsllink_usb_vid", vsllink_handle_usb_vid_command,
429 COMMAND_CONFIG, NULL);
430 register_command(cmd_ctx, NULL, "vsllink_usb_pid", vsllink_handle_usb_pid_command,
431 COMMAND_CONFIG, NULL);
432 register_command(cmd_ctx, NULL, "vsllink_usb_bulkin", vsllink_handle_usb_bulkin_command,
433 COMMAND_CONFIG, NULL);
434 register_command(cmd_ctx, NULL, "vsllink_usb_bulkout", vsllink_handle_usb_bulkout_command,
435 COMMAND_CONFIG, NULL);
436
437 return ERROR_OK;
438 }
439
440 static int vsllink_init(void)
441 {
442 int check_cnt;
443 int result;
444 char version_str[100];
445
446 vsllink_usb_in_buffer = malloc(VSLLINK_BufferSize);
447 vsllink_usb_out_buffer = malloc(VSLLINK_BufferSize);
448 if ((vsllink_usb_in_buffer == NULL) || (vsllink_usb_out_buffer == NULL))
449 {
450 LOG_ERROR("Not enough memory");
451 exit(-1);
452 }
453
454 vsllink_jtag_handle = vsllink_usb_open();
455
456 if (vsllink_jtag_handle == 0)
457 {
458 LOG_ERROR("Can't find USB JTAG Interface! Please check connection and permissions.");
459 return ERROR_JTAG_INIT_FAILED;
460 }
461
462 check_cnt = 0;
463 while (check_cnt < 3)
464 {
465 vsllink_simple_command(VSLLINK_CMD_CONN);
466 result = vsllink_usb_read(vsllink_jtag_handle);
467
468 if (result > 2)
469 {
470 vsllink_usb_in_buffer[result] = 0;
471 VSLLINK_BufferSize = vsllink_usb_in_buffer[0] + (vsllink_usb_in_buffer[1] << 8);
472 strncpy(version_str, (char *)vsllink_usb_in_buffer + 2, sizeof(version_str));
473 LOG_INFO("%s", version_str);
474
475 // free the pre-alloc memroy
476 free(vsllink_usb_in_buffer);
477 free(vsllink_usb_out_buffer);
478 vsllink_usb_in_buffer = NULL;
479 vsllink_usb_out_buffer = NULL;
480
481 // alloc new memory
482 vsllink_usb_in_buffer = malloc(VSLLINK_BufferSize);
483 vsllink_usb_out_buffer = malloc(VSLLINK_BufferSize);
484 if ((vsllink_usb_in_buffer == NULL) || (vsllink_usb_out_buffer == NULL))
485 {
486 LOG_ERROR("Not enough memory");
487 exit(-1);
488 }
489 else
490 {
491 LOG_INFO("buffer size for USB is %d bytes", VSLLINK_BufferSize);
492 }
493 break;
494 }
495 vsllink_simple_command(VSLLINK_CMD_DISCONN);
496
497 check_cnt++;
498 }
499
500 if (check_cnt == 3)
501 {
502 // It's dangerout to proced
503 LOG_ERROR("VSLLink initial failed");
504 exit(-1);
505 }
506
507 // Set SRST and TRST to output, Set USR1 and USR2 to input
508 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR;
509 vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST | JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2;
510 vsllink_usb_out_buffer[2] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST;
511 if (vsllink_usb_write(vsllink_jtag_handle, 3) != 3)
512 {
513 LOG_ERROR("VSLLink USB send data error");
514 exit(-1);
515 }
516
517 vsllink_reset(0, 0);
518
519 LOG_INFO("VSLLink JTAG Interface ready");
520
521 vsllink_tap_init();
522
523 return ERROR_OK;
524 }
525
526 static int vsllink_quit(void)
527 {
528 if ((vsllink_usb_in_buffer != NULL) && (vsllink_usb_out_buffer != NULL))
529 {
530 // Set all pins to input
531 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR;
532 vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST | JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2;
533 vsllink_usb_out_buffer[2] = 0;
534 if (vsllink_usb_write(vsllink_jtag_handle, 3) != 3)
535 {
536 LOG_ERROR("VSLLink USB send data error");
537 exit(-1);
538 }
539
540 // disconnect
541 vsllink_simple_command(VSLLINK_CMD_DISCONN);
542 vsllink_usb_close(vsllink_jtag_handle);
543 }
544
545 if (vsllink_usb_in_buffer != NULL)
546 {
547 free(vsllink_usb_in_buffer);
548 }
549 if (vsllink_usb_out_buffer != NULL)
550 {
551 free(vsllink_usb_out_buffer);
552 }
553 return ERROR_OK;
554 }
555
556 // when vsllink_tms_data_len > 0, vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] is the byte that need to be appended.
557 // length of VSLLINK_CMDJTAGSEQ_TMSBYTE has been set, no need to set it here.
558 static void vsllink_append_tms(void)
559 {
560 u8 tms_scan = VSLLINK_TAP_MOVE(tap_get_state(), tap_get_end_state());
561 u16 tms2;
562 tap_state_t end_state = tap_get_end_state();
563
564 if (((tap_get_state() != TAP_RESET) && (tap_get_state() != TAP_IDLE) && (tap_get_state() != TAP_DRPAUSE) && (tap_get_state() != TAP_IRPAUSE)) || \
565 (vsllink_tms_data_len <= 0) || (vsllink_tms_data_len >= 8) || \
566 (vsllink_tms_cmd_pos == NULL))
567 {
568 LOG_ERROR("There MUST be some bugs in the driver");
569 exit(-1);
570 }
571
572 tms2 = (tms_scan & VSLLINK_BIT_MSK[VSLLINK_TAP_MOVE_INSERT_INSIGNIFICANT[tap_move_ndx(tap_get_state())][tap_move_ndx(end_state)].insert_position]) << \
573 vsllink_tms_data_len;
574 if (VSLLINK_TAP_MOVE_INSERT_INSIGNIFICANT[tap_move_ndx(tap_get_state())][tap_move_ndx(end_state)].insert_value == 1)
575 {
576 tms2 |= VSLLINK_BIT_MSK[8 - vsllink_tms_data_len] << \
577 (vsllink_tms_data_len + VSLLINK_TAP_MOVE_INSERT_INSIGNIFICANT[tap_move_ndx(tap_get_state())][tap_move_ndx(end_state)].insert_position);
578 }
579 tms2 |= (tms_scan >> VSLLINK_TAP_MOVE_INSERT_INSIGNIFICANT[tap_move_ndx(tap_get_state())][tap_move_ndx(end_state)].insert_position) << \
580 (8 + VSLLINK_TAP_MOVE_INSERT_INSIGNIFICANT[tap_move_ndx(tap_get_state())][tap_move_ndx(end_state)].insert_position);
581
582 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] |= (tms2 >> 0) & 0xff;
583 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (tms2 >> 8) & 0xff;
584
585 vsllink_tms_data_len = 0;
586 vsllink_tms_cmd_pos = NULL;
587 }
588
589 /***************************************************************************/
590 /* Queue command implementations */
591
592 static void vsllink_end_state(tap_state_t state)
593 {
594 if (tap_is_state_stable(state))
595 {
596 tap_set_end_state(state);
597 }
598 else
599 {
600 LOG_ERROR("BUG: %i is not a valid end state", state);
601 exit(-1);
602 }
603 }
604
605 /* Goes to the end state. */
606 static void vsllink_state_move(void)
607 {
608 if (vsllink_tms_data_len > 0)
609 {
610 vsllink_append_tms();
611 }
612 else
613 {
614 vsllink_tap_ensure_space(0, 2);
615
616 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSBYTE;
617 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_TAP_MOVE(tap_get_state(), tap_get_end_state());
618 }
619
620 tap_set_state(tap_get_end_state());
621 }
622
623 // write tms from current vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx]
624 static void vsllink_add_path(int start, int num, tap_state_t *path)
625 {
626 int i;
627
628 for (i = start; i < (start + num); i++)
629 {
630 if ((i & 7) == 0)
631 {
632 if (i > 0)
633 {
634 vsllink_usb_out_buffer_idx++;
635 }
636 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] = 0;
637 }
638
639 if (path[i - start] == tap_state_transition(tap_get_state(), true))
640 {
641 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] |= 1 << (i & 7);
642 }
643 else if (path[i - start] == tap_state_transition(tap_get_state(), false))
644 {
645 // nothing to do
646 }
647 else
648 {
649 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(path[i]));
650 exit(-1);
651 }
652 tap_set_state(path[i - start]);
653 }
654 if ((i > 0) && ((i & 7) == 0))
655 {
656 vsllink_usb_out_buffer_idx++;
657 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] = 0;
658 }
659
660 tap_set_end_state(tap_get_state());
661 }
662
663 static void vsllink_path_move(int num_states, tap_state_t *path)
664 {
665 int i, tms_len, tms_cmd_pos, path_idx = 0;
666
667 if (vsllink_tms_data_len > 0)
668 {
669 // there are vsllink_tms_data_len more tms bits to be shifted
670 // so there are vsllink_tms_data_len + num_states tms bits in all
671 tms_len = vsllink_tms_data_len + num_states;
672 if (tms_len <= 16)
673 {
674 // merge into last tms shift
675 if (tms_len < 8)
676 {
677 // just append tms data to the last tms byte
678 vsllink_add_path(vsllink_tms_data_len, num_states, path);
679 }
680 else if (tms_len == 8)
681 {
682 // end last tms shift command
683 (*vsllink_tms_cmd_pos)--;
684 vsllink_add_path(vsllink_tms_data_len, num_states, path);
685 }
686 else if (tms_len < 16)
687 {
688 if ((*vsllink_tms_cmd_pos & VSLLINK_CMDJTAGSEQ_LENMSK) < VSLLINK_CMDJTAGSEQ_LENMSK)
689 {
690 // every tms shift command can contain VSLLINK_CMDJTAGSEQ_LENMSK + 1 bytes in most
691 // there is enought tms length in the current tms shift command
692 (*vsllink_tms_cmd_pos)++;
693 vsllink_add_path(vsllink_tms_data_len, num_states, path);
694 }
695 else
696 {
697 // every tms shift command can contain VSLLINK_CMDJTAGSEQ_LENMSK + 1 bytes in most
698 // not enough tms length in the current tms shift command
699 // so a new command should be added
700 // first decrease byte length of last tms shift command
701 (*vsllink_tms_cmd_pos)--;
702 // append tms data to the last tms byte
703 vsllink_add_path(vsllink_tms_data_len, 8 - vsllink_tms_data_len, path);
704 path += 8 - vsllink_tms_data_len;
705 // add new command(3 bytes)
706 vsllink_tap_ensure_space(0, 3);
707 vsllink_tms_cmd_pos = &vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx];
708 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSBYTE | 1;
709 vsllink_add_path(0, num_states - (8 - vsllink_tms_data_len), path);
710 }
711 }
712 else if (tms_len == 16)
713 {
714 // end last tms shift command
715 vsllink_add_path(vsllink_tms_data_len, num_states, path);
716 }
717
718 vsllink_tms_data_len = (vsllink_tms_data_len + num_states) & 7;
719 if (vsllink_tms_data_len == 0)
720 {
721 vsllink_tms_cmd_pos = NULL;
722 }
723 num_states = 0;
724 }
725 else
726 {
727 vsllink_add_path(vsllink_tms_data_len, 16 - vsllink_tms_data_len, path);
728
729 path += 16 - vsllink_tms_data_len;
730 num_states -= 16 - vsllink_tms_data_len;
731 vsllink_tms_data_len = 0;
732 vsllink_tms_cmd_pos = NULL;
733 }
734 }
735
736 if (num_states > 0)
737 {
738 // Normal operation, don't need to append tms data
739 vsllink_tms_data_len = num_states & 7;
740
741 while (num_states > 0)
742 {
743 if (num_states > ((VSLLINK_CMDJTAGSEQ_LENMSK + 1) * 8))
744 {
745 i = (VSLLINK_CMDJTAGSEQ_LENMSK + 1) * 8;
746 }
747 else
748 {
749 i = num_states;
750 }
751 tms_len = (i + 7) >> 3;
752 vsllink_tap_ensure_space(0, tms_len + 2);
753 tms_cmd_pos = vsllink_usb_out_buffer_idx;
754 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSBYTE | (tms_len - 1);
755
756 vsllink_add_path(0, i, path + path_idx);
757
758 path_idx += i;
759 num_states -= i;
760 }
761
762 if (vsllink_tms_data_len > 0)
763 {
764 if (tms_len < (VSLLINK_CMDJTAGSEQ_LENMSK + 1))
765 {
766 vsllink_tms_cmd_pos = &vsllink_usb_out_buffer[tms_cmd_pos];
767 (*vsllink_tms_cmd_pos)++;
768 }
769 else
770 {
771 vsllink_usb_out_buffer[tms_cmd_pos]--;
772
773 tms_len = vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx];
774 vsllink_tap_ensure_space(0, 3);
775 vsllink_tms_cmd_pos = &vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx];
776 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSBYTE | 1;
777 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] = tms_len;
778 }
779 }
780 }
781 }
782
783 static void vsllink_stableclocks(int num_cycles, int tms)
784 {
785 int tms_len;
786 u16 tms_append_byte;
787
788 if (vsllink_tms_data_len > 0)
789 {
790 // there are vsllink_tms_data_len more tms bits to be shifted
791 // so there are vsllink_tms_data_len + num_cycles tms bits in all
792 tms_len = vsllink_tms_data_len + num_cycles;
793 if (tms > 0)
794 {
795 // append '1' for tms
796 tms_append_byte = (u16)((((1 << num_cycles) - 1) << vsllink_tms_data_len) & 0xFFFF);
797 }
798 else
799 {
800 // append '0' for tms
801 tms_append_byte = 0;
802 }
803 if (tms_len <= 16)
804 {
805 // merge into last tms shift
806 if (tms_len < 8)
807 {
808 // just add to vsllink_tms_data_len
809 // same result if tun through
810 //vsllink_tms_data_len += num_cycles;
811 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] |= (u8)(tms_append_byte & 0xFF);
812 }
813 else if (tms_len == 8)
814 {
815 // end last tms shift command
816 // just reduce it, and append last tms byte
817 (*vsllink_tms_cmd_pos)--;
818 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] |= (u8)(tms_append_byte & 0xFF);
819 }
820 else if (tms_len < 16)
821 {
822 if ((*vsllink_tms_cmd_pos & VSLLINK_CMDJTAGSEQ_LENMSK) < VSLLINK_CMDJTAGSEQ_LENMSK)
823 {
824 // every tms shift command can contain VSLLINK_CMDJTAGSEQ_LENMSK + 1 bytes in most
825 // there is enought tms length in the current tms shift command
826 // increase the tms byte length by 1 and set the last byte to 0
827 (*vsllink_tms_cmd_pos)++;
828 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] |= (u8)(tms_append_byte & 0xFF);
829 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] = (u8)(tms_append_byte >> 8);
830 }
831 else
832 {
833 // every tms shift command can contain VSLLINK_CMDJTAGSEQ_LENMSK + 1 bytes in most
834 // not enough tms length in the current tms shift command
835 // so a new command should be added
836 // first decrease byte length of last tms shift command
837 (*vsllink_tms_cmd_pos)--;
838 // append last tms byte and move the command pointer to the next empty position
839 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] |= (u8)(tms_append_byte & 0xFF);
840 // add new command(3 bytes)
841 vsllink_tap_ensure_space(0, 3);
842 vsllink_tms_cmd_pos = &vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx];
843 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSBYTE | 1;
844 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] = (u8)(tms_append_byte >> 8);
845 }
846 }
847 else if (tms_len == 16)
848 {
849 // end last tms shift command
850 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] |= (u8)(tms_append_byte & 0xFF);
851 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (u8)(tms_append_byte >> 8);
852 }
853
854 vsllink_tms_data_len = tms_len & 7;
855 if (vsllink_tms_data_len == 0)
856 {
857 vsllink_tms_cmd_pos = NULL;
858 }
859 num_cycles = 0;
860 }
861 else
862 {
863 // more shifts will be needed
864 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] |= (u8)(tms_append_byte & 0xFF);
865 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (u8)(tms_append_byte >> 8);
866
867 num_cycles -= 16 - vsllink_tms_data_len;
868 vsllink_tms_data_len = 0;
869 vsllink_tms_cmd_pos = NULL;
870 }
871 }
872 // from here vsllink_tms_data_len == 0 or num_cycles == 0
873
874 if (vsllink_tms_data_len > 0)
875 {
876 // num_cycles == 0
877 // no need to shift
878 if (num_cycles > 0)
879 {
880 LOG_ERROR("There MUST be some bugs in the driver");
881 exit(-1);
882 }
883 }
884 else
885 {
886 // get number of bytes left to be sent
887 tms_len = num_cycles >> 3;
888 if (tms_len > 0)
889 {
890 vsllink_tap_ensure_space(1, 5);
891 // if tms_len > 0, vsllink_tms_data_len == 0
892 // so just add new command
893 // LSB of the command byte is the tms value when do the shifting
894 if (tms > 0)
895 {
896 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSCLOCK | 1;
897 }
898 else
899 {
900 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSCLOCK;
901 }
902 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (tms_len >> 0) & 0xff;
903 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (tms_len >> 8) & 0xff;
904 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (tms_len >> 16) & 0xff;
905 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (tms_len >> 24) & 0xff;
906
907 vsllink_usb_in_want_length += 1;
908 pending_scan_results_buffer[pending_scan_results_length].buffer = NULL;
909 pending_scan_results_length++;
910
911 if (tms_len > 0xFFFF)
912 {
913 vsllink_tap_execute();
914 }
915 }
916
917 // post-process
918 vsllink_tms_data_len = num_cycles & 7;
919 if (vsllink_tms_data_len > 0)
920 {
921 vsllink_tap_ensure_space(0, 3);
922 vsllink_tms_cmd_pos = &vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx];
923 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_TMSBYTE | 1;
924 if (tms > 0)
925 {
926 // append '1' for tms
927 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] = (1 << vsllink_tms_data_len) - 1;
928 }
929 else
930 {
931 // append '0' for tms
932 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] = 0x00;
933 }
934 }
935 }
936 }
937
938 static void vsllink_runtest(int num_cycles)
939 {
940 tap_state_t saved_end_state = tap_get_end_state();
941
942 if (tap_get_state() != TAP_IDLE)
943 {
944 // enter into IDLE state
945 vsllink_end_state(TAP_IDLE);
946 vsllink_state_move();
947 }
948
949 vsllink_stableclocks(num_cycles, 0);
950
951 // post-process
952 // set end_state
953 vsllink_end_state(saved_end_state);
954 tap_set_state(TAP_IDLE);
955 if (tap_get_end_state() != TAP_IDLE)
956 {
957 vsllink_state_move();
958 }
959 }
960
961 static void vsllink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command)
962 {
963 tap_state_t saved_end_state;
964 u8 bits_left, tms_tmp, tdi_len;
965 int i;
966
967 if (0 == scan_size )
968 {
969 return;
970 }
971
972 tdi_len = ((scan_size + 7) >> 3);
973 if ((tdi_len + 7) > VSLLINK_BufferSize)
974 {
975 LOG_ERROR("Your implementation of VSLLink has not enough buffer");
976 exit(-1);
977 }
978
979 saved_end_state = tap_get_end_state();
980
981 /* Move to appropriate scan state */
982 vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
983
984 if (vsllink_tms_data_len > 0)
985 {
986 if (tap_get_state() == tap_get_end_state())
987 {
988 // already in IRSHIFT or DRSHIFT state
989 // merge tms data in the last tms shift command into next scan command
990 if(*vsllink_tms_cmd_pos < 1)
991 {
992 LOG_ERROR("There MUST be some bugs in the driver");
993 exit(-1);
994 }
995 else if(*vsllink_tms_cmd_pos < 2)
996 {
997 tms_tmp = vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx];
998 vsllink_usb_out_buffer_idx--;
999 }
1000 else
1001 {
1002 tms_tmp = vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx];
1003 *vsllink_tms_cmd_pos -= 2;
1004 }
1005
1006 vsllink_tap_ensure_space(1, tdi_len + 7);
1007 // VSLLINK_CMDJTAGSEQ_SCAN ored by 1 means that tms_before is valid
1008 // which is merged from the last tms shift command
1009 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_SCAN | 1;
1010 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = ((tdi_len + 1) >> 0) & 0xff;
1011 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = ((tdi_len + 1)>> 8) & 0xff;
1012 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = tms_tmp;
1013 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = buffer[0] << (8 - vsllink_tms_data_len);
1014
1015 for (i = 0; i < tdi_len; i++)
1016 {
1017 buffer[i] >>= 8 - vsllink_tms_data_len;
1018 if (i != tdi_len)
1019 {
1020 buffer[i] += buffer[i + 1] << vsllink_tms_data_len;
1021 }
1022 }
1023
1024 vsllink_tap_append_scan(scan_size - vsllink_tms_data_len, buffer, command, vsllink_tms_data_len);
1025 scan_size -= 8 - vsllink_tms_data_len;
1026 vsllink_tms_data_len = 0;
1027 }
1028 else
1029 {
1030 vsllink_append_tms();
1031 vsllink_tap_ensure_space(1, tdi_len + 5);
1032
1033 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_SCAN;
1034 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (tdi_len >> 0) & 0xff;
1035 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = (tdi_len >> 8) & 0xff;
1036
1037 vsllink_tap_append_scan(scan_size, buffer, command, 0);
1038 }
1039 }
1040 else
1041 {
1042 vsllink_tap_ensure_space(1, tdi_len + 7);
1043
1044 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_CMDJTAGSEQ_SCAN | 1;
1045 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = ((tdi_len + 1) >> 0) & 0xff;
1046 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = ((tdi_len + 1)>> 8) & 0xff;
1047 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_TAP_MOVE(tap_get_state(), tap_get_end_state());
1048 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = 0;
1049
1050 vsllink_tap_append_scan(scan_size, buffer, command, 8);
1051 }
1052 vsllink_end_state(saved_end_state);
1053
1054 bits_left = scan_size & 0x07;
1055 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
1056
1057 if (bits_left > 0)
1058 {
1059 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = 1 << (bits_left - 1);
1060 }
1061 else
1062 {
1063 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = 1 << 7;
1064 }
1065
1066 if (tap_get_state() != tap_get_end_state())
1067 {
1068 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = VSLLINK_TAP_MOVE(tap_get_state(), tap_get_end_state());
1069 }
1070 else
1071 {
1072 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = 0;
1073 }
1074
1075 tap_set_state(tap_get_end_state());
1076 }
1077
1078 static void vsllink_reset(int trst, int srst)
1079 {
1080 int result;
1081
1082 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
1083
1084 /* Signals are active low */
1085 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORT;
1086 vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST;
1087 vsllink_usb_out_buffer[2] = 0;
1088 if (srst == 0)
1089 {
1090 vsllink_usb_out_buffer[2] |= JTAG_PINMSK_SRST;
1091 }
1092 if (trst == 0)
1093 {
1094 vsllink_usb_out_buffer[2] |= JTAG_PINMSK_TRST;
1095 }
1096
1097 result = vsllink_usb_write(vsllink_jtag_handle, 3);
1098 if (result != 3)
1099 {
1100 LOG_ERROR("VSLLink command VSLLINK_CMD_SET_PORT failed (%d)", result);
1101 }
1102 }
1103
1104 static void vsllink_simple_command(u8 command)
1105 {
1106 int result;
1107
1108 DEBUG_JTAG_IO("0x%02x", command);
1109
1110 vsllink_usb_out_buffer[0] = command;
1111 result = vsllink_usb_write(vsllink_jtag_handle, 1);
1112
1113 if (result != 1)
1114 {
1115 LOG_ERROR("VSLLink command 0x%02x failed (%d)", command, result);
1116 }
1117 }
1118
1119 static int vsllink_handle_usb_vid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1120 {
1121 if (argc != 1) {
1122 LOG_ERROR("parameter error, should be one parameter for VID");
1123 return ERROR_OK;
1124 }
1125
1126 vsllink_vid = strtol(args[0], NULL, 0);
1127
1128 return ERROR_OK;
1129 }
1130
1131 static int vsllink_handle_usb_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1132 {
1133 if (argc != 1) {
1134 LOG_ERROR("parameter error, should be one parameter for PID");
1135 return ERROR_OK;
1136 }
1137
1138 vsllink_pid = strtol(args[0], NULL, 0);
1139
1140 return ERROR_OK;
1141 }
1142
1143 static int vsllink_handle_usb_bulkin_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1144 {
1145 if (argc != 1) {
1146 LOG_ERROR("parameter error, should be one parameter for BULKIN endpoint");
1147 return ERROR_OK;
1148 }
1149
1150 vsllink_bulkin = strtol(args[0], NULL, 0) | 0x80;
1151
1152 return ERROR_OK;
1153 }
1154
1155 static int vsllink_handle_usb_bulkout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1156 {
1157 if (argc != 1) {
1158 LOG_ERROR("parameter error, should be one parameter for BULKOUT endpoint");
1159 return ERROR_OK;
1160 }
1161
1162 vsllink_bulkout = strtol(args[0], NULL, 0);
1163
1164 return ERROR_OK;
1165 }
1166
1167 /***************************************************************************/
1168 /* VSLLink tap functions */
1169
1170 static void vsllink_tap_init(void)
1171 {
1172 vsllink_usb_out_buffer_idx = 0;
1173 vsllink_usb_in_want_length = 0;
1174 pending_scan_results_length = 0;
1175 }
1176
1177 static void vsllink_tap_ensure_space(int scans, int bytes)
1178 {
1179 int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
1180 int available_bytes = VSLLINK_BufferSize - vsllink_usb_out_buffer_idx;
1181
1182 if (scans > available_scans || bytes > available_bytes)
1183 {
1184 vsllink_tap_execute();
1185 }
1186 }
1187
1188 static void vsllink_tap_append_scan(int length, u8 *buffer, scan_command_t *command, int offset)
1189 {
1190 pending_scan_result_t *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length];
1191 int i;
1192
1193 if (offset > 0)
1194 {
1195 vsllink_usb_in_want_length += ((length + 7) >> 3) + 1;
1196 }
1197 else
1198 {
1199 vsllink_usb_in_want_length += (length + 7) >> 3;
1200 }
1201 pending_scan_result->length = length;
1202 pending_scan_result->offset = offset;
1203 pending_scan_result->command = command;
1204 pending_scan_result->buffer = buffer;
1205
1206 for (i = 0; i < ((length + 7) >> 3); i++)
1207 {
1208 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = buffer[i];
1209 }
1210
1211 pending_scan_results_length++;
1212 }
1213
1214 /* Pad and send a tap sequence to the device, and receive the answer.
1215 * For the purpose of padding we assume that we are in reset or idle or pause state. */
1216 static int vsllink_tap_execute(void)
1217 {
1218 int i;
1219 int result;
1220 int first = 0;
1221
1222 if (vsllink_tms_data_len > 0)
1223 {
1224 if((tap_get_state() != TAP_RESET) && (tap_get_state() != TAP_IDLE) && (tap_get_state() != TAP_IRPAUSE) && (tap_get_state() != TAP_DRPAUSE))
1225 {
1226 LOG_WARNING("%s is not in RESET or IDLE or PAUSR state", tap_state_name(tap_get_state()));
1227 }
1228
1229 if (vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx] & (1 << (vsllink_tms_data_len - 1)))
1230 {
1231 // last tms bit is '1'
1232 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] |= 0xFF << vsllink_tms_data_len;
1233 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = 0xFF;
1234 vsllink_tms_data_len = 0;
1235 }
1236 else
1237 {
1238 // last tms bit is '0'
1239 vsllink_usb_out_buffer_idx++;
1240 vsllink_usb_out_buffer[vsllink_usb_out_buffer_idx++] = 0;
1241 vsllink_tms_data_len = 0;
1242 }
1243 }
1244
1245 if (vsllink_usb_out_buffer_idx > 3)
1246 {
1247 if (vsllink_usb_out_buffer[0] == VSLLINK_CMD_HW_JTAGSEQCMD)
1248 {
1249 vsllink_usb_out_buffer[1] = (vsllink_usb_out_buffer_idx >> 0) & 0xff;
1250 vsllink_usb_out_buffer[2] = (vsllink_usb_out_buffer_idx >> 8) & 0xff;
1251 }
1252
1253 result = vsllink_usb_message(vsllink_jtag_handle, vsllink_usb_out_buffer_idx, vsllink_usb_in_want_length);
1254
1255 if (result == vsllink_usb_in_want_length)
1256 {
1257 for (i = 0; i < pending_scan_results_length; i++)
1258 {
1259 pending_scan_result_t *pending_scan_result = &pending_scan_results_buffer[i];
1260 u8 *buffer = pending_scan_result->buffer;
1261 int length = pending_scan_result->length;
1262 int offset = pending_scan_result->offset;
1263 scan_command_t *command = pending_scan_result->command;
1264
1265 if (buffer != NULL)
1266 {
1267 // IRSHIFT or DRSHIFT
1268 buf_set_buf(vsllink_usb_in_buffer, first * 8 + offset, buffer, 0, length);
1269 first += (length + offset + 7) >> 3;
1270
1271 DEBUG_JTAG_IO("JTAG scan read(%d bits):", length);
1272 #ifdef _DEBUG_JTAG_IO_
1273 vsllink_debug_buffer(buffer, (length + 7) >> 3);
1274 #endif
1275
1276 if (jtag_read_buffer(buffer, command) != ERROR_OK)
1277 {
1278 vsllink_tap_init();
1279 return ERROR_JTAG_QUEUE_FAILED;
1280 }
1281
1282 free(pending_scan_result->buffer);
1283 pending_scan_result->buffer = NULL;
1284 }
1285 else
1286 {
1287 first++;
1288 }
1289 }
1290 }
1291 else
1292 {
1293 LOG_ERROR("vsllink_tap_execute, wrong result %d, expected %d", result, vsllink_usb_in_want_length);
1294 return ERROR_JTAG_QUEUE_FAILED;
1295 }
1296
1297 vsllink_tap_init();
1298 }
1299
1300 vsllink_usb_out_buffer[0] = VSLLINK_CMD_HW_JTAGSEQCMD;
1301 vsllink_usb_out_buffer_idx = 3;
1302
1303 return ERROR_OK;
1304 }
1305
1306 /*****************************************************************************/
1307 /* VSLLink USB low-level functions */
1308
1309 vsllink_jtag_t* vsllink_usb_open(void)
1310 {
1311 struct usb_bus *busses;
1312 struct usb_bus *bus;
1313 struct usb_device *dev;
1314
1315 vsllink_jtag_t *result;
1316
1317 result = (vsllink_jtag_t*) malloc(sizeof(vsllink_jtag_t));
1318
1319 usb_init();
1320 usb_find_busses();
1321 usb_find_devices();
1322
1323 busses = usb_get_busses();
1324
1325 /* find vsllink_jtag device in usb bus */
1326
1327 for (bus = busses; bus; bus = bus->next)
1328 {
1329 for (dev = bus->devices; dev; dev = dev->next)
1330 {
1331 if ((dev->descriptor.idVendor == vsllink_vid) && (dev->descriptor.idProduct == vsllink_pid))
1332 {
1333 result->usb_handle = usb_open(dev);
1334
1335 /* usb_set_configuration required under win32 */
1336 usb_set_configuration(result->usb_handle, dev->config[0].bConfigurationValue);
1337 usb_claim_interface(result->usb_handle, 0);
1338
1339 #if 0
1340 /*
1341 * This makes problems under Mac OS X. And is not needed
1342 * under Windows. Hopefully this will not break a linux build
1343 */
1344 usb_set_altinterface(result->usb_handle, 0);
1345 #endif
1346 return result;
1347 }
1348 }
1349 }
1350
1351 free(result);
1352 return NULL;
1353 }
1354
1355 static void vsllink_usb_close(vsllink_jtag_t *vsllink_jtag)
1356 {
1357 usb_close(vsllink_jtag->usb_handle);
1358 free(vsllink_jtag);
1359 }
1360
1361 /* Send a message and receive the reply. */
1362 static int vsllink_usb_message(vsllink_jtag_t *vsllink_jtag, int out_length, int in_length)
1363 {
1364 int result;
1365
1366 result = vsllink_usb_write(vsllink_jtag, out_length);
1367 if (result == out_length)
1368 {
1369 if (in_length > 0)
1370 {
1371 result = vsllink_usb_read(vsllink_jtag);
1372 if (result == in_length )
1373 {
1374 return result;
1375 }
1376 else
1377 {
1378 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length, result);
1379 return -1;
1380 }
1381 }
1382 return 0;
1383 }
1384 else
1385 {
1386 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
1387 return -1;
1388 }
1389 }
1390
1391 /* Write data from out_buffer to USB. */
1392 static int vsllink_usb_write(vsllink_jtag_t *vsllink_jtag, int out_length)
1393 {
1394 int result;
1395
1396 if (out_length > VSLLINK_BufferSize)
1397 {
1398 LOG_ERROR("vsllink_jtag_write illegal out_length=%d (max=%d)", out_length, VSLLINK_BufferSize);
1399 return -1;
1400 }
1401
1402 result = usb_bulk_write(vsllink_jtag->usb_handle, vsllink_bulkout, \
1403 (char *)vsllink_usb_out_buffer, out_length, VSLLINK_USB_TIMEOUT);
1404
1405 DEBUG_JTAG_IO("vsllink_usb_write, out_length = %d, result = %d", out_length, result);
1406
1407 #ifdef _DEBUG_USB_COMMS_
1408 LOG_DEBUG("USB out:");
1409 vsllink_debug_buffer(vsllink_usb_out_buffer, out_length);
1410 #endif
1411
1412 #ifdef _VSLLINK_IN_DEBUG_MODE_
1413 usleep(100000);
1414 #endif
1415
1416 return result;
1417 }
1418
1419 /* Read data from USB into in_buffer. */
1420 static int vsllink_usb_read(vsllink_jtag_t *vsllink_jtag)
1421 {
1422 int result = usb_bulk_read(vsllink_jtag->usb_handle, vsllink_bulkin, \
1423 (char *)vsllink_usb_in_buffer, VSLLINK_BufferSize, VSLLINK_USB_TIMEOUT);
1424
1425 DEBUG_JTAG_IO("vsllink_usb_read, result = %d", result);
1426
1427 #ifdef _DEBUG_USB_COMMS_
1428 LOG_DEBUG("USB in:");
1429 vsllink_debug_buffer(vsllink_usb_in_buffer, result);
1430 #endif
1431 return result;
1432 }
1433
1434 #define BYTES_PER_LINE 16
1435
1436 #ifdef _DEBUG_USB_COMMS_
1437 static void vsllink_debug_buffer(u8 *buffer, int length)
1438 {
1439 char line[81];
1440 char s[4];
1441 int i;
1442 int j;
1443
1444 for (i = 0; i < length; i += BYTES_PER_LINE)
1445 {
1446 snprintf(line, 5, "%04x", i);
1447 for (j = i; j < i + BYTES_PER_LINE && j < length; j++)
1448 {
1449 snprintf(s, 4, " %02x", buffer[j]);
1450 strcat(line, s);
1451 }
1452 LOG_DEBUG("%s", line);
1453 }
1454 }
1455 #endif // _DEBUG_USB_COMMS_

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)