aboutsummaryrefslogtreecommitdiff
path: root/src/jtag/drivers/usb_blaster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jtag/drivers/usb_blaster.c')
-rw-r--r--src/jtag/drivers/usb_blaster.c577
1 files changed, 0 insertions, 577 deletions
diff --git a/src/jtag/drivers/usb_blaster.c b/src/jtag/drivers/usb_blaster.c
deleted file mode 100644
index 2ef800d..0000000
--- a/src/jtag/drivers/usb_blaster.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/***************************************************************************
- * Driver for USB-JTAG, Altera USB-Blaster and compatibles *
- * Original code from Kolja Waschk's USB-JTAG project *
- * (http://www.ixo.de/info/usb_jtag/). *
- * Some updates by Anthony Liu (2006). *
- * Minor updates and cleanup by Catalin Patulea (2009). *
- * Speed updates by Ali Lown (2011). *
- * *
- * Copyright (C) 2011 Ali Lown *
- * ali@lown.me.uk *
- * *
- * Copyright (C) 2009 Catalin Patulea *
- * cat@vv.carleton.ca *
- * *
- * Copyright (C) 2006 Kolja Waschk *
- * usbjtag@ixo.de *
- * *
- * Based on ft2232.c and bitbang.c, *
- * Copyright (C) 2004,2006 by Dominic Rath *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-/*
- * The following information is originally from Kolja Waschk's USB-JTAG,
- * where it was obtained by reverse engineering an Altera USB-Blaster.
- * See http://www.ixo.de/info/usb_jtag/ for USB-Blaster block diagram and
- * usb_jtag-20080705-1200.zip#usb_jtag/host/openocd for protocol.
- *
- * The same information is also on the UrJTAG mediawiki, with some additional
- * notes on bits marked as "unknown" by usb_jtag.
- * (http://sourceforge.net/apps/mediawiki/urjtag/index.php?
- * title=Cable_Altera_USB-Blaster)
- *
- * USB-JTAG, Altera USB-Blaster and compatibles are typically implemented as
- * an FTDIChip FT245 followed by a CPLD which handles a two-mode protocol:
- *
- * _________
- * | |
- * | AT93C46 |
- * |_________|
- * __|__________ _________
- * | | | |
- * USB__| FTDI 245BM |__| EPM7064 |__JTAG (B_TDO,B_TDI,B_TMS,B_TCK)
- * |_____________| |_________|
- * __|__________ _|___________
- * | | | |
- * | 6 MHz XTAL | | 24 MHz Osc. |
- * |_____________| |_____________|
- *
- * Protocol details are given in the code below.
- *
- * It is also possible to emulate this configuration using a single-chip USB
- * controller like the Cypress FX2 (again, see usb_jtag for details).
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if IS_CYGWIN == 1
-#include "windows.h"
-#undef LOG_ERROR
-#endif
-
-/* project specific includes */
-#include <jtag/interface.h>
-#include <jtag/commands.h>
-#include <helper/time_support.h>
-
-/* system includes */
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "bitbang.h"
-
-#if (BUILD_USB_BLASTER_FTD2XX == 1 && BUILD_USB_BLASTER_LIBFTDI == 1)
-#error "BUILD_USB_BLASTER_FTD2XX && BUILD_USB_BLASTER_LIBFTDI "
-"are mutually exclusive"
-#elif (BUILD_USB_BLASTER_FTD2XX != 1 && BUILD_USB_BLASTER_LIBFTDI != 1)
-#error "BUILD_USB_BLASTER_FTD2XX || BUILD_USB_BLASTER_LIBFTDI must be chosen"
-#endif
-
-/* USB_BLASTER access library includes */
-#if BUILD_USB_BLASTER_FTD2XX == 1
-#include <ftd2xx.h>
-#include "ftd2xx_common.h"
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
-#include <ftdi.h>
-#endif
-
-#include <sys/time.h>
-#include <time.h>
-
-static char *usb_blaster_device_desc;
-static uint16_t usb_blaster_vid = 0x09fb; /* Altera */
-static uint16_t usb_blaster_pid = 0x6001; /* USB-Blaster */
-
-/* last output byte in simple bit banging (legacy) mode */
-static uint8_t out_value;
-/* global output buffer for bit banging */
-#define BUF_LEN 64 /* Size of EP1 */
-static uint8_t out_buffer[BUF_LEN];
-static uint16_t out_count;
-
-#if BUILD_USB_BLASTER_FTD2XX == 1
-static FT_HANDLE ftdih;
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
-static struct ftdi_context ftdic;
-#endif
-
-static int usb_blaster_buf_write(
- uint8_t *buf, int size, uint32_t *bytes_written)
-{
-#if BUILD_USB_BLASTER_FTD2XX == 1
- FT_STATUS status;
- DWORD dw_bytes_written;
-
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG("usb_blaster_buf_write %02X (%d)", buf[0], size);
-#endif
- status = FT_Write(ftdih, buf, size, &dw_bytes_written);
- if (status != FT_OK) {
- *bytes_written = dw_bytes_written;
- LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(status));
- return ERROR_JTAG_DEVICE_ERROR;
- }
- *bytes_written = dw_bytes_written;
- return ERROR_OK;
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
- int retval;
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG("usb_blaster_buf_write %02X (%d)", buf[0], size);
-#endif
- retval = ftdi_write_data(&ftdic, buf, size);
- if (retval < 0) {
- *bytes_written = 0;
- LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic));
- return ERROR_JTAG_DEVICE_ERROR;
- }
- *bytes_written = retval;
- return ERROR_OK;
-#endif
-}
-
-static int usb_blaster_buf_read(uint8_t *buf, unsigned size, uint32_t *bytes_read)
-{
-#if BUILD_USB_BLASTER_FTD2XX == 1
- DWORD dw_bytes_read;
- FT_STATUS status;
-
- status = FT_Read(ftdih, buf, size, &dw_bytes_read);
- if (status != FT_OK) {
- *bytes_read = dw_bytes_read;
- LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(status));
- return ERROR_JTAG_DEVICE_ERROR;
- }
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG("usb_blaster_buf_read %02X (%" PRIu32 ")", buf[0], dw_bytes_read);
-#endif
- *bytes_read = dw_bytes_read;
- return ERROR_OK;
-
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
- int retval;
- int timeout = 100;
-
- *bytes_read = 0;
- while ((*bytes_read < size) && timeout--) {
- retval = ftdi_read_data(&ftdic, buf + *bytes_read,
- size - *bytes_read);
- if (retval < 0) {
- *bytes_read = 0;
- LOG_ERROR("ftdi_read_data: %s",
- ftdi_get_error_string(&ftdic));
- return ERROR_JTAG_DEVICE_ERROR;
- }
- *bytes_read += retval;
- }
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG("usb_blaster_buf_read %02X (%d)", buf[0], *bytes_read);
-#endif
- return ERROR_OK;
-#endif
-}
-
-/* The following code doesn't fully utilize the possibilities of the
- * USB-Blaster. It only buffers data up to the maximum packet size of 64 bytes.
- *
- * Actually, the USB-Blaster offers a byte-shift mode to transmit up to 504 data
- * bits (bidirectional) in a single USB packet. A header byte has to be sent as
- * the first byte in a packet with the following meaning:
- *
- * Bit 7 (0x80): Must be set to indicate byte-shift mode.
- * Bit 6 (0x40): If set, the USB-Blaster will also read data, not just write.
- * Bit 5..0: Define the number N of following bytes
- *
- * All N following bytes will then be clocked out serially on TDI. If Bit 6 was
- * set, it will afterwards return N bytes with TDO data read while clocking out
- * the TDI data. LSB of the first byte after the header byte will appear first
- * on TDI.
- */
-
-/* Simple bit banging mode:
- *
- * Bit 7 (0x80): Must be zero (see byte-shift mode above)
- * Bit 6 (0x40): If set, you will receive a byte indicating the state of TDO
- * in return.
- * Bit 5 (0x20): Output Enable/LED.
- * Bit 4 (0x10): TDI Output.
- * Bit 3 (0x08): nCS Output (not used in JTAG mode).
- * Bit 2 (0x04): nCE Output (not used in JTAG mode).
- * Bit 1 (0x02): TMS Output.
- * Bit 0 (0x01): TCK Output.
- *
- * For transmitting a single data bit, you need to write two bytes. Up to 64
- * bytes can be combined in a single USB packet.
- * It isn't possible to read a data without transmitting data.
- */
-
-#define TCK (1 << 0)
-#define TMS (1 << 1)
-#define NCE (1 << 2)
-#define NCS (1 << 3)
-#define TDI (1 << 4)
-#define LED (1 << 5)
-#define READ (1 << 6)
-#define SHMODE (1 << 7)
-#define OTHERS ((1 << 2) | (1 << 3) | (1 << 5))
-
-#define READ_TDO (1 << 0)
-
-static void usb_blaster_write_databuffer(uint8_t *buf, uint16_t len)
-{
- uint32_t bytes_written;
- usb_blaster_buf_write(buf, len, &bytes_written);
- out_count = 0;
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG("---- WROTE %d", bytes_written);
-#endif
-}
-
-static void usb_blaster_addtowritebuffer(uint8_t value, bool forcewrite)
-{
- out_buffer[out_count] = value;
- out_count += 1;
- if (out_count == BUF_LEN || forcewrite)
- usb_blaster_write_databuffer(out_buffer, out_count);
-}
-
-static int usb_blaster_read_data(void)
-{
- int status;
- uint8_t buf[1];
- uint32_t bytes_read;
-
- if (out_count > 0)
- usb_blaster_write_databuffer(out_buffer, out_count);
-
- out_value |= READ;
- usb_blaster_addtowritebuffer(out_value, true);
- out_value &= ~READ;
-
- status = usb_blaster_buf_read(buf, 1, &bytes_read);
- if (status < 0)
- return 0;
-
- return !!(buf[0] & READ_TDO);
-}
-
-static void usb_blaster_write(int tck, int tms, int tdi)
-{
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG("---- usb_blaster_write(%d,%d,%d)", tck, tms, tdi);
-#endif
- out_value &= ~(TCK | TMS | TDI);
- if (tck)
- out_value |= TCK;
- if (tms)
- out_value |= TMS;
- if (tdi)
- out_value |= TDI;
-
- usb_blaster_addtowritebuffer(out_value, false);
-}
-
-static void usb_blaster_reset(int trst, int srst)
-{
- LOG_DEBUG("TODO: usb_blaster_reset(%d,%d) isn't implemented!",
- trst, srst);
-}
-
-static void usb_blaster_blink(int state)
-{
- out_value = 0x00;
- if (state)
- out_value |= LED;
-
- usb_blaster_addtowritebuffer(out_value, true);
-}
-
-static struct bitbang_interface usb_blaster_bitbang = {
- .read = usb_blaster_read_data,
- .write = usb_blaster_write,
- .reset = usb_blaster_reset,
- .blink = usb_blaster_blink,
-};
-
-static int usb_blaster_init(void)
-{
- uint8_t latency_timer;
-
-#if BUILD_USB_BLASTER_FTD2XX == 1
- FT_STATUS status;
-#endif
-
-#if BUILD_USB_BLASTER_FTD2XX == 1
- LOG_DEBUG("'usb_blaster' interface using FTD2XX");
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
- LOG_DEBUG("'usb_blaster' interface using libftdi");
-#endif
-
-#if BUILD_USB_BLASTER_FTD2XX == 1
- /* Open by device description */
- if (usb_blaster_device_desc == NULL) {
- LOG_WARNING("no usb_blaster device description specified, "
- "using default 'USB-Blaster'");
- usb_blaster_device_desc = strdup("USB-Blaster");
- }
-
-#if IS_WIN32 == 0
- /* Add non-standard Vid/Pid to the linux driver */
- status = FT_SetVIDPID(usb_blaster_vid, usb_blaster_pid);
- if (status != FT_OK) {
- LOG_WARNING("couldn't add %4.4x:%4.4x",
- usb_blaster_vid, usb_blaster_pid);
- }
-#endif
-
- status = FT_OpenEx(usb_blaster_device_desc, FT_OPEN_BY_DESCRIPTION,
- &ftdih);
- if (status != FT_OK) {
- DWORD num_devices;
-
- LOG_ERROR("unable to open ftdi device: %s",
- ftd2xx_status_string(status));
- status = FT_ListDevices(&num_devices, NULL,
- FT_LIST_NUMBER_ONLY);
- if (status == FT_OK) {
- char **desc_array = malloc(sizeof(char *)
- * (num_devices + 1));
- unsigned int i;
-
- for (i = 0; i < num_devices; i++)
- desc_array[i] = malloc(64);
- desc_array[num_devices] = NULL;
-
- status = FT_ListDevices(desc_array, &num_devices,
- FT_LIST_ALL | FT_OPEN_BY_DESCRIPTION);
-
- if (status == FT_OK) {
- LOG_ERROR("ListDevices: %" PRIu32, (uint32_t)num_devices);
- for (i = 0; i < num_devices; i++)
- LOG_ERROR("%i: %s", i, desc_array[i]);
- }
-
- for (i = 0; i < num_devices; i++)
- free(desc_array[i]);
- free(desc_array);
- } else
- printf("ListDevices: NONE\n");
- return ERROR_JTAG_INIT_FAILED;
- }
-
- status = FT_SetLatencyTimer(ftdih, 2);
- if (status != FT_OK) {
- LOG_ERROR("unable to set latency timer: %s",
- ftd2xx_status_string(status));
- return ERROR_JTAG_INIT_FAILED;
- }
-
- status = FT_GetLatencyTimer(ftdih, &latency_timer);
- if (status != FT_OK) {
- LOG_ERROR("unable to get latency timer: %s",
- ftd2xx_status_string(status));
- return ERROR_JTAG_INIT_FAILED;
- }
- LOG_DEBUG("current latency timer: %i", latency_timer);
-
- status = FT_SetBitMode(ftdih, 0x00, 0);
- if (status != FT_OK) {
- LOG_ERROR("unable to disable bit i/o mode: %s",
- ftd2xx_status_string(status));
- return ERROR_JTAG_INIT_FAILED;
- }
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
- if (ftdi_init(&ftdic) < 0)
- return ERROR_JTAG_INIT_FAILED;
-
- /* context, vendor id, product id */
- if (ftdi_usb_open(&ftdic, usb_blaster_vid, usb_blaster_pid) < 0) {
- LOG_ERROR("unable to open ftdi device: %s", ftdic.error_str);
- return ERROR_JTAG_INIT_FAILED;
- }
-
- if (ftdi_usb_reset(&ftdic) < 0) {
- LOG_ERROR("unable to reset ftdi device");
- return ERROR_JTAG_INIT_FAILED;
- }
-
- if (ftdi_set_latency_timer(&ftdic, 2) < 0) {
- LOG_ERROR("unable to set latency timer");
- return ERROR_JTAG_INIT_FAILED;
- }
-
- if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0) {
- LOG_ERROR("unable to get latency timer");
- return ERROR_JTAG_INIT_FAILED;
- }
- LOG_DEBUG("current latency timer: %u", latency_timer);
-
- ftdi_disable_bitbang(&ftdic);
-#endif
-
- bitbang_interface = &usb_blaster_bitbang;
-
-#if 0
-#if BUILD_USB_BLASTER_FTD2XX == 1
- status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX);
- if (status != FT_OK) {
- LOG_ERROR("error purging ftd2xx device: %i", status);
- return ERROR_JTAG_INIT_FAILED;
- }
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
- if (ftdi_usb_purge_buffers(&ftdic) < 0) {
- LOG_ERROR("ftdi_purge_buffers: %s", ftdic.error_str);
- return ERROR_JTAG_INIT_FAILED;
- }
-#endif
-#endif
-
- return ERROR_OK;
-}
-
-static int usb_blaster_quit(void)
-{
- if (out_count > 0)
- usb_blaster_write_databuffer(out_buffer, out_count);
-
-#if BUILD_USB_BLASTER_FTD2XX == 1
- FT_STATUS status;
-
- status = FT_Close(ftdih);
-#elif BUILD_USB_BLASTER_LIBFTDI == 1
- ftdi_usb_close(&ftdic);
- ftdi_deinit(&ftdic);
-#endif
-
- if (usb_blaster_device_desc) {
- free(usb_blaster_device_desc);
- usb_blaster_device_desc = NULL;
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(usb_blaster_handle_device_desc_command)
-{
- if (CMD_ARGC == 1)
- usb_blaster_device_desc = strdup(CMD_ARGV[0]);
- else
- LOG_ERROR("require exactly one argument to "
- "usb_blaster_device_desc <description>");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(usb_blaster_handle_vid_pid_command)
-{
- if (CMD_ARGC > 2) {
- LOG_WARNING("ignoring extra IDs in usb_blaster_vid_pid "
- "(maximum is 1 pair)");
- CMD_ARGC = 2;
- }
- if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], usb_blaster_vid);
- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], usb_blaster_pid);
- } else
- LOG_WARNING("incomplete usb_blaster_vid_pid configuration");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(usb_blaster_handle_pin_command)
-{
- if (CMD_ARGC == 2) {
- const char *const pin_name = CMD_ARGV[0];
- uint8_t mask;
- unsigned int state;
-
- if (!strcmp(pin_name, "pin6"))
- mask = NCE;
- else if (!strcmp(pin_name, "pin8"))
- mask = NCS;
- else {
- LOG_ERROR("%s: pin name must be \"pin6\" or \"pin8\"",
- CMD_NAME);
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], state);
- if (state == 0) {
- out_value &= ~mask;
- usb_blaster_addtowritebuffer(out_value, true);
- } else if (state == 1) {
- out_value |= mask;
- usb_blaster_addtowritebuffer(out_value, true);
- } else {
- LOG_ERROR("%s: pin state must be 0 or 1", CMD_NAME);
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- return ERROR_OK;
- } else {
- LOG_ERROR("%s takes exactly two arguments", CMD_NAME);
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-}
-
-static const struct command_registration usb_blaster_command_handlers[] = {
- {
- .name = "usb_blaster_device_desc",
- .handler = usb_blaster_handle_device_desc_command,
- .mode = COMMAND_CONFIG,
- .help = "set the USB device description of the USB-Blaster",
- .usage = "description-string",
- },
- {
- .name = "usb_blaster_vid_pid",
- .handler = usb_blaster_handle_vid_pid_command,
- .mode = COMMAND_CONFIG,
- .help = "the vendor ID and product ID of the USB-Blaster",
- .usage = "vid pid",
- },
- {
- .name = "usb_blaster",
- .handler = usb_blaster_handle_pin_command,
- .mode = COMMAND_ANY,
- .help = "set pin state for the unused GPIO pins",
- .usage = "(pin6|pin8) (0|1)",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-struct jtag_interface usb_blaster_interface = {
- .name = "usb_blaster",
- .commands = usb_blaster_command_handlers,
- .supported = DEBUG_CAP_TMS_SEQ,
-
- .execute_queue = bitbang_execute_queue,
-
- .init = usb_blaster_init,
- .quit = usb_blaster_quit,
-};