Exemplo n.º 1
0
static void
flushrx(void)
{
  uint8_t dummy;
  
  FASTSPI_READ_FIFO_BYTE(dummy);
  FASTSPI_STROBE(CC2420_SFLUSHRX);
  FASTSPI_STROBE(CC2420_SFLUSHRX);
  rxptr = 0;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
//-------------------------------------------------------------------------------------------------------
//  BYTE rf_tx_packet(RF_TX_INFO *pRTI)
//
//  DESCRIPTION:
//		Transmits a packet using the IEEE 802.15.4 MAC data packet format with short addresses. CCA is
//		measured only once before backet transmission (not compliant with 802.15.4 CSMA-CA).
//		The function returns:
//			- When pRTI->ackRequest is FALSE: After the transmission has begun (SFD gone high)
//			- When pRTI->ackRequest is TRUE: After the acknowledgment has been received/declared missing.
//		The acknowledgment is received through the FIFOP interrupt.
//
//  ARGUMENTS:
//      RF_TX_INFO *pRTI
//          The transmission structure, which contains all relevant info about the packet.
//
//  RETURN VALUE:
//		uint8_t
//			Successful transmission (acknowledgment received)
//-------------------------------------------------------------------------------------------------------
uint8_t rf_tx_packet(RF_TX_INFO *pRTI)
{
    uint16_t frameControlField;
    uint8_t packetLength, length;
    uint8_t success;
    uint8_t spiStatusByte;
    uint8_t checksum,i;

#ifdef RADIO_PRIORITY_CEILING
    nrk_sem_pend(radio_sem);
#endif

#ifdef CC2420_OSC_OPT
    FASTSPI_STROBE(CC2420_SXOSCON);
    nrk_spin_wait_us(OSC_STARTUP_DELAY);
#endif
    if(security_enable)
        FASTSPI_STROBE(CC2420_STXENC);

    checksum=0;
    for(i=0; i<pRTI->length; i++ )
    {
        // lets do our own payload checksum because we don't trust the CRC
        checksum+=pRTI->pPayload[i];
    }
    // Write the packet to the TX FIFO (the FCS is appended automatically when AUTOCRC is enabled)

    // These are only the MAC AGNOSTIC parameters...
    // Slots for example are at a slighly higher later since they assume TDMA
    packetLength = pRTI->length + RF_PACKET_OVERHEAD_SIZE + CHECKSUM_OVERHEAD;
    if(security_enable) packetLength+=4;  // for CTR counter


    // XXX 2 below are hacks...
    FASTSPI_STROBE(CC2420_SFLUSHRX);
    FASTSPI_STROBE(CC2420_SFLUSHRX);
    // Wait until the transceiver is idle
    while (FIFOP_IS_1 || SFD_IS_1);
    // Turn off global interrupts to avoid interference on the SPI interface
    DISABLE_GLOBAL_INT();
    // Flush the TX FIFO just in case...
    FASTSPI_STROBE(CC2420_SFLUSHTX);
    FASTSPI_STROBE(CC2420_SFLUSHTX);

    /*
        // Turn on RX if necessary
        if (!rfSettings.receiveOn) {
    		FASTSPI_STROBE(CC2420_SRXON);
    		}

        // Wait for the RSSI value to become valid
        do {
            FASTSPI_UPD_STATUS(spiStatusByte);
        } while (!(spiStatusByte & BM(CC2420_RSSI_VALID)));

    	// TX begins after the CCA check has passed
        do {
    		FASTSPI_STROBE(CC2420_STXONCCA);
    		FASTSPI_UPD_STATUS(spiStatusByte);
    		halWait(100);
        } while (!(spiStatusByte & BM(CC2420_TX_ACTIVE)));
    */
    FASTSPI_WRITE_FIFO((uint8_t*)&packetLength, 1);               // Packet length
    frameControlField = RF_FCF_NOACK;   // default
    if(auto_ack_enable) frameControlField |= RF_ACK_BM;
    if(security_enable) frameControlField |= RF_SEC_BM;
    FASTSPI_WRITE_FIFO((uint8_t*) &frameControlField, 2);         // Frame control field
    FASTSPI_WRITE_FIFO((uint8_t*) &rfSettings.txSeqNumber, 1);    // Sequence number
    FASTSPI_WRITE_FIFO((uint8_t*) &rfSettings.panId, 2);          // Dest. PAN ID
    FASTSPI_WRITE_FIFO((uint8_t*) &pRTI->destAddr, 2);            // Dest. address
    FASTSPI_WRITE_FIFO((uint8_t*) &rfSettings.myAddr, 2);         // Source address
    if(security_enable)
        FASTSPI_WRITE_FIFO((uint8_t*) &tx_ctr, 4);         // CTR counter

    FASTSPI_WRITE_FIFO((uint8_t*) pRTI->pPayload, pRTI->length);  // Payload
    FASTSPI_WRITE_FIFO((uint8_t*) &checksum, 1);         // Checksum

    if (pRTI->cca == TRUE)
    {
        uint8_t cnt;
        if (!rfSettings.receiveOn)
        {
            FASTSPI_STROBE (CC2420_SRXON);
        }

        // Wait for the RSSI value to become valid
        do
        {
            FASTSPI_UPD_STATUS (spiStatusByte);
        }
        while (!(spiStatusByte & BM (CC2420_RSSI_VALID)));
        // TX begins after the CCA check has passed
        cnt = 0;
        do
        {
            FASTSPI_STROBE (CC2420_STXONCCA);
            FASTSPI_UPD_STATUS (spiStatusByte);
            cnt++;
            if (cnt > 100)
            {
                ENABLE_GLOBAL_INT ();
                nrk_sem_post(radio_sem);
                return FALSE;
            }
            halWait (100);
        }
        while (!(spiStatusByte & BM (CC2420_TX_ACTIVE)));
    }
    else
        FASTSPI_STROBE (CC2420_STXON);

    ENABLE_GLOBAL_INT();
    // Wait for the transmission to begin before exiting (makes sure that this function cannot be called
    // a second time, and thereby cancelling the first transmission (observe the FIFOP + SFD test above).
    while (!SFD_IS_1);
    success = TRUE;

    // Turn interrupts back on
//	ENABLE_GLOBAL_INT();

    while (SFD_IS_1); // wait for packet to finish

    // Wait for the acknowledge to be received, if any
    if (auto_ack_enable)
    {
//		rfSettings.ackReceived = FALSE;

        // Wait for the SFD to go low again
        //	while (SFD_IS_1);
        // We'll enter RX automatically, so just wait until we can be sure that the
        // ack reception should have finished
        // The timeout consists of a 12-symbol turnaround time, the ack packet duration,
        // and a small margin
        halWait((12 * RF_SYMBOL_DURATION) + (RF_ACK_DURATION) + (2 * RF_SYMBOL_DURATION) + 100);

        if(FIFO_IS_1)
        {
            FASTSPI_READ_FIFO_BYTE(length);
            length &= RF_LENGTH_MASK; // Ignore MSB
            success = TRUE;

        }
        else
        {
            FASTSPI_STROBE(CC2420_SFLUSHRX);
            FASTSPI_STROBE(CC2420_SFLUSHRX);
            success = FALSE;
        }

    }


    // Turn off the receiver if it should not continue to be enabled

    DISABLE_GLOBAL_INT();
    //FASTSPI_STROBE(CC2420_SFLUSHRX);
    //FASTSPI_STROBE(CC2420_SFLUSHRX);
    //FASTSPI_STROBE(CC2420_SFLUSHTX);
    //FASTSPI_STROBE(CC2420_SFLUSHTX);

#ifdef CC2420_OSC_OPT
    FASTSPI_STROBE(CC2420_SXOSCOFF);
#endif
    FASTSPI_STROBE(CC2420_SRFOFF);  // shut off radio
    ENABLE_GLOBAL_INT();

    // agr XXX hack to test time issue
    //rf_rx_on();

    // Increment the sequence number, and return the result
    rfSettings.txSeqNumber++;
//	while (SFD_IS_1);
#ifdef RADIO_PRIORITY_CEILING
    nrk_sem_post(radio_sem);
#endif
    return success;

}
Exemplo n.º 4
0
static void
getrxbyte(uint8_t *byte)
{
  FASTSPI_READ_FIFO_BYTE(*byte);
  rxptr = (rxptr + 1) & 0x7f;
}
Exemplo n.º 5
0
/*
 * 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;
}