Problem with Olimex/OpenOCD/STM32

I have done a considerable amount of development on an STM32 target using an Eclipse IDE. However, yesterday I hit a problem that I can’t resolve:

I found my firmware would run on the emulator but not standalone. In an attempt to locate the source of this problem I added an infinite loop that toggles a spare I/O pin near the beginning of the code. Now OpenOCD is unable to connect. it gives an error “JTAG scan chain interrogation failed: all zeroes”. Every time I try to connect the I/O pin I am monitoring toggles for a short while then stops, indicating that the CPU starts running.

I have tried 4 different targets, two different connecting leads, two different Olimex dongles and two different PC’s. The setup works on another type of hardware target. It appears therefore that the problem is due to the firmware I have downloaded to the targets, but I cannot understand why.

The code that is executed before reaching the loop that toggles the I/O pin initialises the RCC clock then initialises SysTick and the I/O pins. My guess is that the toggling is executed until the next SysTick interrupt, then the CPU hangs.

I thought OpenOCD should take control of the target CPU via the Olimex dongle immediately after a reset, so should be unaffected by the code loaded on the target. Until I can get OpenOCD to connect I can’t write different firmware to the target, so I am stuck.

Does anyone have any ideas?

Additional details:

I have an Olimex ARM-USB-OCD dongle. The OpenOCD configuration file is as follows:

source [find interface/olimex-arm-usb-ocd.cfg]
# source target
source [find target/stm32.cfg]
init
reset halt

I have tried changing ‘reset halt’ to ‘reset init’ and ‘reset’ to no effect.

The OpenOCD diagnostic output reads:

  • Open On-Chip Debugger 0.5.0-dev (2010-06-17-21:25)

    Licensed under GNU GPL v2

    For bug reports, read

    http://openocd.berlios.de/doc/doxygen/bugs.html

    1000 kHz

    adapter_nsrst_delay: 100

    jtag_ntrst_delay: 100

    Info : clock speed 1000 kHz

    Error: JTAG scan chain interrogation failed: all zeroes

    Error: Check JTAG interface, timings, target power, etc.

    Error: JTAG scan chain interrogation failed: all zeroes

    Error: Check JTAG interface, timings, target power, etc.

    Command handler execution failed

    in procedure ‘jtag’ called at file “command.c”, line 654

    called at file “command.c”, line 365

    Warn : jtag initialization failed; try ‘jtag init’ again.

    Error: JTAG scan chain interrogation failed: all zeroes

    Error: Check JTAG interface, timings, target power, etc.

    error: -100

    Command handler execution failed

    in procedure ‘script’ called at file “command.c”, line 654

    called at file “embedded:startup.tcl”, line 57

    in procedure ‘reset’ called at file “openocd.cfg”, line 15

    called at file “command.c”, line 365


  • If I connect to a good, working CPU using the same configuration the OpenOCD diagnostics reads:

  • Open On-Chip Debugger 0.5.0-dev (2010-06-17-21:25)

    Licensed under GNU GPL v2

    For bug reports, read

    http://openocd.berlios.de/doc/doxygen/bugs.html

    1000 kHz

    adapter_nsrst_delay: 100

    jtag_ntrst_delay: 100

    Info : clock speed 1000 kHz

    Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)

    Info : JTAG tap: stm32.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)

    Info : stm32.cpu: hardware has 6 breakpoints, 4 watchpoints

    Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)

    Info : JTAG tap: stm32.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)

    target state: halted

    target halted due to debug-request, current mode: Thread

    xPSR: 0x01000000 pc: 0x08003494 msp: 0x200012a8

    requesting target halt and executing a soft reset

    target state: halted

    target halted due to debug-request, current mode: Thread

    xPSR: 0x01000000 pc: 0x08003494 msp: 0x200012a8


  • Further update:

    I have tried connecting TSRT and #RESET together, and the diagnostic message changes as follows:

  • Open On-Chip Debugger 0.5.0-dev (2010-06-17-21:25)

    Licensed under GNU GPL v2

    For bug reports, read

    http://openocd.berlios.de/doc/doxygen/bugs.html

    1000 kHz

    adapter_nsrst_delay: 100

    jtag_ntrst_delay: 100

    Info : clock speed 1000 kHz

    Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)

    Info : JTAG tap: stm32.bs tap/device found: 0x06414041 (mfg: 0x020, part: 0x6414, ver: 0x0)

    Warn : Unexpected idcode after end of chain: 64 0x00000ff0

    Warn : Unexpected idcode after end of chain: 96 0x00000ff0

    Warn : Unexpected idcode after end of chain: 128 0x00000ff0

    Warn : Unexpected idcode after end of chain: 160 0x00000ff0

    Warn : Unexpected idcode after end of chain: 192 0x00000ff0

    Warn : Unexpected idcode after end of chain: 224 0x00000ff0

    Warn : Unexpected idcode after end of chain: 256 0x00000ff0

    Warn : Unexpected idcode after end of chain: 288 0x00000ff0

    Warn : Unexpected idcode after end of chain: 320 0x00000ff0

    Warn : Unexpected idcode after end of chain: 352 0x00000ff0

    Warn : Unexpected idcode after end of chain: 384 0x00000ff0

    Warn : Unexpected idcode after end of chain: 416 0x00000ff0

    Warn : Unexpected idcode after end of chain: 448 0x00000ff0

    Warn : Unexpected idcode after end of chain: 480 0x00000ff0

    Warn : Unexpected idcode after end of chain: 512 0x00000ff0

    Warn : Unexpected idcode after end of chain: 544 0x00000ff0

    Warn : Unexpected idcode after end of chain: 576 0x00000ff0

    Warn : Unexpected idcode after end of chain: 608 0x00000ff0

    Error: double-check your JTAG setup (interface, speed, missing TAPs, …)

    Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)

    Info : JTAG tap: stm32.bs tap/device found: 0x06414041 (mfg: 0x020, part: 0x6414, ver: 0x0)

    Warn : Unexpected idcode after end of chain: 64 0x00000ff0

    Warn : Unexpected idcode after end of chain: 96 0x00000ff0

    Warn : Unexpected idcode after end of chain: 128 0x00000ff0

    Warn : Unexpected idcode after end of chain: 160 0x00000ff0

    Warn : Unexpected idcode after end of chain: 192 0x00000ff0

    Warn : Unexpected idcode after end of chain: 224 0x00000ff0

    Warn : Unexpected idcode after end of chain: 256 0x00000ff0

    Warn : Unexpected idcode after end of chain: 288 0x00000ff0

    Warn : Unexpected idcode after end of chain: 320 0x00000ff0

    Warn : Unexpected idcode after end of chain: 352 0x00000ff0

    Warn : Unexpected idcode after end of chain: 384 0x00000ff0

    Warn : Unexpected idcode after end of chain: 416 0x00000ff0

    Warn : Unexpected idcode after end of chain: 448 0x00000ff0

    Warn : Unexpected idcode after end of chain: 480 0x00000ff0

    Warn : Unexpected idcode after end of chain: 512 0x00000ff0

    Warn : Unexpected idcode after end of chain: 544 0x00000ff0

    Warn : Unexpected idcode after end of chain: 576 0x00000ff0

    Warn : Unexpected idcode after end of chain: 608 0x00000ff0

    Error: double-check your JTAG setup (interface, speed, missing TAPs, …)

    Command handler execution failed

    in procedure ‘jtag’ called at file “command.c”, line 654

    called at file “command.c”, line 365

    Warn : jtag initialization failed; try ‘jtag init’ again.

    Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)

    Info : JTAG tap: stm32.bs tap/device found: 0x06414041 (mfg: 0x020, part: 0x6414, ver: 0x0)

    Warn : Unexpected idcode after end of chain: 64 0x00000ff0

    Warn : Unexpected idcode after end of chain: 96 0x00000ff0

    Warn : Unexpected idcode after end of chain: 128 0x00000ff0

    Warn : Unexpected idcode after end of chain: 160 0x00000ff0

    Warn : Unexpected idcode after end of chain: 192 0x00000ff0

    Warn : Unexpected idcode after end of chain: 224 0x00000ff0

    Warn : Unexpected idcode after end of chain: 256 0x00000ff0

    Warn : Unexpected idcode after end of chain: 288 0x00000ff0

    Warn : Unexpected idcode after end of chain: 320 0x00000ff0

    Warn : Unexpected idcode after end of chain: 352 0x00000ff0

    Warn : Unexpected idcode after end of chain: 384 0x00000ff0

    Warn : Unexpected idcode after end of chain: 416 0x00000ff0

    Warn : Unexpected idcode after end of chain: 448 0x00000ff0

    Warn : Unexpected idcode after end of chain: 480 0x00000ff0

    Warn : Unexpected idcode after end of chain: 512 0x00000ff0

    Warn : Unexpected idcode after end of chain: 544 0x00000ff0

    Warn : Unexpected idcode after end of chain: 576 0x00000ff0

    Warn : Unexpected idcode after end of chain: 608 0x00000ff0

    Error: double-check your JTAG setup (interface, speed, missing TAPs, …)

    error: -100

    Command handler execution failed

    in procedure ‘script’ called at file “command.c”, line 654

    called at file “embedded:startup.tcl”, line 57

    in procedure ‘reset’ called at file “openocd.cfg”, line 15

    called at file “command.c”, line 365


  • This shows that the target CPU can respond to the JTag dongle, but still doesn’t give the expected response.

    As before, any suggestions would be welcome

    RouseA, have you experimented with the adapter_nrst_delay and jtag_nrst_delay?

    I hope someone knowledgeable responds. My understanding is that with those values set to 100, openOCD will let the chip run for 100 msec after reset before trying to get control of the chip.**

    The purist approach here would definitely be to spend the time to understand all the interaction between your board and your debug system at startup. If you just want to get your board working again, my guess is that it would be quicker to rig up a connection to UART1 and use the built-in bootloader to wipe out your trouble-making code.

    Good luck,

    -Hugh

    ** I guess this makes a certain amount of sense on e.g. LPC21xx chips where the bootloader always runs. For an STM32 I would have thought a low value like 1 msec or even zero would be more appropriate. I’ve been baffled by the results of my experiments with a generic STM32 board, openOCD, Olimex’s arm-usb-ocd, and gdb. Sometimes (with those delays at zero) I can halt just a few lines into crt0.s, and other times the main loop has run hundreds of times before the debugger takes control (missing any break points set elsewhere).

    Thanks for your ideas.

    I did try adding timeouts before the Reset command, but it didn’t make any difference. This led me to look closer into the script that launches OpenOCD:

    source [find interface/olimex-arm-usb-ocd.cfg]
    # source target
    source [find target/stm32.cfg]
    init
    reset halt
    

    I tried putting deliberate errors into this to see how far it was getting before it crashed. This proved that the error happened within the line source [find target/stm32.cfg]. I then toyed with the code in the file OpenOCD\target\stm32.cfg to find where it crashed. This includes the lines

    adapter_nsrst_delay 100
    jtag_ntrst_delay 100
    

    However, changing these made no difference. I also tried adding a command within this file to reset the CPU, but all ‘reset’ command are rejected.

    I then hit on the idea of trying to start the CPU in boot mode, even though my target doesn’t have the facility to use UART1 as required by the embedded bootloader. This meant I had to break the existing link between the STM32’s BOOT2 pin and 0V and instead provide the facility to link it to Vdd as the processor was reset. This was not easy, since it required a very steady hand on a soldering iron to lift the pin on the LQFP100 package.

    IT WORKED! I was then able to connect to the processor and download new firmware to it. After a second reset (this time with BOOT2 connected to 0V) the CPU started as it should.

    However, it puzzled me that the same fault recurred, even though I had removed the infinite loop that I assumed was the cause. I repeated the exercise using an older version of the firmware from my archive and it ran correctly. I then used Winmerge to compare the two sets of code and gradually imported the latest changes in the hope of finding the bit of code that was causing the problem. However, I ended up with all the latest code imported into a copy of the archive code and it still worked.

    I am happy that I have been able to fix the problem, but I still cannot understand what was in my code to prevent the Olimex from connecting. It does appear that when OpenOCD initialises the processor starts running its flash firmware before OpenOCD takes control, and something in the firmware can cause OpenOCD to fail. This surprises me, because if you connect to a new, virgin CPU the flash is blank, so there is no firmware to run.