BusPirate / Bus_Pirate

Community driven firmware and hardware for Bus Pirate version 3 and 4
630 stars 132 forks source link

Unable to get BPv4 & openocd JTAG working #103

Closed hb9xar closed 5 years ago

hb9xar commented 6 years ago

Hello there,

I'm trying to get the new JTAG feature on Buspirate V4 working. So far no luck:

I did not yet look into the code, just wondering if someone did actually get it working. As I have a test setup here and am able to build the firmware from source I'm willing to help testing.

I'm unable to attach a file (github gives me a very unspecific error) so cut&paste of the important parts:

Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Warn : Adapter driver 'buspirate' did not declare which transports it allows; assuming legacy JTAG-only
Info : only one transport option; autoselect 'jtag'
srst_only separate srst_gates_jtag srst_open_drain connect_deassert_srst
adapter speed: 2000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
cortex_m reset_config sysresetreq
Info : Some stale data from a previous connection was discarded.
Info : Buspirate Interface ready!
Info : This adapter doesn't support configurable speed
Info : JTAG tap: stm32f4x.cpu tap/device found: 0x060001e1 (mfg: 0x0f0 (AMCC), part: 0x6000, ver: 0x0)
Warn : JTAG tap: stm32f4x.cpu       UNEXPECTED: 0x060001e1 (mfg: 0x0f0 (AMCC), part: 0x6000, ver: 0x0)
Error: JTAG tap: stm32f4x.cpu  expected 1 of 1: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
Info : TAP stm32f4x.bs does not have IDCODE
Info : TAP auto0.tap does not have IDCODE
Info : TAP auto1.tap does not have IDCODE
Info : TAP auto2.tap does not have IDCODE
Info : TAP auto3.tap does not have IDCODE
Info : TAP auto4.tap does not have IDCODE
Info : TAP auto5.tap does not have IDCODE
Info : TAP auto6.tap does not have IDCODE
Info : TAP auto7.tap does not have IDCODE
Info : TAP auto8.tap does not have IDCODE
Info : TAP auto9.tap does not have IDCODE
Info : TAP auto10.tap does not have IDCODE
Info : TAP auto11.tap does not have IDCODE
Info : TAP auto12.tap does not have IDCODE
Info : TAP auto13.tap does not have IDCODE
Info : TAP auto14.tap does not have IDCODE
Info : TAP auto15.tap does not have IDCODE
Info : TAP auto16.tap does not have IDCODE
Info : TAP auto17.tap does not have IDCODE
Info : TAP auto18.tap does not have IDCODE
Warn : Unexpected idcode after end of chain: 52 0x00000000
Warn : Unexpected idcode after end of chain: 84 0x00000000
Warn : Unexpected idcode after end of chain: 116 0x00000000
Warn : Unexpected idcode after end of chain: 148 0x00000000
Warn : Unexpected idcode after end of chain: 180 0x00000000
Warn : Unexpected idcode after end of chain: 212 0x00000000
Warn : Unexpected idcode after end of chain: 244 0x00000000
Warn : Unexpected idcode after end of chain: 276 0x00000000
Warn : Unexpected idcode after end of chain: 308 0x00000000
Warn : Unexpected idcode after end of chain: 340 0x00000000
Warn : Unexpected idcode after end of chain: 372 0x00000000
Warn : Unexpected idcode after end of chain: 404 0x00000000
Warn : Unexpected idcode after end of chain: 436 0x00000000
Warn : Unexpected idcode after end of chain: 468 0x00000000
Warn : Unexpected idcode after end of chain: 500 0x00000000
Warn : Unexpected idcode after end of chain: 532 0x00000000
Warn : Unexpected idcode after end of chain: 564 0x00000000
Warn : Unexpected idcode after end of chain: 596 0x00000000
Warn : Unexpected idcode after end of chain: 628 0x00000000
Error: double-check your JTAG setup (interface, speed, ...)
Error: Trying to use configured scan chain anyway...
Error: stm32f4x.cpu: IR capture error; saw 0x09 not 0x01
Warn : Bypassing JTAG setup events due to errors
Error: Invalid ACK (3) in DAP response
Error: Invalid ACK (0) in DAP response
Error: Debug regions are unpowered, an unexpected reset might have happened
Error: JTAG-DP STICKY ERROR
[... repeating 28 times ...]
Error: Debug regions are unpowered, an unexpected reset might have happened
Error: JTAG-DP STICKY ERROR
Error: Invalid ACK (0) in DAP response
Error: Could not initialize the debug port
hb9xar commented 6 years ago

See PR #104, makes things much better, but still not working as expected. After a few dialogues between openocd and BPv4 (Scan commands), BP suddenly starts responding with funny data (string "BBIO1") - this leads me to think than code execution somehow jumps into other code or a reset/watchdog hits.

agatti commented 6 years ago

Hrmm, that looks like such a thing indeed. I'll give this one another shot tomorrow with my custom STM32F7 board and see if that triggers a crash.

hb9xar commented 6 years ago

I may have found the reason why Bpv4 leaves the binary JTAG mode. The CMD_UNKNOWK case is triggered, causing it to return from binOpenOCD().

For testing, send an 0xA5 character via serial if CMD_UNKNOWN is triggered:

    switch (inByte) {
    case CMD_UNKNOWN:
      user_serial_transmit_character(0xA5); // FOR DEBUG: indicate exit for debugging purpose via serial
      return;

In the openocd debug log I do see this 0xA5 byte (headed by 0 zero bytes). Then the sequence 43 43 49 ... starts.

My educated guess would be, something is fishy in reading the correct number of bytes from openocd (TMS and TDI), causing things get out of sync. Then everything breaks down - no way to recover and at some point (more sooner than later) the CMD_UNKNOWN is triggered..

This said, the code always reads 2 byte pairs (2 bytes TMS, 2 bytes TDI) - is this correct? If the number of bits to clock indicate an odd number of bytes then this will fail (reading one byte pair too much from serial) - as far as my understanding of the protocol between openocd and BPv4 goes? Should the inner loop (clocking the bits out) not just be 8 bit wide? I'm just thinking aloud...

agatti commented 6 years ago

That's what the v3 integration code does:

        ;   Fetch and organize 2x16 bits
        mov.w   [w7++], w2      ;   w2 = *((uint16_t*)w7++);
        mov.w   [w7++], w3      ;   w3 = *((uint16_t*)w7++);

            ; If memory had bytes 0xAA 0xBB 0xCC 0xDD,
            ; we now have:
            ;   w2 = 0xBBAA;
            ;   w3 = 0xDDCC;
            ;
            ; and we want:
            ;   w2 = 0xCCAA;    /* TDI bits (lsb out first) */
            ;   w3 = 0xDDBB;    /* TMS bits (lsb out first) */
        swap.w  w2          ;   w2 = swap_bytes(w2);
        xor.w   w2, w3, w4      ;   w4 = w2 ^ w3;
        and.w   #0xff, w4       ;   w4 &= 0xff;
        xor.w   w2, w4, w2      ;   w2 = w2 ^ w4;
        xor.w   w3, w4, w3      ;   w3 = w3 ^ w4;
        swap.w  w2          ;   w2 = swap_bytes(w2);

        ;   Compute how many bits to process
        mov.w   #15, w0         ;   w0 = min(15, w6)
        cpsgt.w w6, w0
        mov.w   w6, w0

So the issue might be somewhere else - on the other hand I do not remember getting an odd number of bytes clocked in. Can you hook a logic analyser up and see exactly what you get?

hb9xar commented 6 years ago

OK, I quickly hooped up a logic analyzer. Attached openocd debug output as well as a Logic analyzer capture (Saleae Logik 16, free download, you should be able to open the dump with the software in demo mode) https://www.saleae.com/downloads/

tgz containing debug log and login capture: 20180903_capture.tar.gz

Actually, the answers from BPv4 start looking bad at

Debug: 897 746 buspirate.c:1125 buspirate_print_buffer(): 00 98 98 a5 42 42 49 4f 31 42 42 49 4f 31 

this is the first response from BPv4 to openocd that does not start with 0x05 (TAP SHIFT)

I've not looked deeper into it yet.

hb9xar commented 6 years ago

I've looked a bit further into the code and ended up in the USB Serial code.

I'm quite sure that the openocd part of the code is OK. In my opinion, the serial (ok, serial over USB) communication gets out of sync (dropped/missed serial character somewhere in the code?), this in turn causing openocd to fail and exit due to an unknown command from the host.

I can confirm that the CMD_UNKNOWN: case as well as the default: case are triggered (switch (inByte){}).

Maybe this helps a bit further.

agatti commented 6 years ago

This is indeed weird. A plausible explanation would be that multiple OpenOCD commands arriving in a particular sequence do overrun each other's buffer area, but from what I can see after a quick look at the code for binOpenOCD all commands do write data to the terminal buffer prior to reading from it. Moreover, the v4 implementation for TAP/SHIFT isn't even touching the buffer at all.

Considering that TAP/SHIFT data coming out is effectively in lockstep with the OpenOCD requests, the chances for an overrun are a bit low, especially since putc_cdc does stall execution waiting for the TX buffer descriptor to be available before writing.

I'm not entirely ruling this out, but I think the problem may happen a bit earlier in the code...

hb9xar commented 6 years ago

PR #105 At least I had a refresher on PIC and USB until it hit me. Does seem work now fine.

agatti commented 6 years ago

@kallisti5, with OpenOCD for v4 brought in I guess it's time to release 7.1 for real this time™ - what do you think?