Unbrick MAX32660 that is programmed to drive SWD pin?

I thought I was being clever by remapping my UART output to the SWD output pin. I'm not a fan of debuggers (they don't scale). I assumed I could just reprogram my MAX32660 by holding it in reset, such as one does with AVRs for example.

Well it turns out that neither OpenOCD nor PyOCD wants to talk to the MAX32660 while it's in reset. For example, PyOCD says "Device state is Reset". I can't even halt the device.

It's hard to believe that there is no way to get the SWD function back. But in this thread about another Arm that (similarly to the MAX32660) can reassign the SWD pins, they claim that the device can only be reprogrammed if there is sufficient delay between the start of reset vector code and the time that it reassigns the SWD pins.

I am using a MAX32660 EVSYS to program the part. Can this programmer (which only supports SWD) unbrick the part? Could a JTAG programmer unbrick the part?

• If you have the debugger setup to drive the hardware reset a command such as "reset halt" may do it. Then you erase the offending flash. This works on ST not sure about your part but it is likely as the debug functionality comes from ARM, it is the flash part that is vendor. Beware the debugger may not be driving the hardware reset when you think it is... Try a scope without any target connected to verify. Also see if the vendor flash loader tool has any special modes, ST's has a "connect under reset" in an options menu. – Chris Stratton Jul 1 '20 at 12:13
• @Chris. Brilliant! I was able to erase the flash through the following sequence: ground the reset pin using jumper, then in PyOCD: set nreset 0 (and leave interactive window open), remove jumper, and in PyOCD: reset halt (and close PyOCD), and finally in openocd: flash erase_address 0 0x40000. Not sure why I couldn't do it all in one program, but hopefully I don't make this same mistake too often. Thank you. – personal_cloud Jul 1 '20 at 18:55
• Lots of configurations default to doing a soft reset of the target, it can take some real persistence to get a hardware reset happening, and test equipment to verify that it truly is. Also there are some cheap SWD dongles on the market where the hardware reset header is simply not connected where the dongle firmware thinks it is... – Chris Stratton Jul 1 '20 at 18:58

I assumed I could just reprogram my MAX32660 by holding it in reset, such as one does with AVRs for example.

yeah, no. What the reset pin means and what a programming mode is depends on what the manufacturer designs it to be!

Since modern ARM MCUs tend to be much, much nicer than AVRs ever where, many of them have a boot pin with which you can select a bootloader to be started and wait for commands on e.g. UART and USB (!). That bootloader can then only be disabled by the engineer by writing to a specific address in flash.

This is a very common method to program in production. Another very common method is indeed using SWD and loading firmware that, like yours, simply disables SWD if you don't want people to have a debug interface. (I don't think "debuggers don't scale" is a true statement hence. In fact, SWD is a pretty nice thing and allows for a lot of in-system programmability, eg. when you want to update the firmware of your power controller on your PC/laptop mainboard. This scales to a couple million units...)

device can only be reprogrammed if there is sufficient delay between the start of reset vector code and the time that it reassigns the SWD pins.

Exactly. The trick they do is: set up a debugger to continously try to debug, and then release the reset. There's no guarantee this works on the first try, so you might need to try multiple times.

You could try releasing the reset pin and immediately clocking the SWD clock.

If that doesn't work on the first try, variate the timing between these two.

Do that as often as it takes before it works. Might take a couple thousand tries until random variations make that work.

Or, you could use an external clock instead of a crystal oscillator to clock the core, and simply stop clocking it after clocking one clock cycle after releasing reset, then try to do SWD; if that doesn't work, try two clock cycles, and so on.

Neither is something an eval board does out of the box. You'd want something like an FPGA board and have to write extensive gateware or use e.g. Scanlime's existing glitching framework.

• This might work, but Chris's solution (to use a form of the halt command that works while reset is asserted) was much easier. SWD scales to millions of units, yes. But if I already have another form of connectivity, I can use that for firmware updates. My statement was that debuggers don't scale, which is true (try debugging anything involving network protocols without tcpdump or some other form of high-throughput logging). – personal_cloud Sep 7 '20 at 20:27
• @personal_cloud that's still not true. – Marcus Müller Sep 7 '20 at 20:29

Chris's solution (first comment) worked for me.

If you have the debugger setup to drive the hardware reset a command such as "reset halt" may do it. Then you erase the offending flash. This works on ST not sure about your part but it is likely as the debug functionality comes from ARM, it is the flash part that is vendor. Beware the debugger may not be driving the hardware reset when you think it is... Try a scope without any target connected to verify. Also see if the vendor flash loader tool has any special modes, ST's has a "connect under reset" in an options menu.