1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Driver for USB-JTAG, Altera USB-Blaster and compatibles
6 * Inspired from original code from Kolja Waschk's USB-JTAG project
7 * (http://www.ixo.de/info/usb_jtag/), and from openocd project.
9 * Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr
10 * Copyright (C) 2011 Ali Lown ali@lown.me.uk
11 * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca
12 * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de
19 #include <jtag/interface.h>
20 #include <jtag/commands.h>
22 #include "ublast_access.h"
25 static struct ftdi_context
*ublast_getftdic(struct ublast_lowlevel
*low
)
30 static int ublast_ftdi_read(struct ublast_lowlevel
*low
, uint8_t *buf
,
31 unsigned size
, uint32_t *bytes_read
)
35 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
38 while ((*bytes_read
< size
) && timeout
--) {
39 retval
= ftdi_read_data(ftdic
, buf
+ *bytes_read
,
43 LOG_ERROR("ftdi_read_data: %s",
44 ftdi_get_error_string(ftdic
));
45 return ERROR_JTAG_DEVICE_ERROR
;
47 *bytes_read
+= retval
;
52 static int ublast_ftdi_write(struct ublast_lowlevel
*low
, uint8_t *buf
, int size
,
53 uint32_t *bytes_written
)
56 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
58 retval
= ftdi_write_data(ftdic
, buf
, size
);
61 LOG_ERROR("ftdi_write_data: %s",
62 ftdi_get_error_string(ftdic
));
63 return ERROR_JTAG_DEVICE_ERROR
;
65 *bytes_written
= retval
;
69 static int ublast_ftdi_init(struct ublast_lowlevel
*low
)
71 uint8_t latency_timer
;
72 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
74 LOG_INFO("usb blaster interface using libftdi");
75 if (ftdi_init(ftdic
) < 0)
76 return ERROR_JTAG_INIT_FAILED
;
78 /* context, vendor id, product id */
79 if (ftdi_usb_open(ftdic
, low
->ublast_vid
, low
->ublast_pid
) < 0) {
80 LOG_ERROR("unable to open ftdi device: %s", ftdic
->error_str
);
81 return ERROR_JTAG_INIT_FAILED
;
84 if (ftdi_usb_reset(ftdic
) < 0) {
85 LOG_ERROR("unable to reset ftdi device");
86 return ERROR_JTAG_INIT_FAILED
;
89 if (ftdi_set_latency_timer(ftdic
, 2) < 0) {
90 LOG_ERROR("unable to set latency timer");
91 return ERROR_JTAG_INIT_FAILED
;
94 if (ftdi_get_latency_timer(ftdic
, &latency_timer
) < 0)
95 LOG_ERROR("unable to get latency timer");
97 LOG_DEBUG("current latency timer: %u", latency_timer
);
99 ftdi_disable_bitbang(ftdic
);
103 static int ublast_ftdi_quit(struct ublast_lowlevel
*low
)
105 struct ftdi_context
*ftdic
= ublast_getftdic(low
);
107 ftdi_usb_close(ftdic
);
112 static struct ublast_lowlevel_priv
{
113 struct ftdi_context ftdic
;
116 static struct ublast_lowlevel low
= {
117 .open
= ublast_ftdi_init
,
118 .close
= ublast_ftdi_quit
,
119 .read
= ublast_ftdi_read
,
120 .write
= ublast_ftdi_write
,
124 struct ublast_lowlevel
*ublast_register_ftdi(void)