Esempio n. 1
0
void Radio_Count_states (void)
{
  INT8U st = 0;
  st = PHYGetLongRAMAddr(RFSTATE);   
  st = (INT8U)((st & 0xE0) >> 5); 
  Radio_State_Counter.st_counts[st]++;
}
Esempio n. 2
0
/*********************************************************************
 * Function:        void MRF24J40Wake(void)
 *
 * PreCondition:    BoardInit (or other initialzation code is required)
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    the ZigBee stack is initialized
 *
 * Overview:        This function initializes the ZigBee stack and is required
 *                  before stack operations can continue
 ********************************************************************/
void MRF24J40Wake(void)
{
    BYTE results;
    TICK failureTimer;
    TICK currentDifference;
     
    //;wake up the device
    PHY_WAKE = 1;

    failureTimer = TickGet();

    while(1)
    {
        currentDifference = TickGet();
            
        currentDifference.Val = TickGetDiff(currentDifference,failureTimer);
        
        if(currentDifference.Val > 6250)
        {
            break;
        }
    
        results = PHYGetShortRAMAddr(ISRSTS);
        if((results & 0x40))
        {
            break;
        }
    }
    
    while(1)
    {
        currentDifference = TickGet();
        
        currentDifference.Val = TickGetDiff(currentDifference, failureTimer);
        
        if( currentDifference.Val > 6250 )
        {
            break;
        }
        
        results = PHYGetLongRAMAddr(RFSTATE);
        if( (results & 0xE0) == 0xA0 )
        {
            break;
        }
    }
   
   /* Keep track of radio status - now awake */
   #if defined(I_AM_RFD)        
    ZigBeeStatus.flags.bits.bRadioIsSleeping = 0;
   #endif
}
Esempio n. 3
0
/*********************************************************************
 * Function:        CIPHER_STATUS PHYCipher(INPUT CIPHER_MODE CipherMode, INPUT SECURITY_INPUT SecurityInput, OUTPUT BYTE *OutData, OUTPUT BYTE *OutDataLen)
 *
 * PreCondition:    Called by DataEncrypt or DataDecrypt
 *
 * Input:           CIPHER_MODE CipherMode       - Either MODE_ENCRYPTION or MODE_DECRYPTION
 *                  SECURITY_INPUT SecurityInput - Cipher operation input. Filled by DataEncryption or DataDecryption
 *
 * Output:          BYTE *OutData                - Encrypted or decrypted data, including MIC
 *                  BYTE *OutDataLen             - Data length after cipher operation, including MIC bytes
 *                  CIPHER_STATUS                - Cipher operation result
 *
 * Side Effects:    Input data get encrypted or decrypted and put into output buffer
 *
 * Overview:        This is the function that invoke the hardware cipher to do encryption and decryption
 ********************************************************************/
CIPHER_STATUS PHYCipher(INPUT CIPHER_MODE CipherMode, INPUT SECURITY_INPUT SecurityInput, OUTPUT BYTE *OutData, OUTPUT BYTE *OutDataLen)
{
    BYTE CipherRetry = CIPHER_RETRY;
    BYTE i;
    WORD loc;

    // make sure that we are not in the process of sending out a packet
    loc = 0;
    while( !TxStat.finished )
    {
        loc++;
        if( loc > 0xfff )
        {
            PHY_RESETn = 0;
            MACEnable();
            TxStat.finished = 1;
        }
#if defined(__C30__)
        if(RF_INT_PIN == 0)
        {
            RFIF = 1;
        }
#else
        if( PORTBbits.RB0 == 0 )
        {
            INTCONbits.INT0IF = 1;
        }
#endif

        Nop();
    }

CipherOperationStart:

    // step 1, set the normal FIFO
    // step 1a, fill the length of the header
    if( SecurityInput.cipherMode > 0x04 )
    {
        PHYSetLongRAMAddr(0x000, SecurityInput.HeaderLen+SecurityInput.TextLen+14);
    } else {
        PHYSetLongRAMAddr(0x000, SecurityInput.HeaderLen+14);
    }

    // step 1b, fill the length of the packet
    if( CipherMode == MODE_ENCRYPTION )
    {
        PHYSetLongRAMAddr(0x001, SecurityInput.TextLen+SecurityInput.HeaderLen+14);
    } else {
        PHYSetLongRAMAddr(0x001, SecurityInput.TextLen+SecurityInput.HeaderLen+16);// two additional bytes FCS
    }

    // step 1c, fill the header
    loc = 0x002;
    for(i = 0; i < SecurityInput.HeaderLen; i++)
    {
        PHYSetLongRAMAddr(loc++, SecurityInput.Header[i]);
    }

    // step 1d, fill the auxilary header
    PHYSetLongRAMAddr(loc++, SecurityInput.SecurityControl.Val | nwkSecurityLevel);
    for(i = 0; i < 4; i++)
    {
        PHYSetLongRAMAddr(loc++, SecurityInput.FrameCounter.v[i]);
    }
    for(i = 0; i < 8; i++)
    {
        PHYSetLongRAMAddr(loc++, SecurityInput.SourceAddress->v[i]);
    }
    PHYSetLongRAMAddr(loc++, SecurityInput.KeySeq);

    // step 1e, fill the data to be encrypted or decrypted
    for(i = 0; i < SecurityInput.TextLen; i++)
    {
        PHYSetLongRAMAddr(loc++, SecurityInput.InputText[i]);
    }

    // step 2, set nounce
    SetNonce(SecurityInput.SourceAddress, &(SecurityInput.FrameCounter), SecurityInput.SecurityControl);

    // step 3, set TXNFIFO security key
    loc = 0x280;
    for(i = 0; i < 16; i++)
    {
        PHYSetLongRAMAddr(loc++, SecurityInput.SecurityKey[i]);
    }

    // step 4, set cipher mode either encryption or decryption
    if( CipherMode == MODE_ENCRYPTION )
    {
        PHYSetShortRAMAddr(SECCR2, 0x40);
    } else {
        PHYSetShortRAMAddr(SECCR2, 0x80);
    }

    // step 5, fill the encryption mode
    PHYSetShortRAMAddr(SECCR0, SecurityInput.cipherMode);

    TxStat.cipher = 1;
    // step 6, trigger
    PHYSetShortRAMAddr(TXNMTRIG, 0x03);

    i = 0;
    while( TxStat.cipher )
    {
#if defined(__C30__)
        if(RF_INT_PIN == 0)
        {
            RFIF = 1;
        }
#else
        if( PORTBbits.RB0 == 0 )
        {
            INTCONbits.INT0IF = 1;
        }
#endif
        i++;
#if 1
        // in rare condition, the hardware cipher will stall. Handle such condition
        // here
        if(i > 0x1f)
        {
            // in certain rare cases, the RX and Upper Cipher will block each other
            // in case that happens, reset the RF chip to avoid total disfunction
            ConsolePutROMString((ROM char*)"X");
            PHYTasksPending.Val = 0;
            PHY_RESETn = 0;
            MACEnable();
            break;
        }
#endif
    }
    //PHYSetShortRAMAddr(0x0d, 0x01);

    // if MIC is generated, check MIC here
    if( (CipherMode == MODE_DECRYPTION) && (SecurityInput.cipherMode != 0x01))
    {
        BYTE MIC_check = PHYGetShortRAMAddr(0x30);
        if( MIC_check & 0x40 )
        {
            PHYSetShortRAMAddr(0x30, 0x40);
            // there is a small chance that the hardware cipher will not
            // decrypt for the first time, retry to solve this problem.
            // details documented in errata
            if( CipherRetry )
            {
                CipherRetry--;
                for(loc = 0; loc < 0x255; loc++);
                goto CipherOperationStart;
            }
            PHY_RESETn = 0;
            MACEnable();
            ConsolePutROMString((ROM char *)"MIC error");
            return CIPHER_MIC_ERROR;
        }
    }

    if( TxStat.success )
    {
        // get output data length
        *OutDataLen = PHYGetLongRAMAddr(0x001) - SecurityInput.HeaderLen - 14;
        // get the index of data encrypted or decrypted
        loc = 0x002 + SecurityInput.HeaderLen + 14;

        // if this is a decryption operation, get rid of the useless MIC and two bytes of FCS
        if( CipherMode == MODE_DECRYPTION )
        {
            switch( SecurityInput.cipherMode )
            {
            case 0x02:
            case 0x05:
                *OutDataLen -= 18;
                break;
            case 0x03:
            case 0x06:
                *OutDataLen -= 10;
                break;
            case 0x04:
            case 0x07:
                *OutDataLen -= 6;
                break;
            case 0x01:
                *OutDataLen-= 2;
                break;
            }
        }

        // copy the output data
        for(i = 0; i < *OutDataLen; i++)
        {
            OutData[i] = PHYGetLongRAMAddr(loc++);
        }
        return CIPHER_SUCCESS;
    }

    return CIPHER_ERROR;
}
Esempio n. 4
0
    void _ISRFAST __attribute__((interrupt, auto_psv)) _INT1Interrupt(void)
#endif
{
    volatile BYTE    CheckInterrupt;
    BYTE    TxStatus;

    // Check if our interrupt came from the INT pin on the MRF24J40
    if(RFIF)
    {
        if(RFIE)
        {
            // Clear interrupt
            RFIF = 0;

            // Reading this interrupt register will clear the interrupts
            CheckInterrupt = PHYGetShortRAMAddr(0x31);
            

            /* Check the Transmit interrupt first */
            if (CheckInterrupt & 0x01)
            {
                TxStat.finished = 1;
                //Transmit FIFO release interrupt
                // The release status will be set to ok if an ACK was required and
                // was received successfully

                TxStatus = PHYGetShortRAMAddr(0x24);
                if( TxStat.cipher == 0)
                {
                    if (TxStatus & 0x20)
                    {
                        // Channel Busy, CSMA-CA failure
                        TxStat.success = 0;
                    }
                    else if (TxStatus & 0x01)
                    {
                        //Failure- No ack back
                        TxStat.success = 0;
                        TxStat.no_ack = 1;
                    }
                }
                TxStat.cipher = 0;
                if( (TxStatus & 0x21) == 0 )
                {
                    BYTE Pending = PHYGetShortRAMAddr(0x1b);
                    if(( currentPacket.info.bits.RX_association && (Pending & 0b00000100 )) ||
                        currentPacket.info.bits.disassociation )
                    {
                        macTasksPending.bits.bSendUpMACConfirm = 1;
                    }
                    if( currentPacket.info.bits.data_request == 1 )
                    {
                        pendingAckFrameControl.word.Val = 0;
                        pendingAckFrameControl.bits.FrameType = MAC_FRAME_TYPE_ACK;
                        if( Pending & 0b00010000 )
                        {
                            pendingAckFrameControl.bits.FramePending = 1;
                        } else {
                            PHYTasksPending.bits.PHY_DATA_REQUEST = 0;
                        }
                    }
                    //success
                    TxStat.success = 1;
                }
                PHYTasksPending.bits.PHY_TX = 0;

            }

			#ifdef I_SUPPORT_SECURITY_SPEC
            if( CheckInterrupt & 0x10 )
            {
                // security interrupt from MAC layer
                BYTE i;
                BYTE loc;
                BYTE KeySeq;
                BYTE FrameControlMSB;
                BYTE FrameControlLSB;
                BYTE SecurityLevel = SwitchTable[nwkSecurityLevel]; //SecurityLevel_ZIGBEE_2_IEEE(nwkSecurityLevel);
                PHYTasksPending.bits.PHY_SECURITY = 1;

                FrameControlLSB = PHYGetLongRAMAddr((WORD)0x301);
                FrameControlMSB = PHYGetLongRAMAddr((WORD)0x302);

                loc = 0x04;

                i = FrameControlMSB & 0b0000001100;
                if( i != 0 ) // has destination PANID
                {
                    loc += 2;
                    if( i == 0b00001000 ) // short address
                    {
                        loc += 2;
                    }
                    else if( i == 0b00001100 ) // long address
                    {
                        loc += 8;
                    }
                }


                i = FrameControlMSB & 0b11000000;
                if( i != 0 ) // has destination PANID
                {
                    if( (FrameControlLSB & 0b01000000) == 0x00 )
                    {
                        loc += 2;
                    }
                    if( i == 0b10000000 ) // short address
                    {
                        loc += 2;
                    }
                    else if( i == 0b11000000 ) // long address
                    {
                        loc += 8;
                    }
                }

                
                loc += 4;

                KeySeq = PHYGetLongRAMAddr((WORD)(0x300) + loc);
                for(i = 0; i < 2; i++)
                {
                    #ifdef USE_EXTERNAL_NVM
						if( plainSecurityKey[i].SeqNumber.v[0] == KeySeq &&
							plainSecurityKey[i].SeqNumber.v[1] == nwkMAGICResSeq )
                    #else
                        GetNwkKeyInfo(&currentNetworkKeyInfo, &(networkKeyInfo[i]));
						if( currentNetworkKeyInfo.SeqNumber.v[0] == KeySeq &&
							currentNetworkKeyInfo.SeqNumber.v[1] == nwkMAGICResSeq)
					#endif
                    {
                        break;
                    }
                }

                if( i == 2 )
                {
                    // cannot find the key, ignore
                    PHYSetShortRAMAddr(SECCR0, 0x80);   // cannot find the key, ignore
                }
                else {
                    WORD myloc = 0x2B0;
					#ifdef USE_EXTERNAL_NVM
						BYTE KeyIndex = i;
					#endif
                    for(i = 0; i < 16; i++)
                    {
						#if defined(USE_EXTERNAL_NVM)
							PHYSetLongRAMAddr(myloc++, plainSecurityKey[KeyIndex].NetKey.v[i];
						#else
							PHYSetLongRAMAddr(myloc++, currentNetworkKeyInfo.NetKey.v[i]);
						#endif
                    }
                    // set security level and trigger the decryption
                    PHYSetShortRAMAddr(SECCR0, SecurityLevel << 3 | 0x40);
                }
            }
			#endif
			
			/* check and process the Rx interrupt */
            if (CheckInterrupt & 0x08)
            {
                BYTE_VAL ack_status;
                BYTE count;
                BYTE counter;
                BYTE_VAL w;
                //static BYTE rc = 0;

                #if (RX_BUFFER_SIZE > 256)
                        #error "Rx buffer must be <= 256"
                #else
                        #define BUFFER_CAST BYTE
                        BYTE RxBytesRemaining;
                        BYTE OldRxWrite;
                #endif

                //rc++;
				#ifdef I_SUPPORT_SECURITY
                	PHYTasksPending.bits.PHY_SECURITY = 0;
				#endif

                ack_status.Val = 0;
                count = 0;
                counter = 0x00;

                /* Process errata #2 RXMAC here */
                /* Hold off further recieving of bytes until the entire packet has been read */
                PHYSetShortRAMAddr(BBREG1, 0x04);
                
                // Receive ok interrupt
                if(RxData.inUse == 0)
                {
                    RxData.size = PHYGetLongRAMAddr ((WORD)(0x300 + counter++));
                    RxData.inUse=1;
                }

                OldRxWrite = RxWrite;
                if(RxWrite < RxRead)
                {
                    RxBytesRemaining = (BUFFER_CAST)(RxRead - RxWrite - 1);
                }
                else
                {
                    RxBytesRemaining = (BUFFER_CAST)(RX_BUFFER_SIZE - 1 - RxWrite + RxRead);
                }

                w.Val = RxData.size;
                
                /* this is less then because we need one extra byte for the length (which worst case would make it equivent to less then or equal to )*/
                if(w.Val < RxBytesRemaining)
                {
                    MAC_FRAME_CONTROL mfc;

                    /* there is room in the buffer */
                    RxData.inUse = 0;

                    /* add the packet */
                    RxBuffer[RxWrite++]=w.Val;

                    if(RxWrite==(BYTE)RX_BUFFER_SIZE)
                    {
                        RxWrite = 0;
                    }

                    while(w.Val--)
                    {
                        //Note: I am counting on the fact that RxWrite doesn't get incremented here anymore such that the ACK packet doesn't get written into the Buffer and the RxWrite doesn't get modified.
                        if (w.Val == 1)
                        {
                            // The last two bytes will be the 16-bit CRC.  Instead, we will read out the RSSI value
                            // for the link quality and stick it in the second to last byte.  We still need to read the
                            // last byte of the CRC to trigger the device to flush the packet.
                            RxBuffer[RxWrite] = PHYGetLongRAMAddr ((WORD)(0x300 + counter+3));

                            counter++;
                        }
                        else
                        {
                            RxBuffer[RxWrite] = PHYGetLongRAMAddr ((WORD)(0x300 + counter++));
                        }

                        if(count==0)
                        {
                            //if the frame control indicates that this packet is an ack

                            mfc.word.byte.LSB=RxBuffer[RxWrite];

                            if(mfc.bits.FrameType == 0b010)
                            {
                                //it was an ack then set the ack_status.bits.b0 to 1 showing it was an ack
                                ack_status.bits.b0 = 1;
                            }
                        }
                        else if(count==2)
                        {
                            //if we are reading the sequence number and the packet was an ack
                            if(ack_status.bits.b0)
                            {

                                if ((macTasksPending.bits.packetPendingAck) &&
                                    (RxBuffer[RxWrite] == currentPacket.sequenceNumber))
                                {
                                    // If this is the ACK we've been waiting for, set the flag to
                                    // send up the confirm and save the Frame Control.
                                    macTasksPending.bits.bSendUpMACConfirm = 1;
                                    pendingAckFrameControl = mfc;
                                }
                                RxWrite = OldRxWrite;
                                goto DoneReceivingPacket;
                            }
                        }

                        count++;
                        RxWrite++;
                        //roll buffer if required
                        if(RxWrite==(BYTE)RX_BUFFER_SIZE)
                        {
                            RxWrite = 0;
                        }
                    }

                    if(RxWrite==0)
                    {
                        w.Val = RxBuffer[RX_BUFFER_SIZE-1];
                    }
                    else
                    {
                        w.Val = RxBuffer[RxWrite - 1];
                    }

                    #if 0
                    if(PHYGetShortRAMAddr(RXSR) & 0x08 )
                    {
                        /* crc failed.  Erase packet from the array */
                        RxWrite = OldRxWrite;
                        // Flush the RX FIFO
                        PHYSetShortRAMAddr (RXFLUSH, 0x01);
                    }
                    else
                    #endif
                    {
                        ZigBeeStatus.flags.bits.bHasBackgroundTasks = 1;
                        PHYTasksPending.bits.PHY_RX = 1;
                    }
                }
                else
                {
                    RxWrite = OldRxWrite;
                    ZigBeeStatus.flags.bits.bRxBufferOverflow = 1;
                }

DoneReceivingPacket: 

                PHYSetShortRAMAddr(RXFLUSH, 0x01);
                PHYSetShortRAMAddr(BBREG1, 0x00);

                NOP();
            }
            
         }

    }
Esempio n. 5
0
void PHYInit(void)
{
        BYTE i;
        WORD j;

        PHY_RESETn_TRIS = 0;

        RxData.inUse        = 0;
        PHYTasksPending.Val = 0;

        CLRWDT();

        /* Do a hard reset */
        PHY_RESETn = 0;
        for(j=0;j< (WORD)300;j++){}
            
        PHY_RESETn = 1;
        for(j=0;j<(WORD)300;j++){}
            
        /* Do a soft reset - power mgrmnt, baseband, and mac resets */
        PHYSetShortRAMAddr(SOFTRST, 0x07);
        do
        {
            i = PHYGetShortRAMAddr(SOFTRST);
        }while((i & 0x07) != (BYTE)0x00);
        for(j=0; j < (WORD)1000; j++) {};

      
        /* Do a soft reset - power mgrmnt, baseband, and mac resets */
        PHYSetShortRAMAddr(SOFTRST, 0x07);
        do
        {
            i = PHYGetShortRAMAddr(SOFTRST);
        }while((i & 0x07) != (BYTE)0x00);
        for(j=0; j < (WORD)1000; j++) {};

        /* flush the RX fifo */
        //PHYSetShortRAMAddr(RXFLUSH,0x01);
        PHYSetShortRAMAddr(RXFLUSH,0x61);


        /* Program the short MAC Address, 0xffff */
        PHYSetShortRAMAddr(SADRL,0xFF);
        PHYSetShortRAMAddr(SADRH,0xFF);
        PHYSetShortRAMAddr(PANIDL,0xFF);
        PHYSetShortRAMAddr(PANIDH,0xFF);

        /* Program Long MAC Address, 0xaaaaaaaaaaaaaaaaaa*/
        PHYSetShortRAMAddr(EADR0, MAC_LONG_ADDR_BYTE0);
        PHYSetShortRAMAddr(EADR1, MAC_LONG_ADDR_BYTE1);
        PHYSetShortRAMAddr(EADR2, MAC_LONG_ADDR_BYTE2);
        PHYSetShortRAMAddr(EADR3, MAC_LONG_ADDR_BYTE3);
        PHYSetShortRAMAddr(EADR4, MAC_LONG_ADDR_BYTE4);
        PHYSetShortRAMAddr(EADR5, MAC_LONG_ADDR_BYTE5);
        PHYSetShortRAMAddr(EADR6, MAC_LONG_ADDR_BYTE6);
        PHYSetShortRAMAddr(EADR7, MAC_LONG_ADDR_BYTE7);


        /* setup */
        PHYSetLongRAMAddr(RFCTRL2,0x80);   /* RF Optimization */

        /* set the power level to max level */
        PHYSetOutputPower( PA_LEVEL );

        /* program RSSI ADC with 2.5 MHz clock */
        PHYSetLongRAMAddr(RFCTRL6,0x90);     /* RF Optimization */
        
        PHYSetLongRAMAddr(RFCTRL7,0x80);     /* RF Optimization */

        /* Program CCA mode using RSSI */
        PHYSetShortRAMAddr(BBREG2,0x80);    /* Set CCA mode = ED and threshold = b0000 */
        
        /* Enable the packet RSSI */
        PHYSetShortRAMAddr(BBREG6,0x40);    /* Append RSSI value in RxFIFO */
        
        /* Program CCA, RSSI threshold values */
        PHYSetShortRAMAddr(RSSITHCCA,0x60);

        #ifdef I_AM_FFD
            PHYSetShortRAMAddr(ACKTMOUT,0xB9);
        #endif

        /* Set up device to operate over wider temps */
        PHYSetLongRAMAddr(RFCTRL0, 0x03);
        PHYSetLongRAMAddr(RFCTRL1, 0x02);
        
        /* Configure to use external PA LNA */
        #if defined(USE_EXT_PA_LNA) && defined(__C30__)
            PHYSetLongRAMAddr(TESTMODE, 0x0F);
        #endif
        
        /* Set interrupt mask, handle only Rx and Tx for now */
        #ifdef I_SUPPORT_SECURITY_SPEC
            PHYSetShortRAMAddr(INTMSK, 0b11100110);
        #else
            PHYSetShortRAMAddr(INTMSK, 0b11110110);  /* this is what we currently use */
        #endif

        PHYSetLongRAMAddr(RFCTRL1,0x01);/* set optimal VCO current value */
        
        PHYSetShortRAMAddr(TXPEMISP, 0x95);
        
        /* Transmit ON time setting = 0x6 */
        PHYSetShortRAMAddr(FFOEN, 0x98);  /* Tx and Rx FIFO output enable signal - via state machine */
        
        /* Set sleep clk div = 1 */
        PHYSetLongRAMAddr(SCLKDIV, 0x01);
        
        /* System clock (20MHZz) recovery time = 0x5f */
        PHYSetShortRAMAddr(SLPACK, 0x5f);
        
        /* VCO control equals 1 */
        PHYSetLongRAMAddr(RFCTRL8, 0x10);  /* RF Optimization */
        
        /* waiting until state machine is in Rx Mode */
        PHYSetShortRAMAddr(TXPEMISP, 0x95);
               
       
        /* wait until state machine is in Rx Mode */
        do
        {
            i = PHYGetLongRAMAddr(RFSTATE);
        }
        while((i&0xE0) != 0xA0);
}