void nrf_pwr_mgmt_run(void) { #if NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED /* * Clear FPU exceptions. * Without this step, the FPU interrupt is marked as pending, * preventing system from sleeping. */ uint32_t fpscr = __get_FPSCR(); __set_FPSCR(fpscr & ~0x9Fu); __DMB(); NVIC_ClearPendingIRQ(FPU_IRQn); // Assert if a critical FPU exception is signaled. ASSERT((fpscr & 0x03) == 0); #endif // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED SLEEP_LOCK(); #if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED uint32_t sleep_start; uint32_t sleep_end; uint32_t sleep_duration; sleep_start = app_timer_cnt_get(); #endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED DEBUG_PIN_SET(); // Wait for an event. #ifdef SOFTDEVICE_PRESENT ret_code_t ret_code = sd_app_evt_wait(); if (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED) { __WFE(); __SEV(); __WFE(); } else { APP_ERROR_CHECK(ret_code); } #else __WFE(); __SEV(); __WFE(); #endif // SOFTDEVICE_PRESENT DEBUG_PIN_CLEAR(); #if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED sleep_end = app_timer_cnt_get(); UNUSED_VARIABLE(app_timer_cnt_diff_compute(sleep_end, sleep_start, &sleep_duration)); m_ticks_sleeping += sleep_duration; #endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED SLEEP_RELEASE(); }
__INLINE void ctrl_signal_handler(uint8_t sig) { switch (sig) { case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START: DEBUG_PIN_POKE(3); adv_evt_setup(); sm_enter_adv_send(); break; case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO: { DEBUG_PIN_POKE(0); /* check state, and act accordingly */ switch (sm_state) { case STATE_ADV_SEND: if (RADIO_EVENT(EVENTS_DISABLED)) { DEBUG_PIN_POKE(12); DEBUG_PIN_POKE(13); sm_exit_adv_send(); #if TS_SEND_SCAN_RSP sm_enter_scan_req_rsp(); #else sm_enter_wait_for_idle(false); #endif } break; case STATE_SCAN_REQ_RSP: if (RADIO_EVENT(EVENTS_DISABLED)) { DEBUG_PIN_POKE(12); DEBUG_PIN_POKE(14); sm_exit_scan_req_rsp(); sm_enter_wait_for_idle(is_scan_req_for_me()); } break; case STATE_WAIT_FOR_IDLE: if (RADIO_EVENT(EVENTS_DISABLED)) { DEBUG_PIN_POKE(12); DEBUG_PIN_POKE(15); /* state exit function returns whether the adv event is complete */ bool adv_evt_done = sm_exit_wait_for_idle(); if (adv_evt_done) { next_timeslot_schedule(); } else { sm_enter_adv_send(); } } break; default: /* Shouldn't happen */ ASSERT(false); } } break; case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0: DEBUG_PIN_POKE(5); sm_exit_scan_req_rsp(); /* go to wait for idle, no packet was accepted */ sm_enter_wait_for_idle(false); PERIPHERAL_TASK_TRIGGER(NRF_RADIO->TASKS_DISABLE); break; default: /* shouldn't happen in this advertiser. */ DEBUG_PIN_SET(LED_0); DEBUG_PIN_POKE(13); DEBUG_PIN_POKE(14); } }