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

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)