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