/****************************************************************************** * @fn broadcast_channel_change * * @brief For Access Point only: broadcast a channel change frame. * * input parameters * @param idx - index into channel table of new (logical) channel * * @return none. */ #ifdef ACCESS_POINT #define CC_REDUNDANCY 1 /* Change-channel redundancy count */ static void broadcast_channel_change(uint8_t idx) { ioctlRawSend_t send; uint8_t msg[FREQ_REQ_MOVE_FRAME_SIZE]; uint8_t repeat = CC_REDUNDANCY; if (idx >= NWK_FREQ_TBL_SIZE) { return; } msg[FB_APP_INFO_OS] = FREQ_REQ_MOVE; msg[F_CHAN_OS] = idx; send.addr = (addr_t *)nwk_getBCastAddress(); send.msg = msg; send.len = sizeof(msg); send.port = SMPL_PORT_FREQ; SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); /* Redundancy addresses the fact that an RE (or any always-listening * device) might miss the command */ while (repeat--) { NWK_DELAY(250); SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); } }
/* channel handle * if appInFrame->msg[0] == 0x00, then get current channel * if is 0x01, then set current channel */ void channelHandle(struct AppFrame* appInFrame, struct AppFrame* appOutFrame) { if(appInFrame->len == 0) return; if(appInFrame->msg[0] == GET) { SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_GET, &channel); appOutFrame->msg[0] = (channel.logicalChan); appOutFrame->len = 1; logTemp[0] = 2;/* the length of logTemp*/ logTemp[1] = SEND_CHANNEL; log(INFO_OTHER, logTemp); //log(INFO, "Send channel"); } else { if(appInFrame->msg[0] == SET && appInFrame->len >= 2) { channel.logicalChan = appInFrame->msg[1]; SMPL_Ioctl( IOCTL_OBJ_FREQ, IOCTL_ACT_SET, &channel); appOutFrame->len = 0; logTemp[0] = 2;/* the length of logTemp*/ logTemp[1] = SET_CHANNEL; log(INFO_OTHER, logTemp); //log(INFO, "Set channel"); } } return; }
void main(void) { BSP_Init(); // Initialisation de la librairie BSP NWK_DELAY(500); SMPL_Init(&RxCallBack); // Initialisation de la librairie simpliciTI SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); // Activation de la radio pour permettre la réception des messages COM_Init(); // Initialisation du port COM while (1) { if(broadSem) { memset(msg, 0, sizeof(msg)); if ((SMPL_Receive(SMPL_LINKID_USER_UUD, msg, &msgLen)) == SMPL_SUCCESS) // Cette fonction permet de stocker les messages reçu par un périphérique en spécifiant son linkID { sigInfo.lid = SMPL_LINKID_USER_UUD; // Permet d'indiquer les informations de quel périphérique sont demandées SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SIGINFO, &sigInfo); // On récupère les informations sur la force de connexion dans la structure sigInfo msg[5] = 'S'; msg[6] = sigInfo.sigInfo.rssi+128; msg[7] = 'L'; msg[8] = sigInfo.sigInfo.lqi; msg[9] = 0xFF; broadSem--; TXString(msg, sizeof(msg)); } } } }
// ************************************************************************************************* // @fn simpliciti_main_tx_only // @brief Get data through callback. Transfer data when external trigger is set. // @param none // @return none // ************************************************************************************************* void simpliciti_main_tx_only(void) { while (1) { // Get end device data from callback function simpliciti_get_ed_data_callback(); // Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA)) { // Get radio ready. Wakes up in IDLE state. SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); // Acceleration / button events packets are 4 bytes long SMPL_SendOpt(sLinkID1, simpliciti_data, 4, SMPL_TXOPTION_NONE); // Put radio back to SLEEP state SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA); } // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) { // Clean up SimpliciTI stack to enable restarting sInit_done = 0; break; } } }
// ************************************************************************************************* // @fn simpliciti_main_sync // @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply. // Decode received host command and trigger action. // @param none // @return none // ************************************************************************************************* void simpliciti_main_sync(void) { uint8_t len, i; uint8_t ed_data[2]; while (1) { // Sleep 0.5sec between ready-to-receive packets // SimpliciTI has no low power delay function, so we have to use ours Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); // Get radio ready. Radio wakes up in IDLE state. SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); // Send 2 byte long ready-to-receive packet to stimulate host reply ed_data[0] = SYNC_ED_TYPE_R2R; ed_data[1] = 0xCB; SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE); // Wait shortly for host reply SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); NWK_DELAY(10); // Check if a command packet was received while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS) { // Decode received data if (len > 0) { // Use callback function in application to decode data and react simpliciti_sync_decode_ap_cmd_callback(); // Get reply data and send out reply packet burst (19 bytes each) for (i = 0; i < simpliciti_reply_count; i++) { NWK_DELAY(10); simpliciti_sync_get_data_callback(i); SMPL_SendOpt(sLinkID1, simpliciti_data, BM_SYNC_DATA_LENGTH, SMPL_TXOPTION_NONE); } } } // Put radio back to sleep SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); // Service watchdog WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) { // Clean up SimpliciTI stack to enable restarting sInit_done = 0; break; } } }
/****************************************************************************** * @fn nwk_poll * * @brief Poll S&F server for any waiting frames. * * input parameters * @param port - Port on peer. * @param addr - SimpliciTI address of peer. * * output parameters * * @return SMPL_SUCCESS * SMPL_NO_AP_ADDRESS - We don't know Access Point's address * SMPL_NOMEM - no room in output frame queue * SMPL_TX_CCA_FAIL - CCA failure */ smplStatus_t nwk_poll(uint8_t port, uint8_t *addr) { uint8_t msg[MGMT_POLL_FRAME_SIZE]; ioctlRawSend_t send; msg[MB_APP_INFO_OS] = MGMT_REQ_POLL; msg[MB_TID_OS] = sTid; msg[M_POLL_PORT_OS] = port; memcpy(msg+M_POLL_ADDR_OS, addr, NET_ADDR_SIZE); /* it's OK to increment the TID here because the reply will not be * matched based on this number. The reply to the poll comes back * to the client port, not the Management port. */ sTid++; if (!sAPAddr) { sAPAddr = nwk_getAPAddress(); if (!sAPAddr) { return SMPL_NO_AP_ADDRESS; } } send.addr = (addr_t *)sAPAddr; send.msg = msg; send.len = sizeof(msg); send.port = SMPL_PORT_MGMT; return SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); }
static void start2Babble() { uint8_t msg[1]; /* frequency hopping doesn't support sleeping just yet */ #ifndef FREQUENCY_HOPPING /* wake up radio. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); #endif /* Send the bad news message. To prevent confusion with different "networks" * such as neighboring smoke alarm arrays send a token controlled by a DIP * switch, for example, and filter in this token. */ msg[0] = BAD_NEWS; while (1) { FHSS_ACTIVE( nwk_pllBackgrounder( false ) ); /* manage FHSS */ /*wait "a while" */ NWK_DELAY(100); /* babble... */ SMPL_Send(SMPL_LINKID_USER_UUD, msg, sizeof(msg)); toggleLED(2); } }
static void Connect(void) { Task_t tasks[2]; /* listen for link forever... */ while (1) { if (SMPL_SUCCESS == SMPL_LinkListen(&sLinkID2)) { break; } /* Implement fail-to-link policy here. otherwise, listen again. */ } LedOff(&led_red); LedOff(&led_green); /* turn on RX. default is RX off. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); TaskLoopCtor(&tasks[0], PingCheckStep); TaskLoopCtor(&tasks[1], MotorStep); TaskMasterRun(&tasks, 2); //begin our scheduler.. not coming back }
//***************************************************************************** // // Change to a different SimpliciTI channel number (frequency). // //***************************************************************************** static void ChangeChannel(void) { #ifdef FREQUENCY_AGILITY freqEntry_t sFreq; // // Cycle to the next channel, wrapping from the top of the table back // to the bottom if necessary. // if (++g_ucChannel >= NWK_FREQ_TBL_SIZE) { g_ucChannel = 0; } // // Set the radio frequency. // sFreq.logicalChan = g_ucChannel; SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SET, &sFreq); // // Turn both of the "LEDs" off and set the flag we use to tell the main // loop that it should blink the LEDs until a new message is received from // an end device. // SetLED(1, false); SetLED(2, false); g_ulBlinky = 1; #endif return; }
/* implement auto-channel-change policy here... */ static void checkChangeChannel(void) { #ifdef FREQUENCY_AGILITY int8_t dbm, inARow = 0; uint8_t i; memset(sSample, 0x0, SSIZE); for (i=0; i<SSIZE; ++i) { /* quit if we need to service an app frame */ if (sPeerFrameSem || sJoinSem) { return; } NWK_DELAY(1); SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RSSI, (void *)&dbm); sSample[i] = dbm; if (dbm > INTERFERNCE_THRESHOLD_DBM) { if (++inARow == IN_A_ROW) { changeChannel(); break; } } else { inARow = 0; } } #endif return; }
void main (void) { BSP_Init( ); SET_MAIN_CLOCK_SOURCE(CRYSTAL); initUART(); printf( "Start iwsn system...\n" ); InitRFIO(); /* set io as normal io, not uart */ //P0DIR &= ~0x03; /* Set button as input */ EnableRecv(); SMPL_Init( NULL ); /* turn on the radio so we are always able to receive data asynchronously */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, NULL ); /* turn on LED. */ BSP_TURN_ON_LED1( ); BSP_TURN_ON_LED2( ); /* never coming back... */ framework_entry(); /* but in case we do... */ while (1) ; }
/*********************************************************************************** * @fn SMPL_Init * * @brief Initialize the SimpliciTI stack. * * input parameters * @param f - Pointer to call back function. Function called by NWK when * user application frame received. The callback is done in the * ISR thread. Argument is Link ID associated with frame. Function * returns 0 if frame is to be kept by NWK, otherwise 1. Frame * should be kept if application will do a SMPL_Receive() in the * user thread (recommended). Pointer may be NULL. * * output parameters * * @return Status of operation: * SMPL_SUCCESS * SMPL_NO_JOIN No Join reply. AP possibly not yet up. * SMPL_NO_CHANNEL Only if Frequency Agility enabled. Channel scan * failed. AP possibly not yet up. */ smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t)) { smplStatus_t rc; if (!sInit_done) { /* set up radio. */ MRFI_Init(); /* initialize network */ if ((rc=nwk_nwkInit(f)) != SMPL_SUCCESS) { return rc; } MRFI_WakeUp(); #if defined( FREQUENCY_AGILITY ) { freqEntry_t chan; chan.logicalChan = 0; /* ok to set default channel explicitly now that MRFI initialized. */ nwk_setChannel(&chan); } #endif /* don't turn Rx on if we're an end device that isn't always on. */ /* but do turn the radio on for PLL operations */ #if !defined( END_DEVICE ) || defined( NWK_PLL ) MRFI_RxOn(); #endif #if defined( END_DEVICE ) /* All except End Devices are in promiscuous mode */ MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress()); MRFI_EnableRxAddrFilter(); #endif } sInit_done = 1; #ifdef NWK_PLL /* If the PLL is enabled then it must get running before the join * request or the system may lock up in the join request becuase * PLL is not locked in. */ // turn on the PLL SMPL_Ioctl(IOCTL_OBJ_PLL, IOCTL_ACT_ON, NULL); // reference clocks are by definition always locked. #ifndef NWK_PLL_REFERENCE_CLOCK // wait for a 5ms failure rate to be achieved while( nwk_pllIsLocked( 0 ) == false ) nwk_pllBackgrounder( false ); #endif #endif /* Join. if no AP or Join fails that status is returned. */ rc = nwk_join(); return rc; }
static void linkTo() { uint8_t msg[10], delay = 0; memset(msg, 0, 10); while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) { /* blink LEDs until we link successfully */ toggleLED(1); toggleLED(2); SPIN_ABOUT_A_SECOND; } /* we're linked. turn off red LED. received messages will toggle the green LED. */ if (BSP_LED2_IS_ON()) { toggleLED(2); } /* turn on RX. default is RX off. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); /* put LED to toggle in the message */ msg[0] = 2; /* toggle red */ while (1) { __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt SPIN_ABOUT_A_SECOND; if (delay > 0x00) { SPIN_ABOUT_A_SECOND; } if (delay > 0x01) { SPIN_ABOUT_A_SECOND; } if (delay > 0x02) { SPIN_ABOUT_A_SECOND; } /* delay longer and longer -- then start over */ delay = (delay+1) & 0x03; /* put the sequence ID in the message */ msg[9] = ++sTxTid; ReadRTCCTimeDate(&Rtcctimedate); /* put data into packet */ msg[1] = Rtcctimedate.Sec; msg[2] = Rtcctimedate.Min; msg[3] = Rtcctimedate.Hour; msg[4] = Rtcctimedate.Day; msg[5] = Rtcctimedate.Date; msg[6] = Rtcctimedate.Month; msg[7] = Rtcctimedate.Year; SMPL_Send(sLinkID1, msg, sizeof(msg)); } }
//***************************************************************************** // // This function listens for a link request from another SimpliciTI device. // //***************************************************************************** tBoolean LinkFrom(void) { smplStatus_t eRetcode; unsigned long ulCount; // // Tell SimpliciTI to try to link to an access point. // for(ulCount = 1; ulCount <= 10; ulCount++) { // // Update the displayed count. Note that we must process the widget // message queue here to ensure that the change makes it onto the // display. // UpdateStatus(false, "Listening %d (%s)", ulCount, (ulCount > 1) ? MapSMPLStatus(eRetcode) : "Waiting"); WidgetMessageQueueProcess(); // // Try to link to the access point. // eRetcode = SMPL_LinkListen(&sLinkID); if(eRetcode == SMPL_SUCCESS) { break; } } // // Did we manage to link to the access point? // if(eRetcode == SMPL_SUCCESS) { UpdateStatus(false, "Listen successful."); // // Turn on RX. Default is off. // SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); // // Tell the main loop that we established communication successfully. // return(true); } else { UpdateStatus(false, "No link request received."); // // Tell the main loop that we failed to establish communication. // return(false); } }
void linkToRep() { // listen for link forever... while (SMPL_SUCCESS != SMPL_LinkListen(&myLinkID)) { /* Implement fail-to-link policy here. otherwise, listen again. */ toggleLED(2); // red led } /* turn on RX. default is RX off. */ SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); }
static void linkFrom() { uint8_t msg[2], tid = 0; /* Turn off one LED so we can tell the device is now listening. * Received messages will toggle the other LED. */ //toggleLED(1); /* listen for link forever... */ while (1) { if (SMPL_SUCCESS == SMPL_LinkListen(&sLinkID2)) { break; } /* Implement fail-to-link policy here. otherwise, listen again. */ } /* we're linked. turn off red LED. Received messages will toggle the green LED. */ if (BSP_LED2_IS_ON()) { toggleLED(2); } if (BSP_LED1_IS_ON()) { toggleLED(1); } /* turn on LED1 on the peer in response to receiving a frame. */ *msg = 0x01; /* toggle red led */ /* turn on RX. default is RX off. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); while (1) { /* Wait for a frame to be received. The Rx handler, which is running in * ISR thread, will post to this semaphore allowing the application to * send the reply message in the user thread. */ if (sSemaphore) { *(msg+1) = ++tid; SMPL_Send(sLinkID2, msg, 2); /* Reset semaphore. This is not properly protected and there is a race * here. In theory we could miss a message. Good enough for a demo, though. */ sSemaphore = 0; } } }
void main (void) { BSP_Init(); /* If an on-the-fly device address is generated it must be done before the * call to SMPL_Init(). If the address is set here the ROM value will not * be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call * will not take effect. One shot only. The IOCTL call below is conformal. */ #ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE { addr_t lAddr; lAddr.addr[0]=0x35; lAddr.addr[1]=0x35; lAddr.addr[2]=0x35; lAddr.addr[3]=0x35; //createRandomAddress(&lAddr); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); } #endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */ /* This call will fail because the join will fail since there is no Access Point * in this scenario. But we don't care -- just use the default link token later. * We supply a callback pointer to handle the message returned by the peer. */ SMPL_Init(sRxCallback); /* turn on LEDs. */ if (!BSP_RED_LED_IS_ON()) { toggleLED(RED); } if (!BSP_GREEN_LED_IS_ON()) { toggleLED(GREEN); } /* wait for a button press... */ do { if (BSP_BUTTON() ) { break; } } while (1); /* never coming back... */ linkFrom(); /* but in case we do... */ while (1) ; }
void main() { BSP_Init(); // Initialisation de la librairie BSP NWK_DELAY(500); SMPL_Init(0); // Initialisation de la librairie SimpliciTI SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); // Initialisation Timer A BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO TACCTL0 = CCIE; // TACCR0 interrupt enabled msg[0] = '#'; msg[1] = REPERE_ID; msg[2] = ':'; msg[3] = 'V'; msg[4] = 0; msg[5] = 0xFF; timeCounter = 250; unsyncRepere(); while (1) { SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); __bis_SR_register(LPM3_bits + GIE); SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); SMPL_SendOpt(SMPL_LINKID_USER_UUD, msg, sizeof(msg), SMPL_TXOPTION_NONE); BSP_TOGGLE_LED1(); if (timeCounter >= 300) // Quand timeCounter a été incrémenté depuis 1 minute (0.2sec x 300) { voltAction(); msg[4] = ((uint8_t*)&volt)[3]; timeCounter = 0; } } }
void unsyncRepere() { uint8_t msgTemp[10] = {0,0,0,0,0,0,0,0,0,0}; uint8_t msgLen = 0; SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); // Activation de la radio pour permettre la réception des messages NWK_DELAY(10); while((SMPL_Receive(SMPL_LINKID_USER_UUD, msgTemp, &msgLen)) == SMPL_SUCCESS) // Boucle de désynchronisation des repères { BSP_TOGGLE_LED2(); NWK_DELAY(10); } if(BSP_LED2_IS_ON()) BSP_TOGGLE_LED2(); TACCR0 = 2280; // ~ 0.2sec - 10 msec TACTL = TASSEL_1 + MC_1; // ACLK, upmode __bis_SR_register(LPM3_bits + GIE); TACCR0 = 2400; // ~ 0.2sec TACTL = TASSEL_1 + MC_1; // ACLK, upmode SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0); // Désactivation de la réception des messages }
//***************************************************************************** // // Set the SimpliciTI device address based on the fixed address from header // file simpliciti_config.h. Care must be taken when doing this since devices // on the network are required to have unique addresses. // //***************************************************************************** tBoolean SetSimpliciTIAddress(void) { static addr_t sAddr = THIS_DEVICE_ADDRESS; // // Tell the SimpliciTI stack which device address we want to use. // SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &sAddr); // // If we get here, all is well. // return(true); }
int main (void) { WDTCTL = WDTPW + WDTHOLD; BSP_Init(); /* If an on-the-fly device address is generated it must be done before the * call to SMPL_Init(). If the address is set here the ROM value will not * be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call * will not take effect. One shot only. The IOCTL call below is conformal. */ #ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE { addr_t lAddr; createRandomAddress(&lAddr); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); } #endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */ /* This call will fail because the join will fail since there is no Access Point * in this scenario. But we don't care -- just use the default link token later. * We supply a callback pointer to handle the message returned by the peer. */ toggleLED(1); SMPL_Init(sRxCallback); /* turn on LEDs. */ toggleLED(2); NWK_DELAY(500); int i; for (i = 10; --i >= 0; ) { toggleLED(1); toggleLED(2); NWK_DELAY(100); } toggleLED(2); /* never coming back... */ linkFrom(); /* but in case we do... */ while (1) ; }
static void changeChannel(void) { #ifdef FREQUENCY_AGILITY freqEntry_t freq; if (++sChannel >= NWK_FREQ_TBL_SIZE) { sChannel = 0; } freq.logicalChan = sChannel; SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SET, &freq); BSP_TURN_OFF_LED1(); BSP_TURN_OFF_LED2(); sBlinky = 1; #endif return; }
void main (void) { BSP_Init(); /* If an on-the-fly device address is generated it must be done before the * call to SMPL_Init(). If the address is set here the ROM value will not * be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call * will not take effect. One shot only. The IOCTL call below is conformal. */ #ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE { addr_t lAddr; createRandomAddress(&lAddr); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); } #endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */ /* Keep trying to join (a side effect of successful initialization) until * successful. Toggle LEDS to indicate that joining has not occurred. */ while (SMPL_SUCCESS != SMPL_Init(0)) { toggleLED(1); toggleLED(2); SPIN_ABOUT_A_SECOND; } /* LEDs on solid to indicate successful join. */ if (!BSP_LED2_IS_ON()) { toggleLED(2); } if (!BSP_LED1_IS_ON()) { toggleLED(1); } /* Unconditional link to AP which is listening due to successful join. */ linkTo(); while (1) ; }
int main (void) { BSP_Init(); /* If an on-the-fly device address is generated it must be done before the * call to SMPL_Init(). If the address is set here the ROM value will not * be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call * will not take effect. One shot only. The IOCTL call below is conformal. */ #ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE { addr_t lAddr; createRandomAddress(&lAddr); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); } #endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */ /* This call will fail because the join will fail since there is no Access Point * in this scenario. but we don't care -- just use the default link token later. * we supply a callback pointer to handle the message returned by the peer. */ SMPL_Init(0); /* turn on LEDs. */ if (!BSP_LED2_IS_ON()) toggleLED(2); if (!BSP_LED1_IS_ON()) toggleLED(1); /* wait for a button press... */ do { FHSS_ACTIVE( nwk_pllBackgrounder( false ) ); /* manage FHSS */ if (BSP_BUTTON1() || BSP_BUTTON2()) break; } while (1); /* never coming back... */ monitorForBadNews(); /* but in case we do... */ while (1) ; }
static void broadcast_channel_change(uint8_t idx) { ioctlRawSend_t send; uint8_t msg[FREQ_REQ_MOVE_FRAME_SIZE]; if (idx >= NWK_FREQ_TBL_SIZE) { return; } msg[FB_APP_INFO_OS] = FREQ_REQ_MOVE; msg[F_CHAN_OS] = idx; send.addr = (addr_t *)nwk_getBCastAddress(); send.msg = msg; send.len = sizeof(msg); send.port = SMPL_PORT_FREQ; SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); }
//***************************************************************************** // // This function is called whenever an alert is received from another device. // It retransmits the alert every 100mS and toggles an LED to indicate that // the alarm has been sounded. // // This function does not return. // //***************************************************************************** void Start2Babble() { uint8_t pucMsg[1]; // // Tell the user what we are doing. // UpdateStatus(false, "Retransmitting alert"); /* wake up radio. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); // // Send the bad news message. In a real application, to prevent confusion // with different "networks" such as neighboring smoke alarm arrays send a // token controlled by a DIP switch, for example, and filter in this token. // pucMsg[0] = BAD_NEWS; // // Keep sending the alert forever. In "real life" you would provide a method // to stop sending the alert when the sensor was reset or the alert condition // cleared. // while (1) { // // Wait 100mS or so. // ApplicationDelay(100); // // Babble... // SMPL_Send(SMPL_LINKID_USER_UUD, pucMsg, sizeof(pucMsg)); ToggleLED(2); } }
int main (void) { WDTCTL = WDTPW + WDTHOLD; (void)TimerMasterInit(10); //tick every 0.1ms //void PwmCtor( /*@out@*/Pwm_t * pwm, DioPort_t my_port, DioPin_t my_pin); PwmCtor(&pwm_left_fwd, kPort4, kPin3); PwmCtor(&pwm_left_rev, kPort4, kPin4); PwmCtor(&pwm_right_fwd, kPort4, kPin5); PwmCtor(&pwm_right_rev, kPort4, kPin6); MotorSet( 50, 50); BSP_Init(); LedCtor(&led_red, kPort1, kPin0); //P1.0 (red) LedCtor(&led_green, kPort1, kPin1); //P1.1 (green) LedOn(&led_red); #ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE { addr_t lAddr; createRandomAddress(&lAddr); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); } #endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */ SMPL_Init(sRxCallback); /* never coming back... */ Connect(); /* but in case we do... */ while (1); }
/****************************************************************************** * @fn nwk_scanForChannels * * @brief Scan for channels by sending a ping frame on each channel in the * channel table and listen for a reply. * * input parameters * @param channels - pointer to area to receive list of channels from which * ping replies were received. * * output parameters * @param channels - populated list of channels. * * @return statuis of operation.. */ uint8_t nwk_scanForChannels(freqEntry_t *channels) { uint8_t msg[FREQ_REQ_PING_FRAME_SIZE], i, num=0, notBcast = 1; addr_t *apAddr, retAddr; uint8_t radioState = MRFI_GetRadioState(); freqEntry_t chan; freqEntry_t curChan; union { ioctlRawSend_t send; ioctlRawReceive_t recv; } ioctl_info; nwk_getChannel(&curChan); /* send to AP. If we don't know AP address, broadcast. */ apAddr = (addr_t *)nwk_getAPAddress(); if (!apAddr) { apAddr = (addr_t *)nwk_getBCastAddress(); notBcast = 0; } for (i=0; i<NWK_FREQ_TBL_SIZE; ++i) { chan.logicalChan = i; nwk_setChannel(&chan); ioctl_info.send.addr = apAddr; ioctl_info.send.msg = msg; ioctl_info.send.len = sizeof(msg); ioctl_info.send.port = SMPL_PORT_FREQ; msg[FB_APP_INFO_OS] = FREQ_REQ_PING; msg[FB_TID_OS] = sTid; SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); ioctl_info.recv.port = SMPL_PORT_FREQ; ioctl_info.recv.msg = msg; ioctl_info.recv.addr = &retAddr; 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)) { /* Once we know the Access Point we're related to we only accept * ping replies from that one. */ if (!notBcast || (notBcast && !memcmp(&retAddr, apAddr, NET_ADDR_SIZE))) { channels[num++].logicalChan = i; } } sTid++; if (num && notBcast) { /* we're done...only one possible channel if we know the AP address. */ break; } /* TODO: process encryption stuff */ } /* reset original channel */ nwk_setChannel(&curChan); return num; }
//***************************************************************************** // // This is the main monitoring function for the applicaiton. It "sleeps" for // 5 seconds or so then checks to see if there are any alerts being broadcast. // If not, it toggles a LED and goes back to "sleep". If an alert is received // it switches into "babbling" mode where it retransmits the alert every 100mS // to propagate the alert through the network. // // This function does not return. // //***************************************************************************** void MonitorForBadNews(void) { uint8_t pucMsg[1], ucLen; unsigned long ulLoop; // // Turn off LEDs. Check for bad news will toggle one LED. The other LED will // toggle when bad news message is sent. // SetLED(2, false); SetLED(1, false); // // Start with radio sleeping. // SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); while (1) { // // Spoof MCU sleeping... // for (ulLoop = 0; ulLoop < CHECK_RATE; ulLoop++) { SPIN_ABOUT_A_SECOND; } ToggleLED(1); // // Check the "sensor" to see if we need to send an alert. // if (g_bAlarmRaised) { // // The sensor has been activated. Start babbling. This function // will not return. // Start2Babble(); } // // Wake up the radio and receiver so that we can listen for others // babbling. // SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); // // Stay on "long enough" to see if someone else is babbling // SPIN_ABOUT_A_QUARTER_SECOND; // // We're done with the radio so shut it down. // SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); // // Did we receive a message while the radio was on? // if (SMPL_SUCCESS == SMPL_Receive(SMPL_LINKID_USER_UUD, pucMsg, &ucLen)) { // // Did we receive something and, if so, is it bad news? // if (ucLen && (pucMsg[0] == BAD_NEWS)) { // // Bad news has been received so start babbling to pass the // alert on to the other devices in the network. // UpdateStatus(true, "Alarm received!"); Start2Babble(); } } } }
//***************************************************************************** // // Set the SimpliciTI device address as the least significant 4 digits of the // device Ethernet MAC address. This ensures that the address is unique across // Stellaris devices. If the MAC address has not been set, we return false to // indicate failure. // //***************************************************************************** tBoolean SetSimpliciTIAddress(void) { unsigned long ulUser0, ulUser1; addr_t sAddr; // // Make sure we are using 4 byte addressing. // ASSERT(NET_ADDR_SIZE == 4); // // Get the MAC address from the non-volatile user registers. // ROM_FlashUserGet(&ulUser0, &ulUser1); // // Has the MAC address been programmed? // if((ulUser0 == 0xffffffff) || (ulUser1 == 0xffffffff)) { // // No - we don't have an address so return a failure. // UpdateStatus(false, "Flash user registers are clear"); UpdateStatus(true, "Error - address not set!"); return(false); } else { // // The MAC address is stored with 3 bytes in each of the 2 flash user // registers. Extract the least significant 4 MAC bytes for use as the // SimpliciTI device address. // sAddr.addr[0] = ((ulUser1 >> 16) & 0xff); sAddr.addr[1] = ((ulUser1 >> 8) & 0xff); sAddr.addr[2] = ((ulUser1 >> 0) & 0xff); sAddr.addr[3] = ((ulUser0 >> 16) & 0xff); // // SimpliciTI requires that the first byte of the device address is // never either 0x00 or 0xFF so we check for these cases and invert the // first bit if either is detected. This does result in the // possibility of two devices having the same address but, for example // purposes, is likely to be fine. // if((sAddr.addr[0] == 0x00) || (sAddr.addr[0] == 0xFF)) { sAddr.addr[0] ^= 0x80; } // // Tell the SimpliciTI stack which device address we want to use. // SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &sAddr); } // // If we get here, all is well. // return(true); }