コード例 #1
0
ファイル: basic_rf.c プロジェクト: adamselevan/dicio
int8_t rf_polling_rx_packet()
{
    uint8_t tmp;

#ifdef RADIO_PRIORITY_CEILING
    nrk_sem_pend(radio_sem);
#endif

    if(FIFOP_IS_1 )
    {
        uint16_t frameControlField;
        int8_t length;
        uint8_t pFooter[2];
        uint8_t checksum,rx_checksum,i;

        last_pkt_encrypted=0;

//	FASTSPI_STROBE(CC2420_SRXON);
//	FASTSPI_STROBE(CC2420_SFLUSHRX);

//	while(!SFD_IS_1);
//  XXX Need to make sure SFD has gone down to be sure packet finished!
//	while(SFD_IS_1);
        // Clean up and exit in case of FIFO overflow, which is indicated by FIFOP = 1 and FIFO = 0
        if((FIFOP_IS_1) && (!(FIFO_IS_1)))
        {
            // always read 1 byte before flush (data sheet pg 62)
            FASTSPI_READ_FIFO_BYTE(tmp);
            FASTSPI_STROBE(CC2420_SFLUSHRX);
            FASTSPI_STROBE(CC2420_SFLUSHRX);
#ifdef RADIO_PRIORITY_CEILING
            nrk_sem_post(radio_sem);
#endif
            return -1;
        }

        // Payload length
        FASTSPI_READ_FIFO_BYTE(length);
        length &= RF_LENGTH_MASK; // Ignore MSB
        // Ignore the packet if the length is too short
        if(length<=0)
        {
            // always read 1 byte before flush (data sheet pg 62)
            FASTSPI_READ_FIFO_BYTE(tmp);
            FASTSPI_STROBE(CC2420_SFLUSHRX);
            FASTSPI_STROBE(CC2420_SFLUSHRX);
#ifdef RADIO_PRIORITY_CEILING
            nrk_sem_post(radio_sem);
#endif
            return -2;
        }
        if (length < (RF_PACKET_OVERHEAD_SIZE + CHECKSUM_OVERHEAD)/*RF_ACK_PACKET_SIZE*/ || (length-RF_PACKET_OVERHEAD_SIZE)> rfSettings.pRxInfo->max_length)
        {
            FASTSPI_READ_FIFO_GARBAGE(length);
            FASTSPI_READ_FIFO_BYTE(tmp);
            FASTSPI_STROBE(CC2420_SFLUSHRX);
            FASTSPI_STROBE(CC2420_SFLUSHRX);
#ifdef RADIO_PRIORITY_CEILING
            nrk_sem_post(radio_sem);
#endif
            return -3;
            //printf_u( "Bad length: %d %d\n",length, rfSettings.pRxInfo->max_length );
            // Otherwise, if the length is valid, then proceed with the rest of the packet
        }
        else
        {
            // Register the payload length
            rfSettings.pRxInfo->length = length - RF_PACKET_OVERHEAD_SIZE - CHECKSUM_OVERHEAD;
            // Read the frame control field and the data sequence number
            FASTSPI_READ_FIFO_NO_WAIT((uint8_t*) &frameControlField, 2);
            rfSettings.pRxInfo->ackRequest = !!(frameControlField & RF_FCF_ACK_BM);
            FASTSPI_READ_FIFO_BYTE(rfSettings.pRxInfo->seqNumber);

            // Is this an acknowledgment packet?
            /*
                	if ((length == RF_ACK_PACKET_SIZE) && (frameControlField == RF_ACK_FCF) && (rfSettings.pRxInfo->seqNumber == rfSettings.txSeqNumber)) {

             	       	// Read the footer and check for CRC OK
            			FASTSPI_READ_FIFO_NO_WAIT((uint8_t*) pFooter, 2);

            			// Indicate the successful ack reception (this flag is polled by the transmission routine)
            			if (pFooter[1] & RF_CRC_OK_BM) rfSettings.ackReceived = TRUE;

            		// Too small to be a valid packet?
            		} else if (length < RF_PACKET_OVERHEAD_SIZE) {
            			FASTSPI_READ_FIFO_GARBAGE(length - 3);

            		// Receive the rest of the packet
            		} else {
            */
            // Skip the destination PAN and address (that's taken care of by harware address recognition!)
            FASTSPI_READ_FIFO_GARBAGE(4);

            // Read the source address
            FASTSPI_READ_FIFO_NO_WAIT((uint8_t*) &rfSettings.pRxInfo->srcAddr, 2);

            if(frameControlField & RF_SEC_BM)
            {
                uint8_t n;
                // READ rx_ctr and set it
                FASTSPI_READ_FIFO_NO_WAIT((uint8_t*) &rx_ctr, 4);
                FASTSPI_WRITE_RAM(&rx_ctr[0],(CC2420RAM_RXNONCE+9),2,n);
                FASTSPI_WRITE_RAM(&rx_ctr[2],(CC2420RAM_RXNONCE+11),2,n);
                FASTSPI_STROBE(CC2420_SRXDEC);  // if packet is encrypted then decrypt
                last_pkt_encrypted=1;
                rfSettings.pRxInfo->length -= 4;
            }

            // Read the packet payload
            FASTSPI_READ_FIFO_NO_WAIT(rfSettings.pRxInfo->pPayload, rfSettings.pRxInfo->length);
            FASTSPI_READ_FIFO_NO_WAIT(&rx_checksum, 1 );

            // Read the footer to get the RSSI value
            FASTSPI_READ_FIFO_NO_WAIT((uint8_t*) pFooter, 2);
            rfSettings.pRxInfo->rssi = pFooter[0];
            checksum=0;
            for(i=0; i<rfSettings.pRxInfo->length; i++ )
            {
                checksum+=rfSettings.pRxInfo->pPayload[i];
                //printf( "%d ", rfSettings.pRxInfo->pPayload[i]);
            }

            if(checksum!=rx_checksum)
            {
                //printf( "Checksum failed %d %d\r",rx_checksum, checksum );
                // always read 1 byte before flush (data sheet pg 62)
                FASTSPI_READ_FIFO_BYTE(tmp);
                FASTSPI_STROBE(CC2420_SFLUSHRX);
                FASTSPI_STROBE(CC2420_SFLUSHRX);
#ifdef RADIO_PRIORITY_CEILING
                nrk_sem_post(radio_sem);
#endif
                return -4;
            }
            if (pFooter[1] & RF_CRC_OK_BM)
            {
                //rfSettings.pRxInfo = rf_rx_callback(rfSettings.pRxInfo);
                rx_ready++;
#ifdef RADIO_PRIORITY_CEILING
                nrk_sem_post(radio_sem);
#endif
                return 1;
            }
            else
            {
                // always read 1 byte before flush (data sheet pg 62)
                FASTSPI_READ_FIFO_BYTE(tmp);
                FASTSPI_STROBE(CC2420_SFLUSHRX);
                FASTSPI_STROBE(CC2420_SFLUSHRX);
#ifdef RADIO_PRIORITY_CEILING
                nrk_sem_post(radio_sem);
#endif
                return -5;
            }
//		}

        }


    }
#ifdef RADIO_PRIORITY_CEILING
    nrk_sem_post(radio_sem);
#endif
    return 0;
}
コード例 #2
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();
}
コード例 #3
0
ファイル: cc2420.c プロジェクト: kincki/contiki
static void
getrxdata(void *buf, int len)
{
  FASTSPI_READ_FIFO_NO_WAIT(buf, len);
  rxptr = (rxptr + len) & 0x7f;
}
コード例 #4
0
ファイル: cc2420.c プロジェクト: EDAyele/ptunes
/*
 * Interrupt either leaves frame intact in FIFO or reads *only* the
 * MAC header and sets rx_fifo_remaining_bytes.
 *
 * In order to quickly empty the FIFO ack processing is done at
 * interrupt priority rather than poll priority.
 */
int
__cc2420_intr(void)
{
  u8_t length;
  const u8_t *const ack_footer = (u8_t *)&h.dst_pan;

  CLEAR_FIFOP_INT();
    
  if (spi_busy || rx_fifo_remaining_bytes > 0) {
    /* SPI bus hardware is currently used elsewhere (UART0 or I2C bus)
     * or we already have a packet in the works and will have to defer
     * interrupt processing of this packet in a fake interrupt.
     */
    process_poll(&cc2420_process);
    return 1;
  }

  FASTSPI_READ_FIFO_BYTE(length);
  if (length > MAX_PACKET_LEN) {
    /* Oops, we must be out of sync. */
    FASTSPI_STROBE(CC2420_SFLUSHRX);
    FASTSPI_STROBE(CC2420_SFLUSHRX);
    return 0;
  }

  h.len = length;

  if (length < ACK_PACKET_LEN) {
    FASTSPI_READ_FIFO_GARBAGE(length); /* Rubbish */
    return 0;
  }

  FASTSPI_READ_FIFO_NO_WAIT(&h.fc0, 5); /* fc0, fc1, seq, dst_pan */

  /* Is this an ACK packet? */
  if (length == ACK_PACKET_LEN && (h.fc0 & FC0_TYPE_MASK) == FC0_TYPE_ACK) {
    if (ack_footer[1] & FOOTER1_CRC_OK) {
      if (h.seq == last_used_seq) { /* Matching ACK number? */
	cc2420_ack_received = 1;
	process_poll(&cc2420_retransmit_process);
#if 0
	cc2420_last_rssi = ack_footer[0];
	cc2420_last_correlation = ack_footer[1] & FOOTER1_CORRELATION;
#endif
      }
    }
    return 1;
  }

  if (length < (MAC_HDR_LEN + 2)) {
    FASTSPI_READ_FIFO_GARBAGE(length - 5);
    return 0;
  }

  FASTSPI_READ_FIFO_NO_WAIT(&h.dst, 4); /* dst and src */

  /* The payload and footer is now left in the RX FIFO and will be
   * picked up asynchronously at poll priority in the cc2420_process
   * below.
   */
  rx_fifo_remaining_bytes = length - MAC_HDR_LEN;
  process_poll(&cc2420_process);
  return 1;
}