⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basic_rf.c

📁 RF tranceiver MSP430F1611+CC2420 with FreeRTOS
💻 C
字号:
/*******************************************************************************************************
 *                                                                                                     *
 *        **********                                                                                   *
 *       ************                                                                                  *
 *      ***        ***                                                                                 *
 *      ***   +++   ***                                                                                *
 *      ***   + +   ***                                                                                *
 *      ***   +                               CHIPCON CC2420 BASIC RF LIBRARY                          *
 *      ***   + +   ***             Initialization, Packet transmission, Packet reception,             *
 *      ***   +++   ***                                                                                *
 *      ***        ***                                                                                 *
 *       ************                                                                                  *
 *        **********                                                                                   *
 *                                                                                                     *
 *******************************************************************************************************/
#include "..\include\rfcom.h"
#include "..\..\..\Os\include\FreeRTOS.h"


//-------------------------------------------------------------------------------------------------------
// The RF settings structure is declared here, since we'll always need halRfInit()
volatile BASIC_RF_SETTINGS rfSettings;
//-------------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------------
//  void basicRfInit(BASIC_RF_RX_INFO *pRRI, UINT8 channel, WORD panId, WORD myAddr)
//
//  DESCRIPTION:
//      Initializes CC2420 for radio communication via the basic RF library functions. Turns on the
//		voltage regulator, resets the CC2420, turns on the crystal oscillator, writes all necessary
//		registers and protocol addresses (for automatic address recognition). Note that the crystal
//		oscillator will remain on (forever).
//
//  ARGUMENTS:
//      BASIC_RF_RX_INFO *pRRI
//          A pointer the BASIC_RF_RX_INFO data structure to be used during the first packet reception.
//			The structure can be switched upon packet reception.
//      UINT8 channel
//          The RF channel to be used (11 = 2405 MHz to 26 = 2480 MHz)
//      WORD panId
//          The personal area network identification number
//      WORD myAddr
//          The 16-bit short address which is used by this node. Must together with the PAN ID form a
//			unique 32-bit identifier to avoid addressing conflicts. Normally, in a 802.15.4 network, the
//			short address will be given to associated nodes by the PAN coordinator.
//-------------------------------------------------------------------------------------------------------
void basicRfInit (BASIC_RF_RX_INFO *pRRI, UINT8 channel, WORD panId, WORD myAddr)
{
    UINT8 n;

// Make sure that the voltage regulator is on, and that the reset pin is inactive
    SET_VREG_ACTIVE();
    halWait(1000);
    SET_RESET_ACTIVE();
    halWait(1000);
    SET_RESET_INACTIVE();
    halWait(500);

// Initialize the FIFOP external interrupt
    FIFOP_INT_INIT();
    ENABLE_FIFOP_INT();

// Turn off all interrupts while we're accessing the CC2420 registers
    portDISABLE_INTERRUPTS();

// Register modifications
    FASTSPI_STROBE(CC2420_SXOSCON);
    FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2); // Turn on automatic packet acknowledgment
    FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0500); // Set the correlation threshold = 20
    FASTSPI_SETREG(CC2420_IOCFG0, 0x007F);   // Set the FIFOP threshold to maximum
    FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C4); // Turn off "Security enable"

// Set the RF channel
    halRfSetChannel(channel);

// Turn interrupts back on
    portENABLE_INTERRUPTS();

// Set the protocol configuration
    rfSettings.pRxInfo     = pRRI;
    rfSettings.panId       = panId;
    rfSettings.myAddr      = myAddr;
    rfSettings.txSeqNumber = 0;
    rfSettings.receiveOn   = FALSE;

// Wait for the crystal oscillator to become stable
    halRfWaitForCrystalOscillator();

// Write the short address and the PAN ID to the CC2420 RAM (requires that the XOSC is on and stable)
    portDISABLE_INTERRUPTS();
    FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n);
    FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n);
    portENABLE_INTERRUPTS();

} // basicRfInit







//-------------------------------------------------------------------------------------------------------
//  BYTE basicRfSendPacket(BASIC_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:
//      BASIC_RF_TX_INFO *pRTI
//          The transmission structure, which contains all relevant info about the packet.
//
//  RETURN VALUE:
//		BOOL
//			Successful transmission (acknowledgment received)
//-------------------------------------------------------------------------------------------------------
BOOL basicRfSendPacket (BASIC_RF_TX_INFO *pRTI)
{
    WORD frameControlField;
    UINT8 packetLength;
    BOOL success;
    BYTE spiStatusByte;

// Wait until the transceiver is idle
    while (FIFOP_IS_1 || SFD_IS_1);

// Turn off global interrupts to avoid interference on the SPI interface
    portDISABLE_INTERRUPTS();

// Flush the TX FIFO just in case...
    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(1);
    } while (!(spiStatusByte & BM(CC2420_TX_ACTIVE)));
     */
// Write the packet to the TX FIFO (the FCS is appended automatically when AUTOCRC is enabled)

    packetLength = pRTI->length + BASIC_RF_PACKET_OVERHEAD_SIZE;
    frameControlField = pRTI->ackRequest ? BASIC_RF_FCF_ACK : BASIC_RF_FCF_NOACK;
    FASTSPI_WRITE_FIFO((BYTE*)&packetLength, 1);                                   // Packet length
    FASTSPI_WRITE_FIFO((BYTE*)&frameControlField, 2);                              // Frame control field
    FASTSPI_WRITE_FIFO((BYTE*)&rfSettings.txSeqNumber, 1);                         // Sequence number
    FASTSPI_WRITE_FIFO((BYTE*)&rfSettings.panId, 2);                               // Dest. PAN ID
    FASTSPI_WRITE_FIFO((BYTE*)&pRTI->destAddr, 2);                                 // Dest. address
    FASTSPI_WRITE_FIFO((BYTE*)&rfSettings.myAddr, 2);                              // Source address
    FASTSPI_WRITE_FIFO((BYTE*)pRTI->pPayload, pRTI->length);                       // Payload

// 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).

    FASTSPI_STROBE(CC2420_STXONCCA);

    while (!SFD_IS_1);
	
// Turn interrupts back on
    portENABLE_INTERRUPTS();

// Wait for the acknowledge to be received, if any
    if (pRTI->ackRequest)
    {
        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 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + (2 * BASIC_RF_SYMBOL_DURATION) + 100);

// If an acknowledgment has been received (by the FIFOP interrupt), the ackReceived flag should be set
        success = rfSettings.ackReceived;
    } else {
        success= TRUE;
    }

// Turn off the receiver if it should not continue to be enabled
    portDISABLE_INTERRUPTS();
    if (!rfSettings.receiveOn) FASTSPI_STROBE(CC2420_SRFOFF);
    portENABLE_INTERRUPTS();

// Increment the sequence number, and return the result
    rfSettings.txSeqNumber++;
    return success;

} // halRfSendPacket





//-------------------------------------------------------------------------------------------------------
//  void halRfReceiveOn(void)
//
//  DESCRIPTION:
//      Enables the CC2420 receiver and the FIFOP interrupt. When a packet is received through this
//      interrupt, it will call halRfReceivePacket(...), which must be defined by the application
//-------------------------------------------------------------------------------------------------------
void basicRfReceiveOn (void)
{
    rfSettings.receiveOn = TRUE;
    FASTSPI_STROBE(CC2420_SRXON);
    FASTSPI_STROBE(CC2420_SFLUSHRX);
    FIFOP_INT_INIT();
    ENABLE_FIFOP_INT();
} // basicRfReceiveOn




//-------------------------------------------------------------------------------------------------------
//  void halRfReceiveOff(void)
//
//  DESCRIPTION:
//      Disables the CC2420 receiver and the FIFOP interrupt.
//-------------------------------------------------------------------------------------------------------
void basicRfReceiveOff (void)
{
    rfSettings.receiveOn = FALSE;
    FASTSPI_STROBE(CC2420_SRFOFF);
    DISABLE_FIFOP_INT();
} // basicRfReceiveOff




//-------------------------------------------------------------------------------------------------------
//  SIGNAL(SIG_INTERRUPT0) - CC2420 FIFOP interrupt service routine
//
//  DESCRIPTION:
//		When a packet has been completely received, this ISR will extract the data from the RX FIFO, put
//		it into the active BASIC_RF_RX_INFO structure, and call basicRfReceivePacket() (defined by the
//		application). FIFO overflow and illegally formatted packets is handled by this routine.
//
//      Note: Packets are acknowledged automatically by CC2420 through the auto-acknowledgment feature.
//-------------------------------------------------------------------------------------------------------


#pragma vector=PORT2_VECTOR
__interrupt void fifo_rx (void)
{
    WORD frameControlField;
    INT8 length;
    BYTE pFooter[2];

    CLEAR_FIFOP_INT();

// 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)))
    {	
        FASTSPI_STROBE(CC2420_SFLUSHRX);
        FASTSPI_STROBE(CC2420_SFLUSHRX);
        return;
    }

// Payload length
    FASTSPI_READ_FIFO_BYTE(length);

    length &= BASIC_RF_LENGTH_MASK; // Ignore MSB

// Ignore the packet if the length is too short
    if (length < BASIC_RF_ACK_PACKET_SIZE)
    {
        FASTSPI_READ_FIFO_GARBAGE(length);

// Otherwise, if the length is valid, then proceed with the rest of the packet
    } else {
// Register the payload length
        rfSettings.pRxInfo->length = length - BASIC_RF_PACKET_OVERHEAD_SIZE;

// Read the frame control field and the data sequence number
        FASTSPI_READ_FIFO_NO_WAIT((BYTE*) &frameControlField, 2);
        rfSettings.pRxInfo->ackRequest = !!(frameControlField & BASIC_RF_FCF_ACK_BM);
    	FASTSPI_READ_FIFO_BYTE(rfSettings.pRxInfo->seqNumber);

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

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

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

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

		// 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((BYTE*) &rfSettings.pRxInfo->srcAddr, 2);

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

			// Read the footer to get the RSSI value
			FASTSPI_READ_FIFO_NO_WAIT((BYTE*) pFooter, 2);
			rfSettings.pRxInfo->rssi = pFooter[0];

			// Notify the application about the received _data_ packet if the CRC is OK
			if (((frameControlField & (BASIC_RF_FCF_BM)) == BASIC_RF_FCF_NOACK) && (pFooter[1] & BASIC_RF_CRC_OK_BM)) {
				rfSettings.pRxInfo = basicRfReceivePacket(rfSettings.pRxInfo);
			}
		}
    }

} // fifo_rx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -