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
)
141 char devname
[FT_DEVICE_NAME_LEN
];
145 unsigned long ftbytes
;
147 presto
->handle
=INVALID_HANDLE_VALUE
;
149 presto
->buff_out_pos
=0;
150 presto
->buff_in_pos
=0;
151 presto
->buff_in_len
=0;
152 presto
->buff_in_exp
=0;
159 presto
->jtag_tdi_data
=0;
160 presto
->jtag_tdi_count
=0;
162 if (FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
)!=FT_OK
) return PRST_ERR
;
163 for (i
=0; i
<numdevs
; i
++)
165 if (FT_Open(i
, &(presto
->handle
))!=FT_OK
) continue;
166 if (FT_GetDeviceInfo(presto
->handle
,&device
,&vidpid
,presto
->serial
,devname
,NULL
)==FT_OK
)
168 if (vidpid
==PRESTO_VID_PID
&& (req_serial
==NULL
|| !strcmp(presto
->serial
,req_serial
)))
171 FT_Close(presto
->handle
);
172 presto
->handle
=INVALID_HANDLE_VALUE
;
175 if (presto
->handle
==INVALID_HANDLE_VALUE
) return PRST_ERR
;
177 if ((presto
->status
=FT_SetLatencyTimer(presto
->handle
,1))!=FT_OK
) return PRST_ERR
;
178 if ((presto
->status
=FT_SetTimeouts(presto
->handle
,100,0))!=FT_OK
) return PRST_ERR
;
179 if ((presto
->status
=FT_Purge(presto
->handle
, FT_PURGE_TX
|FT_PURGE_RX
))!=FT_OK
) return PRST_ERR
;
182 if ((presto
->status
=FT_Write(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
183 if ((presto
->status
=FT_Read(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
187 if ((presto
->status
=FT_SetBitMode(presto
->handle
,0x80,1))!=FT_OK
) return PRST_ERR
;
188 if ((presto
->status
=FT_Purge(presto
->handle
, FT_PURGE_TX
|FT_PURGE_RX
))!=FT_OK
) return PRST_ERR
;
189 if ((presto
->status
=FT_SetBaudRate(presto
->handle
,9600))!=FT_OK
) return PRST_ERR
;
192 for (i
=0; i
<4*62; i
++)
193 if ((presto
->status
=FT_Write(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
197 if ((presto
->status
=FT_SetBitMode(presto
->handle
,0x00,0))!=FT_OK
) return PRST_ERR
;
198 if ((presto
->status
=FT_Purge(presto
->handle
, FT_PURGE_TX
|FT_PURGE_RX
))!=FT_OK
) return PRST_ERR
;
201 if ((presto
->status
=FT_Write(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
202 if ((presto
->status
=FT_Read(presto
->handle
,&presto_data
,1,&ftbytes
))!=FT_OK
) return PRST_ERR
;
203 if (ftbytes
!=1) return PRST_ERR
;
206 if ((presto
->status
=FT_SetTimeouts(presto
->handle
,0,0))!=FT_OK
) return PRST_ERR
;
208 presto
->status
=FT_Write(presto
->handle
,&presto_init_seq
,sizeof(presto_init_seq
),&ftbytes
);
209 if (presto
->status
!=FT_OK
) return PRST_ERR
;
210 if (ftbytes
!=sizeof(presto_init_seq
)) return PRST_TIMEOUT
;
216 int presto_close(void)
218 unsigned long ftbytes
;
222 if (presto
->handle
==INVALID_HANDLE_VALUE
) return result
;
224 presto
->status
=FT_Write(presto
->handle
,&presto_init_seq
,sizeof(presto_init_seq
),&ftbytes
);
225 if (presto
->status
!=FT_OK
) result
=PRST_ERR
;
226 if (ftbytes
!=sizeof(presto_init_seq
)) result
=PRST_TIMEOUT
;
228 if ((presto
->status
=FT_SetLatencyTimer(presto
->handle
,16))!=FT_OK
) result
=PRST_ERR
;
230 if ((presto
->status
=FT_Close(presto
->handle
))!=FT_OK
) result
=PRST_ERR
;
231 else presto
->handle
=INVALID_HANDLE_VALUE
;
237 int presto_flush(void)
239 unsigned long ftbytes
;
241 if (presto
->buff_out_pos
==0) return PRST_OK
;
242 if (presto
->status
!=FT_OK
) return PRST_ERR
;
244 if ((presto
->status
=FT_Write(presto
->handle
, presto
->buff_out
, presto
->buff_out_pos
, &ftbytes
))!=FT_OK
)
246 presto
->buff_out_pos
=0;
250 presto
->total_out
+=ftbytes
;
252 if (presto
->buff_out_pos
!=ftbytes
)
254 presto
->buff_out_pos
=0;
258 presto
->buff_out_pos
=0;
260 if (presto
->buff_in_exp
==0) return PRST_OK
;
262 presto
->buff_in_pos
=0;
263 presto
->buff_in_len
=0;
265 if ((presto
->status
=FT_Read(presto
->handle
, presto
->buff_in
, presto
->buff_in_exp
, &ftbytes
))!=FT_OK
)
267 presto
->buff_in_exp
=0;
271 presto
->total_in
+=ftbytes
;
273 if (ftbytes
!=presto
->buff_in_exp
)
275 presto
->buff_in_exp
=0;
279 presto
->buff_in_len
=presto
->buff_in_exp
;
280 presto
->buff_in_exp
=0;
286 int presto_sendbyte(int data
)
288 if (data
==EOF
) return presto_flush();
290 if (presto
->buff_out_pos
< BUFFER_SIZE
)
292 presto
->buff_out
[presto
->buff_out_pos
++]=(BYTE
)data
;
293 if (((data
&0xC0)==0x40) || ((data
&0xD0)==0xD0))
294 presto
->buff_in_exp
++;
296 else return PRST_ERR
;
298 if (presto
->buff_out_pos
>= BUFFER_SIZE
) return presto_flush();
303 int presto_getbyte(void)
305 if (presto
->buff_in_pos
<presto
->buff_in_len
)
306 return presto
->buff_in
[presto
->buff_in_pos
++];
308 if (presto
->buff_in_exp
==0) return -1;
309 if (presto_flush()!=PRST_OK
) return -1;
311 if (presto
->buff_in_pos
<presto
->buff_in_len
)
312 return presto
->buff_in
[presto
->buff_in_pos
++];
318 /* -------------------------------------------------------------------------- */
321 int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
323 unsigned char cmdparam
;
325 if (presto
->jtag_tck
==0)
327 presto_sendbyte(0xA4);
331 else if (!tdo_req
&& tms
==presto
->jtag_tms
)
333 if (presto
->jtag_tdi_count
==0) presto
->jtag_tdi_data
=(tdi
!=0);
334 else presto
->jtag_tdi_data
|=(tdi
!=0)<<presto
->jtag_tdi_count
;
335 if (++presto
->jtag_tdi_count
==4)
337 presto
->jtag_tdi_data
|=(presto
->jtag_tdi_count
-1)<<4;
338 presto_sendbyte(presto
->jtag_tdi_data
);
339 presto
->jtag_tdi_count
=0;
344 if (presto
->jtag_tdi_count
)
346 presto
->jtag_tdi_data
|=(presto
->jtag_tdi_count
-1)<<4;
347 presto_sendbyte(presto
->jtag_tdi_data
);
348 presto
->jtag_tdi_count
=0;
351 if (tdi
) cmdparam
=0x0B;
354 presto_sendbyte(0xC0|cmdparam
);
356 if (tms
!=presto
->jtag_tms
)
358 if (tms
) presto_sendbyte(0xEC);
359 else presto_sendbyte(0xE8);
360 presto
->jtag_tms
=tms
;
363 if (tdo_req
) presto_sendbyte(0xD4|cmdparam
);
364 else presto_sendbyte(0xC4|cmdparam
);
370 int presto_bitq_flush(void)
372 if (presto
->jtag_tdi_count
)
374 presto
->jtag_tdi_data
|=(presto
->jtag_tdi_count
-1)<<4;
375 presto_sendbyte(presto
->jtag_tdi_data
);
376 presto
->jtag_tdi_count
=0;
379 presto_sendbyte(0xCA);
382 presto_sendbyte(0xA0);
384 return presto_flush();
388 int presto_bitq_in_rdy(void)
390 if (presto
->buff_in_pos
>=presto
->buff_in_len
) return 0;
391 return presto
->buff_in_len
-presto
->buff_in_pos
;
395 int presto_bitq_in(void)
397 if (presto
->buff_in_pos
>=presto
->buff_in_len
) return -1;
398 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08) return 1;
403 int presto_bitq_sleep(unsigned long us
)
415 while (waits
--) presto_sendbyte(0x80);
421 int presto_bitq_reset(int trst
, int srst
)
426 if (presto
->jtag_tms
) cmd
|=0x04;
428 if (trst
|| srst
) cmd
|=0x02;
430 presto_sendbyte(cmd
);
435 /* -------------------------------------------------------------------------- */
438 int presto_jtag_speed(int speed
)
447 int presto_handle_serial_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
451 if (presto_serial
) free(presto_serial
);
452 presto_serial
= strdup(args
[0]);
456 ERROR("expected exactly one argument to presto_serial <serial-number>");
463 int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
)
465 register_command(cmd_ctx
, NULL
, "presto_serial", presto_handle_serial_command
,
466 COMMAND_CONFIG
, NULL
);
471 int presto_jtag_init(void)
473 if (presto_open(presto_serial
)!=0)
476 if (presto_serial
!=NULL
) ERROR("Cannot open PRESTO, serial number %s", presto_serial
);
477 else ERROR("Cannot open PRESTO");
478 return ERROR_JTAG_INIT_FAILED
;
480 INFO("PRESTO open, serial number %s", presto
->serial
);
482 bitq_interface
=&presto_bitq
;
487 int presto_jtag_quit(void)
491 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)