Joe, I suggest you drop an anvil on it or perhaps set it on fire. No more hard faults.
Seriously though I think you are left with two paths.
Dissect the hard fault in detail using the link I posted earlier. That might help you reconstruct how you got to the hard fault.
Continue changing stimulus to narrow down the cause. You might try changing the parser to dump the zero byte or perhaps change a good byte into a zero byte just to see what happens. Or maybe don’t initialize the USART until after the break but manually insert a zero byte into the RX queue. Or any other ideas you might come up with to divide and conquer. If you have a suspect (like the break for example) then attack that.
(3. Use a full trace system but I’m guessing you don’t have that.)
Another suspect would be DMA of any kind. Accidentally leaving a DMA enabled, or configuring a DMA to write to a buffer stored on the stack, or any other number of mistakes with DMA, can lead to this kind of memory corruption. Might be a good idea to temporarily eliminate all uses of DMA.
Can you clarify one thing? When you said this:
Did you mean two separate guards – one during function entry and one during function exit? Or did you mean you simply disabled the interrupt, called the function which then executed with the interrupt disabled, and then enabled the interrupt again after the function returned? I’m starting to think you meant the latter.
I will post what I have seen in the hardfaults. When I reconstruct the circumstances, I do not see the cause of the hardfault but what appears to be normal operation. Perhaps I am missing something.
Oddly, the zero byte is there so long as the RX line is low. But the fault will not occur unless I allow the line to go high again. So some part of the UART machinery is implicated.
Trace lines are taken by the application, sadly. It would be interesting if I could repeat this hardfault on a discovery board. Then trace would become available. Hmm…
DMA. That is a good test. I’ll try it.
Clarification:
Yes. I did both. Both work without a hardfault. One disables the GPTimer NVIC before and after the CalcAuth() function call