From: Robert Jarzmik Date: Sun, 27 Jul 2014 10:30:13 +0000 (+0200) Subject: jtag: usb_blaster: fix initialization regression X-Git-Tag: v0.9.0-rc1~303 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=73123ccc57050bfdf84c707daa9052fc3f78efae jtag: usb_blaster: fix initialization regression As Daniel pointed out, since the rewrite of the USB Blaster driver, the initialization behaviour has change. The initial flush of the FIFOs is not longer done with a specific USB setup packet, but with a write filling up the blaster queues. The problem is, quoting Daniel : When the CPLD is in bit banging mode (as is usually the case), the first 0x00 byte sets all pins to low and disables the output driver. Disabling the output drivers is a few nanoseconds slower than changing a pin from high to low, so I see a spike towards GND on my reset line when that byte is sent over USB. The spike is too short to have an effect on the board. When the 4096 0x00 bytes are processed and the TMS=1 is to be generated, all I see is several microseconds of low level on all pins, resetting my board. This patch changes the way the initialization is done : - at driver init, nothing is sent towards the usb-blaster This gives time for init script to setup PIN6 and PIN8 (resets) - at the very first driver command, the initialization is done : - the output is in bit bigbang mode - the PIN6 and PIN8 are computed according to init script - the 4096 computed output is sent Change-Id: If7ceee957f6b59bcb27c8f912f1cfdd0f94f75ed Reported-by: Daniel Glöckner Cc: Franck Jullien Signed-off-by: Robert Jarzmik Reviewed-on: http://openocd.zylin.com/2229 Tested-by: jenkins Reviewed-by: Franck Jullien Reviewed-by: Daniel Glöckner Reviewed-by: Spencer Oliver --- diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index d64a7ea827..82e5537f55 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -756,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) { @@ -801,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) { @@ -846,18 +874,13 @@ static int ublast_init(void) 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; }