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

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)