Пример #1
0
void halRfFlushRx(void) {
	/* Flush RX FIFO twice instead of once. See bug #1 in
	 * http://www.ti.com/lit/er/swrz024/swrz024.pdf */
	halRfDisableRxInterrupt();
	CC2520_RXBUF8();
	CC2520_INS_STROBE(CC2520_INS_SFLUSHRX);
	CC2520_INS_STROBE(CC2520_INS_SFLUSHRX);
	halRfEnableRxInterrupt();
}
Пример #2
0
/***********************************************************************************
 * @fn      halRfReceiveOn
 *
 * @brief   Turn receiver on
 *
 * @param   none
 *
 * @return  none
 */
void halRfReceiveOn(void) {
	/* Flush RX FIFO if needed.
	 * See bug #1 in http://www.ti.com/lit/er/swrz024/swrz024.pdf */
	halRfDisableRxInterrupt();
	CC2520_INS_STROBE(CC2520_INS_SFLUSHRX);
	uint8_t rx_fifo_cnt = CC2520_REGRD8(CC2520_RXFIFOCNT);

	CC2520_INS_STROBE(CC2520_INS_SRXON);

	if (rx_fifo_cnt != CC2520_REGRD8(CC2520_RXFIFOCNT)) {
		CC2520_INS_STROBE(CC2520_INS_SFLUSHRX);
	}
	halRfEnableRxInterrupt();
}
Пример #3
0
/***********************************************************************************
 * @fn      halRfReceiveOff
 *
 * @brief   Turn receiver off
 *
 * @param   none
 *
 * @return  none
 */
void halRfReceiveOff(void) {
	/* Flush RX FIFO if needed.
	 * See bug #1 in http://www.ti.com/lit/er/swrz024/swrz024.pdf */
	halRfDisableRxInterrupt();
	CC2520_INS_STROBE(CC2520_INS_SFLUSHRX);
	uint8_t rx_fifo_cnt = CC2520_REGRD8(CC2520_RXFIFOCNT);

	CC2520_INS_STROBE(CC2520_INS_SRFOFF);

	if (rx_fifo_cnt != CC2520_REGRD8(CC2520_RXFIFOCNT)) {
		CC2520_INS_STROBE(CC2520_INS_SFLUSHRX);
		// Software clean-up
		// Reset software for frame reception...
	}
	halRfEnableRxInterrupt();
}
Пример #4
0
//RF ISR
void  GPABC_IRQHandler(void){
	if(GPIOB_ISRC&0x00000200UL){
		disable_rf_int();
		uz2400_isr_handler();
		enable_rf_int();
	}
	GPIOB_ISRC = GPIOB_ISRC;		
#if 0	
    if (EXTI_GetITStatus(EXTI_Line4) != RESET){
		#ifdef SELECT_CC2520
			halRfDisableRxInterrupt();
			cc2520_isr_handler();
			halRfEnableRxInterrupt();
		#else
			//disable_rf_int();
			uz2400_isr_handler();
			//enable_rf_int();
		#endif
		EXTI4_ClearBit();
    }
#endif    
}
Пример #5
0
/***********************************************************************************
 * @fn      halRfInit
 *
 * @brief   Power up, sets default tuning settings, enables autoack and configures
 *          chip IO
 *
 * @param   none
 *
 * @return  SUCCESS if the radio has started, FAILURE otherwise
 */
uint8 halRfInit(void) {
	regVal_t* p;
	uint8 val;

	// Avoid GPIO0 interrupts during reset
	halRfDisableRxInterrupt();

	// Make sure to pull the CC2520 RESETn pin low
	CC2520_RESET_OPIN(0);
	CC2520_SPI_END();
	chThdSleepMilliseconds(2);

	// Make sure MISO is configured as output.
	CC2520_MISO_DIR_OUT();

	// Release reset
	CC2520_RESET_OPIN(1);

	// Wait for XOSC stable to be announced on the MISO pin
	if (halRfWaitRadioReady() == FAILED) {
		return FAILED;
	}

	// Write non-default register values
	p = regval;
	while (p->reg != 0) {
		CC2520_MEMWR8(p->reg, p->val);
		p++;
	}

	// ISR Thread
	chThdCreateStatic(waIsrTx, sizeof(waIsrTx), NORMALPRIO + 2, isrThread, NULL );

	// Verify a register
	val = CC2520_MEMRD8(CC2520_MDMCTRL0);
	return val == 0x85 ? SUCCESS : FAILED;
}
Пример #6
0
/***********************************************************************************
* @fn          basicRfSendPacket
*
* @brief       Send packet
*
* @param       destAddr - destination short address
*              pPayload - pointer to payload buffer. This buffer must be
*                         allocated by higher layer.
*              length - length of payload
*              txState - file scope variable that keeps tx state info
*              mpdu - file scope variable. Buffer for the frame to send
*
* @return      basicRFStatus_t - SUCCESS or FAILED
*/
uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length)
{
    uint8 mpduLength;
    uint8 status;

    // Turn on receiver if its not on
    if(!txState.receiveOn) {
        halRfReceiveOn();
    }

    // Check packet length
    length = min(length, BASIC_RF_MAX_PAYLOAD_SIZE);

    // Wait until the transceiver is idle
    halRfWaitTransceiverReady();

    // Turn off RX frame done interrupt to avoid interference on the SPI interface
    halRfDisableRxInterrupt();

    mpduLength = basicRfBuildMpdu(destAddr, pPayload, length);

    #ifdef SECURITY_CCM
    halRfWriteTxBufSecure(txMpdu, mpduLength, length, BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M);
    txState.frameCounter++;     // Increment frame counter field
    #else
    halRfWriteTxBuf(txMpdu, mpduLength);
    #endif

    // Turn on RX frame done interrupt for ACK reception
    halRfEnableRxInterrupt();

    // Send frame with CCA. return FAILED if not successful
    if(halRfTransmit() != SUCCESS) {
        status = FAILED;
    }

    // Wait for the acknowledge to be received, if any
    if (pConfig->ackRequest) {
        txState.ackReceived = FALSE;

        // 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
        halMcuWaitUs((12 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + (2 * BASIC_RF_SYMBOL_DURATION) + 10);

        // If an acknowledgment has been received (by RxFrmDoneIsr), the ackReceived flag should be set
        status = txState.ackReceived ? SUCCESS : FAILED;

    } else {
        status = SUCCESS;
    }

    // Turn off the receiver if it should not continue to be enabled
    if (!txState.receiveOn) {
        halRfReceiveOff();
    }

    if(status == SUCCESS) {
        txState.txSeqNumber++;
    }

#ifdef SECURITY_CCM
    halRfIncNonceTx();          // Increment nonce value
#endif

    return status;

}
Пример #7
0
/***********************************************************************************
* @fn          basicRfRxFrmDoneIsr
*
* @brief       Interrupt service routine for received frame from radio
*              (either data or acknowlegdement)
*
* @param       rxi - file scope variable info extracted from the last incoming
*                    frame
*              txState - file scope variable that keeps tx state info
*
* @return      none
*/
static void basicRfRxFrmDoneIsr(void)
{
    basicRfPktHdr_t *pHdr;
    uint8 *pStatusWord;
    #ifdef SECURITY_CCM
    uint8 authStatus=0;
    #endif

    // Map header to packet buffer
    pHdr= (basicRfPktHdr_t*)rxMpdu;

    // Clear interrupt and disable new RX frame done interrupt
    halRfDisableRxInterrupt();

    // Enable all other interrupt sources (enables interrupt nesting)
    halIntOn();

    // Read payload length.
    halRfReadRxBuf(&pHdr->packetLength,1);
    pHdr->packetLength &= BASIC_RF_PLD_LEN_MASK; // Ignore MSB
    
    // Is this an acknowledgment packet?
    // Only ack packets may be 5 bytes in total.
    if (pHdr->packetLength == BASIC_RF_ACK_PACKET_SIZE) {

        // Read the packet
        halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength);

        // Make sure byte fields are changed from network to host byte order
    	UINT16_NTOH(pHdr->panId);
    	UINT16_NTOH(pHdr->destAddr);
    	UINT16_NTOH(pHdr->srcAddr);
        #ifdef SECURITY_CCM
        UINT32_NTOH(pHdr->frameCounter);
        #endif

        rxi.ackRequest = !!(pHdr->fcf0 & BASIC_RF_FCF_ACK_BM_L);

        // Read the status word and check for CRC OK
        pStatusWord= rxMpdu + 4;

        // Indicate the successful ACK reception if CRC and sequence number OK
        if ((pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (pHdr->seqNumber == txState.txSeqNumber)) {
            txState.ackReceived = TRUE;
        }

        // No, it is data
    } else {

        // It is assumed that the radio rejects packets with invalid length.
        // Subtract the number of bytes in the frame overhead to get actual payload.

        rxi.length = pHdr->packetLength - BASIC_RF_PACKET_OVERHEAD_SIZE;

        #ifdef SECURITY_CCM
        rxi.length -= (BASIC_RF_AUX_HDR_LENGTH + BASIC_RF_LEN_MIC);
        authStatus = halRfReadRxBufSecure(&rxMpdu[1], pHdr->packetLength, rxi.length,
                                        BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M);
        #else
        halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength);
        #endif

        // Make sure byte fields are changed from network to host byte order
    	UINT16_NTOH(pHdr->panId);
    	UINT16_NTOH(pHdr->destAddr);
    	UINT16_NTOH(pHdr->srcAddr);
        #ifdef SECURITY_CCM
        UINT32_NTOH(pHdr->frameCounter);
        #endif

        rxi.ackRequest = !!(pHdr->fcf0 & BASIC_RF_FCF_ACK_BM_L);

        // Read the source address
        rxi.srcAddr= pHdr->srcAddr;

        // Read the packet payload
        rxi.pPayload = rxMpdu + BASIC_RF_HDR_SIZE;

        // Read the FCS to get the RSSI and CRC
        pStatusWord= rxi.pPayload+rxi.length;
        #ifdef SECURITY_CCM
        pStatusWord+= BASIC_RF_LEN_MIC;
        #endif
        rxi.rssi = pStatusWord[0];

        // Notify the application about the received data packet if the CRC is OK
        // Throw packet if the previous packet had the same sequence number
        if( (pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (rxi.seqNumber != pHdr->seqNumber) ) {
            // If security is used check also that authentication passed
            #ifdef SECURITY_CCM
            if( authStatus==SUCCESS ) {
                if ( (pHdr->fcf0 & BASIC_RF_FCF_BM_L) ==
                    (BASIC_RF_FCF_NOACK_L | BASIC_RF_SEC_ENABLED_FCF_BM_L)) {
                        rxi.isReady = TRUE;
                }
            }
            #else
            if ( ((pHdr->fcf0 & (BASIC_RF_FCF_BM_L)) == BASIC_RF_FCF_NOACK_L) ) {
                rxi.isReady = TRUE;
            }              
            #endif
        }
        rxi.seqNumber = pHdr->seqNumber;
    }
  
    // Enable RX frame done interrupt again
    halIntOff();
    halRfEnableRxInterrupt();
}