示例#1
0
文件: cc2420.c 项目: EDAyele/ptunes
void
cc2420_on(void)
{
  if (receive_on)
    return;
  receive_on = 1;

  cc2420_strobe(CC2420_SRXON);
  cc2420_strobe(CC2420_SFLUSHRX);
  ENABLE_FIFOP_INT();
}
示例#2
0
int cc2420_rx(cc2420_t *dev, uint8_t *buf, size_t max_len, void *info)
{
    (void)info;

    uint8_t len;
    uint8_t crc_corr;

    /* without a provided buffer, only readout the length and return it */
    if (buf == NULL) {
        /* get the packet length (without dropping it) (first byte in RX FIFO) */
        cc2420_ram_read(dev, CC2420_RAM_RXFIFO, &len, 1);
        len -= 2;   /* subtract RSSI and FCF */
        DEBUG("cc2420: recv: packet of length %i in RX FIFO\n", (int)len);
    }
    else {
        /* read length byte */
        cc2420_fifo_read(dev, &len, 1);
        len -= 2;   /* subtract RSSI and FCF */

        /* if a buffer is given, read (and drop) the packet */
        len = (len > max_len) ? max_len : len;

        /* read fifo contents */
        DEBUG("cc2420: recv: reading %i byte of the packet\n", (int)len);
        cc2420_fifo_read(dev, buf, len);

        int8_t rssi;
        cc2420_fifo_read(dev, (uint8_t*)&rssi, 1);
        DEBUG("cc2420: recv: RSSI is %i\n", (int)rssi);

        /* fetch and check if CRC_OK bit (MSB) is set */
        cc2420_fifo_read(dev, &crc_corr, 1);
        if (!(crc_corr & 0x80)) {
            DEBUG("cc2420: recv: CRC_OK bit not set, dropping packet\n");
            /* drop the corrupted frame from the RXFIFO */
            len = 0;
        }
        if (info != NULL) {
            netdev_ieee802154_rx_info_t *radio_info = info;
            radio_info->rssi = CC2420_RSSI_OFFSET + rssi;
            radio_info->lqi = crc_corr & CC2420_CRCCOR_COR_MASK;
        }

        /* finally flush the FIFO */
        cc2420_strobe(dev, CC2420_STROBE_FLUSHRX);
        cc2420_strobe(dev, CC2420_STROBE_FLUSHRX);
    }

    return (int)len;
}
示例#3
0
size_t cc2420_tx_prepare(cc2420_t *dev, const iolist_t *iolist)
{
    size_t pkt_len = 2;     /* include the FCS (frame check sequence) */

    /* wait for any ongoing transmissions to be finished */
    DEBUG("cc2420: tx_exec: waiting for any ongoing transmission\n");
    while (cc2420_get_state(dev) & NETOPT_STATE_TX) {}

    /* get and check the length of the packet */
    for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
        pkt_len += iol->iol_len;
    }
    if (pkt_len >= CC2420_PKT_MAXLEN) {
        DEBUG("cc2420: tx_prep: unable to send, pkt too large\n");
        return 0;
    }

    /* flush TX FIFO and write new packet to it */
    cc2420_strobe(dev, CC2420_STROBE_FLUSHTX);
    /* push packet length to TX FIFO */
    cc2420_fifo_write(dev, (uint8_t *)&pkt_len, 1);
    /* push packet to TX FIFO */
    for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
        cc2420_fifo_write(dev, iol->iol_base, iol->iol_len);
    }
    DEBUG("cc2420: tx_prep: loaded %i byte into the TX FIFO\n", (int)pkt_len);

    return pkt_len;
}
示例#4
0
文件: cc2420.c 项目: EDAyele/ptunes
/*
 * Request packet to be sent using CSMA-CA. Requires that RSSI is
 * valid.
 *
 * Return UIP_FW_DROPPED on failure.
 */
int
cc2420_resend(void)
{
  unsigned i;
  
  if (FIFOP_IS_1 && !FIFO_IS_1) {
    process_poll(&cc2420_process);
    PRINTF("rxfifo overflow!\n");
  }

  /* The TX FIFO can only hold one packet! Make sure to not overrun
   * FIFO by waiting for transmission to start here and synchronizing
   * with the CC2420_TX_ACTIVE check in cc2420_send.
   *
   * Note that we may have to wait up to 320 us (20 symbols) before
   * transmission starts.
   */
#ifdef TMOTE_SKY
#define LOOP_20_SYMBOLS 100	/* 326us (msp430 @ 2.4576MHz) */
#elif __AVR__
#define LOOP_20_SYMBOLS 500	/* XXX */
#endif
  if (CCA_IS_1) {
    cc2420_strobe(CC2420_STXONCCA);
    for (i = LOOP_20_SYMBOLS; i > 0; i--)
      if (SFD_IS_1) {
	if (cc2420_status() & BV(CC2420_TX_ACTIVE))
	  return UIP_FW_OK;	/* Transmission has started. */
	else
	  break;		/* We must be receiving. */
      }
  }

  return UIP_FW_DROPPED;	/* Transmission never started! */
}
示例#5
0
void cc2420_tx_exec(cc2420_t *dev)
{
    /* trigger the transmission */
    if (dev->options & CC2420_OPT_TELL_TX_START) {
        dev->netdev.netdev.event_callback(&dev->netdev.netdev,
                                          NETDEV_EVENT_TX_STARTED);
    }
    DEBUG("cc2420: tx_exec: TX_START\n");
    if (dev->options & CC2420_OPT_CSMA) {
        DEBUG("cc2420: tx_exec: triggering TX with CCA\n");
        cc2420_strobe(dev, CC2420_STROBE_TXONCCA);
    }
    else {
        DEBUG("cc2420: tx_exec: triggering TX without CCA\n");
        cc2420_strobe(dev, CC2420_STROBE_TXON);
    }
}
示例#6
0
文件: cc2420.c 项目: DonjuanChu/RIOT
void cc2420_init(int tpid)
{
    uint16_t reg;
    transceiver_pid = tpid;

    cc2420_spi_init();
    hwtimer_wait(CC2420_WAIT_TIME);
    cc2420_reset();

    cc2420_strobe(CC2420_STROBE_XOSCON);               //enable crystal

    while((cc2420_strobe(NOBYTE) & 0x40) == 0);        //wait for crystal to be stable
    hwtimer_wait(CC2420_WAIT_TIME);

    reg = cc2420_read_reg(CC2420_REG_MDMCTRL0);
    reg |= CC2420_ADR_DECODE;                          //enable adr decode
    reg |= CC2420_AUTOACK;                             //enable auto ack
    reg |= CC2420_AUTOCRC;                             //enable auto crc
    reg &= ~(CC2420_RES_FRM_MODE);                     //disable reserved frames
    cc2420_write_reg(CC2420_REG_MDMCTRL0, reg);

    /* Change default values as recomended in the data sheet, */
    /* RX bandpass filter = 1.3uA. */
    reg = cc2420_read_reg(CC2420_REG_RXCTRL1);
    reg |= CC2420_RXBPF_LOCUR;
    cc2420_write_reg(CC2420_REG_RXCTRL1, reg);

    /* Set the FIFOP threshold to maximum. */
    cc2420_write_reg(CC2420_REG_IOCFG0, 127);

    /* Turn off "Security enable" (page 32). */
    reg = cc2420_read_reg(CC2420_REG_SECCTRL0);
    reg &= ~CC2420_RXFIFO_PROTECTION;
    cc2420_write_reg(CC2420_REG_SECCTRL0, reg);

    /* set output power to 0dbm */
    cc2420_write_reg(CC2420_REG_TXCTRL, 0xA0FF);

    cc2420_set_channel(CC2420_DEFAULT_CHANNR);
    cc2420_set_pan(0x1111);
    DEBUG("CC2420 initialized and set to channel %i and pan %i\n", radio_channel, radio_pan);
    cc2420_init_interrupts();
    cc2420_switch_to_rx();

}
示例#7
0
文件: cc2420.c 项目: EDAyele/ptunes
void
cc2420_off(void)
{
  u8_t spiStatusByte;

  if (receive_on == 0)
    return;
  receive_on = 0;
  /* Wait for transmission to end before turning radio off. */
  do {
    spiStatusByte = cc2420_status();
  } while (spiStatusByte & BV(CC2420_TX_ACTIVE));

  cc2420_strobe(CC2420_SRFOFF);
  DISABLE_FIFOP_INT();
}
示例#8
0
文件: cc2420.c 项目: EDAyele/ptunes
void
cc2420_init(void)
{
  u16_t reg;
  {
    int s = splhigh();
    __cc2420_arch_init();		/* Initalize ports and SPI. */
    DISABLE_FIFOP_INT();
    FIFOP_INT_INIT();
    splx(s);
  }

  /* Turn on voltage regulator and reset. */
  SET_VREG_ACTIVE();
  //clock_delay(250); OK
  SET_RESET_ACTIVE();
  clock_delay(127);
  SET_RESET_INACTIVE();
  //clock_delay(125); OK


  /* Turn on the crystal oscillator. */
  cc2420_strobe(CC2420_SXOSCON);

  /* Turn on automatic packet acknowledgment. */
  reg = cc2420_getreg(CC2420_MDMCTRL0);
  reg |= AUTOACK;
  cc2420_setreg(CC2420_MDMCTRL0, reg);

  /* Change default values as recomended in the data sheet, */
  /* correlation threshold = 20, RX bandpass filter = 1.3uA. */
  cc2420_setreg(CC2420_MDMCTRL1, CORR_THR(20));
  reg = cc2420_getreg(CC2420_RXCTRL1);
  reg |= RXBPF_LOCUR;
  cc2420_setreg(CC2420_RXCTRL1, reg);
  
  /* Set the FIFOP threshold to maximum. */
  cc2420_setreg(CC2420_IOCFG0, FIFOP_THR(127));

  /* Turn off "Security enable" (page 32). */
  reg = cc2420_getreg(CC2420_SECCTRL0);
  reg &= ~RXFIFO_PROTECTION;
  cc2420_setreg(CC2420_SECCTRL0, reg);

  cc2420_set_chan_pan_addr(11, 0xffff, 0x0000, NULL);
}
示例#9
0
文件: cc2420.c 项目: EDAyele/ptunes
int
cc2420_send(struct hdr_802_15 *hdr, u8_t hdr_len,
	    const u8_t *payload, u8_t payload_len)
{
  u8_t spiStatusByte;
  int s;

  /* struct hdr_802_15::len shall *not* be counted, thus the -1.
   * 2 == sizeof(footer).
   */
  if (((hdr_len - 1) + payload_len + 2) > MAX_PACKET_LEN)
    return -1;

  /* This code uses the CC2420 CCA (Clear Channel Assessment) to
   * implement Carrier Sense Multiple Access with Collision Avoidance
   * (CSMA-CA) and requires the receiver to be enabled and ready.
   */
  if (!receive_on)
    return -2;

  /* Wait for previous transmission to finish and RSSI. */
  do {
    spiStatusByte = cc2420_status();
    if (!(spiStatusByte & BV(CC2420_RSSI_VALID))) /* RSSI needed by CCA */
      continue;
  } while (spiStatusByte & BV(CC2420_TX_ACTIVE));

  hdr->dst_pan = pan_id;	/* Not at fixed position! xxx/bg */
  last_dst = hdr->dst;		/* Not dst either. */
  last_used_seq++;
  hdr->seq = last_used_seq;
  cc2420_ack_received = 0;

  /* Write packet to TX FIFO, appending FCS if AUTOCRC is enabled. */
  cc2420_strobe(CC2420_SFLUSHTX); /* Cancel send that never started. */
  s = splhigh();
  FASTSPI_WRITE_FIFO(hdr, hdr_len);
  FASTSPI_WRITE_FIFO(payload, payload_len);
  splx(s);

  /* Send stuff from FIFO now! */
  process_post_synch(&cc2420_retransmit_process, PROCESS_EVENT_MSG, NULL);

  return UIP_FW_OK;
}
示例#10
0
文件: cc2420.c 项目: DonjuanChu/RIOT
void cc2420_rxoverflow_irq(void)
{
    cc2420_strobe(CC2420_STROBE_FLUSHRX);
    //Datasheets says do this twice...
    cc2420_strobe(CC2420_STROBE_FLUSHRX);
}
示例#11
0
文件: cc2420.c 项目: DonjuanChu/RIOT
void cc2420_switch_to_rx(void) {
    cc2420_strobe(CC2420_STROBE_RFOFF);
    cc2420_strobe(CC2420_STROBE_FLUSHRX);
    cc2420_strobe(CC2420_STROBE_FLUSHRX);
    cc2420_strobe(CC2420_STROBE_RXON);
}
示例#12
0
文件: cc2420.c 项目: EDAyele/ptunes
PROCESS_THREAD(cc2420_process, ev, data)
{
  PROCESS_BEGIN();

  process_start(&cc2420_retransmit_process, NULL);

  while (1) {
    unsigned len;
    int s;

    PROCESS_YIELD();

    len = rx_fifo_remaining_bytes;
    if (len > 0) {
      /* Read payload and two bytes of footer */
      if ((len - 2) > (UIP_BUFSIZE - UIP_LLH_LEN) || len < 2) {
	PRINTF("cc2420_process too big len=%d\n", len);
	s = splhigh();
	FASTSPI_READ_FIFO_GARBAGE(len);
	rx_fifo_remaining_bytes = 0; /* RX FIFO emptied! */
	splx(s);
	len = 0;
      } else {
	u8_t footer[2];
	uip_len = 0;
	s = splhigh();
	if (len > 2)
	  FASTSPI_READ_FIFO_NO_WAIT(&uip_buf[UIP_LLH_LEN], len - 2);
	FASTSPI_READ_FIFO_NO_WAIT(footer, 2);
	rx_fifo_remaining_bytes = 0; /* RX FIFO emptied! */
	splx(s);
	if (footer[1] & FOOTER1_CRC_OK) {
	  cc2420_last_rssi = footer[0];
	  cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION;
	  if ((h.fc0 & FC0_TYPE_MASK) == FC0_TYPE_DATA)
	    uip_len = len - 2;
	}
      }
    }

    if (len == 2)
      PRINTF("recv data_ack\n");

    /* Clean up in case of FIFO overflow!  This happens for every full
     * length frame and is signaled by FIFOP = 1 and FIFO = 0.
     */
    if (FIFOP_IS_1 && !FIFO_IS_1) {
      cc2420_strobe(CC2420_SFLUSHRX);
      cc2420_strobe(CC2420_SFLUSHRX);
    }

    if (FIFOP_IS_1) {
      s = splhigh();
      __cc2420_intr();		/* Fake interrupt! */
      splx(s);
    }

    if (len == 2) {		/* A DATA ACK packet. */
      if (last_dst == h.src)
	cc2420_ack_received = 1;
      neigbour_update(h.src, 0);
    } else if (len > 2 && uip_len > 0
       && uip_len == (((u16_t)(BUF->len[0]) << 8) + BUF->len[1])) {
      /*
       * If we are the unique receiver send DATA ACK.
       */
      if (h.dst == 0xffff
	  && uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr))
	cc2420_send_data_ack(h.src);
      leds_toggle(LEDS_GREEN);
      cc2420_is_input = 1;
      tcpip_input();
      cc2420_is_input = 0;
      leds_toggle(LEDS_GREEN);
    }
  }

  PROCESS_END();
}