Other Parts Discussed in Thread: CC2541
This probably is very similar to this one:

but with a few additional gotchyas.
Our product has a few external controls on it (buttons, for example) that can trigger an interrupt on Port1. If the interrupt happens when the device is asleep (PM2), the ISR runs and the device goes back to sleep until the sleep timer expires. Once the sleep timer expires (once a second), the device runs through its main loop, takes some measurements, and then advertises on all 3 BLE advertising channels using a proprietary radio packet.
Here's the problem: The advertising code (below) will sometimes hang up on the "while(!(RFIRQF1 & TASKDONE))" statement if the interrupt was fired at some point during the last sleep cycle. We advertise on 37-38-39 in that order, and it can hang up after advertising on any of them. The channel does not matter.
If the interrupt did not fire, then it will not hang on "while(!(RFIRQF1 & TASKDONE))". If the interrupt did fire, then it might hang on the last statement. If it does hang, it always hangs on the last statement.
We do have the fix (set LLECTRL to 0 before going to sleep) in place, and this problem still pops up.
void advertise(uint8 channel_number)
{
set_channel(channel_number);
// Clear the interrupt flags
S1CON = 0;
RFERRF = 0;
RFIRQF0 = 0;
RFIRQF1 = 0;
radio_lle_command(CMD_TX);
// Wait for the radio to finish
while (!(RFIRQF1 & TXDONE) && !(RFIRQF1 & TASKDONE))
;
// Clear the interrupt flag
RFIRQF1 = 0;
// Reuse the FIFO
radio_lle_command(CMD_TXFIFO_RETRY);
// Wait for the radio to finish
while (!(RFIRQF1 & TASKDONE))
;
}