/********************************************************************* * Function: void PHYSetDeviceAddress(WORD PANID, WORD shortAddress) * * PreCondition: Communication port to the MRF24J40 initialized * * Input: WORD PANID is the PANID you want to operate on * WORD shortAddress is the short address you want to use on that network * * Output: None * * Side Effects: None * * Overview: This function sets the short address for the IEEE address * filtering ********************************************************************/ void PHYSetDeviceAddress(INT16U PANID, INT16U shortAddress) { PHYSetShortRAMAddr(WRITE_SADRL,(INT8U)(PANID&0x00FF)); PHYSetShortRAMAddr(WRITE_SADRH,(INT8U)(PANID>>8)); PHYSetShortRAMAddr(WRITE_PANIDL,(INT8U)(shortAddress & 0x00FF)); PHYSetShortRAMAddr(WRITE_PANIDH,(INT8U)(shortAddress>>8)); }
/********************************************************************* * Function: void SetChannel(BYTE channel) * * PreCondition: MRF24J40 is initialized * * Input: BYTE channel - this is the channel that you wish * to operate on. This should be CHANNEL_11, CHANNEL_12, * ..., CHANNEL_26. * * Output: None * * Side Effects: the MRF24J40 now operates on that channel * * Overview: This function sets the current operating channel * of the MRF24J40 ********************************************************************/ void SetChannel(INT8U channel) { INT16U z; PHYSetLongRAMAddr(RFCTRL0, (channel | 0x02)); PHYSetShortRAMAddr(WRITE_RFCTL,0x04); for(z=0;z<600;z++){}; PHYSetShortRAMAddr(WRITE_RFCTL,0x00); for(z=0;z<600;z++){}; }
void PHYSetAutoACK(INT8U autoack){ #if (defined AUTO_ACK_CONTROL) && (AUTO_ACK_CONTROL == 1) INT8U reg; reg = PHYGetShortRAMAddr(READ_RXMCR); if(autoack){ PHYSetShortRAMAddr(WRITE_RXMCR,reg | 0x04); }else{ PHYSetShortRAMAddr(WRITE_RXMCR,reg & ~0x04); } #else (void)autoack; #endif }
/********************************************************************* * Function: void MRF24J40Sleep(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 be performed ********************************************************************/ void MRF24J40Sleep(void) { /* keep track of the status of the radio */ #if defined(I_AM_RFD) ZigBeeStatus.flags.bits.bRadioIsSleeping = 1; #endif //clear the WAKE pin in order to allow the device to go to sleep PHY_WAKE = 0; // make a power management reset to ensure device goes to sleep PHYSetShortRAMAddr(SOFTRST, 0x04); //;write the registers required to place the device in sleep PHYSetShortRAMAddr(TXBCNINTL, 0x80); PHYSetShortRAMAddr(RXFLUSH, 0x60); PHYSetShortRAMAddr(SLPACK, 0x80); }
/********************************************************************* * 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(); //these commands in the following of this function are added by lab411 @dat_a3cbq91 // Initialisation, only one time needed PHY_WAKE_TRIS = 0; //Set PHY_Wake to 0 that we can pull it high to activat MRF24J40 PHY_WAKE = 0; //1. Set Short Reg 0x22 to be 0x80 (TXBCNINTL) PHYSetShortRAMAddr(TXBCNINTL,0x80); //2. Set Short Reg 0x0D to be 0x60 (RXFLUSH) PHYSetShortRAMAddr(RXFLUSH,0x60); //3. Set Short Reg 0x35 to be 0x80 (SLPACK) PHYSetShortRAMAddr(SLPACK,0x80); while(1) { currentDifference = TickGet(); currentDifference.Val = TickGetDiff(currentDifference, failureTimer); if( currentDifference.Val > FIVE_MILI_SECOND ) { break; } } // Re-enable PA/LNA module PHYSetShortRAMAddr(WRITE_GPIODIR, 0x00); PHYSetLongRAMAddr(TESTMODE, 0x0F); /* Keep track of radio status - now awake */ #if defined(I_AM_RFD) ZigBeeStatus.flags.bits.bRadioIsSleeping = 0; #endif }
/********************************************************************* * Function: void MRF24J40Sleep(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 be performed ********************************************************************/ void MRF24J40Sleep(void) { /* keep track of the status of the radio */ #if defined(I_AM_RFD) ZigBeeStatus.flags.bits.bRadioIsSleeping = 1; #endif //clear the WAKE pin in order to allow the device to go to sleep PHY_WAKE = 0; //these command are added by lab411 @dat_a3cbq91 PHYSetLongRAMAddr(TESTMODE, 0x08); // Disable automatic switch on PA/LNA PHYSetShortRAMAddr(WRITE_GPIODIR, 0x0F); // Set GPIO direction PHYSetShortRAMAddr(WRITE_GPIO, 0x00); // Disable PA and LNA //PHYSetShortRAMAddr(WRITE_RFCTL,0x00); //;write the registers required to place the device in sleep PHYSetShortRAMAddr(WRITE_RXFLUSH,0x60); PHYSetShortRAMAddr(WRITE_TXBCNINTL,0x80); // make a power management reset to ensure device goes to sleep PHYSetShortRAMAddr(WRITE_SOFTRST, 0x04); PHYSetShortRAMAddr(WRITE_SLPACK,0x80); }
/********************************************************************* * 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; }
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(¤tNetworkKeyInfo, &(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(); } } }
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); }
/********************************************************************* * Function: void MRF24J40Reset(void) * * PreCondition: BoardInit (or other initialzation code is required) * * Input: None * * Output: None * * Side Effects: MRF24J40 is initialized * * Overview: This function initializes the MRF24J40 and is required * before stack operation is available ********************************************************************/ void MRF24J40Reset(void) { volatile INT8U i; volatile INT16U j; Radio_Count_states(); PHY_RESETn_LOW; for(j=0;j<7000;j++){}; PHY_RESETn_HIGH; for(j=0;j<7000;j++){}; /* do a soft reset */ PHYSetShortRAMAddr(WRITE_SOFTRST,0x07); for(j=0;j<1000;j++){}; PHYSetShortRAMAddr(WRITE_RFCTL,0x04); PHYSetShortRAMAddr(WRITE_RFCTL,0x00); for(j=0;j<1000;j++){}; // Enable FIFO and TX Enable //PHYSetShortRAMAddr(WRITE_FFOEN, 0x98); PHYSetShortRAMAddr(WRITE_FFOEN, 0x98); PHYSetShortRAMAddr(WRITE_TXPEMISP, 0x95); /* setup */ PHYSetLongRAMAddr(RFCTRL0,0x03); PHYSetLongRAMAddr(RFCTRL1,RFCTRL1_VAL); /* enable the RF-PLL */ PHYSetLongRAMAddr(RFCTRL2,0x80); /* set TX output power */ PHYSetLongRAMAddr(RFCTRL3, currentTxPower); /* program RSSI ADC with 2.5 MHz clock */ //PHYSetLongRAMAddr(RFCTRL6,0x04); PHYSetLongRAMAddr(RFCTRL6,0x90); PHYSetLongRAMAddr(RFCTRL7,0x80); PHYSetLongRAMAddr(RFCTRL8,0x10); // Disable clockout PHYSetLongRAMAddr(SCLKDIV,0x21); #if (DEVICE_TYPE != PAN_COORDINATOR) // Join network as router // and Automatic Acknowledgment enabled PHYSetShortRAMAddr(WRITE_RXMCR, 0x04); #else // Join network as PAN Coordinator // and Automatic Acknowledgment enabled PHYSetShortRAMAddr(WRITE_RXMCR, 0x0C); #endif /* flush the RX fifo */ PHYSetShortRAMAddr(WRITE_RXFLUSH,0x01); // Configure Unslotted CSMA-CA Mode i = PHYGetShortRAMAddr(READ_TXMCR); i = i & 0xDF; PHYSetShortRAMAddr(WRITE_TXMCR,i); // Define Nonbeacon-Enabled Network PHYSetShortRAMAddr(WRITE_ORDER,0xFF); /* Program CCA mode using RSSI */ // 0x80 é o valor default, 0xB8 é o recomendado //PHYSetShortRAMAddr(WRITE_BBREG2,0xB8); PHYSetShortRAMAddr(WRITE_BBREG2,0xB8); //PHYSetShortRAMAddr(WRITE_BBREG2,0x80); /* Program CCA, RSSI threshold values */ // Valor Default é 0x00, recomendado é 0x60 // Determina o níve de sinal que indica o canal como ocupado // 0x60 = -69 dBm PHYSetShortRAMAddr(WRITE_RSSITHCCA,0x60); //PHYSetShortRAMAddr(WRITE_RSSITHCCA,0x00); /* Enable the packet RSSI */ PHYSetShortRAMAddr(WRITE_BBREG6,0x40); /* Program the short MAC Address, 0xffff */ #if (DEVICE_TYPE != PAN_COORDINATOR) PHYSetShortRAMAddr(WRITE_SADRL,(INT8U)(macAddr & 0xFF)); PHYSetShortRAMAddr(WRITE_SADRH,(INT8U)(macAddr >> 8)); #else PHYSetShortRAMAddr(WRITE_SADRL,0x00); PHYSetShortRAMAddr(WRITE_SADRH,0x00); #endif /* and the short PanId Identifier, 0xffff */ // #if (DEVICE_TYPE != PAN_COORDINATOR) PHYSetShortRAMAddr(WRITE_PANIDL,(INT8U)(macPANId & 0xFF)); PHYSetShortRAMAddr(WRITE_PANIDH,(INT8U)(macPANId >> 8)); //#else // PHYSetShortRAMAddr(WRITE_PANIDL,0x42); // PHYSetShortRAMAddr(WRITE_PANIDH,0x47); // #endif // Program Long MAC Address for(i=0;i<8;i++) { PHYSetShortRAMAddr(WRITE_EADR0+i*2,mac64Address[7-i]); } // Configura o canal do radio SetChannel(CHANNEL_INIT_VALUE); for(j=0;j<1000;j++){}; PHYSetShortRAMAddr(WRITE_FFOEN, 0x98); // Habilita interrupções PHYSetShortRAMAddr(WRITE_INTMSK,0xF6); // bypass the errata to make RF communication stable PHYSetLongRAMAddr(RFCTRL1, RFCTRL1_VAL); }
/********************************************************************* * Function: INT8U MRF24J40Init(void) * * PreCondition: BoardInit (or other initialzation code is required) * * Input: None * * Output: Success/error * * Side Effects: MRF24J40 is initialized * * Overview: This function initializes the MRF24J40 ********************************************************************/ INT8U MRF24J40Init(void) { volatile INT8U i; volatile INT16U j; #if PROCESSOR == COLDFIRE_V1 iNesting++; #endif PHY_RESETn_LOW; for(j=0;j<7000;j++) { }; PHY_RESETn_HIGH; for(j=0;j<7000;j++) { }; /* do a soft reset */ PHYSetShortRAMAddr(WRITE_SOFTRST,0x07); for(j=0;j<1000;j++){}; PHYSetShortRAMAddr(WRITE_RFCTL,0x04); PHYSetShortRAMAddr(WRITE_RFCTL,0x00); for(j=0;j<1000;j++){}; // Enable FIFO and TX Enable PHYSetShortRAMAddr(WRITE_FFOEN, 0x98); PHYSetShortRAMAddr(WRITE_TXPEMISP, 0x95); /* program the RF and Baseband Register */ //PHYSetLongRAMAddr(RFCTRL4,0x02); /* Enable the RX */ //PHYSetLongRAMAddr(RFRXCTRL,0x01); /* setup */ PHYSetLongRAMAddr(RFCTRL0,0x03); PHYSetLongRAMAddr(RFCTRL1,RFCTRL1_VAL); /* enable the RF-PLL */ PHYSetLongRAMAddr(RFCTRL2,0x80); /* set TX output power */ PHYSetLongRAMAddr(RFCTRL3,TX_POWER_LEVEL); /* program RSSI ADC with 2.5 MHz clock */ //PHYSetLongRAMAddr(RFCTRL6,0x04); PHYSetLongRAMAddr(RFCTRL6,0x90); //PHYSetLongRAMAddr(RFCTRL7,0b00000000); //PHYSetLongRAMAddr(RFCTRL7,0b10011000); PHYSetLongRAMAddr(RFCTRL7,0x80); PHYSetLongRAMAddr(RFCTRL8,0x10); // Disable clockout PHYSetLongRAMAddr(SCLKDIV,0x21); #if (DEVICE_TYPE != PAN_COORDINATOR) // Join network as router // and Automatic Acknowledgment enabled PHYSetShortRAMAddr(WRITE_RXMCR, 0x04); #else // Join network as PAN Coordinator // and Automatic Acknowledgment enabled PHYSetShortRAMAddr(WRITE_RXMCR, 0x0C); #endif /* flush the RX fifo */ PHYSetShortRAMAddr(WRITE_RXFLUSH,0x01); // Configure Unslotted CSMA-CA Mode i = PHYGetShortRAMAddr(READ_TXMCR); i = i & 0xDF; PHYSetShortRAMAddr(WRITE_TXMCR,i); // Define Nonbeacon-Enabled Network PHYSetShortRAMAddr(WRITE_ORDER,0xFF); /* Program CCA mode using RSSI */ // 0x80 é o valor default, 0xB8 é o recomendado PHYSetShortRAMAddr(WRITE_BBREG2,0xB8); //PHYSetShortRAMAddr(WRITE_BBREG2,0x80); /* Program CCA, RSSI threshold values */ // Valor Default é 0x00, recomendado é 0x60 // Determina o níve de sinal que indica o canal como ocupado // 0x60 = -69 dBm PHYSetShortRAMAddr(WRITE_RSSITHCCA,0x60); //PHYSetShortRAMAddr(WRITE_RSSITHCCA,0x00); /* Enable the packet RSSI */ PHYSetShortRAMAddr(WRITE_BBREG6,0x40); /* Program the short MAC Address, 0xffff */ #if (DEVICE_TYPE != PAN_COORDINATOR) PHYSetShortRAMAddr(WRITE_SADRL,0xFF); PHYSetShortRAMAddr(WRITE_SADRH,0xFF); #else PHYSetShortRAMAddr(WRITE_SADRL,0x00); PHYSetShortRAMAddr(WRITE_SADRH,0x00); #endif /* and the short PanId Identifier, 0xffff */ #if (DEVICE_TYPE != PAN_COORDINATOR) PHYSetShortRAMAddr(WRITE_PANIDL,0xFF); PHYSetShortRAMAddr(WRITE_PANIDH,0xFF); #else PHYSetShortRAMAddr(WRITE_PANIDL,(PANID_INIT_VALUE & 0xFF)); PHYSetShortRAMAddr(WRITE_PANIDH,((PANID_INIT_VALUE>>8) & 0xFF)); #endif /* Test radio */ do { PHYSetShortRAMAddr(WRITE_EADR0,0xCA); i = PHYGetShortRAMAddr(READ_EADR0); if(i!= 0xCA) goto EXIT_ERROR; PHYSetShortRAMAddr(WRITE_EADR1,0xF1); i = PHYGetShortRAMAddr(READ_EADR1); if(i!= 0xF1) goto EXIT_ERROR; PHYSetShortRAMAddr(WRITE_EADR2,0x05); i = PHYGetShortRAMAddr(READ_EADR2); if(i!= 0x05) goto EXIT_ERROR; PHYSetShortRAMAddr(WRITE_EADR3,0xBA); i = PHYGetShortRAMAddr(READ_EADR3); if(i!= 0xBA) goto EXIT_ERROR; PHYSetShortRAMAddr(WRITE_EADR4,0xFF); i = PHYGetShortRAMAddr(READ_EADR4); if(i!= 0xFF) goto EXIT_ERROR; PHYSetShortRAMAddr(WRITE_EADR5,0x10); i = PHYGetShortRAMAddr(READ_EADR5); if(i!= 0x10) goto EXIT_ERROR; PHYSetShortRAMAddr(WRITE_EADR6,0x4E); i = PHYGetShortRAMAddr(READ_EADR6); if(i!= 0x4E) goto EXIT_ERROR; PHYSetShortRAMAddr(WRITE_EADR7,0x11); i = PHYGetShortRAMAddr(READ_EADR7); if(i!= 0x11) goto EXIT_ERROR; break; EXIT_ERROR: #if PROCESSOR == COLDFIRE_V1 iNesting--; #endif return RADIO_ERROR; }while(0); // Inicializa o módulo de memória FLASH InitFlash(); #if (PROCESSOR == ARM_Cortex_M0) if ((mac64Address[0] == 0xFF) && (mac64Address[1] == 0xFF) && (mac64Address[2] == 0xFF) && (mac64Address[3] == 0xFF)) { INT8U tmp_mac64[8] = {EUI_0,EUI_1,EUI_2,EUI_3,EUI_4,EUI_5,EUI_6,EUI_7}; EraseFlash(0x0001F000, 1024); WriteToFlash((INT8U*)&tmp_mac64, MAC64_MEM_ADDRESS, 8); } #endif /* Program Long MAC Address*/ for(i=0;i<8;i++) { PHYSetShortRAMAddr(WRITE_EADR0+i*2,mac64Address[7-i]); } SetChannel(CHANNEL_INIT_VALUE); for(j=0;j<1000;j++){}; //i = PHYGetShortRAMAddr(READ_ISRSTS); PHYSetShortRAMAddr(WRITE_FFOEN, 0x98); // Habilita interrupções PHYSetShortRAMAddr(WRITE_INTMSK,0xF6); // bypass the errata to make RF communication stable PHYSetLongRAMAddr(RFCTRL1, RFCTRL1_VAL); #if PROCESSOR == COLDFIRE_V1 iNesting--; #endif return RADIO_OK; }