예제 #1
0
파일: debugcmds.c 프로젝트: N7QWT/klipper
void
command_start_group(uint32_t *args)
{
    sched_del_timer(&group_timer);
    group_timer.func = group_end_event;
    group_timer.waketime = args[0];
    sched_add_timer(&group_timer);
}
예제 #2
0
파일: main.c 프로젝트: texane/dibal
static void object_avoider_next(object_avoider_state_t* oas)
{
  if (oas->timer == NULL)
    {
      /* rotate one quadran (freq ~= 2) */

      is_rotate_done = 0;
      move_rotate_left();
      oas->timer = sched_add_timer(2, on_rotate_timer, 1);
    }
  else if (is_rotate_done)
    {
      object_avoider_stop(oas);
    }
}
예제 #3
0
// Schedule a set of steps with a given timing
void
command_queue_step(uint32_t *args)
{
    struct stepper *s = stepper_oid_lookup(args[0]);
    struct stepper_move *m = move_alloc();
    m->interval = args[1];
    m->count = args[2];
    if (!m->count)
        shutdown("Invalid count parameter");
    m->add = args[3];
    m->next = NULL;
    m->flags = 0;

    irq_disable();
    uint8_t flags = s->flags;
    if (!!(flags & SF_LAST_DIR) != !!(flags & SF_NEXT_DIR)) {
        flags ^= SF_LAST_DIR;
        m->flags |= MF_DIR;
    }
    flags &= ~SF_NO_NEXT_CHECK;
    if (m->count == 1 && (m->flags || flags & SF_LAST_RESET))
        // count=1 moves after a reset or dir change can have small intervals
        flags |= SF_NO_NEXT_CHECK;
    s->flags = flags & ~SF_LAST_RESET;
    if (s->count) {
        if (s->first)
            *s->plast = m;
        else
            s->first = m;
        s->plast = &m->next;
    } else if (flags & SF_NEED_RESET) {
        move_free(m);
    } else {
        s->first = m;
        stepper_load_next(s, s->next_step_time + m->interval);
        sched_add_timer(&s->time);
    }
    irq_enable();
}
예제 #4
0
파일: main.c 프로젝트: texane/dibal
void main(void)
{
  sched_timer_t* light_timer;
  sched_timer_t* dist_timer;

  unsigned char is_light_disabled;
  unsigned char is_dist_disabled;

  osc_setup();
  int_setup();

  srf04_setup();
  sched_setup();

  behavior_setup();

  /* sensor timers */

  light_timer = sched_add_timer(2, on_light_timer, 1);
  is_light_disabled = 0;

  dist_timer = sched_add_timer(2, on_distance_timer, 1);
  is_dist_disabled = 0;

  /* default behaviour */

  behavior_start(BEHAVIOR_ID_LAND_EXPLORER);

  /* main loop */

  sched_enable();

  while (1)
    {
      /* sensors. order matters so that object
	 avoider takes priority over light tracker.
	 this can be removed as soon as behavior
	 priority is implemented.
       */

      if (TIMER_MAP_ISSET(DISTANCE))
	{
	  {
#define MIN_DISTANCE_VALUE 0x0a00 /* 20 cms */
	    unsigned int dist = srf04_get_distance(MIN_DISTANCE_VALUE);

	    if (dist <= MIN_DISTANCE_VALUE)
	      {
		if (behavior_switch(BEHAVIOR_ID_OBJECT_AVOIDER) != -1)
		  {
		    sched_disable_timer(dist_timer);
		    is_dist_disabled = 1;
		  }
	      }
	  }

	  /* clear after the timer may have been disabled */

	  TIMER_MAP_CLEAR(DISTANCE);
	}

      if (TIMER_MAP_ISSET(LIGHT))
	{
	  {
	    unsigned short light = adc_read(LIGHT_ADC_CHANNEL);

	    if ((light <= ADC_QUANTIZE_5_10(2.35)) || (light >= ADC_QUANTIZE_5_10(2.65)))
	      {
		if (behavior_switch(BEHAVIOR_ID_LIGHT_TRACKER) != -1)
		  {
		    sched_disable_timer(light_timer);
		    is_light_disabled = 1;
		  }
	      }
	  }

	  TIMER_MAP_CLEAR(LIGHT);
	}

      /* schedule behavior */

      behavior_next();

      if (behavior_is_done())
	{
	  /* reenable timer */

	  if (is_light_disabled)
	    {
	      sched_enable_timer(light_timer);
	      is_light_disabled = 0;
	    }

	  if (is_dist_disabled)
	    {
	      sched_enable_timer(dist_timer);
	      is_dist_disabled = 0;
	    }

	  /* switch to default behavior */

	  behavior_switch(BEHAVIOR_ID_DEFAULT);
	}
    }
}
예제 #5
0
파일: main.c 프로젝트: texane/dibal
static void light_tracker_next(light_tracker_state_t* lts)
{
  switch (lts->state)
    {
    case LIGHT_TRACKER_STATE_INIT:
      {
	lts->state = LIGHT_TRACKER_STATE_SENSE;

	/* fallthru */
      }

    case LIGHT_TRACKER_STATE_SENSE:
      {
	void (*rotate)(void);
	unsigned short cur_level;
	unsigned short cur_delta;

	cur_level = adc_read(LIGHT_ADC_CHANNEL);

	if (cur_level >= ADC_QUANTIZE_5_10(2.35))
	  if (cur_level <= ADC_QUANTIZE_5_10(2.65))
	    {
	      /* found, we are done */

	      lts->state = LIGHT_TRACKER_STATE_DONE;

	      break;
	    }

	if (cur_level >= ADC_QUANTIZE_5_10(2.5))
	  {
	    cur_delta = cur_level - ADC_QUANTIZE_5_10(2.5);
	    rotate = move_rotate_left;
	  }
	else
	  {
	    cur_delta = ADC_QUANTIZE_5_10(2.5) - cur_level;
	    rotate = move_rotate_right;
	  }

	if (lts->prev_delta < cur_delta)
	  {
	    /* diverging, we are done */

	    lts->state = LIGHT_TRACKER_STATE_DONE;

	    break;
	  }

	lts->prev_delta = cur_delta;
	lts->rem_delta = cur_delta;

	rotate();

	lts->timer = sched_add_timer(0, on_light_tracker_timer, 0);

	lts->state = LIGHT_TRACKER_STATE_ROTATE;

	break;
      }

    case LIGHT_TRACKER_STATE_ROTATE:
      {
	unsigned int tmp;

	if (!lts->rem_delta)
	  {
	    /* rotation done */

	    move_stop();

	    sched_del_timer(lts->timer);
	    lts->timer = NULL;

	    lts->state = LIGHT_TRACKER_STATE_SENSE;

	    break;
	  }

	tmp = delta_to_freq(lts->rem_delta);
	if (tmp > SCHED_MAX_FREQ)
	  tmp = SCHED_MAX_FREQ;

	sched_set_timer_freq(lts->timer, tmp);

	tmp = freq_to_delta(tmp);
	if (tmp > lts->rem_delta)
	  tmp = lts->rem_delta;

	lts->rem_delta -= tmp;

	lts->state = LIGHT_TRACKER_STATE_WAIT;
	is_rotation_done = 0;
	sched_enable_timer(lts->timer);

	break;
      }

    case LIGHT_TRACKER_STATE_WAIT:
      {
	/* wait for the rotation to finish */

	if (!is_rotation_done)
	  break;

	sched_disable_timer(lts->timer);

	lts->state = LIGHT_TRACKER_STATE_ROTATE;

	break;
      }

    case LIGHT_TRACKER_STATE_DONE:
    default:
      {
	light_tracker_stop(lts);

	break;
      }
    }
}