Ejemplo n.º 1
0
/*
 * On success return number of bytes sent
 */
int tty_write_timeout(const unsigned char *buf, size_t size, int timeout)
{
	time_t timer;
	int rc, pos = 0;
	
	DEB((D_TTYIO, "tty_write_timeout: want write %d byte(s), timeout = %d", size, timeout));
	
	tty_status = TTY_SUCCESS;
	timer_set(&timer, timeout);
	
	while( pos < size )
	{
		if( timer_expired(timer) )
		{
			break;
		}
		else if( (rc = tty_write(buf + pos, size - pos)) < 0 )
		{
			if( rc == TTY_TIMEOUT )
				usleep(10000);	/* 0.01 sec */
			else
				return rc;
		}
		else /* ( rc > 0 ) */
		{
			DEB((D_TTYIO, "tty_write_timeout: written %d byte(s)", rc));
			pos += rc;
		}
	}
	
	return (pos > 0) ? pos : TTY_TIMEOUT;
}
Ejemplo n.º 2
0
PROCESS_THREAD(ir_receiver_process, ev, data) {

    PROCESS_BEGIN();

    while(1) {
        PROCESS_WAIT_EVENT();

        if(ev == PROCESS_EVENT_POLL) {
            if(ir_repeat) {
                PRINTF("Got repeat signal \n");
                ir_repeat = 0;
            } else {
                if(*(int32_t*)ir_prev_data != *(int32_t*)ir_last_data || timer_expired(&ir_rep_timer) || to_be_repeated()) {
                    memcpy(ir_prev_data, ir_last_data, 4);
                    timer_restart(&ir_rep_timer);
                    PRINTF("Got new command %d,%d,%d,%d!\n", ir_last_data[0],ir_last_data[1],ir_last_data[2],ir_last_data[3]);
                    broadcast_value(30);
                } else {
                    timer_restart(&ir_rep_timer);
                }
            }
        }
    }

    PROCESS_END();
}
Ejemplo n.º 3
0
/*---------------------------------------------------------------------------*/
static void
weather_meter_interrupt_handler(uint8_t port, uint8_t pin)
{
  uint32_t aux;

  /* Prevent bounce events */
  if(!timer_expired(&debouncetimer)) {
    return;
  }

  timer_set(&debouncetimer, DEBOUNCE_DURATION);

  /* We make a process_post() to check in the pollhandler any specific threshold
   * value
   */

  if((port == ANEMOMETER_SENSOR_PORT) && (pin == ANEMOMETER_SENSOR_PIN)) {
    weather_sensors.anemometer.ticks++;
    process_post(&weather_meter_int_process, anemometer_int_event, NULL);
  } else if((port == RAIN_GAUGE_SENSOR_PORT) && (pin == RAIN_GAUGE_SENSOR_PIN)) {
    weather_sensors.rain_gauge.ticks++;
    aux = weather_sensors.rain_gauge.ticks * WEATHER_METER_AUX_RAIN_MM;
    aux /= 1000;
    weather_sensors.rain_gauge.value = (uint16_t)aux;
    process_post(&weather_meter_int_process, rain_gauge_int_event, NULL);
  }
}
Ejemplo n.º 4
0
void SerialIPStack::tick()
{
	uip_len = slipdev_poll();
	if(uip_len > 0) {
		uip_input();
		// If the above function invocation resulted in data that
		// should be sent out on the network, the global variable
		// uip_len is set to a value > 0.
		if (uip_len > 0) slipdev_send();

	} else if (timer_expired(&periodic_timer)) {
		timer_reset(&periodic_timer);
		for (int i = 0; i < UIP_CONNS; i++) {
			uip_periodic(i);
			// If the above function invocation resulted in data that
			// should be sent out on the network, the global variable
			// uip_len is set to a value > 0.
			if (uip_len > 0) slipdev_send();
		}

#if UIP_UDP
		for (int i = 0; i < UIP_UDP_CONNS; i++) {
			uip_udp_periodic(i);
			// If the above function invocation resulted in data that
			// should be sent out on the network, the global variable
			// uip_len is set to a value > 0. */
			if (uip_len > 0) slipdev_send();
		}
#endif /* UIP_UDP */
	}
}
Ejemplo n.º 5
0
/*---------------------------------------------------------------------------*/
static int
user_button_value(int type)
{
  return (GPIO_READ_PIN(USER_BUTTON_PORT_BASE,
                        USER_BUTTON_PIN_MASK) == 0) ||
    !timer_expired(&debouncetimer);
}
Ejemplo n.º 6
0
static void igmp_group_periodic(igmp_group_state_t *s)
{
  switch (s->state)
    {
    case NON_MEMBER:
    case IDLE_MEMBER:
      break;
    case PENDING_JOIN:      
      send_membership_report(s);
      s->flag = 1;
      s->state = DELAYED_MEMBER;
      timer_set(&s->timer, UNSOLICITED_REPORT_INTERVAL * CLOCK_SECOND);
      break;
    case DELAYED_MEMBER:
      if (timer_expired(&s->timer))  {
        send_membership_report(s);
        s->flag = 1;
        s->state = IDLE_MEMBER;
      }
      break;
    case PENDING_LEAVE:
      if (s->flag)
        send_leave_group(s);
      s->state = NON_MEMBER;
      break;
    }  
  return;
}
Ejemplo n.º 7
0
void music_bars()
{
    unsigned int eq_buffer[14];
    int i;
    
    // Run this for 10 seconds
    set_timer(10000);
    
    while(!timer_expired())
    {
        EQ_Read(eq_buffer);
        fill(0x00);
        // Basen längst bak
        box_filled(7, 0, 0, 6, 3, (eq_buffer[0] / 128));
        box_filled(7, 4, 0, 6, 7, (eq_buffer[7] / 128));
        
        for(i = 1; i < 7; i++)
        {
            if(i % 2 == 1)
            {
                box_filled((7 - i), 0, 0, (6 - i), 1, (eq_buffer[i] / 128));
                box_filled((7 - i), 6, 0, (6 - i), 7, (eq_buffer[i + 7] / 128));
            }
            else
            {
                box_filled((7 - i), 2, 0, (6 - i), 3, (eq_buffer[i] / 128));
                box_filled((7 - i), 4, 0, (6 - i), 5, (eq_buffer[i + 7] / 128));

            }
        }
    }
}
Ejemplo n.º 8
0
//PROCESS_THREAD(etimer_process, ev, data)
void
etimer_poll()
{
  struct etimer *t, *u;
  //etimer_cb p;

again:
  u = NULL;
  for(t = timerlist; t != NULL; t = t->next) {
      if(timer_expired(&t->timer)) {
	      //p = t->p;
	      //t->p = NULL;
          if (u != NULL) {
              u->next = t->next;
          } else {
              timerlist = t->next;
          }
          t->next = NULL;
          update_time();
          //if (p != NULL)
          t->p(EVENT_TIMER, t);
          goto again;
      }
      u = t;
  }
}
Ejemplo n.º 9
0
void kbi4_isr(void) {
	if(timer_expired(&debouncetimer)) {
		timer_set(&debouncetimer, CLOCK_SECOND / 4);
		sensors_changed(&button_sensor);
	}
	clear_kbi_evnt(4);
}
Ejemplo n.º 10
0
void timer_query_driven_test( uint8 id )
{
	TiTimerAdapter *timer;
	timer = timer_construct( (void *)&g_timer, sizeof(g_timer) );
    timer_open( timer, id, NULL, NULL, 0x00 ); 
	timer_setinterval( timer,5, 1 );  //(timer,interval,repeat)  the range of the interval  1~8
	timer_start( timer );
//next is the function for the query model
	int i;

	while (1)
	{

        i=0;
        while(i<100)
        {
            // todo: maybe mistake here. shall we restart the timer manualy here?
		    if(timer_expired(timer))
		        i++;
		}
		led_toggle( LED_RED );
		led_toggle(LED_GREEN);
	}

  //  timer_close( timer );
}
Ejemplo n.º 11
0
static int
value(int type)
{
 return (PINE & _BV(PE4) ? 0 : 1) || !timer_expired(&debouncetimer);

 //return 0;
}
Ejemplo n.º 12
0
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void *state)
{
  struct httpd_state *s = (struct httpd_state *)state;

  if(uip_closed() || uip_aborted() || uip_timedout()) {
    if(s != NULL) {
      memb_free(&conns, s);
    }
  } else if(uip_connected()) {
    s = (struct httpd_state *)memb_alloc(&conns);
    if(s == NULL) {
      uip_abort();
      return;
    }
    tcp_markconn(uip_conn, s);
    PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
    PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
    PT_INIT(&s->outputpt);
    s->state = STATE_WAITING;
    timer_set(&s->timer, CLOCK_SECOND * 10);
    handle_connection(s);
  } else if(s != NULL) {
    if(uip_poll()) {
      if(timer_expired(&s->timer)) {
	uip_abort();
      }
    } else {
      timer_reset(&s->timer);
    }
    handle_connection(s);
  } else {
    uip_abort();
  }
}
Ejemplo n.º 13
0
struct uaodv_rt_entry *
uaodv_request_route_to(uip_ipaddr_t *host)
{
  struct uaodv_rt_entry *route = uaodv_rt_lookup(host);

  if(route != NULL) {
    uaodv_rt_lru(route);
    return route;
  }

  /*
   * Broadcast protocols must be rate-limited!
   */
  if(!timer_expired(&next_time)) {
    return NULL;
  }

  if(command != COMMAND_NONE) {
    return NULL;
  }

  uip_ipaddr_copy(&rreq_addr, host);
  command = COMMAND_SEND_RREQ;
  process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
  timer_set(&next_time, CLOCK_SECOND/8); /* Max 10/s per RFC3561. */
  return NULL;
}
Ejemplo n.º 14
0
static void openrisc_timer_cb(void *opaque)
{
    OpenRISCCPU *cpu = opaque;

    if ((cpu->env.ttmr & TTMR_IE) &&
         timer_expired(cpu->env.timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))) {
        CPUState *cs = CPU(cpu);

        cpu->env.ttmr |= TTMR_IP;
        cs->interrupt_request |= CPU_INTERRUPT_TIMER;
    }

    switch (cpu->env.ttmr & TTMR_M) {
    case TIMER_NONE:
        break;
    case TIMER_INTR:
        cpu->env.ttcr = 0;
        cpu_openrisc_count_start(cpu);
        break;
    case TIMER_SHOT:
        cpu_openrisc_count_stop(cpu);
        break;
    case TIMER_CONT:
        cpu_openrisc_count_start(cpu);
        break;
    }
}
bool PicoIPv6StateSendingDAOState::has_timer_expired(){
  if (currentState == WAITING_DAO_ACK){
    if (timer_expired(&wait_dao_ack_timer))
      return true;
  }  
  return false;  
}
Ejemplo n.º 16
0
/*---------------------------------------------------------------------------*/
void extint_detection_callback(void)
{
  if(timer_expired(&debouncetimer)) {
    timer_set(&debouncetimer, CLOCK_SECOND / 8);
    sensors_changed(&button_sensor);
  }
}
Ejemplo n.º 17
0
/**
 * \brief Handler for Sensortag-CC26XX button presses
 */
static void
button_press_handler(uint8_t ioid)
{
  if(ioid == BOARD_IOID_KEY_LEFT) {
    if(!timer_expired(&left_timer.debounce)) {
      return;
    }

    timer_set(&left_timer.debounce, DEBOUNCE_DURATION);

    /*
     * Start press duration counter on press (falling), notify on release
     * (rising)
     */
    if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) {
      left_timer.start = clock_time();
      left_timer.duration = 0;
    } else {
      left_timer.duration = clock_time() - left_timer.start;
      sensors_changed(&button_left_sensor);
    }
  }

  if(ioid == BOARD_IOID_KEY_RIGHT) {
    if(BUTTON_SENSOR_ENABLE_SHUTDOWN == 0) {
      if(!timer_expired(&right_timer.debounce)) {
        return;
      }

      timer_set(&right_timer.debounce, DEBOUNCE_DURATION);

      /*
       * Start press duration counter on press (falling), notify on release
       * (rising)
       */
      if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) {
        right_timer.start = clock_time();
        right_timer.duration = 0;
      } else {
        right_timer.duration = clock_time() - right_timer.start;
        sensors_changed(&button_right_sensor);
      }
    } else {
      lpm_shutdown(BOARD_IOID_KEY_RIGHT);
    }
  }
}
Ejemplo n.º 18
0
/* (called from interrupt context) */
void devfd_spindown(void)
{
    if (spindown_timer && timer_expired(spindown_timer))
    {
        mod_control(0x20, 0x00); /* motor off (active low) */
        spindown_timer = 0;
    }
}
Ejemplo n.º 19
0
/*---------------------------------------------------------------------------*/
static int
is_receiving(void)
{
  if(timer_expired(&rxstate.timer)) {
    restart_input();
  }
  return rxstate.receiving;
}
Ejemplo n.º 20
0
void busy_wait(U16 msec)
{
    timer_set(&tmr, msec);
    while (!timer_expired(&tmr))
    {
        ;
    }
}
Ejemplo n.º 21
0
static void devide_delay(void)
{
    timer_t timeout;

    timeout = set_timer_ms(25);

    while(!timer_expired(timeout))
       platform_idle();
}
Ejemplo n.º 22
0
	void SpinView_Impl::on_pointer_decrement_press(PointerEvent &e)
	{
		if (_state_disabled)
			return;
		_state_decrement_pressed = true;
		update_decrement_state();
		mouse_down_mode = mouse_down_button_decr;
		timer_expired();
	}
Ejemplo n.º 23
0
/*---------------------------------------------------------------------------*/
void
telnetd_appcall(void *ts)
{
  if(uip_connected()) {
    if(!connected) {
      buf_init(&buf);
      s.bufptr = 0;
      s.state = STATE_NORMAL;
      connected = 1;
      shell_start();
      timer_set(&s.silence_timer, MAX_SILENCE_TIME);
      ts = (char *)0;
    } else {
      uip_send(telnetd_reject_text, strlen(telnetd_reject_text));
      ts = (char *)1;
    }
    tcp_markconn(uip_conn, ts);
  }

  if(!ts) {
    if(s.state == STATE_CLOSE) {
      s.state = STATE_NORMAL;
      uip_close();
      return;
    }
    if(uip_closed() ||
       uip_aborted() ||
       uip_timedout()) {
      shell_stop();
      connected = 0;
    }
    if(uip_acked()) {
      timer_set(&s.silence_timer, MAX_SILENCE_TIME);
      acked();
    }
    if(uip_newdata()) {
      timer_set(&s.silence_timer, MAX_SILENCE_TIME);
      newdata();
    }
    if(uip_rexmit() ||
       uip_newdata() ||
       uip_acked() ||
       uip_connected() ||
       uip_poll()) {
      senddata();
      if(s.numsent > 0) {
	timer_set(&s.silence_timer, MAX_SILENCE_TIME);
      }
    }
    if(uip_poll()) {
      if(timer_expired(&s.silence_timer)) {
        uip_close();
        tcp_markconn(uip_conn, NULL);
      }
    }
  }
}
Ejemplo n.º 24
0
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
#if DEBOUNCE
  return (BUTTON_S1_INPUT_GPIO & (1<<BUTTON_S1_GPIO_PIN)) || !timer_expired(&debouncetimer);
#else
  return BUTTON_S1_INPUT_GPIO & (1<<BUTTON_S1_GPIO_PIN);
#endif
}
Ejemplo n.º 25
0
/* -----------------------------------------------------------------------------
 *
 * -------------------------------------------------------------------------- */
static void uip_xtcpd_handle_poll(xtcpd_state_t *s)
{
 if (s->s.ack_request) {
   uip_flags |= UIP_NEWDATA;
   uip_slen = 0;
   s->s.ack_request = 0;
 }

  if (s->s.abort_request) {
    /* ----------------------------------- */
    if (uip_udpconnection()) {
      uip_udp_conn->lport = 0;
      xtcpd_event(XTCP_CLOSED, s);
    } else {
      uip_abort();
    }
    s->s.abort_request = 0;
  } else if (s->s.close_request) {
    /* ----------------------------------- */
    if (uip_udpconnection()) {
      uip_udp_conn->lport = 0;
      xtcpd_event(XTCP_CLOSED, s);
    }
    else
      uip_close();
    s->s.close_request = 0;
  } else if (s->s.connect_request) {
      /* ----------------------------------- */
      if (uip_udpconnection()) {
      init_xtcpd_state(s,
                       XTCP_PROTOCOL_UDP,
                       *((xtcp_ipaddr_t *) (&uip_udp_conn->ripaddr)),
                       uip_udp_conn->lport,
                       uip_udp_conn->rport,
                       uip_udp_conn);
      xtcpd_event(XTCP_NEW_CONNECTION, s);
      s->s.connect_request = 0;
    }
  } else if (s->s.send_request) {
     /* ----------------------------------- */
    int len;
    if (s->linknum != -1) {
      len = do_xtcpd_send(xtcp_cons.links[s->linknum],
                       XTCP_REQUEST_DATA,
                       s,
                       uip_appdata,
                       uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss());
      uip_send(uip_appdata, len);
    }
    s->s.send_request--;
  } else if (s->s.poll_interval != 0 &&
           timer_expired(&(s->s.tmr))){
    /* ----------------------------------- */
    xtcpd_event(XTCP_POLL, s);
    timer_set(&(s->s.tmr), s->s.poll_interval);
  }
}
Ejemplo n.º 26
0
/*---------------------------------------------------------------------------*/
void
phase_update(const struct phase_list *list,
             const rimeaddr_t *neighbor, rtimer_clock_t time,
             int mac_status)
{
  struct phase *e;
  uint8_t tmp;

  /* If we have an entry for this neighbor already, we renew it. */
  e = find_neighbor(list, neighbor);
  if(e != NULL) {
    if(mac_status == MAC_TX_OK) {
#if PHASE_DRIFT_CORRECT
      e->drift = time-e->time;
#endif
      e->time = time;
    }
    /* If the neighbor didn't reply to us, it may have switched
       phase (rebooted). We try a number of transmissions to it
       before we drop it from the phase list. */
    if(mac_status == MAC_TX_NOACK) {
      PRINTF("phase noacks %d to %d.%d\n", e->noacks, neighbor->u8[0], neighbor->u8[1]);
      tmp=      e->noacks;
      e->noacks=tmp++;
      if(e->noacks == 1) {
        timer_set(&e->noacks_timer, MAX_NOACKS_TIME);
      }
      if(e->noacks >= MAX_NOACKS || timer_expired(&e->noacks_timer)) {
        PRINTF("drop %d\n", neighbor->u8[0]);
        list_remove(*list->list, e);
        memb_free(list->memb, e);
        return;
      }
    } else if(mac_status == MAC_TX_OK) {
      e->noacks = 0;
    }
  } else {
    /* No matching phase was found, so we allocate a new one. */
    if(mac_status == MAC_TX_OK && e == NULL) {
      e = memb_alloc(list->memb);
      if(e == NULL) {
        PRINTF("phase alloc NULL\n");
        /* We could not allocate memory for this phase, so we drop
           the last item on the list and reuse it for our phase. */
        e = list_chop(*list->list);
      }
      rimeaddr_copy(&e->neighbor, neighbor);
      e->time = time;
#if PHASE_DRIFT_CORRECT
      e->drift = 0;
#endif
      e->noacks = 0;
      list_push(*list->list, e);
    }
  }
}
Ejemplo n.º 27
0
bool go_enemy_indep_choser_update(game_object_p self, game_update_p update, game_p game, game_level_p level) {
    assert(NULL != self);
    assert(NULL != update);
    assert(NULL != game);

    if (!timer_expired(self->timer)) {
        return false;
    }

    game_object_p go_enemy_indep_controller = find_game_object_by_type(GO_TYPE_ENEMY5_INDEP_CONTROLLER, game->current_level->game_objects, game->current_level->game_object_count, NULL);
    go_additional_data_enemy_indep_controller_p go_enemy_indep_controller_data = (go_additional_data_enemy_indep_controller_p) go_enemy_indep_controller->additional_data;

    if ((NULL != go_enemy_indep_controller_data->enemy) && go_enemy_indep_controller_data->enemy->active) {
        // active independent enemy
        // choser deactivates
        self->active = false;

        return false;
    }

    int buffer_size = 10;
    int enemy_count = 0;
    game_object_p* enemies = malloc(buffer_size * sizeof(game_object_p));

    for (int i = 0, offset = 0; i < game->current_level->game_object_count; ++i) {
        if ((NULL != game->current_level->game_objects[i]) && !(game->current_level->game_objects[i]->recycle) && megamaniac_go_is_enemy(game->current_level->game_objects[i])) {
            ++enemy_count;

            if (enemy_count >= buffer_size) {
                buffer_size += 1;

                game_object_p* new_go_enemies = realloc(enemies, buffer_size * sizeof(game_object_p));

                if (NULL == new_go_enemies) {
                    continue;
                }

                enemies = new_go_enemies;
            }

            enemies[offset++] = game->current_level->game_objects[i];
        }
    }

    go_enemy_indep_controller_reset_data(go_enemy_indep_controller_data, enemies[rand() % enemy_count]);
    go_enemy_indep_controller_calc_curve(go_enemy_indep_controller_data, game);
    go_enemy_indep_controller_data->enemy->type = GO_TYPE_ENEMY5_INDEP;

    self->active = false;
    go_enemy_indep_controller->active = true;
    reset_timer(go_enemy_indep_controller->timer);

    free(enemies);

    return false;
}
Ejemplo n.º 28
0
/*---------------------------------------------------------------------------*/
void
phase_update(const linkaddr_t *neighbor, rtimer_clock_t time, uint32_t cycle_time,
             int mac_status)
{
  struct phase *e;

  /* If we have an entry for this neighbor already, we renew it. */
  e = nbr_table_get_from_lladdr(nbr_phase, neighbor);
  if(e != NULL) {
    if(mac_status == MAC_TX_OK) {
#if PHASE_DRIFT_CORRECT
      e->drift = time-e->time;
#endif
      e->time = time;
      if(cycle_time!=0){
        e->cycle=cycle_time;
      }
      else{
        e->cycle=CONTIKIMAC_CONF_CYCLE_TIME;
      }
    }
    /* If the neighbor didn't reply to us, it may have switched
       phase (rebooted). We try a number of transmissions to it
       before we drop it from the phase list. */
    if(mac_status == MAC_TX_NOACK) {
      PRINTF("phase noacks %d to %d.%d\n", e->noacks, neighbor->u8[0], neighbor->u8[1]);
      e->noacks++;
      if(e->noacks == 1) {
        timer_set(&e->noacks_timer, MAX_NOACKS_TIME);
      }
      if(e->noacks >= MAX_NOACKS || timer_expired(&e->noacks_timer)) {
        PRINTF("drop %d\n", neighbor->u8[0]);
        nbr_table_remove(nbr_phase, e);
        return;
      }
      if(e->noacks >= MAX_NOACKbis){
        e->cycle=CONTIKIMAC_CONF_CYCLE_TIME;
      }

    } else if(mac_status == MAC_TX_OK) {
      e->noacks = 0;
    }
  } else {
    /* No matching phase was found, so we allocate a new one. */
    if(mac_status == MAC_TX_OK && e == NULL) {
      e = nbr_table_add_lladdr(nbr_phase, neighbor);
      if(e) {
        e->time = time;
#if PHASE_DRIFT_CORRECT
      e->drift = 0;
#endif
      e->noacks = 0;
      }
    }
  }
}
Ejemplo n.º 29
0
void initlcm(void)
{
	timer_set(&delaytimer12864, DELAY_100MS);
	while(!(timer_expired(&delaytimer12864)));
	write(COMMAND, 0x30);//功能设置,一次送8位数据,基本指令集
	write(COMMAND, 0x0C);//0000,1100 整体显示,游标off,游标位置off
	write(COMMAND, 0x01);//0000,0001 清DDRAM
	write(COMMAND, 0x02);//0000,0010 DDRAM地址归位
	write(COMMAND, 0x80);//1000,0000 设定DDRAM 7位地址000,0000到地址计数器AC
}
Ejemplo n.º 30
0
/**
 * \brief Interrupt handler for the user button.
 *
 * \param port The port number that generated the interrupt
 * \param pin The pin number that generated the interrupt.
 *
 * This function is called inside interrupt context.
 */
static void
user_button_irq_handler(uint8_t port, uint8_t pin)
{
  if(!timer_expired(&debouncetimer)) {
    return;
  }

  timer_set(&debouncetimer, CLOCK_SECOND / 8);
  sensors_changed(&button_sensor);
}