1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
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. *
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. *
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 ***************************************************************************/
29 #include "replacements.h"
31 /* project specific includes */
35 #include "configuration.h"
36 #include "time_support.h"
50 int presto_jtag_speed(int speed
);
51 int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
);
52 int presto_jtag_init(void);
53 int presto_jtag_quit(void);
55 jtag_interface_t presto_interface
=
58 .execute_queue
= bitq_execute_queue
,
59 .support_pathmove
= 1,
60 .speed
= presto_jtag_speed
,
61 .register_commands
= presto_jtag_register_commands
,
62 .init
= presto_jtag_init
,
63 .quit
= presto_jtag_quit
,
67 int presto_bitq_out(int tms
, int tdi
, int tdo_req
);
68 int presto_bitq_flush(void);
69 int presto_bitq_sleep(unsigned long us
);
70 int presto_bitq_reset(int rst
, int en
);
71 int presto_bitq_in_rdy(void);
72 int presto_bitq_in(void);
74 bitq_interface_t presto_bitq
=
76 .out
= presto_bitq_out
,
77 .flush
= presto_bitq_flush
,
78 .sleep
= presto_bitq_sleep
,
79 .reset
= presto_bitq_reset
,
80 .in_rdy
= presto_bitq_in_rdy
,
85 /* -------------------------------------------------------------------------- */
88 #define FT_DEVICE_NAME_LEN 64
89 #define FT_DEVICE_SERNUM_LEN 64
91 #define PRESTO_VID_PID 0x0403f1a0
95 #define PRST_TIMEOUT 2
97 #define BUFFER_SIZE (64*62)
100 typedef struct presto_s
105 char serial
[FT_DEVICE_SERNUM_LEN
];
107 BYTE buff_out
[BUFFER_SIZE
];
110 BYTE buff_in
[BUFFER_SIZE
];
111 int buff_in_exp
; /* expected in buffer length */
112 int buff_in_len
; /* length of data received */
115 unsigned long total_out
;
116 unsigned long total_in
;
118 int jtag_tms
; /* last tms state */
119 int jtag_tck
; /* last tck state */
126 presto_t presto_state
;
127 presto_t
*presto
=&presto_state
;
129 BYTE presto_init_seq
[] =
131 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
135 int presto_open(char *req_serial
)
140 char devname
[FT_DEVICE_NAME_LEN
];
144 unsigned long ftbytes
;
146 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
148 presto
->buff_out_pos
=0;
149 presto
->buff_in_pos
=0;
150 presto
->buff_in_len
=0;
151 presto
->buff_in_exp
=0;
158 presto
->jtag_tdi_data
=0;
159 presto
->jtag_tdi_count
=0;
161 if (FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
)!=FT_OK
) return PRST_ERR
;
162 for (i
=0; i
<numdevs
; i
++)
164 if (FT_Open(i
, &(presto
->handle
))!=FT_OK
) continue;
165 if (FT_GetDeviceInfo(presto
->handle
,&device
,&vidpid
,presto
->serial
,devname
,NULL
)==FT_OK
)
167 if (vidpid
==PRESTO_VID_PID
&& (req_serial
==NULL
|| !strcmp(presto
->serial
,req_serial
)))
170 FT_Close(presto
->handle
);
171 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
174 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
) return PRST_ERR
;
176 if ((presto
->status
=FT_SetLatencyTimer(presto
->handle
,1))!=FT_OK
) return PRST_ERR
;
177 if ((presto
->status
=FT_SetTimeouts(presto
->handle
,100,0))!=FT_OK
) return PRST_ERR
;
178 if ((presto
->status
=FT_Purge(presto
->handle
, FT_PURGE_TX
|FT_PURGE_RX
))!=FT_OK
) return PRST_ERR
;
181 if ((presto
->status
=FT_Write(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
182 if ((presto
->status
=FT_Read(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
186 if ((presto
->status
=FT_SetBitMode(presto
->handle
,0x80,1))!=FT_OK
) return PRST_ERR
;
187 if ((presto
->status
=FT_Purge(presto
->handle
, FT_PURGE_TX
|FT_PURGE_RX
))!=FT_OK
) return PRST_ERR
;
188 if ((presto
->status
=FT_SetBaudRate(presto
->handle
,9600))!=FT_OK
) return PRST_ERR
;
191 for (i
=0; i
<4*62; i
++)
192 if ((presto
->status
=FT_Write(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
196 if ((presto
->status
=FT_SetBitMode(presto
->handle
,0x00,0))!=FT_OK
) return PRST_ERR
;
197 if ((presto
->status
=FT_Purge(presto
->handle
, FT_PURGE_TX
|FT_PURGE_RX
))!=FT_OK
) return PRST_ERR
;
200 if ((presto
->status
=FT_Write(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
201 if ((presto
->status
=FT_Read(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
202 if (ftbytes
!=1) return PRST_ERR
;
205 if ((presto
->status
=FT_SetTimeouts(presto
->handle
,0,0))!=FT_OK
) return PRST_ERR
;
207 presto
->status
=FT_Write(presto
->handle
,&presto_init_seq
,sizeof(presto_init_seq
),&ftbytes
);
208 if (presto
->status
!=FT_OK
) return PRST_ERR
;
209 if (ftbytes
!=sizeof(presto_init_seq
)) return PRST_TIMEOUT
;
215 int presto_close(void)
217 unsigned long ftbytes
;
221 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
) return result
;
223 presto
->status
=FT_Write(presto
->handle
,&presto_init_seq
,sizeof(presto_init_seq
),&ftbytes
);
224 if (presto
->status
!=FT_OK
) result
=PRST_ERR
;
225 if (ftbytes
!=sizeof(presto_init_seq
)) result
=PRST_TIMEOUT
;
227 if ((presto
->status
=FT_SetLatencyTimer(presto
->handle
,16))!=FT_OK
) result
=PRST_ERR
;
229 if ((presto
->status
=FT_Close(presto
->handle
))!=FT_OK
) result
=PRST_ERR
;
230 else presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
236 int presto_flush(void)
238 unsigned long ftbytes
;
240 if (presto
->buff_out_pos
==0) return PRST_OK
;
241 if (presto
->status
!=FT_OK
) return PRST_ERR
;
243 if ((presto
->status
=FT_Write(presto
->handle
, presto
->buff_out
, presto
->buff_out_pos
, &ftbytes
))!=FT_OK
)
245 presto
->buff_out_pos
=0;
249 presto
->total_out
+=ftbytes
;
251 if (presto
->buff_out_pos
!=ftbytes
)
253 presto
->buff_out_pos
=0;
257 presto
->buff_out_pos
=0;
259 if (presto
->buff_in_exp
==0) return PRST_OK
;
261 presto
->buff_in_pos
=0;
262 presto
->buff_in_len
=0;
264 if ((presto
->status
=FT_Read(presto
->handle
, presto
->buff_in
, presto
->buff_in_exp
, &ftbytes
))!=FT_OK
)
266 presto
->buff_in_exp
=0;
270 presto
->total_in
+=ftbytes
;
272 if (ftbytes
!=presto
->buff_in_exp
)
274 presto
->buff_in_exp
=0;
278 presto
->buff_in_len
=presto
->buff_in_exp
;
279 presto
->buff_in_exp
=0;
285 int presto_sendbyte(int data
)
287 if (data
==EOF
) return presto_flush();
289 if (presto
->buff_out_pos
< BUFFER_SIZE
)
291 presto
->buff_out
[presto
->buff_out_pos
++]=(BYTE
)data
;
292 if (((data
&0xC0)==0x40) || ((data
&0xD0)==0xD0))
293 presto
->buff_in_exp
++;
295 else return PRST_ERR
;
297 if (presto
->buff_out_pos
>= BUFFER_SIZE
) return presto_flush();
302 int presto_getbyte(void)
304 if (presto
->buff_in_pos
<presto
->buff_in_len
)
305 return presto
->buff_in
[presto
->buff_in_pos
++];
307 if (presto
->buff_in_exp
==0) return -1;
308 if (presto_flush()!=PRST_OK
) return -1;
310 if (presto
->buff_in_pos
<presto
->buff_in_len
)
311 return presto
->buff_in
[presto
->buff_in_pos
++];
317 /* -------------------------------------------------------------------------- */
320 int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
322 unsigned char cmdparam
;
324 if (presto
->jtag_tck
==0)
326 presto_sendbyte(0xA4);
330 else if (!tdo_req
&& tms
==presto
->jtag_tms
)
332 if (presto
->jtag_tdi_count
==0) presto
->jtag_tdi_data
=(tdi
!=0);
333 else presto
->jtag_tdi_data
|=(tdi
!=0)<<presto
->jtag_tdi_count
;
334 if (++presto
->jtag_tdi_count
==4)
336 presto
->jtag_tdi_data
|=(presto
->jtag_tdi_count
-1)<<4;
337 presto_sendbyte(presto
->jtag_tdi_data
);
338 presto
->jtag_tdi_count
=0;
343 if (presto
->jtag_tdi_count
)
345 presto
->jtag_tdi_data
|=(presto
->jtag_tdi_count
-1)<<4;
346 presto_sendbyte(presto
->jtag_tdi_data
);
347 presto
->jtag_tdi_count
=0;
350 if (tdi
) cmdparam
=0x0B;
353 presto_sendbyte(0xC0|cmdparam
);
355 if (tms
!=presto
->jtag_tms
)
357 if (tms
) presto_sendbyte(0xEC);
358 else presto_sendbyte(0xE8);
359 presto
->jtag_tms
=tms
;
362 if (tdo_req
) presto_sendbyte(0xD4|cmdparam
);
363 else presto_sendbyte(0xC4|cmdparam
);
369 int presto_bitq_flush(void)
371 if (presto
->jtag_tdi_count
)
373 presto
->jtag_tdi_data
|=(presto
->jtag_tdi_count
-1)<<4;
374 presto_sendbyte(presto
->jtag_tdi_data
);
375 presto
->jtag_tdi_count
=0;
378 presto_sendbyte(0xCA);
381 presto_sendbyte(0xA0);
383 return presto_flush();
387 int presto_bitq_in_rdy(void)
389 if (presto
->buff_in_pos
>=presto
->buff_in_len
) return 0;
390 return presto
->buff_in_len
-presto
->buff_in_pos
;
394 int presto_bitq_in(void)
396 if (presto
->buff_in_pos
>=presto
->buff_in_len
) return -1;
397 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08) return 1;
402 int presto_bitq_sleep(unsigned long us
)
414 while (waits
--) presto_sendbyte(0x80);
420 int presto_bitq_reset(int trst
, int srst
)
425 if (presto
->jtag_tms
) cmd
|=0x04;
427 if (trst
|| srst
) cmd
|=0x02;
429 presto_sendbyte(cmd
);
434 /* -------------------------------------------------------------------------- */
437 int presto_jtag_speed(int speed
)
446 int presto_handle_serial_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
450 if (presto_serial
) free(presto_serial
);
451 presto_serial
= strdup(args
[0]);
455 ERROR("expected exactly one argument to presto_serial <serial-number>");
462 int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
)
464 register_command(cmd_ctx
, NULL
, "presto_serial", presto_handle_serial_command
,
465 COMMAND_CONFIG
, NULL
);
470 int presto_jtag_init(void)
472 if (presto_open(presto_serial
)!=0)
475 if (presto_serial
!=NULL
) ERROR("Cannot open PRESTO, serial number %s", presto_serial
);
476 else ERROR("Cannot open PRESTO");
477 return ERROR_JTAG_INIT_FAILED
;
479 INFO("PRESTO open, serial number %s", presto
->serial
);
481 bitq_interface
=&presto_bitq
;
486 int presto_jtag_quit(void)
490 INFO("PRESTO closed");
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)