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

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)