예제 #1
1
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);		
	}
	
}