lpcware

Bug: Chip_RGU_TriggerReset starts M0 core

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by dstahlke on Mon Oct 05 22:26:54 MST 2015
I was experiencing an odd crash which, after a half day of debugging, I traced to the Chip_RGU_TriggerReset function.  I'm linking against an older version of LPCOpen, but it looks like 2.16 would have the same issue.  The function itself is quite simple, at least in 2.16:


STATIC INLINE void Chip_RGU_TriggerReset(CHIP_RGU_RST_T ResetNumber)
{
LPC_RGU->RESET_CTRL[ResetNumber >> 5] = 1 << (ResetNumber & 31);
/* Reset will auto clear after 1 clock cycle */
}

Herein lies an insidious bug.  Writing zero to bit 24 of LPC_RGU->RESET_CTRL[1] will start the M0 core.  If you're not expecting that, and haven't set things up properly, M0 will start running random code, leading to unpredictable consequences.

There is a simple workaround:


if((ResetNumber >> 5) == 1) {
LPC_RGU->RESET_CTRL[1] = (1 << (ResetNumber & 31)) | (1 << 24);
} else {
LPC_RGU->RESET_CTRL[ResetNumber >> 5] = 1 << (ResetNumber & 31);
}

... but this assumes you don't want M0 running.  In general, I suppose you could set only bit (ResetNumber & 31) by using the bit-band memory.

It should be noted (if only for the benefit of people debugging via Google) that Chip_RGU_TriggerReset is called by Chip_HSADC_Init and Chip_ENET_Init, so those functions could also lead to a crash.

Outcomes