flash/stm32l4x: support STM32U59/U5Ax devices
[openocd.git] / src / jtag / drivers / usb_blaster / ublast_access_ftdi.c
blobeb312ef4eeab548049f4aa15029969448a08fa42
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /*
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
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19 #include <jtag/interface.h>
20 #include <jtag/commands.h>
22 #include "ublast_access.h"
23 #include <ftdi.h>
25 static struct ftdi_context *ublast_getftdic(struct ublast_lowlevel *low)
27 return low->priv;
30 static int ublast_ftdi_read(struct ublast_lowlevel *low, uint8_t *buf,
31 unsigned size, uint32_t *bytes_read)
33 int retval;
34 int timeout = 100;
35 struct ftdi_context *ftdic = ublast_getftdic(low);
37 *bytes_read = 0;
38 while ((*bytes_read < size) && timeout--) {
39 retval = ftdi_read_data(ftdic, buf + *bytes_read,
40 size - *bytes_read);
41 if (retval < 0) {
42 *bytes_read = 0;
43 LOG_ERROR("ftdi_read_data: %s",
44 ftdi_get_error_string(ftdic));
45 return ERROR_JTAG_DEVICE_ERROR;
47 *bytes_read += retval;
49 return ERROR_OK;
52 static int ublast_ftdi_write(struct ublast_lowlevel *low, uint8_t *buf, int size,
53 uint32_t *bytes_written)
55 int retval;
56 struct ftdi_context *ftdic = ublast_getftdic(low);
58 retval = ftdi_write_data(ftdic, buf, size);
59 if (retval < 0) {
60 *bytes_written = 0;
61 LOG_ERROR("ftdi_write_data: %s",
62 ftdi_get_error_string(ftdic));
63 return ERROR_JTAG_DEVICE_ERROR;
65 *bytes_written = retval;
66 return ERROR_OK;
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");
96 else
97 LOG_DEBUG("current latency timer: %u", latency_timer);
99 ftdi_disable_bitbang(ftdic);
100 return ERROR_OK;
103 static int ublast_ftdi_quit(struct ublast_lowlevel *low)
105 struct ftdi_context *ftdic = ublast_getftdic(low);
107 ftdi_usb_close(ftdic);
108 ftdi_deinit(ftdic);
109 return ERROR_OK;
112 static struct ublast_lowlevel_priv {
113 struct ftdi_context ftdic;
114 } info;
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,
121 .priv = &info,
124 struct ublast_lowlevel *ublast_register_ftdi(void)
126 return &low;