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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
21 * Holds driver for PRESTO programmer from ASIX.
22 * http://tools.asix.net/prg_presto.htm
32 #include <jtag/interface.h>
33 #include <helper/time_support.h>
36 /* PRESTO access library includes */
37 #include "libftdi_helper.h"
39 /* -------------------------------------------------------------------------- */
41 #define FT_DEVICE_NAME_LEN 64
42 #define FT_DEVICE_SERNUM_LEN 64
44 #define PRESTO_VID_PID 0x0403f1a0
45 #define PRESTO_VID (0x0403)
46 #define PRESTO_PID (0xf1a0)
48 #define BUFFER_SIZE (64*62)
51 struct ftdi_context ftdic;
54 char serial[FT_DEVICE_SERNUM_LEN];
56 uint8_t buff_out[BUFFER_SIZE];
59 uint8_t buff_in[BUFFER_SIZE];
60 int buff_in_exp;/* expected in buffer length */
61 int buff_in_len;/* length of data received */
64 unsigned long total_out;
65 unsigned long total_in;
67 int jtag_tms; /* last tms state */
68 int jtag_tck; /* last tck state */
69 int jtag_rst; /* last trst state */
77 static struct presto presto_state;
78 static struct presto *presto = &presto_state;
80 static uint8_t presto_init_seq[] = {
81 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
84 static int presto_write(uint8_t *buf, uint32_t size)
87 presto->retval = ftdi_write_data(&presto->ftdic, buf, size);
88 if (presto->retval < 0) {
89 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic));
90 return ERROR_JTAG_DEVICE_ERROR;
92 ftbytes = presto->retval;
94 if (ftbytes != size) {
95 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
96 (unsigned)ftbytes, (unsigned)size);
97 return ERROR_JTAG_DEVICE_ERROR;
103 static int presto_read(uint8_t *buf, uint32_t size)
105 uint32_t ftbytes = 0;
107 struct timeval timeout, now;
108 gettimeofday(&timeout, NULL);
109 timeval_add_time(&timeout, 1, 0); /* one second timeout */
111 while (ftbytes < size) {
112 presto->retval = ftdi_read_data(&presto->ftdic, buf + ftbytes, size - ftbytes);
113 if (presto->retval < 0) {
114 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic));
115 return ERROR_JTAG_DEVICE_ERROR;
117 ftbytes += presto->retval;
119 gettimeofday(&now, NULL);
120 if (timeval_compare(&now, &timeout) > 0)
124 if (ftbytes != size) {
125 /* this is just a warning, there might have been timeout when detecting PRESTO,
126 *which is not fatal */
127 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)",
128 (unsigned)ftbytes, (unsigned)size);
129 return ERROR_JTAG_DEVICE_ERROR;
135 static int presto_open_libftdi(char *req_serial)
139 LOG_DEBUG("searching for PRESTO using libftdi");
141 /* initialize FTDI context structure */
142 if (ftdi_init(&presto->ftdic) < 0) {
143 LOG_ERROR("unable to init libftdi: %s", presto->ftdic.error_str);
144 return ERROR_JTAG_DEVICE_ERROR;
147 /* context, vendor id, product id */
148 if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0) {
149 LOG_ERROR("unable to open PRESTO: %s", presto->ftdic.error_str);
150 return ERROR_JTAG_DEVICE_ERROR;
153 if (ftdi_usb_reset(&presto->ftdic) < 0) {
154 LOG_ERROR("unable to reset PRESTO device");
155 return ERROR_JTAG_DEVICE_ERROR;
158 if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0) {
159 LOG_ERROR("unable to set latency timer");
160 return ERROR_JTAG_DEVICE_ERROR;
163 if (ftdi_tcioflush(&presto->ftdic) < 0) {
164 LOG_ERROR("unable to flush PRESTO buffers");
165 return ERROR_JTAG_DEVICE_ERROR;
169 if (presto_write(&presto_data, 1) != ERROR_OK) {
170 LOG_ERROR("error writing to PRESTO");
171 return ERROR_JTAG_DEVICE_ERROR;
174 if (presto_read(&presto_data, 1) != ERROR_OK) {
175 LOG_DEBUG("no response from PRESTO, retrying");
177 if (ftdi_tcioflush(&presto->ftdic) < 0)
178 return ERROR_JTAG_DEVICE_ERROR;
181 if (presto_write(&presto_data, 1) != ERROR_OK)
182 return ERROR_JTAG_DEVICE_ERROR;
184 if (presto_read(&presto_data, 1) != ERROR_OK) {
185 LOG_ERROR("no response from PRESTO, giving up");
186 return ERROR_JTAG_DEVICE_ERROR;
190 if (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK) {
191 LOG_ERROR("error writing PRESTO init sequence");
192 return ERROR_JTAG_DEVICE_ERROR;
198 static int presto_open(char *req_serial)
200 presto->buff_out_pos = 0;
201 presto->buff_in_pos = 0;
202 presto->buff_in_len = 0;
203 presto->buff_in_exp = 0;
205 presto->total_out = 0;
206 presto->total_in = 0;
208 presto->jtag_tms = 0;
209 presto->jtag_tck = 0;
210 presto->jtag_rst = 0;
211 presto->jtag_tdi_data = 0;
212 presto->jtag_tdi_count = 0;
214 presto->jtag_speed = 0;
216 return presto_open_libftdi(req_serial);
219 static int presto_close(void)
222 int result = ERROR_OK;
224 presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq));
225 if (presto->retval != sizeof(presto_init_seq))
226 result = ERROR_JTAG_DEVICE_ERROR;
228 presto->retval = ftdi_set_latency_timer(&presto->ftdic, 16);
229 if (presto->retval < 0)
230 result = ERROR_JTAG_DEVICE_ERROR;
232 presto->retval = ftdi_usb_close(&presto->ftdic);
233 if (presto->retval < 0)
234 result = ERROR_JTAG_DEVICE_ERROR;
236 ftdi_deinit(&presto->ftdic);
241 static int presto_flush(void)
243 if (presto->buff_out_pos == 0)
246 if (presto->retval < 0) {
247 LOG_DEBUG("error in previous communication, canceling I/O operation");
248 return ERROR_JTAG_DEVICE_ERROR;
251 if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK) {
252 presto->buff_out_pos = 0;
253 return ERROR_JTAG_DEVICE_ERROR;
256 presto->total_out += presto->buff_out_pos;
257 presto->buff_out_pos = 0;
259 if (presto->buff_in_exp == 0)
262 presto->buff_in_pos = 0;
263 presto->buff_in_len = 0;
265 if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK) {
266 presto->buff_in_exp = 0;
267 return ERROR_JTAG_DEVICE_ERROR;
270 presto->total_in += presto->buff_in_exp;
271 presto->buff_in_len = presto->buff_in_exp;
272 presto->buff_in_exp = 0;
277 static int presto_sendbyte(int data)
280 return presto_flush();
282 if (presto->buff_out_pos < BUFFER_SIZE) {
283 presto->buff_out[presto->buff_out_pos++] = (uint8_t)data;
284 if (((data & 0xC0) == 0x40) || ((data & 0xD0) == 0xD0))
285 presto->buff_in_exp++;
287 return ERROR_JTAG_DEVICE_ERROR;
289 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128
291 if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)
292 return presto_flush();
298 static int presto_getbyte(void)
300 if (presto->buff_in_pos < presto->buff_in_len)
301 return presto->buff_in[presto->buff_in_pos++];
303 if (presto->buff_in_exp == 0)
306 if (presto_flush() != ERROR_OK)
309 if (presto->buff_in_pos < presto->buff_in_len)
310 return presto->buff_in[presto->buff_in_pos++];
316 /* -------------------------------------------------------------------------- */
318 static int presto_tdi_flush(void)
320 if (presto->jtag_tdi_count == 0)
323 if (presto->jtag_tck == 0) {
324 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
328 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
329 presto_sendbyte(presto->jtag_tdi_data);
330 presto->jtag_tdi_count = 0;
331 presto->jtag_tdi_data = 0;
336 static int presto_tck_idle(void)
338 if (presto->jtag_tck == 1) {
339 presto_sendbyte(0xCA);
340 presto->jtag_tck = 0;
346 /* -------------------------------------------------------------------------- */
348 static int presto_bitq_out(int tms, int tdi, int tdo_req)
353 if (presto->jtag_tck == 0)
354 presto_sendbyte(0xA4); /* LED indicator - JTAG active */
355 else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms) {
356 presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;
358 if (++presto->jtag_tdi_count == 4)
366 cmd = tdi ? 0xCB : 0xCA;
367 presto_sendbyte(cmd);
369 if (tms != presto->jtag_tms) {
370 presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0));
371 presto->jtag_tms = tms;
374 /* delay with TCK low */
375 for (i = presto->jtag_speed; i > 1; i--)
376 presto_sendbyte(cmd);
379 presto_sendbyte(cmd | (tdo_req ? 0x10 : 0));
381 /* delay with TCK high */
382 for (i = presto->jtag_speed; i > 1; i--)
383 presto_sendbyte(cmd);
385 presto->jtag_tck = 1;
390 static int presto_bitq_flush(void)
395 presto_sendbyte(0xA0); /* LED indicator - JTAG idle */
397 return presto_flush();
400 static int presto_bitq_in_rdy(void)
402 if (presto->buff_in_pos >= presto->buff_in_len)
404 return presto->buff_in_len-presto->buff_in_pos;
407 static int presto_bitq_in(void)
409 if (presto->buff_in_pos >= presto->buff_in_len)
411 if (presto->buff_in[presto->buff_in_pos++]&0x08)
416 static int presto_bitq_sleep(unsigned long us)
429 waits = us / 170 + 2;
431 presto_sendbyte(0x80);
436 static int presto_bitq_reset(int trst, int srst)
441 /* add a delay after possible TCK transition */
442 presto_sendbyte(0x80);
443 presto_sendbyte(0x80);
445 presto->jtag_rst = trst || srst;
446 presto_sendbyte((presto->jtag_rst ? 0xEA : 0xE8) | (presto->jtag_tms ? 0x04 : 0));
451 static struct bitq_interface presto_bitq = {
452 .out = &presto_bitq_out,
453 .flush = &presto_bitq_flush,
454 .sleep = &presto_bitq_sleep,
455 .reset = &presto_bitq_reset,
456 .in_rdy = &presto_bitq_in_rdy,
457 .in = &presto_bitq_in,
460 /* -------------------------------------------------------------------------- */
462 static int presto_adapter_khz(int khz, int *jtag_speed)
466 return ERROR_COMMAND_SYNTAX_ERROR;
472 *jtag_speed = (1000 + khz-1)/khz;
477 static int presto_jtag_speed_div(int speed, int *khz)
479 if ((speed < 0) || (speed > 1000)) {
481 return ERROR_COMMAND_SYNTAX_ERROR;
492 static int presto_jtag_speed(int speed)
496 if (presto_jtag_speed_div(speed, &khz))
497 return ERROR_COMMAND_SYNTAX_ERROR;
499 presto->jtag_speed = speed;
502 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed, khz/1000);
504 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed, khz);
509 static char *presto_serial;
511 COMMAND_HANDLER(presto_handle_serial_command)
515 presto_serial = strdup(CMD_ARGV[0]);
517 return ERROR_COMMAND_SYNTAX_ERROR;
522 static const struct command_registration presto_command_handlers[] = {
524 .name = "presto_serial",
525 .handler = presto_handle_serial_command,
526 .mode = COMMAND_CONFIG,
527 .help = "Configure USB serial number of Presto device.",
528 .usage = "serial_string",
530 COMMAND_REGISTRATION_DONE
533 static int presto_jtag_init(void)
535 if (presto_open(presto_serial) != ERROR_OK) {
538 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial);
540 LOG_ERROR("Cannot open PRESTO");
541 return ERROR_JTAG_INIT_FAILED;
543 LOG_INFO("PRESTO open, serial number '%s'", presto->serial);
545 bitq_interface = &presto_bitq;
549 static int presto_jtag_quit(void)
553 LOG_INFO("PRESTO closed");
556 presto_serial = NULL;
561 static struct jtag_interface presto_interface = {
562 .execute_queue = bitq_execute_queue,
565 struct adapter_driver presto_adapter_driver = {
567 .transports = jtag_only,
568 .commands = presto_command_handlers,
570 .init = presto_jtag_init,
571 .quit = presto_jtag_quit,
572 .speed = presto_jtag_speed,
573 .khz = presto_adapter_khz,
574 .speed_div = presto_jtag_speed_div,
576 .jtag_ops = &presto_interface,