]> git.sur5r.net Git - openocd/commitdiff
jtag: usb_blaster: fix initialization regression
authorRobert Jarzmik <robert.jarzmik@free.fr>
Sun, 27 Jul 2014 10:30:13 +0000 (12:30 +0200)
committerSpencer Oliver <spen@spen-soft.co.uk>
Tue, 19 Aug 2014 20:21:02 +0000 (20:21 +0000)
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 <daniel-gl@gmx.net>
Cc: Franck Jullien <franck.jullien@gmail.com>
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Reviewed-on: http://openocd.zylin.com/2229
Tested-by: jenkins
Reviewed-by: Franck Jullien <franck.jullien@gmail.com>
Reviewed-by: Daniel Glöckner <daniel-gl@gmx.net>
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/jtag/drivers/usb_blaster/usb_blaster.c

index d64a7ea827a3cbe3adff2f09897bc9c13c99022f..82e5537f55f9d7f1c57889c9fa5344fc85a24bbb 100644 (file)
@@ -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;
 }