2 * Driver for USB-JTAG, Altera USB-Blaster and compatibles
4 * Inspired from original code from Kolja Waschk's USB-JTAG project
5 * (http://www.ixo.de/info/usb_jtag/), and from openocd project.
7 * Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr
8 * Copyright (C) 2011 Ali Lown ali@lown.me.uk
9 * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca
10 * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 #include <jtag/interface.h>
31 #include <jtag/commands.h>
33 #include "ublast_access.h"
36 static struct ftdi_context
*ublast_getftdic(struct ublast_lowlevel
*low
)
41 static int ublast_ftdi_read(struct ublast_lowlevel
*low
, uint8_t *buf
,
42 unsigned size
, uint32_t *bytes_read
)
46 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
49 while ((*bytes_read
< size
) && timeout
--) {
50 retval
= ftdi_read_data(ftdic
, buf
+ *bytes_read
,
54 LOG_ERROR("ftdi_read_data: %s",
55 ftdi_get_error_string(ftdic
));
56 return ERROR_JTAG_DEVICE_ERROR
;
58 *bytes_read
+= retval
;
63 static int ublast_ftdi_write(struct ublast_lowlevel
*low
, uint8_t *buf
, int size
,
64 uint32_t *bytes_written
)
67 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
69 retval
= ftdi_write_data(ftdic
, buf
, size
);
72 LOG_ERROR("ftdi_write_data: %s",
73 ftdi_get_error_string(ftdic
));
74 return ERROR_JTAG_DEVICE_ERROR
;
76 *bytes_written
= retval
;
80 static int ublast_ftdi_init(struct ublast_lowlevel
*low
)
82 uint8_t latency_timer
;
83 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
85 LOG_INFO("usb blaster interface using libftdi");
86 if (ftdi_init(ftdic
) < 0)
87 return ERROR_JTAG_INIT_FAILED
;
89 /* context, vendor id, product id */
90 if (ftdi_usb_open(ftdic
, low
->ublast_vid
, low
->ublast_pid
) < 0) {
91 LOG_ERROR("unable to open ftdi device: %s", ftdic
->error_str
);
92 return ERROR_JTAG_INIT_FAILED
;
95 if (ftdi_usb_reset(ftdic
) < 0) {
96 LOG_ERROR("unable to reset ftdi device");
97 return ERROR_JTAG_INIT_FAILED
;
100 if (ftdi_set_latency_timer(ftdic
, 2) < 0) {
101 LOG_ERROR("unable to set latency timer");
102 return ERROR_JTAG_INIT_FAILED
;
105 if (ftdi_get_latency_timer(ftdic
, &latency_timer
) < 0)
106 LOG_ERROR("unable to get latency timer");
108 LOG_DEBUG("current latency timer: %u", latency_timer
);
110 ftdi_disable_bitbang(ftdic
);
114 static int ublast_ftdi_quit(struct ublast_lowlevel
*low
)
116 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
118 ftdi_usb_close(ftdic
);
123 static struct ublast_lowlevel_priv
{
124 struct ftdi_context ftdic
;
127 static struct ublast_lowlevel low
= {
128 .open
= ublast_ftdi_init
,
129 .close
= ublast_ftdi_quit
,
130 .read
= ublast_ftdi_read
,
131 .write
= ublast_ftdi_write
,
135 struct ublast_lowlevel
*ublast_register_ftdi(void)