I am (also) not quite clear on what "hang" means precisely. But there do seem to be some holes in this logic: 1) The function takes care to maintain the GIE, presumably because it may be called with GIE either 0 or 1. However, if it is called with GIE=0, Pause() will run with GIE=0; if Pause() is an LPM call the CPU will be stuck forever. I suspect you want to unconditionally set GIE=1 before Pause() [but see below]. 2) Separating the GIE setting from the LPM setting introduces a race. If you imagine a one-time-ever wakeup interrupt that occurs between the two steps, it will result in sleeping forever. If you imagine the (more common) case where you have a periodic wakeup interrupt, you will miss one "beat", which may not be immediately noticeable but will subtly throw your timing off. This is why you see the idiom: __bis_SR_register(LPM0_bits+GIE). I wonder if this code was written with the AVR ["sleep" can be turned into a no-op] or an x86 [sleep implicitly sets GIE] in mind.
↧