/* this timer needs to be smaller than the first */ void set_second_random_timer(uint16_t max_value_ms) { uint16_t max_value, random_value, random_less_than_max; max_value = max_value_ms*1000; // measured 1000 = 1 second (8MHz SMCLK) random_value = 0; random_value |= MRFI_RandomByte(); random_value |= (MRFI_RandomByte()<<8); random_less_than_max = random_value%max_value; TBCCTL1 = CCIE; // TBCCR1 interrupt enabled TBCCR1 = random_less_than_max; TBCTL |= TBCLR; // clear the timer }
void set_random_timer(uint16_t max_value_ms) { uint16_t max_value, random_value, random_less_than_max; max_value = max_value_ms*1000; // measured 1000 = 1 second (8MHz SMCLK) random_value = 0; random_value |= MRFI_RandomByte(); random_value |= (MRFI_RandomByte()<<8); random_less_than_max = random_value%max_value; TBCCTL0 = CCIE; // TBCCR0 interrupt enabled TBCCR0 = random_less_than_max; TBCTL = TBSSEL_2 + 0x00C0 + MC_1; // source from SMCLK/8, upmode }
/****************************************************************************** * @fn mrfiLinkSend * * @brief Send data on the RX link. * * @param pBuf - buffer to be transmitted * * @param len - number of bytes to be transmitted * * @return Return code indicates success or failure of transmit: * MRFI_TX_RESULT_SUCCESS - transmit succeeded * MRFI_TX_RESULT_FAILED - transmit failed because CCA or ACK failed */ uint8 mrfiLinkSend(uint8 *pBuf, uint8 len, uint8 nRetrans) { uint8 v,i,status; v= halIntLock(); MRFI_SET_PAYLOAD_LEN(&pkt, len+2); memcpy(MRFI_P_DST_ADDR(&pkt), dest_addr, 4); memcpy(MRFI_P_SRC_ADDR(&pkt), src_addr, 4); MRFI_P_PAYLOAD(&pkt)[0]= seqSend; MRFI_P_PAYLOAD(&pkt)[1]= MRFI_LINK_DATA; memcpy(MRFI_P_PAYLOAD(&pkt)+2, pBuf, len); halIntUnlock(v); for (i=0;i<nRetrans;i++) { status= MRFI_Transmit(&pkt, MRFI_TX_TYPE_CCA); if (status==MRFI_TX_RESULT_SUCCESS) { if (waitForAck(20)) { seqSend++; break; } else { status= MRFI_TX_RESULT_FAILED; // wait random time if sending is not successful // (20-40 milliseconds) halMcuWaitUs( (20000/255*MRFI_RandomByte()) + 20000 ); } } } return status; }
/****************************************************************************** * @fn nwk_joinInit * * @brief Initialize Join application. * * input parameters * * output parameters * * @return void */ void nwk_joinInit(uint8_t (*pf)(linkID_t)) { //-----MSP-EXP430F5137 Edit //-----To modify link token //---before if (!sJoinToken) { sJoinToken = DEFAULT_JOIN_TOKEN; } //---after // sJoinToken = (*(uint32_t *)0x01A0E); spCallback = pf; (void) spCallback; /* keep compiler happy if we don't use this */ sTid = MRFI_RandomByte() ; #ifdef ACCESS_POINT /* set link token to something other than deafult if desired */ nwk_setLinkToken(generateLinkToken()); #if defined(STARTUP_JOINCONTEXT_ON) sJoinOK = 1; #elif defined(STARTUP_JOINCONTEXT_OFF) sJoinOK = 0; #else #error ERROR: Must define either STARTUP_JOINCONTEXT_ON or STARTUP_JOINCONTEXT_OFF #endif spSandFContext = nwk_getSFInfoPtr(); #endif return; }
/****************************************************************************** * @fn nwk_freqInit * * @brief Initialize NWK Frequency application. * * @return none. */ void nwk_freqInit(void) { /* pick a random value to start the transaction ID for this app. */ sTid = MRFI_RandomByte(); return; }
//============================================= void gradient_Init(uint8_t is_sink) { P1OUT &= ~0x03; print_debug("\r\nRESTART",9); //serial communication P3SEL |= 0x30; // P3.4,5 = USCI_A0 TXD/RXD UCA0CTL1 = UCSSEL_2; // SMCLK UCA0BR0 = 0x41; // 9600 from 8Mhz UCA0BR1 = 0x3; UCA0MCTL = UCBRS_2; UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt __enable_interrupt(); //button P1DIR &= ~0x04; // P1.3 input P1OUT = 0x04; P1REN |= 0x04; // P1.3 pullup P1IE |= 0x04; // P1.3 interrupt enabled P1IES |= 0x04; // P1.3 Hi/lo edge P1IFG &= ~0x04; // P1.3 IFG cleared //extension pins used for debugging P4SEL &= ~0x20; // P4.5 generic I/O pin P2DIR |= 0x02; // P2.1 output @ extension pin P4 P2DIR |= 0x08; // P2.3 output @ extension pin P6 P4DIR |= 0x08; // P4.3 output @ extension pin P8 P4DIR |= 0x20; // P4.5 output @ extension pin P10 //set myAddr if(Flash_Addr == 0xFF) // no address set before { myAddr = MRFI_RandomByte(); FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits FCTL1 = FWKEY + WRT; // Set WRT bit for write operation Flash_Addr = myAddr; FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit } else { myAddr=Flash_Addr; } //set height and start clock if (is_sink) { myHeight = 0; BSP_TOGGLE_LED1(); } else { myHeight = 255; //timer A BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO TACCTL0 = CCIE; // TACCR0 interrupt enabled TACCR0 = 1500*WAKEUP_PERIOD_S_FIXED; // 1500=1 second TACTL = TASSEL_1 + MC_1 + ID_3; // ACLK/8, upmode } gradient_set_state(GRADIENT_IDLE); mrfiSpiWriteReg(PATABLE, TX_POWER); print_cc2500_registers(); MRFI_WakeUp(); wor_start(IS_SINK_NODE); }
/****************************************************************************** * @fn nwk_freqInit * * @brief Initialize NWK Frequency application. * * @return none. */ void nwk_freqInit(void) { memset(&sCurLogicalChan, 0x0, sizeof(sCurLogicalChan)); /* pick a random value to start the transaction ID for this app. */ sTid = MRFI_RandomByte(); return; }
void nwk_mgmtInit(void) { sTid = MRFI_RandomByte(); #ifdef ACCESS_POINT memset(&sSFMarker, 0x0, sizeof(sSFMarker)); #endif return; }
/************************************************************************************************** * @fn Mrfi_RandomBackoffDelay * * @brief Waits for random amount of time before returning. * The range is: 1*250 to 16*250 us. * * @param none * * @return none ************************************************************************************************** */ static void Mrfi_RandomBackoffDelay(void) { uint8_t backoffs; uint8_t i; /* calculate random value for backoffs - 1 to 16 */ backoffs = (MRFI_RandomByte() & 0x0F) + 1; /* delay for randomly computed number of backoff periods */ for (i=0; i<backoffs; i++) { Mrfi_DelayUsec( MRFI_BACKOFF_PERIOD_USECS ); } }
void nwk_linkInit(void) { if (!sLinkToken) { /* if the link token has not been set externally by the time we get here * (such as by the ioctl token-setting interface) assign the default */ sLinkToken = DEFAULT_LINK_TOKEN; } /* set a non-zero TID. */ while (!(sTid = MRFI_RandomByte())) ; #if NUM_CONNECTIONS > 0 memset((void *)&sServiceLinkID, 0x0, sizeof(sServiceLinkID)); #endif return; }
void nwk_frameInit(uint8_t (*pF)(linkID_t)) { /****** Fill static values for the DEVICEINFO byte that will go in each frame ******/ /* Rx type when frame originates from this device. Set in nwk_buildFrame() */ /* Tx type when frame sent from this device. Set in nwk_sendframe() */ #if !defined(END_DEVICE) sMyRxType = F_RX_TYPE_USER_CTL; #if defined(ACCESS_POINT) sMyTxType = F_TX_DEVICE_AP; #else sMyTxType = F_TX_DEVICE_RE; #endif #else sMyTxType = F_TX_DEVICE_ED; #if defined(RX_POLLS) sMyRxType = F_RX_TYPE_POLLS; #endif #if defined(RX_USER) sMyRxType = F_RX_TYPE_USER_CTL; #endif #endif /****** DONE fill static values for the DEVICEINFO byte that will go in each frame ******/ #if !defined(RX_POLLS) spCallback = pF; #else (void) pF; #endif sMyAddr = nwk_getMyAddress(); while (!(sTRACTID=MRFI_RandomByte())) ; return; }
void nwk_pingInit(void) { sTid = MRFI_RandomByte(); return; }
static uint8_t smpl_send_link_reply(mrfiPacket_t *frame) { #if NUM_CONNECTIONS > 0 frameInfo_t *pOutFrame; connInfo_t *pCInfo; uint8_t remotePort; uint8_t msg[LINK_REPLY_FRAME_SIZE]; /* Is this a legacy frame? If so continue. Otherwise check version.*/ if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > LINK_LEGACY_MSG_LENGTH) { /* see if protocol version is correct... */ if (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion()) { /* Accommodation of protocol version differences can be noted or accomplished here. * This field was also checked in the join transaction but it is checked again here * because that check may not have occurred if thre is no AP in this topology. * Otherwise, no match and the board goes back */ return SENT_NO_REPLY; } } /* see if token is correct */ { uint32_t lt; nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD( frame) + F_APP_PAYLOAD_OS + L_LINK_TOKEN_OS, <, sizeof(lt)); if (lt != sLinkToken) { return SENT_NO_REPLY; } } /* if we get here the token matched. */ /* is this a duplicate request? */ remotePort = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_RMT_PORT_OS); if (pCInfo = nwk_isLinkDuplicate(MRFI_P_SRC_ADDR(frame), remotePort)) { /* resend reply */ msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; /* sender's TID */ msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); /* Send reply with the local port number so the remote device knows where to * send packets. */ msg[LR_RMT_PORT_OS] = pCInfo->portRx; /* put my Rx type in there. used to know how to set hops when sending back. */ msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); # if defined(SMPL_SECURE) /* Set the Tx counter value for peer's Rx counter object */ nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); /* We also need to save the newly generated Rx counter value. */ nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); # endif if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS - (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT)))) { /* destination address is the source adddress of the received frame. */ memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); # if defined(SMPL_SECURE) nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); # endif /* SMPL_SECURE */ nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); } return SENT_REPLY; } if (!sListenActive) { /* We've checked for duplicate and resent reply. In that case we weren't listening * so just go back`. */ return SENT_NO_REPLY; } /* room to link? */ # if defined(AP_IS_DATA_HUB) pCInfo = nwk_findAlreadyJoined(frame); if (!pCInfo) # endif { pCInfo = nwk_getNextConnection(); } if (pCInfo) { /* yes there's room and it's not a dup. address. */ memcpy(&pCInfo->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); if (!nwk_allocateLocalRxPort(LINK_REPLY, pCInfo)) { nwk_freeConnection(pCInfo); /* we're done with the packet */ return SENT_REPLY; } /* The local Rx port is the one returned in the connection structure. The * caller is waiting on this to be set. The code here is running in an ISR * thread so the caller will see this change after RETI. */ if (NUM_CONNECTIONS == sNumLinkers) { /* Something is wrong -- no room to stack Link request */ nwk_freeConnection(pCInfo); /* we're done with the packet */ return SENT_REPLY; } sServiceLinkID[sNumLinkers++] = pCInfo->thisLinkID; /* save the remote Tx port */ pCInfo->portTx = remotePort; /* connection is valid... */ pCInfo->connState = CONNSTATE_CONNECTED; /* Set hop count. If it's a polling device set the count to the * distance to the AP. otherwise, set it to the max less the remaining * which will be the path taken for this frame. It will be no worse * then tha max and probably will be better. */ if (F_RX_TYPE_POLLS == *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_MY_RXTYPE_OS)) { /* It polls. so. we'll be sending to the AP which will store the * frame. The AP is only MAX_HOPS_FROM_AP hops away from us. */ pCInfo->hops2target = MAX_HOPS_FROM_AP; } else { /* Can't really use this trick because the device could move. If the * devices are all static this may work unless the initial reception * was marginal. */ # if defined(DEVICE_DOES_NOT_MOVE) pCInfo->hops2target = MAX_HOPS - GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT); # else pCInfo->hops2target = MAX_HOPS; # endif } /* Send reply with the local port number so the remote device knows where to * send packets. */ msg[LR_RMT_PORT_OS] = pCInfo->portRx; /* put my Rx type in there. used to know how to set hops when sending back. */ msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; /* sender's TID */ msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); # if defined(SMPL_SECURE) nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); pCInfo->connTxCTR = MRFI_RandomByte() | \ ((uint32_t)(MRFI_RandomByte()) << 8) | \ ((uint32_t)(MRFI_RandomByte()) << 16) | \ ((uint32_t)(MRFI_RandomByte()) << 24); nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); # endif if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS - (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT)))) { /* destination address is the source adddress of the received frame. */ memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); # if defined(SMPL_SECURE) nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); # endif if (SMPL_SUCCESS != nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED)) { /* better release the connection structure */ nwk_freeConnection(pCInfo); } } else { /* better release the connection structure */ nwk_freeConnection(pCInfo); } } /* we're done with the packet */ return SENT_REPLY; #else return SENT_NO_REPLY; #endif /* NUM_CONNECTIONS */ }
smplStatus_t nwk_link(linkID_t *lid) { uint8_t msg[LINK_FRAME_SIZE]; connInfo_t *pCInfo = nwk_getNextConnection(); smplStatus_t rc; if (pCInfo) { addr_t addr; union { ioctlRawSend_t send; ioctlRawReceive_t recv; } ioctl_info; if (!nwk_allocateLocalRxPort(LINK_SEND, pCInfo)) { nwk_freeConnection(pCInfo); return SMPL_NOMEM; } memcpy(addr.addr, nwk_getBCastAddress(), NET_ADDR_SIZE); ioctl_info.send.addr = &addr; ioctl_info.send.msg = msg; ioctl_info.send.len = sizeof(msg); ioctl_info.send.port = SMPL_PORT_LINK; /* Put link token in */ nwk_putNumObjectIntoMsg((void *)&sLinkToken, msg + L_LINK_TOKEN_OS, sizeof(sLinkToken)); /* set port to which the remote device should send */ msg[L_RMT_PORT_OS] = pCInfo->portRx; /* set the transaction ID. this allows target to figure out duplicates */ msg[LB_TID_OS] = sTid; /* set my Rx type */ msg[L_MY_RXTYPE_OS] = nwk_getMyRxType(); /* set request byte */ msg[LB_REQ_OS] = LINK_REQ_LINK; /* protocol version number */ msg[L_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); #if defined(SMPL_SECURE) pCInfo->connTxCTR = MRFI_RandomByte() | \ ((uint32_t)(MRFI_RandomByte()) << 8) | \ ((uint32_t)(MRFI_RandomByte()) << 16) | \ ((uint32_t)(MRFI_RandomByte()) << 24); nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[L_CTR_OS], 4); #endif if (SMPL_SUCCESS != (rc = SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send))) { return rc; } { uint8_t radioState = MRFI_GetRadioState(); ioctl_info.recv.port = SMPL_PORT_LINK; ioctl_info.recv.msg = msg; ioctl_info.recv.addr = (addr_t *)pCInfo->peerAddr; NWK_CHECK_FOR_SETRX(radioState); NWK_REPLY_DELAY(); NWK_CHECK_FOR_RESTORE_STATE(radioState); if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) { uint8_t firstByte = msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT); /* Sanity check for correct reply frame. Older version * has the length instead of the request as the first byte. */ if ((firstByte != LINK_REQ_LINK) && (firstByte != LINK_REPLY_LEGACY_MSG_LENGTH) ) { /* invalidate connection object */ nwk_freeConnection(pCInfo); return SMPL_NO_LINK; } } else { /* no successful receive */ nwk_freeConnection(pCInfo); return SMPL_TIMEOUT; } pCInfo->connState = CONNSTATE_CONNECTED; pCInfo->portTx = msg[LR_RMT_PORT_OS]; /* link reply returns remote port */ *lid = pCInfo->thisLinkID; /* return our local port number */ /* Set hop count. If it's a polling device set the count to the * distance to the AP. Otherwise, set it to the max less the remaining * which will be the path taken for this frame. It will be no worse * then tha max and probably will be better. */ if (F_RX_TYPE_POLLS == msg[LR_MY_RXTYPE_OS]) { pCInfo->hops2target = MAX_HOPS_FROM_AP; } else { /* Can't really use this trick because the device could move. If the * devices are all static this may work unless the initial reception * was marginal. */ #if defined(DEVICE_DOES_NOT_MOVE) pCInfo->hops2target = MAX_HOPS - ioctl_info.recv.hopCount; #else pCInfo->hops2target = MAX_HOPS; #endif } #if defined(SMPL_SECURE) nwk_getNumObjectFromMsg((void *)&msg[LR_CTR_OS], (void *)&pCInfo->connRxCTR, 4); #endif } /* guard against duplicates... */ ++sTid; if (!sTid) { sTid = 1; } return SMPL_SUCCESS; } return SMPL_NOMEM; }