void os_tick_idle(os_time_t ticks) { uint32_t ocmp; OS_ASSERT_CRITICAL(); if (ticks > 0) { /* * Enter tickless regime during long idle durations. */ if (ticks > g_hal_os_tick.max_idle_ticks) { ticks = g_hal_os_tick.max_idle_ticks; } ocmp = g_hal_os_tick.lastocmp + (ticks*g_hal_os_tick.ticks_per_ostick); nrf52_os_tick_set_ocmp(ocmp); } __DSB(); __WFI(); if (ticks > 0) { /* * Update OS time before anything else when coming out of * the tickless regime. */ nrf52_timer_handler(); } }
static inline void nrf52_os_tick_set_ocmp(uint32_t ocmp) { int delta; uint32_t counter; OS_ASSERT_CRITICAL(); while (1) { ocmp &= 0xffffff; OS_TICK_TIMER->CC[OS_TICK_CMPREG] = ocmp; counter = nrf52_os_tick_counter(); /* * From nRF52 Product specification * * - If Counter is 'N' writing (N) or (N + 1) to CC register * may not trigger a compare event. * * - If Counter is 'N' writing (N + 2) to CC register is guaranteed * to trigger a compare event at 'N + 2'. */ delta = sub24(ocmp, counter); if (delta > 2) { break; } ocmp += g_hal_os_tick.ticks_per_ostick; } }
void os_tick_idle(os_time_t ticks) { OS_ASSERT_CRITICAL(); __DSB(); __WFI(); }
static void apollo2_os_tick_set_timer(int os_ticks) { uint32_t sys_ticks; uint32_t cfg; OS_ASSERT_CRITICAL(); sys_ticks = os_ticks * apollo2_os_tick_dur; /* Freeze time, set timer expiry, then unfreeze time. */ cfg = am_hal_stimer_config(AM_HAL_STIMER_CFG_FREEZE); am_hal_stimer_compare_delta_set(0, sys_ticks); am_hal_stimer_config(cfg); }
static inline uint32_t nrf52_os_tick_counter(void) { /* * Make sure we are not interrupted between invoking the capture task * and reading the value. */ OS_ASSERT_CRITICAL(); #if defined(BSP_HAS_32768_XTAL) return OS_TICK_TIMER->COUNTER; #else /* * Capture the current timer value and return it. */ OS_TICK_TIMER->TASKS_CAPTURE[OS_TICK_COUNTER] = 1; return (OS_TICK_TIMER->CC[OS_TICK_COUNTER]); #endif }
void os_tick_idle(os_time_t ticks) { OS_ASSERT_CRITICAL(); /* Since the STIMER only uses relative scheduling, all ticks values are * valid. There is no need to check for wrap around. */ /* Only set the timer for nonzero tick values. For values of 0, just let * the timer expire on the next tick, as scheduled earlier. */ if (ticks > 0) { apollo2_os_tick_set_timer(ticks); } __DSB(); __WFI(); if (ticks > 0) { apollo2_os_tick_handler(); } }