As noted in the last log, I'd seen some on-again, off-again woes in the ST official core for Arduino. I thought they'd been transient, the result of the mismatch of cores and core-specific hacks in Marlin's code, there's a general rule I should have remembered:
If you don't know how you fixed it or why it was broken, it isn't fixed, only hiding.
And sure enough, a few rebuilds later, the behavior manifested again, as though I wasn't feeding the watchdog.
So I did what any good programmer would do, and put watchdog statements in my code and looked for them. Look, I'm feeding the watchdog.
I tested running the temperature ISRs directly from the main() loop.
Then, I stumbled on a key. The behavior only manifested once Marlin had sampled the temperatures enough to average them.
This behavior manifested on a bluepill as well as the M200 mainboard, so I stuck with the bluepill, using gdb to debug, and there I began to unravel a call that made no sense. No matter how often I broke in, the core seemed to be answering an interrupt for timer 4.
No problem, that's the stepper timer, and it runs quite often.
But with GDB, I noted that nothing was getting dispatched, as if my ISR had gotten lost. I stepped back and put a breakpoint on timer initialization, hit the reset button.
Both my ISRs got registered as expected. Perhaps some sort of memory corruption?
But on a whim, I left it running, and a moment later, I hit an unexpected init.
It turns out that ST's official core uses hardware PWM for EVERYTHING. STM32GENERIC uses a single timer for all pwmWrite (analogWrite) calls. Maple uses a mix of hardware and software PWM.
And in ST's official datasheet, the different pins the mini uses for fans and heaters (the two PWM entities) are mapped to timers 2 and 4.
For now, the answer is to shift timers to 1 and 3. 1's the right value for the stepper timer, because it holds a larger (32 bit) value, which is important when we want to run very slowly.
Long term, I'll either need to request (or write and generate a PR) a simpler PWM implementation which doesn't consume every timer on the board.
But with that change, my M200 mainboard remains running. I can print using the LCD...sort of.
We need USB support (coming in 1.5 of ST's official core) before this can be usable by the world, but we're getting there.