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