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...)
Anyway, your IC most definitely has such a bootloader; you should be able to use it to load new firmware onto your device. Read the MAX32660 Bootloader User Guide (UG6471).
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.
PyOCD
:set nreset 0
(and leave interactive window open), remove jumper, and inPyOCD
:reset halt
(and closePyOCD
), and finally inopenocd
: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. \$\endgroup\$