Exemple #1
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(tcpip_process, ev, data, buf)
{
  PROCESS_BEGIN();
  
#if UIP_TCP
 {
   static unsigned char i;
   
   for(i = 0; i < UIP_LISTENPORTS; ++i) {
     s.listenports[i].port = 0;
   }
   s.p = PROCESS_CURRENT();
 }
#endif

  tcpip_event = process_alloc_event();
#if UIP_CONF_ICMP6
  tcpip_icmp6_event = process_alloc_event();
#endif /* UIP_CONF_ICMP6 */
  etimer_set(&periodic, CLOCK_SECOND / 2);

  uip_init();
#ifdef UIP_FALLBACK_INTERFACE
  UIP_FALLBACK_INTERFACE.init();
#endif
/* initialize RPL if configured for using RPL */
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL
  rpl_init();
#endif /* UIP_CONF_IPV6_RPL */

  while(1) {
    PROCESS_YIELD();
    eventhandler(ev, data, buf);
  }
  
  PROCESS_END();
}
PROCESS_THREAD(end_node_process, ev, data)
{
    PROCESS_BEGIN();
    static struct etimer et;
    etimer_set(&et, CLOCK_SECOND);

    printf("Using NodeId: %X\n\r", get_nodeid());

    /* Turn off AES */
    netstack_aes_set_active(1);

    /* Allocate events */
    reconnect_event = process_alloc_event();

    /* Reconnect from here */

    while(1) {
        if(simple_rpl_parent() == NULL) {

            printf("\r\n Connecting to a Wireless Network...\r\n");
            etimer_set(&et, CLOCK_SECOND / 1);
            while(simple_rpl_parent() == NULL) {
                PROCESS_YIELD_UNTIL(etimer_expired(&et));
                etimer_reset(&et);
            }
            printf("\r\n Connected to Wireless network\r\n");
        }

        process_start(&prox_agent_process, NULL);

        /* Reset reconnecting flag */
        reconnecting = 0;

        /* Main loop */
        while(1) {

            PROCESS_WAIT_EVENT();
            if(ev == reconnect_event) {
                reconnecting = 1;
                etimer_set(&reconnect_timer, CLOCK_SECOND*10);
            }
            if(reconnecting &&
                    etimer_expired(&reconnect_timer)) {
                break;
            }
        }
    }
    PROCESS_END();
}
Exemple #3
0
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
  char *appdata;
  unsigned char i;
  blink_event = process_alloc_event();

  if(uip_newdata()) {
    appdata = (char *)uip_appdata;
    appdata[uip_datalen()] = 0;
    for(i = 0; i < 4; i++){
      dht11data[i] = *(appdata + i);
    }
    PRINTF("DATA recv '%s' from ", appdata);
    PRINTF("%d",
           UIP_IP_BUF->srcipaddr.u8[sizeof(UIP_IP_BUF->srcipaddr.u8) - 1]);
    PRINTF("\n");
    PRINTF("wendu is %c%c, shidu is %c%c \n", *appdata,*(appdata+1),*(appdata+2),*(appdata+3));
    
//    PRINTF("DATA sending reply\n");
//    uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
    /*
    if(strncmp(appdata, "RED", 3) == 0) {
      leds_on(LEDS_RED);
      leds_off(LEDS_GREEN);
      sta = 0;
      }
    if(strncmp(appdata, "GREEN", 5) == 0) {
      leds_on(LEDS_GREEN);
      leds_off(LEDS_RED);
      sta = 0;
      }
    if(strncmp(appdata,"BLINK",5) == 0) {
      process_post(&udp_server_process, blink_event, NULL);
      sta = 1;
    }
    if(strncmp(appdata,"OFF",3) == 0) {
      leds_off(LEDS_RED | LEDS_GREEN);
      sta = 0;
    }
#if SERVER_REPLY
    PRINTF("DATA sending reply\n");
    uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
    uip_udp_packet_send(server_conn, "Reply", sizeof("Reply"));
    uip_create_unspecified(&server_conn->ripaddr);
#endif
    */
  }
}
Exemple #4
0
/*---------------------------------------------------------------------------*/
void
mqtt_init(void)
{
  static uint8_t inited = 0;
  if(!inited) {
    mqtt_do_connect_tcp_event = process_alloc_event();
    mqtt_do_connect_mqtt_event = process_alloc_event();
    mqtt_do_disconnect_mqtt_event = process_alloc_event();
    mqtt_do_subscribe_event = process_alloc_event();
    mqtt_do_unsubscribe_event = process_alloc_event();
    mqtt_do_publish_event = process_alloc_event();
    mqtt_do_pingreq_event = process_alloc_event();
    mqtt_continue_send_event = process_alloc_event();
    mqtt_update_event = process_alloc_event();

    list_init(mqtt_conn_list);
    process_start(&mqtt_process, NULL);
    inited = 1;
  }
}
Exemple #5
0
static void network_init(void) {
	struct uip_eth_addr macaddr;

	net_event = process_alloc_event();

#if CONFIG_DRIVERS_ENC28J60
	// Set our MAC address
	memcpy_P(&macaddr, &mac, sizeof(mac));

	// Set up ethernet
	enc28j60Init(&macaddr);
	enc28j60Write(ECOCON, 0 & 0x7); // Disable clock output
	_delay_ms(10);

	/* Magjack leds configuration, see enc28j60 datasheet, page 11 */
	// LEDA=green LEDB=yellow
	//
	// 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
	enc28j60PhyWrite(PHLCON, 0x476);
	_delay_ms(100);
#endif
#if CONFIG_DRIVERS_ENC424J600
	// Initialise the hardware
	enc424j600Init();

	// Disable clock output and set up LED stretch
	uint16_t econ2 = enc424j600ReadReg(ECON2);
	econ2 |= ECON2_STRCH; // stretch LED duration
	econ2 &= ~(ECON2_COCON3 | ECON2_COCON2 | ECON2_COCON1 | ECON2_COCON0);
	enc424j600WriteReg(ECON2, econ2);

	// Set up LEDs
	uint16_t eidled = enc424j600ReadReg(EIDLED);
	eidled &= 0x00ff; // and-out the high byte (LED config)
	eidled |= EIDLED_LACFG1 | EIDLED_LBCFG2 | EIDLED_LBCFG1;
	enc424j600WriteReg(EIDLED, eidled);

	// Get the MAC address
	enc424j600GetMACAddr(macaddr.addr);
#endif

#if !CONFIG_LIB_CONTIKI_IPV6
	// Set up timers
	timer_set(&arp_timer, CLOCK_SECOND * 10);
#endif

	uip_setethaddr(macaddr);
}
// callback for receiving client's needed file ranges
static void server_recv(struct broadcast_conn *c, const rimeaddr_t *from)
{
	// store received data packet
	uint8_t *range_recv = (uint8_t *)packetbuf_dataptr();  //Get a pointer to the data in the packetbuf. 
	// for debugging purposes
	printf("ranges received from %d.%d: '%d, %d'\n",
		from->u8[0], from->u8[1], range_recv[0], range_recv[1]);


	// allocate event that ranges are received
	ranges_ready = process_alloc_event(); //Allocate a global event number. 

	// start the send files process and pass the received ranges
	process_post(&send_files, ranges_ready, range_recv);

}
void drvr_init()
{
    U8 part_num, ver_num, irq;
    U16 man_id = 0;

    memset(&dcb, 0, sizeof(at86_dcb_t));

    delay_us(TIME_TO_ENTER_P_ON);
    hal_init();

    // reset all regs in at86rf
    drvr_at86_reset();

    part_num = hal_register_read(AT86_PART_NUM);
    ver_num = hal_register_read(AT86_VERSION_NUM);
    man_id |= hal_register_read(AT86_MAN_ID_1) << 8;
    man_id |= hal_register_read(AT86_MAN_ID_0);

    hal_register_write(AT86_IRQ_MASK, 0);
    irq = hal_register_read(AT86_IRQ_STATUS);

    // force transceiver off while we configure the intps
    hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF);
    delay_us(TIME_P_ON_TO_TRX_OFF);

    // wait for transceiver to transition to the off state
    while (drvr_get_trx_state() != TRX_OFF);

    hal_register_write(AT86_IRQ_MASK, (1<<IRQ_MASK_TRX_END) | (1<<IRQ_MASK_RX_START));

    // configure the CSMA parameters
    drvr_config_csma(drvr_get_rand() & 0xf, drvr_get_rand() & 0xf, aMinBE, aMacMaxFrameRetries, aMaxCsmaBackoffs);

    // set the default channel
    drvr_set_channel(11);

    // set autocrc mode
    drvr_set_auto_crc(true);

    // start the contiki driver process and register the event number
    process_start(&drvr_process, NULL);
    event_drvr_conf = process_alloc_event();

    // put trx in rx auto ack mode
    drvr_set_trx_state(RX_AACK_ON);
    while (drvr_get_trx_state() != RX_AACK_ON);
}
Exemple #8
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(serial_line_process, ev, data)
{
  static char buf[BUFSIZE];
  static int ptr;

  PROCESS_BEGIN();

  serial_line_event_message = process_alloc_event();
  ptr = 0;

  while(1) {
    /* Fill application buffer until newline or empty */
    int c = ringbuf_get(&rxbuf);
    
    if(c == -1) {
      /* Buffer empty, wait for poll */
      PROCESS_YIELD();
    } else {
      if(c != END) {
        if(ptr < BUFSIZE-1) {
          buf[ptr++] = (uint8_t)c;
        } else {
          /* Ignore character (wait for EOL) */
        }
      } else {
        /* Terminate */
        buf[ptr++] = (uint8_t)'\0';

        /* Broadcast event */
        process_post(PROCESS_BROADCAST, serial_line_event_message, buf);

        /* Wait until all processes have handled the serial line event */
        if(PROCESS_ERR_OK ==
          process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL)) {
          PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE);
        }
        ptr = 0;
      }
    }
  }

  PROCESS_END();
}
Exemple #9
0
/*---------------------------------------------------------------------------*/
void
shell_init(void)
{
  list_init(commands);
  shell_register_command(&help_command);
  shell_register_command(&question_command);
  shell_register_command(&killall_command);
  shell_register_command(&kill_command);
  shell_register_command(&null_command);
  shell_register_command(&exit_command);
  shell_register_command(&quit_command);
  
  shell_event_input = process_alloc_event();
  
  process_start(&shell_process, NULL);
  process_start(&shell_server_process, NULL);

  front_process = &shell_process;
}
Exemple #10
0
// callback for receiving files
static void files_recv(struct broadcast_conn *c, const rimeaddr_t *from)
{
	process_exit(&timerout_proc);
	// storing file received
	uint8_t file_recv = *(uint8_t *)packetbuf_dataptr();

	state = 2;
	//printf("state 2");

	// debugging
	printf("%d", file_recv);

	// allocating event
	files_ready = process_alloc_event();

	// sending event and file number received to recv_files process
	process_post(&recv_files, files_ready, &file_recv);

}
Exemple #11
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sensors_process, ev, data)
{
    static int i;
    static int events;

    PROCESS_BEGIN();

    sensors_event = process_alloc_event();

    for(i = 0; sensors[i] != NULL; ++i)
    {
        sensors_flags[i] = 0;
        sensors[i]->configure(SENSORS_HW_INIT, 0);
    }
    num_sensors = i;

    while(1)
    {

        PROCESS_WAIT_EVENT();

        do
        {
            events = 0;
            for(i = 0; i < num_sensors; ++i)
            {
                if(sensors_flags[i] & FLAG_CHANGED)
                {
                    if(process_post(PROCESS_BROADCAST, sensors_event, (void *)sensors[i]) == PROCESS_ERR_OK)
                    {
                        PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event);
                    }
                    sensors_flags[i] &= ~FLAG_CHANGED;
                    events++;
                }
            }
        }
        while(events);
    }

    PROCESS_END();
}
Exemple #12
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sensors_process, ev, data)
{
  static int i;
  static int events;

  PROCESS_BEGIN();
  
  for(i = 0; sensors[i] != NULL; ++i) {
    sensors_flags[i] = 0;
    sensors[i]->init();
  }
  num_sensors = i;
  
  sensors_event = process_alloc_event();

  irq_init();

  while(1) {

    PROCESS_WAIT_EVENT();

    do {
      events = 0;
      for(i = 0; i < num_sensors; ++i) {
	if(sensors_flags[i] & FLAG_CHANGED) {
	  /*	if(sensors_selecting_proc[i] == SELCOLL
		|| sensors_selecting_proc[i] == NULL)
		process_post(PROCESS_BROADCAST, sensors_event, sensors[i]);
		else
		process_post(sensors_selecting_proc[i], sensors_event, sensors[i]);*/
	  if(process_post(PROCESS_BROADCAST, sensors_event, sensors[i]) == PROCESS_ERR_OK) {
	    PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event);
	  }
	  sensors_flags[i] &= ~FLAG_CHANGED;
	  events++;
	}
      }
    } while(events);
  }

  PROCESS_END();
}
Exemple #13
0
/*
 * Initialize the various elements in the MAC layer. Reset the protocol
 * control block, start the mac process, init the events, and set the mac
 * info base to its default values.
 */
void mac_init()
{
	mac_queue_init();
	mac_indir_init();
	mac_scan_init();

	/*
	 * Set up the processes. First start the mac process,
	 * then allocate the rx event
	 */
	process_start(&mac_process, NULL);
	event_mac_rx = process_alloc_event();

	/* init the pcb */
	memset(&pcb, 0, sizeof(mac_pcb_t));

	/* init the mac pib */
	memset(&pib, 0, sizeof(mac_pib_t));
	pib.ack_wait_duration		= aMacAckWaitDuration;
	pib.resp_wait_time		= aMacResponseWaitTime;
	pib.coord_addr.mode		= SHORT_ADDR;
	pib.coord_addr.short_addr	= 0xFFFF;
	pib.short_addr			= 0xFFFF;
	pib.pan_id			= 0xFFFF;
	pib.rx_on_when_idle		= true;
	pib.assoc_permit		= true;
	pib.max_csma_backoffs		= 3;
	pib.min_be			= 3;
	pib.dsn				= (U8)drvr_get_rand();

#if (TEST_SIM == 1)
	pib.ext_addr = getpid();
#else
	pib.ext_addr = drvr_get_rand();
#endif

	/* set these in the hardware */
	drvr_set_pan_id(pib.pan_id);
	drvr_set_short_addr(pib.short_addr);
	drvr_set_ext_addr(pib.ext_addr);
}
Exemple #14
0
/**
 * \brief Init function for the User button.
 * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1
 *             or 0 respectively)
 *
 * \param value Depends on the value of the type argument
 * \return Depends on the value of the type argument
 */
static int
config_user(int type, int value)
{
  switch(type) {
  case SENSORS_HW_INIT:
    button_press_duration_exceeded = process_alloc_event();

    /* Software controlled */
    GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);

    /* Set pin to input */
    GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);

    /* Enable edge detection */
    GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);

    /* Both Edges */
    GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);

    ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE);

    gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN);
    break;
  case SENSORS_ACTIVE:
    if(value) {
      GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
      nvic_interrupt_enable(BUTTON_USER_VECTOR);
    } else {
      GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
      nvic_interrupt_disable(BUTTON_USER_VECTOR);
    }
    return value;
  case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL:
    press_duration = (clock_time_t)value;
    break;
  default:
    break;
  }

  return 1;
}
Exemple #15
0
void
ieee_init()
{
  void *mac;
  MAC_Pib_s *pib;

  if (process_is_running(&ieee_process))
    return;

  /* initialize ieee_eventhandler and event queue*/
  rxq_init();

  /* setup mac <-> app interface */
  u32AppApiInit((PR_GET_BUFFER) rxq_mlme_alloc, (PR_POST_CALLBACK) ieee_process_poll, NULL,
                (PR_GET_BUFFER) rxq_mcps_alloc, (PR_POST_CALLBACK) ieee_process_poll, NULL);

  /* get mac and pib handles */
  mac   = pvAppApiGetMacHandle();
  pib   = MAC_psPibGetHandle(mac);

  /* do a full reset */
  req_reset(true);

  /* set panid and default parameters */
  MAC_vPibSetPanId(mac, IEEE802154_PANDID);
  MAC_vPibSetRxOnWhenIdle(mac, true, false);

  /* allocate an event for this process */
  ieee_event = process_alloc_event();
  pib->bAutoRequest = true;

  /* bandwidth control, smaller interframe gap and higher data rate,
   * this is not standard conform! */
#if defined(__BA2__) && defined(JENNIC_CONF_JN5148_FASTDATARATE)
  vAHI_BbcSetHigherDataRate(E_AHI_BBC_CTRL_DATA_RATE_1_MBPS);
  vAHI_BbcSetInterFrameGap(48);
#endif

  process_start(&ieee_process, NULL);
}
Exemple #16
0
void mac_init()
{
    mac_queue_init();
    mac_indir_init();
    mac_scan_init();

    // Set up the processes.
    // First start the mac process, then allocate the rx event
    process_start(&mac_process, NULL);
    event_mac_rx = process_alloc_event();

    // init the pcb
    memset(&pcb, 0, sizeof(mac_pcb_t));

    // init the mac pib
    memset(&pib, 0, sizeof(mac_pib_t));
    pib.ack_wait_duration       = aMacAckWaitDuration;
    pib.resp_wait_time          = aMacResponseWaitTime;
    pib.coord_addr.mode         = SHORT_ADDR;
    pib.coord_addr.short_addr   = 0xFFFF;
    pib.short_addr              = 0xFFFF;
    pib.pan_id                  = 0xFFFF;
    pib.rx_on_when_idle         = true;
    pib.assoc_permit            = true;
    pib.max_csma_backoffs       = 3;
    pib.min_be                  = 3;
    pib.dsn                     = (U8)drvr_get_rand();

#if (TEST_SIM == 1)
    //lint -e{732} Info 732: Loss of sign (assignment) (int to unsigned long long)
    pib.ext_addr                = getpid();
#else
    pib.ext_addr                = drvr_get_rand();
#endif

    // set these in the hardware
    drvr_set_pan_id(pib.pan_id);
    drvr_set_short_addr(pib.short_addr);
    drvr_set_ext_addr(pib.ext_addr);
}
Exemple #17
0
PROCESS_THREAD(led_on, ev, data)
{
  static struct etimer etmr;
  
  WDTE=0xac;
  
  PROCESS_BEGIN();
  
  etimer_set(&etmr, CLOCK_CONF_SECOND);
  event_led_on = process_alloc_event();
  
  while(1)
  {
    PROCESS_WAIT_EVENT_UNTIL(ev==PROCESS_EVENT_TIMER);
 //   offled = (~offled);
 //   BELL = 0;
    process_post(&led_off, event_led_on, NULL);
    etimer_reset(&etmr);
  }
  
  PROCESS_END();
}
Exemple #18
0
// callback for receiving Ns
static void client_recv(struct broadcast_conn *c, const rimeaddr_t *from)
{
	start_time = clock_time();
	state = 1;
	// flag for receiving Ns initially
	if (flag==1) {
		// storing Ns from packet
		uint8_t ns_recv = *(uint8_t *)packetbuf_dataptr();
		// for debugging purposes
		
		printf("*");
		printf("Ns received from %d.%d: '%d'\n",
			from->u8[0], from->u8[1], ns_recv);

		// allocating event
		ns_ready = process_alloc_event();

		// send event and Ns to client_broadcast
		process_post(&client_broadcast, ns_ready, &ns_recv);
	}
	
}
Exemple #19
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(serial_line_process, ev, data)
{
  PROCESS_BEGIN();

  bufwptr = 0;
  buffer_full = 0;

  serial_line_event_message = process_alloc_event();

  while(1) {
    PROCESS_YIELD();
    
    if(buffer_full) {
      memcpy(appbuffer, buffer, bufwptr);
      process_post(PROCESS_BROADCAST, serial_line_event_message, appbuffer);
      bufwptr = 0;
      buffer_full = 0;
    }
  }

  PROCESS_END();
}
Exemple #20
0
/*---------------------------------------------------------------------*/
PROCESS_THREAD(codeprop_process, ev, data)
{
  PROCESS_BEGIN();
  
  s.id = 0/*random_rand()*/;
  
  send_time = CLOCK_SECOND/4;
  
  PT_INIT(&s.udpthread_pt);
  PT_INIT(&s.recv_udpthread_pt);
  
  tcp_listen(HTONS(CODEPROP_DATA_PORT));
  
  udp_conn = udp_broadcast_new(HTONS(CODEPROP_DATA_PORT), NULL);
  
  codeprop_event_quit = process_alloc_event();
  
  s.state = STATE_NONE;
  s.received = 0;
  s.addr = 0;
  s.len = 0;

  while(1) {

    PROCESS_YIELD();
  
    if(ev == EVENT_START_PROGRAM) {
      /* First kill old program. */
      elfloader_unload();
      elfloader_load(EEPROMFS_ADDR_CODEPROP);
    } else if(ev == tcpip_event) {
      uipcall(data);
    } else if(ev == PROCESS_EVENT_TIMER) {
      tcpip_poll_udp(udp_conn);
    }
  }

  PROCESS_END();
}
Exemple #21
0
PROCESS_THREAD(accel_process, ev, data) {
  PROCESS_BEGIN();
  {
    int16_t x, y, z;

    serial_shell_init();
    shell_ps_init();
    shell_file_init();  // for printing out files
    shell_text_init();  // for binprint

    /* Register the event used for lighting up an LED when interrupt strikes. */
    ledOff_event = process_alloc_event();

    /* Start and setup the accelerometer with default values, eg no interrupts enabled. */
    accm_init();

    /* Register the callback functions for each interrupt */
    ACCM_REGISTER_INT1_CB(accm_ff_cb);
    ACCM_REGISTER_INT2_CB(accm_tap_cb);

    /* Set what strikes the corresponding interrupts. Several interrupts per pin is 
      possible. For the eight possible interrupts, see adxl345.h and adxl345 datasheet. */
    accm_set_irq(ADXL345_INT_FREEFALL, ADXL345_INT_TAP + ADXL345_INT_DOUBLETAP);

    while (1) {
	    x = accm_read_axis(X_AXIS);
	    y = accm_read_axis(Y_AXIS);
	    z = accm_read_axis(Z_AXIS);
	    printf("x: %d y: %d z: %d\n", x, y, z);

      etimer_set(&et, ACCM_READ_INTERVAL);
      PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    }
  }
  PROCESS_END();
}
PROCESS_THREAD(proc_epoch_syncer, ev, data) {
	static struct etimer send_timer;
	static struct etimer epoch_timer;
	static const struct broadcast_callbacks broadcast_cbs = {__broadcast_recv_cb, __broadcast_sent_cb};
	static struct broadcast_conn conn;

	PROCESS_EXITHANDLER(broadcast_close(&conn));

	PROCESS_BEGIN();


#ifdef TRACK_CONNECTIONS
	/* Log the node id */
	printf("board-id64 0x%.16llx\n", board_get_id64());
#endif
#ifdef XFER_CRC16
	/* Log the node id */
	printf("xfer crc16\n");
#endif
	printf("epoch interval %ld ticks\n", EPOCH_INTERVAL);

	/*
	 * Alloc the two syncer events
	 */
	evt_epoch_synced = process_alloc_event();
	evt_end_of_epoch = process_alloc_event();

	/*
	 * Open a `connection` on the syncer broadcasting channel
	 */
	broadcast_open(&conn, BROADCAST_CHANNEL_TIMESYNC, &broadcast_cbs);

	/*
	 * init the epoch-syncer instance
	 */
	epoch_syncer_init(&__epoch_syncer);

	/*
	 * This is the main syncer loop. Initially we try to sync the
	 * epoch between nodes without concurrently running any other
	 * algo. After a period, at which time the network is synced,
	 * we start generating epoch events which can be
	 * consumed by, e.g., the estimator process.
	 */
	etimer_set(&epoch_timer, __epoch_syncer.epoch_interval);
	__epoch_syncer.epoch_start_time = clock_time();
	__epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer);
	while (1) {
		/*
		 * The start of a new epoch !
		 */
		epoch_syncer_at_epoch_start(&__epoch_syncer);


		clock_time_t now;
		clock_time_t time_to_epoch_end;
			
		now = clock_time();

		assert(__epoch_syncer.epoch_end_time == etimer_expiration_time(&epoch_timer));
		assert(__epoch_syncer.epoch_end_time > now);
		time_to_epoch_end = __epoch_syncer.epoch_end_time - now;

		/* 
		 * Setup a random wait time before sending the sync packet
		 *
		 * ! we cannot let send_timer delay the epoch_timer, especially
		 *   when the next `end-of-epoch-time` has been anticipated by a lot
		 *   (this can happen at startup)
		 */
		if (time_to_epoch_end > __epoch_syncer.epoch_sync_start) {
			long int send_wait;
			long int send_wait_rnd;
			long int rnd;

			rnd = rand();
			send_wait_rnd = (unsigned)rnd % (unsigned) __epoch_syncer.epoch_sync_xfer_interval;
			send_wait = __epoch_syncer.epoch_sync_start + send_wait_rnd;
			assert(send_wait >= __epoch_syncer.epoch_sync_start);
			assert(send_wait <= __epoch_syncer.epoch_sync_start + __epoch_syncer.epoch_sync_xfer_interval);

			if (send_wait > time_to_epoch_end)
				send_wait = __epoch_syncer.epoch_sync_start;

			assert(send_wait < time_to_epoch_end);
			etimer_set(&send_timer, send_wait);

			PROCESS_WAIT_UNTIL(etimer_expired(&send_timer));

			/*
			 * Acquire the radio lock
			 *
			 * ! we don't use WAIT/YIELD_UNTIL() because
			 *   1) we do not want to yield if we can acquire the lock on the first try
			 *   2) no kernel signal is generated when the lock is released (we would `deadlock')
			 */
			do {
				if (!radio_trylock())
					break;

				PROCESS_PAUSE();
			} while (1);


			{
				clock_time_t now;
				struct epoch_sync_packet packet;
					
				/*
				 * broadcast the sync packet
				 *
				 * ! We put this part into its own block since non static stack
				 * variables/allocations in the parent block wouldn't get preserved trough
				 * kernel calls (e.g. the PROCESS_PAUSE() a few lines above)
				 */
#ifdef TRACK_CONNECTIONS
				packet.board_id16 = board_get_id16();
#endif
				packet.epoch = __epoch_syncer.epoch;

				now = clock_time();
				assert(now > __epoch_syncer.epoch_start_time);
				assert(__epoch_syncer.epoch_end_time > now);
				packet.time_from_epoch_start = now - __epoch_syncer.epoch_start_time;
				packet.time_to_epoch_end = __epoch_syncer.epoch_end_time - now;

				
#ifdef XFER_CRC16
				/*
				 * Compute the packet crc with the .crc16 field zeroed
				 */
				{
					uint16_t crc16;

					packet.crc16 = 0;
					crc16 = crc16_data((const unsigned char *)&packet,  sizeof(struct epoch_sync_packet), 0);

					packet.crc16 = crc16;
				}
#endif
				packetbuf_copyfrom(&packet, sizeof(struct epoch_sync_packet));
				broadcast_send(&conn);
			}
		} else {
			printf("epoch-syncer: skipping sync send\n");
		}
			

		/*
		 * We cannot YIELD here: if epoch_timer has already expired there won't be
		 * any event to wake us up.
		 *
		 * FIXME: if we get here and the epoch timer has fired
		 * already print by how much we are late: this can be terribly useful
		 * to trace bugs in the epoch sync code or the kernel.
		 */
		if (etimer_expired(&epoch_timer)) {
			long int now;

			now = clock_time();
			assert(now > __epoch_syncer.epoch_end_time);
			
		} else {
			char do_wait;
			do_wait = 1;

			if (__epoch_syncer.sum_sync_offsets) {
				long int avg_offset = __epoch_syncer.sum_sync_offsets / __epoch_syncer.nr_offsets;
				const long int threshold = CLOCK_SECOND;

				if (avg_offset > threshold) {
					/*
					 * if we are late don't wait until the timer expires
					 * ! this migth give us the opportunity to re-enter the right sync_xfer_interval
					 */
					do_wait = 0;
				} else if (avg_offset < -threshold) {
					/*
					 * we are too fast, delay end of epoch
					 */
					clock_time_t now;
					clock_time_t time_to_epoch_end;
			
					now = clock_time();
					assert(__epoch_syncer.epoch_end_time == etimer_expiration_time(&epoch_timer));
					assert(__epoch_syncer.epoch_end_time > now);
					time_to_epoch_end = __epoch_syncer.epoch_end_time - now;

					long int delay = time_to_epoch_end + (-avg_offset/2);

					static struct etimer delay_timer;
					trace("epoch-syncer: delaying end-of-epoch by %ld ticks\n", (-avg_offset/2));
					etimer_set(&delay_timer, delay);
					__epoch_syncer.epoch_end_time += (-avg_offset/2);

					PROCESS_WAIT_UNTIL(etimer_expired(&delay_timer));
				}
			}

			if (do_wait) {
				PROCESS_WAIT_UNTIL(etimer_expired(&epoch_timer));
			} else {
				trace("epoch-syncer: not waiting for end-of-epoch\n");
			}
		}
		trace("epoch-syncer: epoch %d ended\n",  __epoch_syncer.epoch);

#ifdef TRACK_CONNECTIONS
		connection_print_and_zero(CONNECTION_TRACK_SYNC, __epoch_syncer.epoch);
#endif

		/*
		 * Re-Set the end-of-epoch timer
		 */
		if (__epoch_syncer.epoch == EPOCHS_UNTIL_SYNCED) {
			/*
			 * We have hopefully achieved sync at this point
			 *
			 * 1) update the epoch timings, and set the epoch timer
			 *
			 * 2) signal the size-estimator process that the epoch is now synced
			 */
			__epoch_syncer.epoch_interval = EPOCH_INTERVAL;
			__epoch_syncer.epoch_sync_start = EPOCH_SYNC_START;
			__epoch_syncer.epoch_sync_xfer_interval = EPOCH_SYNC_XFER_INTERVAL;

			etimer_stop(&epoch_timer);
			etimer_set(&epoch_timer, __epoch_syncer.epoch_interval);
			/*
			 * The epoch timer has been re-set: update the time until the next epoch end
			 * Increase the epoch count.
			 * ! these operations must happen in a block which cannot block in kernel calls
			 */
			__epoch_syncer.epoch_start_time = clock_time();
			__epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer);
			__epoch_syncer.epoch++;

			process_post(&proc_size_estimator, evt_epoch_synced, NULL);
		} else {
			/*
			 * Re-set and adjust the epoch timer using the data received trough sync packets
			 * (in this epoch)
			 *
			 * ! using re-set (instead of, e.g., restart) is important here in order to avoid
			 *   drifting
			 */ 
			etimer_reset(&epoch_timer);

			/*
			 * The epoch timer has been re-set: update the time until the next epoch end
			 * Increase the epoch count.
			 * ! these operations must happen in a block which cannot block in kernel calls
			 */
			//__epoch_syncer.epoch_start_time = epoch_timer.timer.start;
			__epoch_syncer.epoch_start_time = clock_time();
			__epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer);
			__epoch_syncer.epoch++;
			if (__epoch_syncer.sum_sync_offsets) {
				long int avg_offset = __epoch_syncer.sum_sync_offsets / __epoch_syncer.nr_offsets;
				const long int threshold = 1;//(CLOCK_SECOND/32);//*3;

#if __CONTIKI_NETSTACK_RDC==__CONTIKI_NETSTACK_RDC_NULL
				const int tx_delay = 0;
#elif __CONTIKI_NETSTACK_RDC==__CONTIKI_NETSTACK_RDC_CXMAC
				/*
				 * When the cxmac RDC is used we must consider an added delay due to the fact that when
				 * other nodes radios are turned off the sync packet must be re-sent.
				 */
				const int tx_delay = 8;
#endif

				/*
				 * estimate the avg tx delay
				 */
				avg_offset += tx_delay;

				trace("epoch-syncer: sync offsets %d ~ %ld < %ld < %ld\n", __epoch_syncer.nr_offsets,  __epoch_syncer.min_offset + tx_delay, avg_offset, __epoch_syncer.max_offset+tx_delay);
				
				if ((avg_offset < -threshold) || (avg_offset > threshold)) {
					clock_time_t new_expiration_time;

					const long int adjust_threshold = CLOCK_SECOND/2;
					long int adjust;
		
					/*
					 * feedback control the next expiration time
					 */
					adjust = -avg_offset/2;
					adjust = min(adjust, adjust_threshold);
					adjust = max(adjust, -adjust_threshold);

					if (adjust)
						etimer_adjust(&epoch_timer, adjust);
						
					new_expiration_time = etimer_expiration_time(&epoch_timer);
					__epoch_syncer.epoch_end_time = new_expiration_time;
				}
			}

			if (__epoch_syncer.epoch > EPOCHS_UNTIL_SYNCED) {
				/*
				 * Signal the estimator-process that this epoch has ended
				 */
				process_post(&proc_size_estimator, evt_end_of_epoch, NULL);
			}
		}
	}

	PROCESS_END();
}
Exemple #23
0
/* this process handle the reception of messages */
PROCESS_THREAD(delugeGroupP, ev, data)
{

	int fd;
	char* buf;
	uint8_t nr_pages_local;
	static struct etimer et;
	
	static struct jsonparse_state jsonState;
	static ContainerRoot * newModel;
	static uip_ipaddr_t addr;

	PROCESS_BEGIN();
	
	/* keep track of the singleton instance */
	instance = (DelugeGroup*)data;

	/* register new event types */
	NEW_AVAILABLE_OA_MODEL = process_alloc_event();
	NEW_OA_MODEL_DOWNLOADED = process_alloc_event();

	/* initialize model announcement's system */
	simple_udp_register(&deluge_group_broadcast, 34555, NULL, 34555, model_version_recv);

	/* set announcement's initial value*/
	instance->info.version = 0;
	instance->info.nr_pages = 0;
	
	/* set timer for announcements */
	etimer_set(&et, CLOCK_SECOND * instance->interval);

	while (1) {
		/* Listen for announcements every interval seconds. */
		PROCESS_WAIT_EVENT();
		if (ev == PROCESS_EVENT_TIMER) {
			/* announce my model */
			uip_create_linklocal_allnodes_mcast(&addr);
  			simple_udp_sendto(&deluge_group_broadcast, &instance->info, sizeof(struct ModelInfo), &addr);
  			
			etimer_restart(&et);
		}
		else if (ev == NEW_AVAILABLE_OA_MODEL){
			/* receive the new over the air model */
			 
			/* contains the number of pages */
			nr_pages_local = instance->info.nr_pages;
			
			/* create the file with the required number of pages */
			cfs_remove(instance->fileNameWithModel);
			fd = cfs_open(instance->fileNameWithModel, CFS_WRITE);
			buf = (char*) malloc(S_PAGE);
			memset(buf, '0' , S_PAGE);
			PRINTF("Number of pages is %d\n", nr_pages_local);
			while(nr_pages_local) {
				cfs_seek(fd, 0, CFS_SEEK_END);
				cfs_write(fd, buf, S_PAGE);
				nr_pages_local--;
			}
			free(buf);
			cfs_close(fd);

			/* Deluge-based dissemination */
			if (deluge_disseminate(instance->fileNameWithModel, 0, modelDownloaded)) {
				PRINTF("ERROR: some problem waiting for new version of the file\n");
			}
			else {
				PRINTF("INFO: Waiting for new version of the file \n");
			}

		}
		else if (ev == NEW_OA_MODEL_DOWNLOADED) {
			/* deserialize the model received over the air */
			PRINTF("New model %s received in group with instance %p\n", instance->fileNameWithModel, instance);
			newModel = NULL;
			
			/* TODO: check if the file exists */
			
			/* parse model from json file */
			jsonparse_setup(&jsonState, instance->fileNameWithModel);
			newModel = JSONKevDeserializer(&jsonState, jsonparse_next(&jsonState));
			cfs_close(jsonState.fd);
			PRINTF("INFO: Deserialization finished in Deluge Group %p\n", newModel);

			/* save a reference to the new model */
			instance->lastReceivedModel = newModel;


			/* Afterwards, just call notifyNewModel */			
			if (newModel != NULL && notifyNewModel(newModel) == PROCESS_ERR_OK) {
				PRINTF("INFO: Model was successfully sent\n");
			}
			else {
				PRINTF("ERROR: The model cannot be loaded!\n");
			}
			
		}
	}

	PROCESS_END();
}

process_event_t wismo218_command_event;

static wismo218_status_t WismoStatus;
static arnGsmRemoteCommand_t* CurrentCommand;

PROCESS(commandmanager_process, "CommandManager");
//AUTOSTART_PROCESSES(&commandmanager_process);

PROCESS_THREAD(commandmanager_process, ev, data)
{
  PROCESS_EXITHANDLER(goto exit);
  PROCESS_BEGIN();
  
  wismo218_command_event = process_alloc_event();
  WismoStatus = init_none;
  
  printf("CommandManager started.\n\r");
  while(1) {
    PROCESS_WAIT_EVENT();
    if (ev == serial_line_event_message) {
      if (data != NULL) {
	char* Dt = data;
	char* CommandParameters;
	CurrentCommand = arnCommand(Dt);
	//printf("%s:%s\n\r",__FUNCTION__,Dt);
	if ((WismoStatus == init_done) && CurrentCommand) {
	  char* pres; 
	  CommandParameters = arnCommandParameters(CurrentCommand,Dt);
	  if (CurrentCommand->Command_handler) {
Exemple #25
0
PROCESS_THREAD(cetic_6lbr_process, ev, data)
{
  static struct etimer timer;
  static int addr_number;
  PROCESS_BEGIN();

  /* Step 0: Basic infrastructure initialization */

  LOG6LBR_NOTICE("Starting 6LBR version " CETIC_6LBR_VERSION " (" CONTIKI_VERSION_STRING ")\n");

  //Turn off radio until 6LBR is properly configured
  NETSTACK_MAC.off(0);

  cetic_6lbr_restart_event = process_alloc_event();
  cetic_6lbr_reload_event = process_alloc_event();
  cetic_6lbr_startup = clock_seconds();

#if CETIC_6LBR_MULTI_RADIO
  network_itf_init();
#endif

  /* Step 1: Platform specific initialization */

  platform_init();

  /* Step 2: Register configuration hooks and set default configuration */

#if CETIC_6LBR_NODE_INFO
  node_info_config();
#endif

  /* Step 3: Load configuration from NVM and configuration file */

  platform_load_config(CONFIG_LEVEL_BOOT);

#if !LOG6LBR_STATIC
  if(nvm_data.log_level != 0xFF) {
    Log6lbr_level = nvm_data.log_level;
    Log6lbr_services = nvm_data.log_services;
  }
  LOG6LBR_NOTICE("Log level: %d (services: %x)\n", Log6lbr_level, Log6lbr_services);
#else
  LOG6LBR_NOTICE("Log level: %d (services: %x)\n", LOG6LBR_LEVEL, LOG6LBR_SERVICE_DEFAULT);
#endif

  /* Step 4: Initialize radio and network interfaces */
#if CETIC_6LBR_FRAMER_WRAPPER
  framer_wrapper_init();
#endif

#if CETIC_6LBR_MAC_WRAPPER
  mac_wrapper_init();
#endif

#if CETIC_6LBR_MULTI_RADIO
  CETIC_6LBR_MULTI_RADIO_DEFAULT_MAC.init();
#endif

#if !CETIC_6LBR_ONE_ITF
  platform_radio_init();
  while(!radio_ready) {
    PROCESS_PAUSE();
  }
#endif

  eth_drv_init();

  while(!ethernet_ready) {
    PROCESS_PAUSE();
  }

  //Turn on radio and keep it always on
  NETSTACK_MAC.off(1);

  /* Step 5: Initialize Network stack */

#if CETIC_6LBR_LLSEC_WRAPPER
#if CETIC_6LBR_WITH_ADAPTIVESEC
  llsec_strategy_wrapper_init();
#endif
  llsec_wrapper_init();
#endif

#if CETIC_6LBR_MULTICAST_WRAPPER
  multicast_wrapper_init();
#endif
  //6LoWPAN init
  memcpy(addr_contexts[0].prefix, nvm_data.wsn_6lowpan_context_0, sizeof(addr_contexts[0].prefix));

  //clean up any early packet
  uip_len = 0;
  process_start(&tcpip_process, NULL);

  PROCESS_PAUSE();

  /* Step 6: Configure network interfaces */

  packet_filter_init();
  cetic_6lbr_init();

  //Wait result of DAD on 6LBR addresses
  addr_number = uip_ds6_get_addr_number(-1);
  LOG6LBR_INFO("Checking addresses duplication\n");
  etimer_set(&timer, CLOCK_SECOND);
  while(uip_ds6_get_addr_number(ADDR_TENTATIVE) > 0) {
    PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
    etimer_set(&timer, CLOCK_SECOND);
  }
  //Can not use equality as autoconf address could be created when running DAD
  if(uip_ds6_get_addr_number(-1) < addr_number) {
    LOG6LBR_FATAL("Addresses duplication failed\n");
    cetic_6lbr_restart_type = CETIC_6LBR_RESTART;
    platform_restart();
  }

  /* Step 7: Finalize configuration of network interfaces */
  cetic_6lbr_init_finalize();

  /* Step 8: Initialize 6LBR core and base applications */

  platform_load_config(CONFIG_LEVEL_CORE);
  PROCESS_PAUSE();

#if CETIC_6LBR_WITH_WEBSERVER
  webserver_init();
#endif

#if CETIC_6LBR_NODE_INFO
  node_info_init();
#endif

#if CETIC_6LBR_NODE_CONFIG
  node_config_init();
#endif

  /* Step 9: Initialize and configure 6LBR applications */

  platform_load_config(CONFIG_LEVEL_BASE);
  PROCESS_PAUSE();

#if CETIC_6LBR_WITH_UDPSERVER
  udp_server_init();
#endif
#if UDPCLIENT
  process_start(&udp_client_process, NULL);
#endif

#if WITH_TINYDTLS
  dtls_init();
#endif

#if WITH_COAPSERVER
  if((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_COAP_SERVER) == 0) {
    coap_server_init();
  }
#endif

#if WITH_DTLS_ECHO
  process_start(&dtls_echo_server_process, NULL);
#endif

#if CETIC_6LBR_WITH_NVM_PROXY
  nvm_proxy_init();
#endif

#if CETIC_6LBR_WITH_DNS_PROXY
  dns_proxy_init();
#endif

  /* Step 10: Finalize platform configuration and load runtime configuration */

  platform_finalize();
  platform_load_config(CONFIG_LEVEL_APP);

  LOG6LBR_INFO("CETIC 6LBR Started\n");

  PROCESS_WAIT_EVENT_UNTIL(ev == cetic_6lbr_restart_event);

  etimer_set(&timer, CLOCK_SECOND);
  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);

  /* Shutdown 6LBR */

  //Turn off radio
  NETSTACK_MAC.off(0);
  platform_restart();

  PROCESS_END();
}
SOL_API struct sol_spi *
sol_spi_open(unsigned int bus, const struct sol_spi_config *config)
{
    struct sol_spi *spi;
    qm_spi_t max_bus_available;
    int ret;

    SOL_LOG_INTERNAL_INIT_ONCE;

    /* QM_SPI_NUM is always considering that both master and the slave
     * exist, so we can't use it to check the valid buses to use */
#if QUARK_SE
    max_bus_available = QM_SPI_MST_1;
#else
    max_bus_available = QM_SPI_MST_0;
#endif

    SOL_EXP_CHECK(bus >= max_bus_available, NULL);
    SOL_NULL_CHECK(config, NULL);

#ifndef SOL_NO_API_VERSION
    if (unlikely(config->api_version != SOL_SPI_CONFIG_API_VERSION)) {
        SOL_WRN("Couldn't open SPI that has unsupported version '%u', "
            "expected version is '%u'",
            config->api_version, SOL_SPI_CONFIG_API_VERSION);
        return NULL;
    }
#endif

    if (config->chip_select > 3) {
        SOL_WRN("Invalid chip_select value '%u'. Value must be between 0 and 3.",
            config->chip_select);
        return NULL;
    }

    if ((config->bits_per_word < 4) || (config->bits_per_word > 32)) {
        SOL_WRN("Invalid bits_per_word value '%" PRIu8 "'. Value must be "
            "between 4 and 32.", config->bits_per_word);
        return NULL;
    }

    spi = calloc(1, sizeof(*spi));
    SOL_NULL_CHECK(spi, NULL);

    if (!spi_irq_event) {
        bool r;

        spi_irq_event = process_alloc_event();
        r = sol_mainloop_contiki_event_handler_add(&spi_irq_event, NULL,
            spi_cb_dispatch, NULL);
        SOL_EXP_CHECK_GOTO(!r, error);
    }

    spi->bus = bus;
    spi->slave = BIT(config->chip_select);
    spi->config.frame_size = config->bits_per_word - 1;
    spi->config.transfer_mode = QM_SPI_TMOD_TX_RX;
    spi->config.bus_mode = config->mode;
    spi->config.clk_divider = 32000000 / config->frequency;

    switch (spi->bus) {
    case QM_SPI_MST_0:
        clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_SPI_M0_REGISTER);
        qm_irq_request(QM_IRQ_SPI_MASTER_0, qm_spi_master_0_isr);
        break;
#if QUARK_SE
    case QM_SPI_MST_1:
        qm_irq_request(QM_IRQ_SPI_MASTER_1, qm_spi_master_1_isr);
        break;
#endif
    case QM_SPI_SLV_0:
    case QM_SPI_NUM:
        /* We checked if we were passed the limit before, so we should never
         * hit this point. Using all the enum values and no default, however,
         * allows us to rely on the compiler to know if there are values
         * we are not considering (depending on warning levels) */
        break;
    }

    ret = spi_set_gpio_ss(spi);
    SOL_INT_CHECK_GOTO(ret, < 0, error);

    return spi;

error:
    free(spi);
    return NULL;
}
Exemple #27
0
int init_knot_network(){
   KNOT_EVENT_SERVICE_FOUND = process_alloc_event();
   KNOT_EVENT_DATA_READY    = process_alloc_event();
   init_link_layer();
   return 1;
}
SOL_API struct sol_i2c *
sol_i2c_open_raw(uint8_t bus, enum sol_i2c_speed speed)
{
    struct sol_i2c *i2c;
    qm_i2c_config_t cfg;
    qm_i2c_speed_t bus_speed;
    qm_rc_t ret;

    if (bus >= QM_I2C_NUM) {
        SOL_WRN("I2C bus #%" PRIu8 " doesn't exist.", bus);
        return NULL;
    }

    if ((i2c = buses[bus]) != NULL)
        return i2c;

    switch (speed) {
    case SOL_I2C_SPEED_10KBIT:
    case SOL_I2C_SPEED_100KBIT:
        bus_speed = QM_I2C_SPEED_STD;
        break;
    case SOL_I2C_SPEED_400KBIT:
        bus_speed = QM_I2C_SPEED_FAST;
        break;
    case SOL_I2C_SPEED_1MBIT:
    case SOL_I2C_SPEED_3MBIT_400KBIT:
        bus_speed = QM_I2C_SPEED_FAST_PLUS;
        break;
    default:
        SOL_WRN("Unsupported speed value: %d", speed);
        return NULL;
    };

    switch (bus) {
    case QM_I2C_0:
        qm_irq_request(QM_IRQ_I2C_0, qm_i2c_0_isr);
        clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_I2C_M0_REGISTER);
        break;
#if QUARK_SE
    case QM_I2C_1:
        qm_irq_request(QM_IRQ_I2C_1, qm_i2c_1_isr);
        clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_I2C_M1_REGISTER);
        break;
#endif
    case QM_I2C_NUM:
        /* We checked if we were passed the limit before, so we should never
         * hit this point. Using all the enum values and no default, however,
         * allows us to rely on the compiler to know if there are values
         * we are not considering (depending on warning levels) */
        break;
    }

    i2c = calloc(1, sizeof(*i2c));
    SOL_NULL_CHECK(i2c, NULL);

    i2c->bus = bus;

    ret = qm_i2c_get_config(i2c->bus, &cfg);
    SOL_EXP_CHECK_GOTO(ret != QM_RC_OK, error);

    cfg.speed = bus_speed;
    cfg.address_mode = QM_I2C_7_BIT;
    cfg.mode = QM_I2C_MASTER;
    cfg.slave_addr = 0;

    ret = qm_i2c_set_config(i2c->bus, &cfg);
    SOL_EXP_CHECK_GOTO(ret != QM_RC_OK, error);

    if (!i2c_irq_event) {
        bool r;

        i2c_irq_event = process_alloc_event();
        r = sol_mainloop_contiki_event_handler_add(&i2c_irq_event, NULL,
            i2c_cb_dispatch, NULL);
        SOL_EXP_CHECK_GOTO(!r, error);
    }

    buses[i2c->bus] = i2c;

    return i2c;

error:
    free(i2c);
    return NULL;
}
Exemple #29
0
PROCESS_THREAD(cetic_6lbr_process, ev, data)
{
  PROCESS_BEGIN();

  cetic_6lbr_restart_event = process_alloc_event();
  cetic_6lbr_startup = clock_seconds();

#if CONTIKI_TARGET_NATIVE
  slip_config_handle_arguments(contiki_argc, contiki_argv);
  if (watchdog_interval) {
    process_start(&native_6lbr_watchdog, NULL);
  } else {
    LOG6LBR_WARN("6LBR Watchdog disabled\n");
  }
#endif

  LOG6LBR_INFO("Starting 6LBR version " CETIC_6LBR_VERSION " (" CONTIKI_VERSION_STRING ")\n");

  load_nvm_config();

  platform_init();

  process_start(&eth_drv_process, NULL);

  while(!ethernet_ready) {
    PROCESS_PAUSE();
  }

  //clean up any early packet
  uip_len = 0;
  process_start(&tcpip_process, NULL);

  PROCESS_PAUSE();

#if CETIC_NODE_INFO
  node_info_init();
#endif

  packet_filter_init();
  cetic_6lbr_init();

#if WEBSERVER
  process_start(&webserver_nogui_process, NULL);
#endif
#if UDPSERVER
  process_start(&udp_server_process, NULL);
#endif
#if UDPCLIENT
  process_start(&udp_client_process, NULL);
#endif
#if WITH_COAP
  process_start(&coap_server_process, NULL);
#endif

#if WITH_NVM_PROXY
  nvm_proxy_init();
#endif

#if CONTIKI_TARGET_NATIVE
  plugins_load();
#endif

  LOG6LBR_INFO("CETIC 6LBR Started\n");

  PROCESS_WAIT_EVENT_UNTIL(ev == cetic_6lbr_restart_event);
  etimer_set(&reboot_timer, CLOCK_SECOND);
  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
#if CONTIKI_TARGET_NATIVE
  switch (cetic_6lbr_restart_type) {
    case CETIC_6LBR_RESTART:
      LOG6LBR_INFO("Exiting...\n");
      exit(0);
      break;
    case CETIC_6LBR_REBOOT:
      LOG6LBR_INFO("Rebooting...\n");
      system("reboot");
      break;
    case CETIC_6LBR_HALT:
      LOG6LBR_INFO("Halting...\n");
      system("halt");
      break;
    default:
      //We should never end up here...
      exit(1);
  }
  //We should never end up here...
  exit(1);
#else
  LOG6LBR_INFO("Rebooting...\n");
  watchdog_reboot();
#endif

  PROCESS_END();
}