|
22 | 22 |
|
23 | 23 | #include "rtos/rtos_idle.h"
|
24 | 24 | #include "platform/mbed_sleep.h"
|
| 25 | +#include "mbed_critical.h" |
| 26 | +#include "hal/ticker_api.h" |
| 27 | +#include "hal/lp_ticker_api.h" |
| 28 | +#include "cmsis_os2.h" |
| 29 | +#include <limits.h> |
| 30 | + |
| 31 | +static ticker_event_t idle_loop_event; |
| 32 | + |
| 33 | +void idle_loop_handler(uint32_t id) |
| 34 | +{ |
| 35 | + (void)id; |
| 36 | +} |
25 | 37 |
|
26 | 38 | static void default_idle_hook(void)
|
27 | 39 | {
|
28 |
| - /* Sleep: ideally, we should put the chip to sleep. |
29 |
| - Unfortunately, this usually requires disconnecting the interface chip (debugger). |
30 |
| - This can be done, but it would break the local file system. |
31 |
| - */ |
| 40 | +#if DEVICE_LOWPOWERTIMER |
| 41 | + uint32_t tick_freq = osKernelGetTickFreq(); |
| 42 | + timestamp_t time_in_sleep = 0UL; |
| 43 | + |
| 44 | + uint32_t ticks_to_sleep = osKernelSuspend(); |
| 45 | + if (ticks_to_sleep) { |
| 46 | + core_util_critical_section_enter(); |
| 47 | + uint64_t us_to_sleep = ticks_to_sleep * tick_freq; |
| 48 | + // Calculate the maximum period we can sleep and stay within |
| 49 | + uint64_t max_us_sleep = (UINT_MAX / tick_freq) * tick_freq; |
| 50 | + if (us_to_sleep > max_us_sleep) { |
| 51 | + us_to_sleep = max_us_sleep; |
| 52 | + } |
| 53 | + |
| 54 | + const ticker_data_t *lp_ticker_data = get_lp_ticker_data(); |
| 55 | + ticker_remove_event(lp_ticker_data, &idle_loop_event); |
| 56 | + ticker_set_handler(lp_ticker_data, &idle_loop_handler); |
| 57 | + timestamp_t start_time = lp_ticker_read(); |
| 58 | + ticker_insert_event_us(lp_ticker_data, &idle_loop_event, us_to_sleep, (uint32_t)&idle_loop_event); |
| 59 | + |
| 60 | + sleep(); |
| 61 | + core_util_critical_section_exit(); |
| 62 | + // calculate how long we slept |
| 63 | + time_in_sleep = lp_ticker_read() - start_time; |
| 64 | + } |
| 65 | + osKernelResume(time_in_sleep / tick_freq); |
| 66 | +#else |
32 | 67 | sleep();
|
| 68 | +#endif |
33 | 69 | }
|
34 | 70 | static void (*idle_hook_fptr)(void) = &default_idle_hook;
|
35 | 71 |
|
|
0 commit comments