static void configure_next_event()
{
    //this function should only be called from an atomic context
	timer_tick_t next_fire_time;
    do
    {
		//find the next event that has not yet passed, and schedule
		//the 'late' events while we're at it
		NG(next_event) = get_next_event();

		if(NG(next_event) != NO_EVENT)
		{
			next_fire_time = NG(timers)[NG(next_event)].next_event;
			if ( (((int32_t)next_fire_time) - ((int32_t)timer_get_counter_value())) <= 0 )
			{
				sched_post_task_prio(NG(timers)[NG(next_event)].f, NG(timers)[NG(next_event)].priority);
				NG(timers)[NG(next_event)].f = 0x0;
			}
		}
    }
    while(NG(next_event) != NO_EVENT && ( (((int32_t)next_fire_time) - ((int32_t)timer_get_counter_value())) <= 0  ) );

    //at this point NG(next_event) is eiter equal to NO_EVENT (no tasks left)
    //or we have the next event we can schedule
    if(NG(next_event) == NO_EVENT)
    {
		//cancel the timer in case it is still running (can happen if we're called from timer_cancel_event)
		NG(hw_event_scheduled) = false;
		hw_timer_cancel(HW_TIMER_ID);
    }
    else
    {
		//calculate schedule time relative to current time rather than
		//latest overflow time, to counteract any delays in updating counter_offset
		//(eg when we're scheduling an event from an interrupt and thereby delaying
		//the updating of counter_offset)
    	timer_tick_t fire_delay = (next_fire_time - timer_get_counter_value());
		//if the timer should fire in less ticks than supported by the HW timer --> schedule it
		//(otherwise it is scheduled from timer_overflow when needed)
		if(fire_delay < COUNTER_OVERFLOW_INCREASE)
		{
			NG(hw_event_scheduled) = true;
			hw_timer_schedule_delay(HW_TIMER_ID, (hwtimer_tick_t)fire_delay);
#ifndef NDEBUG	    
			//check that we didn't try to schedule a timer in the past
			//normally this shouldn't happen but it IS theoretically possible...
			fire_delay = (next_fire_time - timer_get_counter_value());
			//fire_delay should be in [0,COUNTER_OVERFLOW_INCREASE]. if this is not the case, it is because timer_get_counter() is
			//now larger than next_fire_event, which means we 'missed' the event
			assert(((int32_t)fire_delay) > 0);
#endif
		}
		else
		{
			//set hw_event_scheduled explicitly to false to allow timer_overflow
			//to schedule the event when needed
			NG(hw_event_scheduled) = false;
		}
    }
}
static void timer_fired()
{
    assert(NG(next_event) != NO_EVENT);
    assert(NG(timers)[NG(next_event)].f != 0x0);
    sched_post_task_prio(NG(timers)[NG(next_event)].f, NG(timers)[NG(next_event)].priority);
    NG(timers)[NG(next_event)].f = 0x0;
    configure_next_event();
}
Ejemplo n.º 3
0
void packet_received(hw_radio_packet_t* hw_radio_packet)
{
    assert(dll_state == DLL_STATE_FOREGROUND_SCAN || dll_state == DLL_STATE_SCAN_AUTOMATION);

    // we are in interrupt context here, so mark packet for further processing,
    // schedule it and return
    DPRINT("packet received @ %i , RSSI = %i", hw_radio_packet->rx_meta.timestamp, hw_radio_packet->rx_meta.rssi);
    packet_queue_mark_received(hw_radio_packet);

    packet_t* packet = packet_queue_find_packet(hw_radio_packet);

    /* the received packet needs to be handled in priority */
    sched_post_task_prio(&process_received_packets, MAX_PRIORITY);
}
static void rx_cb(uint8_t byte) {
  fifo_put_byte(&rx_fifo, byte);
  if(!sched_is_scheduled(&process_rx_fifo))
    sched_post_task_prio(&process_rx_fifo, MAX_PRIORITY, NULL);
}