command_handler: change 'args' to CMD_ARGV
[openocd.git] / src / jtag / presto.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
3 * chromy@asix.cz *
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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #if IS_CYGWIN == 1
25 #include "windows.h"
26 #endif
27
28 #include "interface.h"
29 #include "time_support.h"
30 #include "bitq.h"
31
32
33 /* PRESTO access library includes */
34 #if BUILD_PRESTO_FTD2XX == 1
35 #include <ftd2xx.h>
36 #elif BUILD_PRESTO_LIBFTDI == 1
37 #include <ftdi.h>
38 #else
39 #error "BUG: either FTD2XX and LIBFTDI has to be used"
40 #endif
41
42 static int presto_jtag_speed(int speed);
43 static int presto_jtag_khz(int khz, int *jtag_speed);
44 static int presto_jtag_speed_div(int speed, int *khz);
45 static int presto_jtag_register_commands(struct command_context *cmd_ctx);
46 static int presto_jtag_init(void);
47 static int presto_jtag_quit(void);
48
49 struct jtag_interface presto_interface =
50 {
51 .name = "presto",
52 .execute_queue = bitq_execute_queue,
53 .speed = presto_jtag_speed,
54 .khz = presto_jtag_khz,
55 .speed_div = presto_jtag_speed_div,
56 .register_commands = presto_jtag_register_commands,
57 .init = presto_jtag_init,
58 .quit = presto_jtag_quit,
59 };
60
61 static int presto_bitq_out(int tms, int tdi, int tdo_req);
62 static int presto_bitq_flush(void);
63 static int presto_bitq_sleep(unsigned long us);
64 static int presto_bitq_reset(int trst, int srst);
65 static int presto_bitq_in_rdy(void);
66 static int presto_bitq_in(void);
67
68 static struct bitq_interface presto_bitq =
69 {
70 .out = presto_bitq_out,
71 .flush = presto_bitq_flush,
72 .sleep = presto_bitq_sleep,
73 .reset = presto_bitq_reset,
74 .in_rdy = presto_bitq_in_rdy,
75 .in = presto_bitq_in,
76 };
77
78 /* -------------------------------------------------------------------------- */
79
80 #define FT_DEVICE_NAME_LEN 64
81 #define FT_DEVICE_SERNUM_LEN 64
82
83 #define PRESTO_VID_PID 0x0403f1a0
84 #define PRESTO_VID (0x0403)
85 #define PRESTO_PID (0xf1a0)
86
87 #define BUFFER_SIZE (64*62)
88
89 struct presto {
90 #if BUILD_PRESTO_FTD2XX == 1
91 FT_HANDLE handle;
92 FT_STATUS status;
93 #elif BUILD_PRESTO_LIBFTDI == 1
94 struct ftdi_context ftdic;
95 int retval;
96 #endif
97
98 char serial[FT_DEVICE_SERNUM_LEN];
99
100 uint8_t buff_out[BUFFER_SIZE];
101 int buff_out_pos;
102
103 uint8_t buff_in[BUFFER_SIZE];
104 int buff_in_exp; /* expected in buffer length */
105 int buff_in_len; /* length of data received */
106 int buff_in_pos;
107
108 unsigned long total_out;
109 unsigned long total_in;
110
111 int jtag_tms; /* last tms state */
112 int jtag_tck; /* last tck state */
113 int jtag_rst; /* last trst state */
114
115 int jtag_tdi_data;
116 int jtag_tdi_count;
117
118 int jtag_speed;
119 };
120
121 static struct presto presto_state;
122 static struct presto *presto = &presto_state;
123
124 static uint8_t presto_init_seq[] =
125 {
126 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
127 };
128
129 static int presto_write(uint8_t *buf, uint32_t size)
130 {
131 #if BUILD_PRESTO_FTD2XX == 1
132 DWORD ftbytes;
133 if ((presto->status = FT_Write(presto->handle, buf, size, &ftbytes)) != FT_OK)
134 {
135 LOG_ERROR("FT_Write returned: %lu", presto->status);
136 return ERROR_JTAG_DEVICE_ERROR;
137 }
138
139 #elif BUILD_PRESTO_LIBFTDI == 1
140 uint32_t ftbytes;
141 if ((presto->retval = ftdi_write_data(&presto->ftdic, buf, size)) < 0)
142 {
143 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic));
144 return ERROR_JTAG_DEVICE_ERROR;
145 }
146 ftbytes = presto->retval;
147 #endif
148
149 if (ftbytes != size)
150 {
151 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
152 (unsigned)ftbytes, (unsigned)size);
153 return ERROR_JTAG_DEVICE_ERROR;
154 }
155
156 return ERROR_OK;
157 }
158
159 static int presto_read(uint8_t* buf, uint32_t size)
160 {
161 #if BUILD_PRESTO_FTD2XX == 1
162 DWORD ftbytes;
163 if ((presto->status = FT_Read(presto->handle, buf, size, &ftbytes)) != FT_OK)
164 {
165 LOG_ERROR("FT_Read returned: %lu", presto->status);
166 return ERROR_JTAG_DEVICE_ERROR;
167 }
168
169 #elif BUILD_PRESTO_LIBFTDI == 1
170 uint32_t ftbytes = 0;
171
172 struct timeval timeout, now;
173 gettimeofday(&timeout, NULL);
174 timeval_add_time(&timeout, 1, 0); /* one second timeout */
175
176 while (ftbytes < size)
177 {
178 if ((presto->retval = ftdi_read_data(&presto->ftdic, buf + ftbytes, size - ftbytes)) < 0)
179 {
180 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic));
181 return ERROR_JTAG_DEVICE_ERROR;
182 }
183 ftbytes += presto->retval;
184
185 gettimeofday(&now, NULL);
186 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec)))
187 break;
188 }
189 #endif
190
191 if (ftbytes != size)
192 {
193 /* this is just a warning, there might have been timeout when detecting PRESTO, which is not fatal */
194 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)",
195 (unsigned)ftbytes, (unsigned)size);
196 return ERROR_JTAG_DEVICE_ERROR;
197 }
198
199 return ERROR_OK;
200 }
201
202 #if BUILD_PRESTO_FTD2XX == 1
203 static int presto_open_ftd2xx(char *req_serial)
204 {
205 uint32_t i;
206 DWORD numdevs;
207 DWORD vidpid;
208 char devname[FT_DEVICE_NAME_LEN];
209 FT_DEVICE device;
210
211 BYTE presto_data;
212 DWORD ftbytes;
213
214 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
215
216 #if IS_WIN32 == 0
217 /* Add non-standard Vid/Pid to the linux driver */
218 if ((presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID)) != FT_OK)
219 {
220 LOG_ERROR("couldn't add PRESTO VID/PID");
221 exit(-1);
222 }
223 #endif
224
225 if ((presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY)) != FT_OK)
226 {
227 LOG_ERROR("FT_ListDevices failed: %i", (int)presto->status);
228 return ERROR_JTAG_DEVICE_ERROR;
229 }
230
231 LOG_DEBUG("FTDI devices available: %lu", numdevs);
232 for (i = 0; i < numdevs; i++)
233 {
234 if ((presto->status = FT_Open(i, &(presto->handle))) != FT_OK)
235 {
236 /* this is not fatal, the device may be legitimately open by other process, hence debug message only */
237 LOG_DEBUG("FT_Open failed: %i", (int)presto->status);
238 continue;
239 }
240 LOG_DEBUG("FTDI device %i open", (int)i);
241
242 if ((presto->status = FT_GetDeviceInfo(presto->handle, &device, &vidpid,
243 presto->serial, devname, NULL)) == FT_OK)
244 {
245 if (vidpid == PRESTO_VID_PID
246 && (req_serial == NULL || !strcmp(presto->serial, req_serial)))
247 break;
248 }
249 else
250 LOG_DEBUG("FT_GetDeviceInfo failed: %lu", presto->status);
251
252 LOG_DEBUG("FTDI device %i does not match, closing", (int)i);
253 FT_Close(presto->handle);
254 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
255 }
256
257 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
258 return ERROR_JTAG_DEVICE_ERROR; /* presto not open, return */
259
260 if ((presto->status = FT_SetLatencyTimer(presto->handle, 1)) != FT_OK)
261 return ERROR_JTAG_DEVICE_ERROR;
262
263
264 if ((presto->status = FT_SetTimeouts(presto->handle, 100, 0)) != FT_OK)
265 return ERROR_JTAG_DEVICE_ERROR;
266
267 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
268 return ERROR_JTAG_DEVICE_ERROR;
269
270 presto_data = 0xD0;
271 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
272 return ERROR_JTAG_DEVICE_ERROR;
273
274 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
275 probably a bug in library threading */
276 usleep(100000);
277 if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
278 return ERROR_JTAG_DEVICE_ERROR;
279
280 if (ftbytes != 1)
281 {
282 LOG_DEBUG("PRESTO reset");
283
284 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
285 return ERROR_JTAG_DEVICE_ERROR;
286 if ((presto->status = FT_SetBitMode(presto->handle, 0x80, 1)) != FT_OK)
287 return ERROR_JTAG_DEVICE_ERROR;
288 if ((presto->status = FT_SetBaudRate(presto->handle, 9600)) != FT_OK)
289 return ERROR_JTAG_DEVICE_ERROR;
290
291 presto_data = 0;
292 for (i = 0; i < 4 * 62; i++)
293 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
294 return ERROR_JTAG_DEVICE_ERROR;
295
296 usleep(100000);
297
298 if ((presto->status = FT_SetBitMode(presto->handle, 0x00, 0)) != FT_OK)
299 return ERROR_JTAG_DEVICE_ERROR;
300
301 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
302 return ERROR_JTAG_DEVICE_ERROR;
303
304 presto_data = 0xD0;
305 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
306 return ERROR_JTAG_DEVICE_ERROR;
307
308 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
309 probably a bug in library threading */
310 usleep(100000);
311 if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
312 return ERROR_JTAG_DEVICE_ERROR;
313
314 if (ftbytes != 1)
315 {
316 LOG_DEBUG("PRESTO not responding");
317 return ERROR_JTAG_DEVICE_ERROR;
318 }
319 }
320
321 if ((presto->status = FT_SetTimeouts(presto->handle, 0, 0)) != FT_OK)
322 return ERROR_JTAG_DEVICE_ERROR;
323
324
325 presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
326 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
327 return ERROR_JTAG_DEVICE_ERROR;
328
329 return ERROR_OK;
330 }
331
332 #elif BUILD_PRESTO_LIBFTDI == 1
333 static int presto_open_libftdi(char *req_serial)
334 {
335 uint8_t presto_data;
336
337 LOG_DEBUG("searching for PRESTO using libftdi");
338
339 /* initialize FTDI context structure */
340 if (ftdi_init(&presto->ftdic) < 0)
341 {
342 LOG_ERROR("unable to init libftdi: %s", presto->ftdic.error_str);
343 return ERROR_JTAG_DEVICE_ERROR;
344 }
345
346 /* context, vendor id, product id */
347 if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0)
348 {
349 LOG_ERROR("unable to open PRESTO: %s", presto->ftdic.error_str);
350 return ERROR_JTAG_DEVICE_ERROR;
351 }
352
353 if (ftdi_usb_reset(&presto->ftdic) < 0)
354 {
355 LOG_ERROR("unable to reset PRESTO device");
356 return ERROR_JTAG_DEVICE_ERROR;
357 }
358
359 if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0)
360 {
361 LOG_ERROR("unable to set latency timer");
362 return ERROR_JTAG_DEVICE_ERROR;
363 }
364
365 if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
366 {
367 LOG_ERROR("unable to purge PRESTO buffers");
368 return ERROR_JTAG_DEVICE_ERROR;
369 }
370
371 presto_data = 0xD0;
372 if (presto_write(&presto_data, 1) != ERROR_OK)
373 {
374 LOG_ERROR("error writing to PRESTO");
375 return ERROR_JTAG_DEVICE_ERROR;
376 }
377
378 if (presto_read(&presto_data, 1) != ERROR_OK)
379 {
380 LOG_DEBUG("no response from PRESTO, retrying");
381
382 if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
383 return ERROR_JTAG_DEVICE_ERROR;
384
385 presto_data = 0xD0;
386 if (presto_write(&presto_data, 1) != ERROR_OK)
387 return ERROR_JTAG_DEVICE_ERROR;
388
389 if (presto_read(&presto_data, 1) != ERROR_OK)
390 {
391 LOG_ERROR("no response from PRESTO, giving up");
392 return ERROR_JTAG_DEVICE_ERROR;
393 }
394 }
395
396 if (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK)
397 {
398 LOG_ERROR("error writing PRESTO init sequence");
399 return ERROR_JTAG_DEVICE_ERROR;
400 }
401
402 return ERROR_OK;
403 }
404 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
405
406 static int presto_open(char *req_serial)
407 {
408 presto->buff_out_pos = 0;
409 presto->buff_in_pos = 0;
410 presto->buff_in_len = 0;
411 presto->buff_in_exp = 0;
412
413 presto->total_out = 0;
414 presto->total_in = 0;
415
416 presto->jtag_tms = 0;
417 presto->jtag_tck = 0;
418 presto->jtag_rst = 0;
419 presto->jtag_tdi_data = 0;
420 presto->jtag_tdi_count = 0;
421
422 presto->jtag_speed = 0;
423
424 #if BUILD_PRESTO_FTD2XX == 1
425 return presto_open_ftd2xx(req_serial);
426 #elif BUILD_PRESTO_LIBFTDI == 1
427 return presto_open_libftdi(req_serial);
428 #endif
429 }
430
431 static int presto_close(void)
432 {
433
434 int result = ERROR_OK;
435
436 #if BUILD_PRESTO_FTD2XX == 1
437 unsigned long ftbytes;
438
439 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
440 return result;
441
442 presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
443 if (presto->status != FT_OK)
444 result = ERROR_JTAG_DEVICE_ERROR;
445
446 presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
447 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
448 result = ERROR_JTAG_DEVICE_ERROR;
449
450 if ((presto->status = FT_SetLatencyTimer(presto->handle, 16)) != FT_OK)
451 result = ERROR_JTAG_DEVICE_ERROR;
452
453 if ((presto->status = FT_Close(presto->handle)) != FT_OK)
454 result = ERROR_JTAG_DEVICE_ERROR;
455 else
456 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
457
458 #elif BUILD_PRESTO_LIBFTDI == 1
459
460 if ((presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq))) != sizeof(presto_init_seq))
461 result = ERROR_JTAG_DEVICE_ERROR;
462
463 if ((presto->retval = ftdi_set_latency_timer(&presto->ftdic, 16)) < 0)
464 result = ERROR_JTAG_DEVICE_ERROR;
465
466 if ((presto->retval = ftdi_usb_close(&presto->ftdic)) < 0)
467 result = ERROR_JTAG_DEVICE_ERROR;
468 else
469 ftdi_deinit(&presto->ftdic);
470 #endif
471
472 return result;
473 }
474
475 static int presto_flush(void)
476 {
477 if (presto->buff_out_pos == 0)
478 return ERROR_OK;
479
480 #if BUILD_PRESTO_FTD2XX == 1
481 if (presto->status != FT_OK)
482 #elif BUILD_PRESTO_LIBFTDI == 1
483 if (presto->retval < 0)
484 #endif
485 {
486 LOG_DEBUG("error in previous communication, canceling I/O operation");
487 return ERROR_JTAG_DEVICE_ERROR;
488 }
489
490 if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK)
491 {
492 presto->buff_out_pos = 0;
493 return ERROR_JTAG_DEVICE_ERROR;
494 }
495
496 presto->total_out += presto->buff_out_pos;
497 presto->buff_out_pos = 0;
498
499 if (presto->buff_in_exp == 0)
500 return ERROR_OK;
501
502 presto->buff_in_pos = 0;
503 presto->buff_in_len = 0;
504
505 if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK)
506 {
507 presto->buff_in_exp = 0;
508 return ERROR_JTAG_DEVICE_ERROR;
509 }
510
511 presto->total_in += presto->buff_in_exp;
512 presto->buff_in_len = presto->buff_in_exp;
513 presto->buff_in_exp = 0;
514
515 return ERROR_OK;
516 }
517
518 static int presto_sendbyte(int data)
519 {
520 if (data == EOF) return presto_flush();
521
522 if (presto->buff_out_pos < BUFFER_SIZE)
523 {
524 presto->buff_out[presto->buff_out_pos++] = (uint8_t)data;
525 if (((data & 0xC0) == 0x40) || ((data & 0xD0)== 0xD0))
526 presto->buff_in_exp++;
527 }
528 else
529 return ERROR_JTAG_DEVICE_ERROR;
530
531 #if BUILD_PRESTO_FTD2XX == 1
532 if (presto->buff_out_pos >= BUFFER_SIZE)
533 #elif BUILD_PRESTO_LIBFTDI == 1
534 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128 bytes only!) */
535 if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)
536 #endif
537 return presto_flush();
538
539 return ERROR_OK;
540 }
541
542 #if 0
543 static int presto_getbyte(void)
544 {
545 if (presto->buff_in_pos < presto->buff_in_len)
546 return presto->buff_in[presto->buff_in_pos++];
547
548 if (presto->buff_in_exp == 0)
549 return -1;
550
551 if (presto_flush() != ERROR_OK)
552 return -1;
553
554 if (presto->buff_in_pos < presto->buff_in_len)
555 return presto->buff_in[presto->buff_in_pos++];
556
557 return -1;
558 }
559 #endif
560
561 /* -------------------------------------------------------------------------- */
562
563 static int presto_tdi_flush(void)
564 {
565 if (presto->jtag_tdi_count == 0)
566 return 0;
567
568 if (presto->jtag_tck == 0)
569 {
570 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
571 return -1;
572 }
573
574 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
575 presto_sendbyte(presto->jtag_tdi_data);
576 presto->jtag_tdi_count = 0;
577 presto->jtag_tdi_data = 0;
578
579 return 0;
580 }
581
582 static int presto_tck_idle(void)
583 {
584 if (presto->jtag_tck == 1)
585 {
586 presto_sendbyte(0xCA);
587 presto->jtag_tck = 0;
588 }
589
590 return 0;
591 }
592
593 /* -------------------------------------------------------------------------- */
594
595 static int presto_bitq_out(int tms, int tdi, int tdo_req)
596 {
597 int i;
598 unsigned char cmd;
599
600 if (presto->jtag_tck == 0)
601 {
602 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
603 }
604 else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms)
605 {
606 presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;
607
608 if (++presto->jtag_tdi_count == 4)
609 presto_tdi_flush();
610
611 return 0;
612 }
613
614 presto_tdi_flush();
615
616 cmd = tdi ? 0xCB : 0xCA;
617 presto_sendbyte(cmd);
618
619 if (tms != presto->jtag_tms)
620 {
621 presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0));
622 presto->jtag_tms = tms;
623 }
624
625 /* delay with TCK low */
626 for (i = presto->jtag_speed; i > 1; i--)
627 presto_sendbyte(cmd);
628
629 cmd |= 0x04;
630 presto_sendbyte(cmd | (tdo_req ? 0x10 : 0));
631
632 /* delay with TCK high */
633 for (i = presto->jtag_speed; i > 1; i--)
634 presto_sendbyte(cmd);
635
636 presto->jtag_tck = 1;
637
638 return 0;
639 }
640
641 static int presto_bitq_flush(void)
642 {
643 presto_tdi_flush();
644 presto_tck_idle();
645
646 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
647
648 return presto_flush();
649 }
650
651 static int presto_bitq_in_rdy(void)
652 {
653 if (presto->buff_in_pos >= presto->buff_in_len)
654 return 0;
655 return presto->buff_in_len-presto->buff_in_pos;
656 }
657
658 static int presto_bitq_in(void)
659 {
660 if (presto->buff_in_pos >= presto->buff_in_len)
661 return -1;
662 if (presto->buff_in[presto->buff_in_pos++]&0x08) return 1;
663 return 0;
664 }
665
666 static int presto_bitq_sleep(unsigned long us)
667 {
668 long waits;
669
670 presto_tdi_flush();
671 presto_tck_idle();
672
673 if (us > 100000)
674 {
675 presto_bitq_flush();
676 jtag_sleep(us);
677 return 0;
678 }
679
680 waits = us / 170 + 2;
681 while (waits--)
682 presto_sendbyte(0x80);
683
684 return 0;
685 }
686
687 static int presto_bitq_reset(int trst, int srst)
688 {
689 presto_tdi_flush();
690 presto_tck_idle();
691
692 /* add a delay after possible TCK transition */
693 presto_sendbyte(0x80);
694 presto_sendbyte(0x80);
695
696 presto->jtag_rst = trst || srst;
697 presto_sendbyte((presto->jtag_rst ? 0xEA : 0xE8) | (presto->jtag_tms ? 0x04 : 0));
698
699 return 0;
700 }
701
702 /* -------------------------------------------------------------------------- */
703
704 static int presto_jtag_khz(int khz, int *jtag_speed)
705 {
706 if (khz < 0)
707 {
708 *jtag_speed = 0;
709 return ERROR_INVALID_ARGUMENTS;
710 }
711
712 if (khz >= 3000) *jtag_speed = 0;
713 else *jtag_speed = (1000 + khz-1)/khz;
714
715 return 0;
716 }
717
718 static int presto_jtag_speed_div(int speed, int *khz)
719 {
720 if ((speed < 0) || (speed > 1000))
721 {
722 *khz = 0;
723 return ERROR_INVALID_ARGUMENTS;
724 }
725
726 if (speed == 0) *khz = 3000;
727 else *khz = 1000/speed;
728
729 return 0;
730 }
731
732 static int presto_jtag_speed(int speed)
733 {
734 int khz;
735
736 if (presto_jtag_speed_div(speed, &khz))
737 {
738 return ERROR_INVALID_ARGUMENTS;
739 }
740
741 presto->jtag_speed = speed;
742
743 if (khz%1000 == 0)
744 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed, khz/1000);
745 else
746 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed, khz);
747
748 return 0;
749 }
750
751 static char *presto_serial;
752
753 COMMAND_HANDLER(presto_handle_serial_command)
754 {
755 if (CMD_ARGC == 1)
756 {
757 if (presto_serial)
758 free(presto_serial);
759 presto_serial = strdup(CMD_ARGV[0]);
760 }
761 else
762 {
763 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
764 }
765
766 return ERROR_OK;
767 }
768
769 static int presto_jtag_register_commands(struct command_context *cmd_ctx)
770 {
771 register_command(cmd_ctx, NULL, "presto_serial", presto_handle_serial_command,
772 COMMAND_CONFIG, NULL);
773 return ERROR_OK;
774 }
775
776 static int presto_jtag_init(void)
777 {
778 if (presto_open(presto_serial) != ERROR_OK)
779 {
780 presto_close();
781 if (presto_serial != NULL)
782 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial);
783 else
784 LOG_ERROR("Cannot open PRESTO");
785 return ERROR_JTAG_INIT_FAILED;
786 }
787 LOG_INFO("PRESTO open, serial number '%s'", presto->serial);
788
789 /* use JTAG speed setting from configuration file */
790 presto_jtag_speed(jtag_get_speed());
791
792 bitq_interface = &presto_bitq;
793 return ERROR_OK;
794 }
795
796 static int presto_jtag_quit(void)
797 {
798 bitq_cleanup();
799 presto_close();
800 LOG_INFO("PRESTO closed");
801
802 if (presto_serial)
803 {
804 free(presto_serial);
805 presto_serial = NULL;
806 }
807
808 return ERROR_OK;
809 }

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)