X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fusb_blaster%2Fusb_blaster.c;h=82e5537f55f9d7f1c57889c9fa5344fc85a24bbb;hp=00a2cd084bd4ee947c2c78ed789cefe1c610958b;hb=73123ccc57050bfdf84c707daa9052fc3f78efae;hpb=4501e6002fea79ed3deba6dc77d88a4fda97437d diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index 00a2cd084b..82e5537f55 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -4,6 +4,7 @@ * Inspired from original code from Kolja Waschk's USB-JTAG project * (http://www.ixo.de/info/usb_jtag/), and from openocd project. * + * Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com * Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr * Copyright (C) 2011 Ali Lown ali@lown.me.uk * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca @@ -48,6 +49,16 @@ * | 6 MHz XTAL | | 24 MHz Osc. | * |_____________| |_____________| * + * USB-JTAG, Altera USB-Blaster II are typically implemented as a Cypress + * EZ-USB FX2LP followed by a CPLD. + * _____________ _________ + * | | | | + * USB__| EZ-USB FX2 |__| EPM570 |__JTAG (B_TDO,B_TDI,B_TMS,B_TCK) + * |_____________| |_________| + * __|__________ + * | | + * | 24 MHz XTAL | + * |_____________| */ #ifdef HAVE_CONFIG_H @@ -82,6 +93,9 @@ */ #define BUF_LEN 4096 +/* USB-Blaster II specific command */ +#define CMD_COPY_TDO_BUFFER 0x5F + enum gpio_steer { FIXED_0 = 0, FIXED_1, @@ -103,6 +117,9 @@ struct ublast_info { struct ublast_lowlevel *drv; char *ublast_device_desc; uint16_t ublast_vid, ublast_pid; + uint16_t ublast_vid_uninit, ublast_pid_uninit; + int flags; + char *firmware_path; }; /* @@ -132,6 +149,9 @@ static struct drvs_map lowlevel_drivers_map[] = { #endif #if BUILD_USB_BLASTER_FTD2XX { .name = "ftd2xx", .drv_register = ublast_register_ftd2xx }, +#endif +#if BUILD_USB_BLASTER_2 + { .name = "ublast2", .drv_register = ublast2_register_libusb }, #endif { NULL, NULL }, }; @@ -631,8 +651,11 @@ static void ublast_queue_tdi(uint8_t *bits, int nb_bits, enum scan_type scan) ublast_queue_bytes(&bits[i], trans); else ublast_queue_bytes(byte0, trans); - if (read_tdos) + if (read_tdos) { + if (info.flags & COPY_TDO_BUFFER) + ublast_queue_byte(CMD_COPY_TDO_BUFFER); ublast_read_byteshifted_tdos(&tdos[i], trans); + } } /* @@ -645,8 +668,11 @@ static void ublast_queue_tdi(uint8_t *bits, int nb_bits, enum scan_type scan) else ublast_clock_tdi(tdi, scan); } - if (nb1 && read_tdos) + if (nb1 && read_tdos) { + if (info.flags & COPY_TDO_BUFFER) + ublast_queue_byte(CMD_COPY_TDO_BUFFER); ublast_read_bitbang_tdos(&tdos[nb8], nb1); + } if (bits) memcpy(bits, tdos, DIV_ROUND_UP(nb_bits, 8)); @@ -730,11 +756,41 @@ static void ublast_usleep(int us) jtag_sleep(us); } +static void ublast_initial_wipeout(void) +{ + static uint8_t tms_reset = 0xff; + uint8_t out_value; + uint32_t retlen; + int i; + + out_value = ublast_build_out(SCAN_OUT); + for (i = 0; i < BUF_LEN; i++) + info.buf[i] = out_value | ((i % 2) ? TCK : 0); + + /* + * Flush USB-Blaster queue fifos + * - empty the write FIFO (128 bytes) + * - empty the read FIFO (384 bytes) + */ + ublast_buf_write(info.buf, BUF_LEN, &retlen); + /* + * Put JTAG in RESET state (five 1 on TMS) + */ + ublast_tms_seq(&tms_reset, 5); + tap_set_state(TAP_RESET); +} + static int ublast_execute_queue(void) { struct jtag_command *cmd; + static int first_call = 1; int ret = ERROR_OK; + if (first_call) { + first_call--; + ublast_initial_wipeout(); + } + for (cmd = jtag_command_queue; ret == ERROR_OK && cmd != NULL; cmd = cmd->next) { switch (cmd->type) { @@ -775,14 +831,12 @@ static int ublast_execute_queue(void) * * Initialize the device : * - open the USB device - * - empty the write FIFO (128 bytes) - * - empty the read FIFO (384 bytes) + * - pretend it's initialized while actual init is delayed until first jtag command * * Returns ERROR_OK if USB device found, error if not. */ static int ublast_init(void) { - static uint8_t tms_reset = 0xff; int ret, i; if (info.lowlevel_name) { @@ -804,6 +858,7 @@ static int ublast_init(void) LOG_ERROR("no lowlevel driver found"); return ERROR_JTAG_DEVICE_ERROR; } + info.lowlevel_name = strdup(lowlevel_drivers_map[i-1].name); } /* @@ -811,21 +866,21 @@ static int ublast_init(void) */ info.drv->ublast_vid = info.ublast_vid; info.drv->ublast_pid = info.ublast_pid; + info.drv->ublast_vid_uninit = info.ublast_vid_uninit; + info.drv->ublast_pid_uninit = info.ublast_pid_uninit; info.drv->ublast_device_desc = info.ublast_device_desc; + info.drv->firmware_path = info.firmware_path; + + info.flags |= info.drv->flags; ret = info.drv->open(info.drv); - if (ret == ERROR_OK) { - /* - * Flush USB-Blaster queue fifos - */ - uint32_t retlen; - ublast_buf_write(info.buf, BUF_LEN, &retlen); - /* - * Put JTAG in RESET state (five 1 on TMS) - */ - ublast_tms_seq(&tms_reset, 5); - tap_set_state(TAP_RESET); - } + + /* + * Let lie here : the TAP is in an unknown state, but the first + * execute_queue() will trigger a ublast_initial_wipeout(), which will + * put the TAP in RESET. + */ + tap_set_state(TAP_RESET); return ret; } @@ -849,29 +904,36 @@ static int ublast_quit(void) COMMAND_HANDLER(ublast_handle_device_desc_command) { - if (CMD_ARGC == 1) - info.ublast_device_desc = strdup(CMD_ARGV[0]); - else - LOG_ERROR("require exactly one argument to " - "ublast_device_desc "); + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + info.ublast_device_desc = strdup(CMD_ARGV[0]); return ERROR_OK; } COMMAND_HANDLER(ublast_handle_vid_pid_command) { - if (CMD_ARGC > 2) { + if (CMD_ARGC > 4) { LOG_WARNING("ignoring extra IDs in ublast_vid_pid " - "(maximum is 1 pair)"); - CMD_ARGC = 2; + "(maximum is 2 pairs)"); + CMD_ARGC = 4; } - if (CMD_ARGC == 2) { + + if (CMD_ARGC >= 2) { COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], info.ublast_vid); COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], info.ublast_pid); } else { LOG_WARNING("incomplete ublast_vid_pid configuration"); } + if (CMD_ARGC == 4) { + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2], info.ublast_vid_uninit); + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], info.ublast_pid_uninit); + } else { + LOG_WARNING("incomplete ublast_vid_pid configuration"); + } + return ERROR_OK; } @@ -913,7 +975,7 @@ COMMAND_HANDLER(ublast_handle_pin_command) if (strlen(pin_value) > 1) val = '?'; - switch (tolower(val)) { + switch (tolower((unsigned char)val)) { case '0': *steer = FIXED_0; break; @@ -943,14 +1005,25 @@ COMMAND_HANDLER(ublast_handle_pin_command) COMMAND_HANDLER(ublast_handle_lowlevel_drv_command) { - if (CMD_ARGC == 1) - info.lowlevel_name = strdup(CMD_ARGV[0]); - else - LOG_ERROR("require exactly one argument to " - "usb_blaster_lowlevel_driver (ftdi|ftd2xx)"); + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + info.lowlevel_name = strdup(CMD_ARGV[0]); + + return ERROR_OK; +} + +COMMAND_HANDLER(ublast_firmware_command) +{ + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + info.firmware_path = strdup(CMD_ARGV[0]); + return ERROR_OK; } + static const struct command_registration ublast_command_handlers[] = { { .name = "usb_blaster_device_desc", @@ -963,15 +1036,17 @@ static const struct command_registration ublast_command_handlers[] = { .name = "usb_blaster_vid_pid", .handler = ublast_handle_vid_pid_command, .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the USB-Blaster", - .usage = "vid pid", + .help = "the vendor ID and product ID of the USB-Blaster and " \ + "vendor ID and product ID of the uninitialized device " \ + "for USB-Blaster II", + .usage = "vid pid vid_uninit pid_uninit", }, { .name = "usb_blaster_lowlevel_driver", .handler = ublast_handle_lowlevel_drv_command, .mode = COMMAND_CONFIG, - .help = "set the lowlevel access for the USB Blaster (ftdi, ftd2xx)", - .usage = "(ftdi|ftd2xx)", + .help = "set the lowlevel access for the USB Blaster (ftdi, ftd2xx, ublast2)", + .usage = "(ftdi|ftd2xx|ublast2)", }, { .name = "usb_blaster_pin", @@ -979,6 +1054,13 @@ static const struct command_registration ublast_command_handlers[] = { .mode = COMMAND_ANY, .help = "show or set pin state for the unused GPIO pins", .usage = "(pin6|pin8) (0|1|s|t)", + }, + { + .name = "usb_blaster_firmware", + .handler = &ublast_firmware_command, + .mode = COMMAND_CONFIG, + .help = "configure the USB-Blaster II firmware location", + .usage = "path/to/blaster_xxxx.hex", }, COMMAND_REGISTRATION_DONE };