Correctly detect and handle the low power run mode when entering and exiting sleep mode.
The generic `hal_sleep` implementation tries to exit LPR mode always, resulting in a spin-loop during a critical section (disabled IRQ).
The new approach returns from LPR to Run mode if enabled (LPR bit set), enters sleep, and resets to the original state on wakeup (WFI).
Replace wait_us with nu_busy_wait_us in lp_ticker since wait_us is not allowed in sleep test
which would suspend us ticker layer on which wait_us relies. nu_busy_wait_us is implemented
by calling us ticker HAL API directly rather than relying on us ticker layer.
There are scenarios where putc is called within a critical section, e.g
to log ASSERTs in early initialization code. The interrupts being
disabled here prevents the handlers for the UARTE from executing.
This breaks the tx_in_progress flag based approach. The tx_in_progress
never gets reset. Poll on the TXDRDY instead.
It can be recreated with a simple program as shown here:
*************** Current Behavior ****************
++ MbedOS Error Info ++
Error Status: 0x80FF0100 Code: 256 Module: 255
Error Message: F
************** With Fix *************************
++ MbedOS Error Info ++
Error Status: 0x80FF0100 Code: 256 Module: 255
Error Message: Fatal Run-time error
Location: 0x2C0A9
Error Value: 0x0
Current Thread: Id: 0x20005520 Entry: 0x30EBF StackSize: 0x1000 StackMem: 0x20004520 SP: 0x20005490
For more info, visit: https://armmbed.github.io/mbedos-error/?error=0x80FF0100
-- MbedOS Error Info --
nrf failure at .\main.cpp:22
***************************************************
For both implementation, RTC and LPTIM, there is some delay in the
set_interrupt function due to HW constraints.
Value has been set to 4 for STM32L0,
because SystemClock is slower than other families.
When both tickless and LPTICKER_DELAY_TICKS are enabled some ST
devices randomly get stuck sleeping forever. This is because the
wake up time passed to the rtc is ignored if the previous match is
about to occur. This causes the device to get stuck in sleep.
This patch prevents matches from getting dropped by the rtc by
deactivating the rtc wake up timer before setting a new value.
Events leading up to this failure for the RTC:
-1st call to lp_ticker_set_interrupt
-delay until ticker interrupt is about to fire
-2nd call to lp_ticker_set_interrupt
-interrupt for 1st call fires and match time for 2nd call is dropped
-LowPowerTickerWrapper gets ticker interrupt but treats it as a
spurious interrupt and drops it since it comes in too early
-device enters sleep without a wakeup source and locks up