Example #1
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(cc2420_process, ev, data)
{
  int len;
  PROCESS_BEGIN();

  PRINTF("cc2420_process: started\n");

  while(1) {
    PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
#if CC2420_TIMETABLE_PROFILING
    TIMETABLE_TIMESTAMP(cc2420_timetable, "poll");
#endif /* CC2420_TIMETABLE_PROFILING */
    
    PRINTF("cc2420_process: calling receiver callback\n");

    packetbuf_clear();
    packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, last_packet_timestamp);
    len = cc2420_read(packetbuf_dataptr(), PACKETBUF_SIZE);
    
    packetbuf_set_datalen(len);
    
    NETSTACK_RDC.input();
#if CC2420_TIMETABLE_PROFILING
    TIMETABLE_TIMESTAMP(cc2420_timetable, "end");
    timetable_aggregate_compute_detailed(&aggregate_time,
                                         &cc2420_timetable);
      timetable_clear(&cc2420_timetable);
#endif /* CC2420_TIMETABLE_PROFILING */
  }

  PROCESS_END();
}
Example #2
0
/* Process to handle input packets
 * Receive interrupts cause this process to be polled
 * It calls the core MAC layer which calls rf230_read to get the packet
*/
PROCESS_THREAD(nrf24l01_process, ev, data)
{
  PROCESS_BEGIN();
  
  while(1) 
  {
    PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
    
#if RF230_TIMETABLE_PROFILING
    TIMETABLE_TIMESTAMP(rf230_timetable, "poll");
#endif /* RF230_TIMETABLE_PROFILING */
        
    if(receiver_callback != NULL) 
    {
      receiver_callback(&nrf24l01_driver);
	  
#if RF230_TIMETABLE_PROFILING
      TIMETABLE_TIMESTAMP(rf230_timetable, "end");
      timetable_aggregate_compute_detailed(&aggregate_time,
					   &rf230_timetable);
      timetable_clear(&rf230_timetable);
#endif /* RF230_TIMETABLE_PROFILING */
    } 
    else 
    {
      PRINTF("nrf24l01_process not receiving function\n");
      //flushrx();
    }
  }

  PROCESS_END();
}
Example #3
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(cc2420_process, ev, data)
{
  PROCESS_BEGIN();

  PRINTF("cc2420_process: started\n");
  
  while(1) {
    PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
#if CC2420_TIMETABLE_PROFILING
    TIMETABLE_TIMESTAMP(cc2420_timetable, "poll");
#endif /* CC2420_TIMETABLE_PROFILING */
        
    if(receiver_callback != NULL) {
      PRINTF("cc2420_process: calling receiver callback\n");
      receiver_callback(&cc2420_driver);
#if CC2420_TIMETABLE_PROFILING
      TIMETABLE_TIMESTAMP(cc2420_timetable, "end");
      timetable_aggregate_compute_detailed(&aggregate_time,
					   &cc2420_timetable);
      timetable_clear(&cc2420_timetable);
#endif /* CC2420_TIMETABLE_PROFILING */
    } else {
      PRINTF("cc2420_process not receiving function\n");
      flushrx();
    }
  }

  PROCESS_END();
}
Example #4
0
/*---------------------------------------------------------------------------*/
void
timetable_init(void)
{
  char dummy1, dummy2;
#define temp_size 4
  TIMETABLE_STATIC(temp);
  
  timetable_clear(&temp);

  /* Measure the time for taking a timestamp. */
  TIMETABLE_TIMESTAMP(temp, &dummy1);
  TIMETABLE_TIMESTAMP(temp, &dummy2);
  timetable_timestamp_time = timetable_timediff(&temp, &dummy1, &dummy2);
}
Example #5
0
/*---------------------------------------------------------------------------*/
static void
off(void)
{
  if(xmac_is_on && radio_is_on != 0) {
    radio_is_on = 0;
    radio->off();
#if WITH_TIMETABLE
    TIMETABLE_TIMESTAMP(xmac_timetable, "off");
#endif
    LEDS_OFF(LEDS_RED);
    CPRINTF("\\");
  }
}
Example #6
0
/*---------------------------------------------------------------------------*/
static void
on(void)
{
  if(xmac_is_on && radio_is_on == 0) {
    radio_is_on = 1;
    radio->on();
    LEDS_ON(LEDS_RED);
    CPRINTF("/");
#if WITH_TIMETABLE
    TIMETABLE_TIMESTAMP(xmac_timetable, "on");
#endif
  }
}
Example #7
0
/*
 * Interrupt leaves frame intact in FIFO.
 */
static volatile rtimer_clock_t interrupt_time;
static volatile int interrupt_time_set;
#if CC2420_TIMETABLE_PROFILING
#define cc2420_timetable_size 16
TIMETABLE(cc2420_timetable);
TIMETABLE_AGGREGATE(aggregate_time, 10);
#endif /* CC2420_TIMETABLE_PROFILING */
int
cc2420_interrupt(void)
{
  interrupt_time = timesynch_time();
  interrupt_time_set = 1;

  CLEAR_FIFOP_INT();
  process_poll(&cc2420_process);
#if CC2420_TIMETABLE_PROFILING
  timetable_clear(&cc2420_timetable);
  TIMETABLE_TIMESTAMP(cc2420_timetable, "interrupt");
#endif /* CC2420_TIMETABLE_PROFILING */
  return 1;
}
/*
 * Interrupt leaves frame intact in FIFO.
 */
#if CC2420_TIMETABLE_PROFILING
#define cc2420_timetable_size 16
TIMETABLE(cc2420_timetable);
TIMETABLE_AGGREGATE(aggregate_time, 10);
#endif /* CC2420_TIMETABLE_PROFILING */
int
cc2420_interrupt(void)
{
  CC2420_CLEAR_FIFOP_INT();
  process_poll(&cc2420_process);
#if CC2420_TIMETABLE_PROFILING
  timetable_clear(&cc2420_timetable);
  TIMETABLE_TIMESTAMP(cc2420_timetable, "interrupt");
#endif /* CC2420_TIMETABLE_PROFILING */

  pending++;
  cc2420_packets_seen++;
  return 1;
}
Example #9
0
/*
 * Interrupt leaves frame intact in FIFO.
 */
#if CC2420_TIMETABLE_PROFILING
#define cc2420_timetable_size 16
TIMETABLE(cc2420_timetable);
TIMETABLE_AGGREGATE(aggregate_time, 10);
#endif /* CC2420_TIMETABLE_PROFILING */
int
cc2420_interrupt(void)
{
	//printf("Enter cc2420 interrupt.\n");
  CC2420_CLEAR_FIFOP_INT();
  process_poll(&cc2420_process);
#if CC2420_TIMETABLE_PROFILING
  timetable_clear(&cc2420_timetable);
  TIMETABLE_TIMESTAMP(cc2420_timetable, "interrupt");
#endif /* CC2420_TIMETABLE_PROFILING */

  last_packet_timestamp = cc2420_sfd_start_time;
  //printf("Radio rec time = %u\n",cc2420_sfd_start_time);
  pending++;
  cc2420_packets_seen++;
  return 1;
}
Example #10
0
void
nrf24l01_interrupt(void)
{
#if RF230_CONF_TIMESTAMPS
  interrupt_time = timesynch_time();
  interrupt_time_set = 1;
#endif /* RF230_CONF_TIMESTAMPS */

  isr_event_write.isr_type= ISR_RX_DR;
  process_poll(&nrf24l01_process); 
  
#if RF230_TIMETABLE_PROFILING
  timetable_clear(&rf230_timetable);
  TIMETABLE_TIMESTAMP(rf230_timetable, "interrupt");
#endif /* RF230_TIMETABLE_PROFILING */
  return;
}
Example #11
0
nRF24L01_ISR()
{
#if RF230_CONF_TIMESTAMPS
  interrupt_time = timesynch_time();
  interrupt_time_set = 1;
#endif /* RF230_CONF_TIMESTAMPS */  

  volatile uint8_t status;    
  status = spi_register_read(NOP);
  //PRINTF("ISR: status=0x%x\r\n", status);
  //Rx FIFO data ready
  if(status & (1 << MASK_RX_DR))
  {        
	uint8_t rx_pipe_no = (status & 0x07);
	if(rx_pipe_no < 6)
	{
	    status_rx_dr_handler(rx_pipe_no);
	}
	sbi(status, MASK_RX_DR);
    }
    //Tx FIFO data has been sent successfully
    else if(status & (1 << MASK_TX_DS))
    {
	status_tx_ds_handler();
	sbi(status, MASK_TX_DS);  //clear intertupt
    }
    //Re transmit is up to the max counter, 
    //Note: 
    // 1. If you don't clear this interrupt, no data can be transmitted any more
    // 2. The package lost counter(PLOS_CNT) is incremented at each MAX_RT interrupt	
    else if(status & (1 << MASK_MAX_RT))
    {
	status_max_rt_handler();
        sbi(status, MASK_MAX_RT);  //clear the interrupt
    }
    else
    {}
    //clean interrupts
    SPI_WRITE_REG(WRITE_REG+STATUS, status);        

    #if RF230_TIMETABLE_PROFILING
      timetable_clear(&rf230_timetable);
      TIMETABLE_TIMESTAMP(rf230_timetable, "interrupt");
    #endif /* RF230_TIMETABLE_PROFILING */
}
Example #12
0
/*---------------------------------------------------------------------------*/
static int
read_packet(void)
{
  struct xmac_hdr *hdr;
  uint8_t len;

  rimebuf_clear();

  len = radio->read(rimebuf_dataptr(), RIMEBUF_SIZE);

  if(len > 0) {
    rimebuf_set_datalen(len);
    hdr = rimebuf_dataptr();

    rimebuf_hdrreduce(sizeof(struct xmac_hdr));

    if(rimebuf_totlen() == 0) {
      CPRINTF(".");
      /* There is no data in the packet so it has to be a strobe. */
      someone_is_sending = 2;
      
      if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_node_addr)) {
	/* This is a strobe packet for us. */

	if(rimeaddr_cmp(&hdr->sender, &rimeaddr_node_addr)) {
	  /* If the sender address is our node address, the strobe is
	     a stray strobe ACK to us, which we ignore unless we are
	     currently sending a packet.  */
	  CPRINTF("&");
	  someone_is_sending = 0;
	} else {
	  struct xmac_hdr msg;
	  /* If the sender address is someone else, we should
	     acknowledge the strobe and wait for the packet. By using
	     the same address as both sender and receiver, we flag the
	     message is a strobe ack. */
#if WITH_TIMETABLE
	  TIMETABLE_TIMESTAMP(xmac_timetable, "read send ack");
#endif
	  rimeaddr_copy(&msg.receiver, &hdr->sender);
	  rimeaddr_copy(&msg.sender, &hdr->sender);
	  CPRINTF("!");
	  /* We turn on the radio in anticipation of the incoming
	     packet. */
	  someone_is_sending = 1;
	  waiting_for_packet = 1;
	  on();
	  radio->send((const uint8_t *)&msg, sizeof(struct xmac_hdr));
	}
      } else if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_null)) {
	/* If the receiver address is null, the strobe is sent to
	   prepare for an incoming broadcast packet. If this is the
	   case, we turn on the radio and wait for the incoming
	   broadcast packet. */
	waiting_for_packet = 1;
	on();
      }
      /* We are done processing the strobe and we therefore return
	 to the caller. */
      return RIME_OK;
    } else {
      CPRINTF("-");
      someone_is_sending = 0;
      if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_node_addr) ||
	 rimeaddr_cmp(&hdr->receiver, &rimeaddr_null)) {
#if WITH_TIMETABLE
	TIMETABLE_TIMESTAMP(xmac_timetable, "read got packet");
#endif
	/* This is a regular packet that is destined to us or to the
	   broadcast address. */
	
	/* We have received the final packet, so we can go back to being
	   asleep. */
	off();
	waiting_for_packet = 0;
	
	/* XXX should set timer to send queued packet later. */
	if(queued_packet != NULL) {
	  queuebuf_free(queued_packet);
	  queued_packet = NULL;
	}
	
	return rimebuf_totlen();
      }
    }
  }
  return 0;
}
Example #13
0
/*---------------------------------------------------------------------------*/
static int
send_packet(void)
{
  rtimer_clock_t t0;
  rtimer_clock_t t;
  int strobes;
  struct xmac_hdr *hdr;
  int got_ack = 0;
  struct xmac_hdr msg;
  int len;
  int is_broadcast = 0;

#if WITH_TIMETABLE
  TIMETABLE_TIMESTAMP(xmac_timetable, "send");
#endif
  
#if WITH_CHANNEL_CHECK
  /* Check if there are other strobes in the air. */
  waiting_for_packet = 1;
  on();
  t0 = RTIMER_NOW();
  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + xmac_config.strobe_wait_time * 2)) {
    len = radio->read(&msg, sizeof(msg));
    if(len > 0) {
      someone_is_sending = 1;
    }
  }
  waiting_for_packet = 0;
  
  while(someone_is_sending); /* {printf("z");}*/

#if WITH_TIMETABLE
  TIMETABLE_TIMESTAMP(xmac_timetable, "send 2");
#endif /* WITH_TIMETABLE */
  
#endif /* WITH_CHANNEL_CHECK */
  
  /* By setting we_are_sending to one, we ensure that the rtimer
     powercycle interrupt do not interfere with us sending the packet. */
  we_are_sending = 1;

  off();

  
  rimebuf_hdralloc(sizeof(struct xmac_hdr));
  hdr = rimebuf_hdrptr();
  rimeaddr_copy(&hdr->sender, &rimeaddr_node_addr);
  rimeaddr_copy(&hdr->receiver, rimebuf_addr(RIMEBUF_ADDR_RECEIVER));
  if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_null)) {
    is_broadcast = 1;
  }
  rimebuf_compact();

  t0 = RTIMER_NOW();
  strobes = 0;

  BB_SET(XMAC_RECEIVER, hdr->receiver.u16[0]);
  
  LEDS_ON(LEDS_BLUE);

  /* Send a train of strobes until the receiver answers with an ACK. */

  /* Turn on the radio to listen for the strobe ACK. */
  if(!is_broadcast) {
    on();
  }

  watchdog_stop();
  got_ack = 0;
  for(strobes = 0;
      got_ack == 0 &&
	RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + xmac_config.strobe_time);
      strobes++) {

    t = RTIMER_NOW();

    rimeaddr_copy(&msg.sender, &rimeaddr_node_addr);
    rimeaddr_copy(&msg.receiver, rimebuf_addr(RIMEBUF_ADDR_RECEIVER));

#if WITH_TIMETABLE
    if(rimeaddr_cmp(&msg.receiver, &rimeaddr_null)) {
      TIMETABLE_TIMESTAMP(xmac_timetable, "send broadcast strobe");
    } else {
      TIMETABLE_TIMESTAMP(xmac_timetable, "send strobe");
    }
#endif
    if(is_broadcast) {
      /* If we are sending a broadcast, we don't send strobes, we
	 simply send the data packet repetedly */
      radio->send(rimebuf_hdrptr(), rimebuf_totlen());
    } else {
      /* Send the strobe packet. */
      radio->send((const uint8_t *)&msg, sizeof(struct xmac_hdr));
    }
    CPRINTF("+");

    while(got_ack == 0 &&
	  RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time)) {
      /* See if we got an ACK */
      len = radio->read((uint8_t *)&msg, sizeof(struct xmac_hdr));
      if(len > 0) {
	CPRINTF("_");
	if(rimeaddr_cmp(&msg.sender, &rimeaddr_node_addr) &&
	   rimeaddr_cmp(&msg.receiver, &rimeaddr_node_addr)) {
#if WITH_TIMETABLE
	  TIMETABLE_TIMESTAMP(xmac_timetable, "send ack received");
#endif
	  CPRINTF("@");
	  /* We got an ACK from the receiver, so we can immediately send
	     the packet. */
	  got_ack = 1;
	}
      }
    }

    /* XXX: turn off radio if we haven't heard an ACK within a
       specified time interval. */

    /*    if(got_ack == 0) {
      off();
      while(RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time));
      on();
      }*/
  }

  if(got_ack /* XXX && needs_ack */) {
#if WITH_TIMETABLE
    TIMETABLE_TIMESTAMP(xmac_timetable, "send got ack");
#endif
    on(); /* Wait for possible ACK packet */
  } else if(!is_broadcast) {
#if WITH_TIMETABLE
    TIMETABLE_TIMESTAMP(xmac_timetable, "send no ack received");
#endif
    on(); /* shell ping don't seem to work with off() here, so we'll
	     keep it on() for a while. */
  }

  /* Send the data packet. */
  if(is_broadcast || got_ack) {
#if WITH_TIMETABLE
    TIMETABLE_TIMESTAMP(xmac_timetable, "send packet");
#endif
    radio->send(rimebuf_hdrptr(), rimebuf_totlen());
    CPRINTF("#");
  }
  watchdog_start();

  PRINTF("xmac: send (strobes=%u,len=%u,%s), done\n", strobes,
	 rimebuf_totlen(), got_ack ? "ack" : "no ack");

  BB_SET(XMAC_STROBES, strobes);
  if(got_ack) {
    BB_INC(XMAC_SEND_WITH_ACK, 1);
  } else {
    BB_INC(XMAC_SEND_WITH_NOACK, 1);
  }

  /*  printf("Strobe %d got_ack %d\n", strobes, got_ack);*/

  we_are_sending = 0;
#if WITH_TIMETABLE
  TIMETABLE_TIMESTAMP(xmac_timetable, "send we_are_sending = 0");
#endif
  LEDS_OFF(LEDS_BLUE);
  return 1;

}
Example #14
0
/*---------------------------------------------------------------------------*/
static char 
powercycle(struct rtimer *t, void *ptr)
{
  int r;
#if WITH_TIMESYNCH
  rtimer_clock_t should_be, adjust;
#endif /* WITH_TIMESYNCH */

  CPRINTF("*");
  
  PT_BEGIN(&pt);

  while(1) {
    /* Only wait for some cycles to pass for someone to start sending */
    if(someone_is_sending > 0) {
      someone_is_sending--;
    }

    if(xmac_config.off_time > 0) {
      if(waiting_for_packet == 0) {
	if(we_are_sending == 0) {
	  off();
	}
      } else {
	waiting_for_packet++;
	if(waiting_for_packet > 2) {
	  /* We should not be awake for more than two consecutive
	     power cycles without having heard a packet, so we turn off
	     the radio. */
	  waiting_for_packet = 0;
#if WITH_TIMETABLE
	  TIMETABLE_TIMESTAMP(xmac_timetable, "off waiting");
#endif
	  off();
	}
      }

#if WITH_TIMESYNCH
#define NUM_SLOTS 8
      should_be = ((timesynch_rtimer_to_time(RTIMER_TIME(t)) +
		    xmac_config.off_time) &
		   ~(xmac_config.off_time + xmac_config.on_time - 1)) +
	(rimeaddr_node_addr.u8[0] % NUM_SLOTS *
	 ((xmac_config.off_time + xmac_config.on_time) / NUM_SLOTS));

      should_be = timesynch_time_to_rtimer(should_be);

      if(should_be - RTIMER_TIME(t) > xmac_config.off_time) {
	adjust = xmac_config.off_time / 2;
      } else {
	adjust = should_be - RTIMER_TIME(t);
      }
      r = rtimer_set(t, RTIMER_TIME(t) + adjust, 1,
		     (void (*)(struct rtimer *, void *))powercycle, ptr);
#else /* WITH_TIMESYNCH */
      r = rtimer_set(t, RTIMER_TIME(t) + xmac_config.off_time, 1,
		     TC(powercycle), ptr);
#endif /* WITH_TIMESYNCH */
      if(r) {
	PRINTF("xmac: 1 could not set rtimer %d\n", r);
      }
      PT_YIELD(&pt);
    }

    if(we_are_sending == 0 &&
       waiting_for_packet == 0) {
      on();
    }
    r = rtimer_set(t, RTIMER_TIME(t) + xmac_config.on_time, 1,
		   TC(powercycle), ptr);
    if(r) {
      PRINTF("xmac: 3 could not set rtimer %d\n", r);
    }

    PT_YIELD(&pt);
  }

  PT_END(&pt);
}