Fashing a bad firmware can drive your crazy

I put by XMC4500 in a state where OpenOCD was unable the communicate with it:

$ sudo openocd -f board/xmc4500-relax.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x0c000000"
Open On-Chip Debugger 0.10.0+dev-00172-g7719e96 (2017-11-12-09:13)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4000 kHz
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : No device selected, using first device.
Info : J-Link Lite-XMC4000 Rev.1 compiled Apr  2 2015 18:25:20
Info : Hardware version: 1.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Error: Could not initialize the debug port
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Error: Could not initialize the debug port
Error: Target not examined, reset NOT asserted!
in procedure 'reset' 
in procedure 'ocd_bouncer'

What happened?

I just changed BOARD_SYSDIV :

#  define BOARD_SYSDIV              0

But in clockconfig.c it does:

  /* Setup fSYS clock */

  regval  = (BOARD_ENABLE_PLL << SCU_SYSCLKCR_SYSSEL);
  regval |= SCU_SYSCLKCR_SYSDIV(BOARD_SYSDIV);
  putreg32(regval, XMC4_SCU_SYSCLKCR);

SCU_SYSCLKCR_SYSDIV is defined this way:

#  define SCU_SYSCLKCR_SYSDIV(n)    ((uint32_t)((n)-1) << SCU_SYSCLKCR_SYSDIV_SHIFT)

So, it wrote 0xffffffff to SCU_SYSCLKCR register. :-/

Then I tried to flash using JLinkExe from Segger, but it also didn’t work:

$ JLinkExe -if SWD
SEGGER J-Link Commander V6.14h (Compiled May 10 2017 18:39:45)
DLL version V6.14h, compiled May 10 2017 18:39:37

Connecting to J-Link via USB...O.K.
Firmware: J-Link Lite-XMC4000 Rev.1 compiled Apr  2 2015 18:25:20
Hardware version: V1.00
S/N: 551014400
VTref = 3.300V


Type "connect" to establish a target connection, '?' for help
J-Link>connect
Please specify device / core. : XMC4500-1024
Type '?' for selection dialog
Device>
Specify target interface speed [kHz]. : 4000 kHz
Speed>
Device "XMC4500-1024" selected.


Performing XMC4500 connection sequence.
No AP preselected. Assuming that AP[0] is the AHB-AP
AP-IDR: 0x24770011, Type: AHB-AP
AHB-AP ROM: 0xE00FF000 (Base addr. of first ROM table)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS
ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU
ROMTbl[0][5]: E0041000, CID: B105900D, PID: 000BB925 ETM
Cortex-M4 identified.
J-Link>loadbin ./nuttx.bin 0
Downloading file [./nuttx.bin]...
Writing target memory failed.

Fortunately the “erase” command worked:

J-Link>erase
Erasing device (XMC4500-1024)...
Comparing flash   [100%] Done.
Erasing flash     [100%] Done.
Verifying flash   [100%] Done.
J-Link: Flash download: Total time needed: 22.650s (Prepare: 0.041s, Compare: 0.000s, Erase: 22.604s, Program: 0.000s, Verify: 0.000s, Restore: 0.004s)
Erasing done.

But even after the flash erase the programming is not working:

J-Link>loadbin ./nuttx.bin 0
Downloading file [./nuttx.bin]...
Writing target memory failed.
J-Link>

Then I decided to try OpenOCD again:

$ sudo openocd -f board/xmc4500-relax.cfg
Open On-Chip Debugger 0.10.0+dev-00172-g7719e96 (2017-11-12-09:13)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4000 kHz
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : No device selected, using first device.
Info : J-Link Lite-XMC4000 Rev.1 compiled Apr  2 2015 18:25:20
Info : Hardware version: 1.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : xmc4500.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting 'telnet' connection on tcp/4444

And using telnet I tried to send the reset command:

$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> reset halt
timed out while waiting for target halted
TARGET: xmc4500.cpu - Not halted
in procedure 'reset' 
in procedure 'ocd_bouncer'


Halt timed out, wake up GDB.
> 

At this moment I thought my board could be damaged, but I decided to try to flash it anyway:

> flash write_image erase nuttx.bin 0x0c000000
auto erase enabled
Cannot communicate... target not halted.
auto_probe failed

Hmm, let to test only “halt” instead of “reset halt” :

> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x41000000 pc: 0x000000e6 msp: 0x2000ff3c

Good, now let to try again:

> flash write_image erase nuttx.bin 0x0c000000
auto erase enabled
Clearing flash status
Clearing flash status
wrote 81920 bytes from file nuttx.bin in 17.523651s (4.565 KiB/s)

Very good, my board is live again!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s