- remove target specific variant and use target->variant member
[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 int presto_jtag_speed(int speed);
53 int presto_jtag_khz(int khz, int *jtag_speed);
54 int presto_jtag_speed_div(int speed, int *khz);
55 int presto_jtag_register_commands(struct command_context_s *cmd_ctx);
56 int presto_jtag_init(void);
57 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 int presto_bitq_out(int tms, int tdi, int tdo_req);
72 int presto_bitq_flush(void);
73 int presto_bitq_sleep(unsigned long us);
74 int presto_bitq_reset(int trst, int srst);
75 int presto_bitq_in_rdy(void);
76 int presto_bitq_in(void);
77
78 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 presto_t presto_state;
134 presto_t *presto = &presto_state;
135
136 u8 presto_init_seq[] =
137 {
138 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
139 };
140
141 int presto_write(u8 *buf, int 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 (%i < %i)", ftbytes, size);
164 return ERROR_JTAG_DEVICE_ERROR;
165 }
166
167 return ERROR_OK;
168 }
169
170 int presto_read(u8* buf, int 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 (%i < %i)", ftbytes, size);
206 return ERROR_JTAG_DEVICE_ERROR;
207 }
208
209 return ERROR_OK;
210 }
211
212 #if BUILD_PRESTO_FTD2XX == 1
213 int presto_open_ftd2xx(char *req_serial)
214 {
215 int 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: %i", 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: %i", 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 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 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 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 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 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 int presto_getbyte(void)
553 {
554 if (presto->buff_in_pos < presto->buff_in_len)
555 return presto->buff_in[presto->buff_in_pos++];
556
557 if (presto->buff_in_exp == 0)
558 return -1;
559
560 if (presto_flush() != ERROR_OK)
561 return -1;
562
563 if (presto->buff_in_pos<presto->buff_in_len)
564 return presto->buff_in[presto->buff_in_pos++];
565
566 return -1;
567 }
568
569 /* -------------------------------------------------------------------------- */
570
571 int presto_tdi_flush(void)
572 {
573 if (presto->jtag_tdi_count == 0)
574 return 0;
575
576 if (presto->jtag_tck == 0)
577 {
578 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
579 return -1;
580 }
581
582 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
583 presto_sendbyte(presto->jtag_tdi_data);
584 presto->jtag_tdi_count = 0;
585 presto->jtag_tdi_data = 0;
586
587 return 0;
588 }
589
590 int presto_tck_idle(void)
591 {
592 if (presto->jtag_tck == 1)
593 {
594 presto_sendbyte(0xCA);
595 presto->jtag_tck = 0;
596 }
597
598 return 0;
599 }
600
601 /* -------------------------------------------------------------------------- */
602
603 int presto_bitq_out(int tms, int tdi, int tdo_req)
604 {
605 int i;
606 unsigned char cmd;
607
608 if (presto->jtag_tck == 0)
609 {
610 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
611 }
612 else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms)
613 {
614 presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;
615
616 if (++presto->jtag_tdi_count == 4)
617 presto_tdi_flush();
618
619 return 0;
620 }
621
622 presto_tdi_flush();
623
624 cmd = tdi ? 0xCB : 0xCA;
625 presto_sendbyte(cmd);
626
627 if (tms != presto->jtag_tms)
628 {
629 presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0));
630 presto->jtag_tms = tms;
631 }
632
633 /* delay with TCK low */
634 for (i=presto->jtag_speed; i>1; i--)
635 presto_sendbyte(cmd);
636
637 cmd |= 0x04;
638 presto_sendbyte(cmd | (tdo_req ? 0x10 : 0));
639
640 /* delay with TCK high */
641 for (i=presto->jtag_speed; i>1; i--)
642 presto_sendbyte(cmd);
643
644 presto->jtag_tck = 1;
645
646 return 0;
647 }
648
649 int presto_bitq_flush(void)
650 {
651 presto_tdi_flush();
652 presto_tck_idle();
653
654 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
655
656 return presto_flush();
657 }
658
659 int presto_bitq_in_rdy(void)
660 {
661 if (presto->buff_in_pos>=presto->buff_in_len)
662 return 0;
663 return presto->buff_in_len-presto->buff_in_pos;
664 }
665
666 int presto_bitq_in(void)
667 {
668 if (presto->buff_in_pos>=presto->buff_in_len)
669 return -1;
670 if (presto->buff_in[presto->buff_in_pos++]&0x08) return 1;
671 return 0;
672 }
673
674 int presto_bitq_sleep(unsigned long us)
675 {
676 long waits;
677
678 presto_tdi_flush();
679 presto_tck_idle();
680
681 if (us > 100000)
682 {
683 presto_bitq_flush();
684 jtag_sleep(us);
685 return 0;
686 }
687
688 waits = us / 170 + 2;
689 while (waits--)
690 presto_sendbyte(0x80);
691
692 return 0;
693 }
694
695 int presto_bitq_reset(int trst, int srst)
696 {
697 presto_tdi_flush();
698 presto_tck_idle();
699
700 /* add a delay after possible TCK transition */
701 presto_sendbyte(0x80);
702 presto_sendbyte(0x80);
703
704 presto->jtag_rst = trst || srst;
705 presto_sendbyte((presto->jtag_rst ? 0xEA : 0xE8) | (presto->jtag_tms ? 0x04 : 0));
706
707 return 0;
708 }
709
710 /* -------------------------------------------------------------------------- */
711
712 int presto_jtag_khz(int khz, int *jtag_speed)
713 {
714 if (khz < 0)
715 {
716 *jtag_speed=0;
717 return ERROR_INVALID_ARGUMENTS;
718 }
719
720 if (khz >= 3000) *jtag_speed = 0;
721 else *jtag_speed = (1000+khz-1)/khz;
722
723 return 0;
724 }
725
726 int presto_jtag_speed_div(int speed, int *khz)
727 {
728 if ((speed < 0) || (speed > 1000))
729 {
730 *khz=0;
731 return ERROR_INVALID_ARGUMENTS;
732 }
733
734 if (speed == 0) *khz = 3000;
735 else *khz = 1000/speed;
736
737 return 0;
738 }
739
740 int presto_jtag_speed(int speed)
741 {
742 int khz;
743
744 if (presto_jtag_speed_div(speed, &khz))
745 {
746 return ERROR_INVALID_ARGUMENTS;
747 }
748
749 presto->jtag_speed = speed;
750
751 if (khz%1000 == 0)
752 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed, khz/1000);
753 else
754 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed, khz);
755
756 return 0;
757 }
758
759 char *presto_serial;
760
761 int presto_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
762 {
763 if (argc == 1)
764 {
765 if (presto_serial)
766 free(presto_serial);
767 presto_serial = strdup(args[0]);
768 }
769 else
770 {
771 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
772 }
773
774 return ERROR_OK;
775 }
776
777 int presto_jtag_register_commands(struct command_context_s *cmd_ctx)
778 {
779 register_command(cmd_ctx, NULL, "presto_serial", presto_handle_serial_command,
780 COMMAND_CONFIG, NULL);
781 return ERROR_OK;
782 }
783
784 int presto_jtag_init(void)
785 {
786 if (presto_open(presto_serial) != ERROR_OK)
787 {
788 presto_close();
789 if (presto_serial != NULL)
790 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial);
791 else
792 LOG_ERROR("Cannot open PRESTO");
793 return ERROR_JTAG_INIT_FAILED;
794 }
795 LOG_INFO("PRESTO open, serial number '%s'", presto->serial);
796
797 /* use JTAG speed setting from configuration file */
798 presto_jtag_speed(jtag_speed);
799
800 bitq_interface = &presto_bitq;
801 return ERROR_OK;
802 }
803
804 int presto_jtag_quit(void)
805 {
806 bitq_cleanup();
807 presto_close();
808 LOG_INFO("PRESTO closed");
809
810 if (presto_serial)
811 {
812 free(presto_serial);
813 presto_serial = NULL;
814 }
815
816 return ERROR_OK;
817 }

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)