inital draft
Dependencies: mbed LoRaWAN-lib SX1272Liby
Fork of LoRaWAN-demo-72_tjm by
main.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2015 Semtech 00008 00009 Description: LoRaMac classA device implementation 00010 00011 License: Revised BSD License, see LICENSE.TXT file include in the project 00012 00013 Maintainer: Miguel Luis and Gregory Cristian 00014 Modified: T. J. Mulrooney J-Factor Embedded Technoligies 00015 00016 Version Date Comments 00017 0.1 3/10/16 first draft of Woodstream Demo 00018 */ 00019 #include "mbed.h" 00020 #include "board.h" 00021 #include "radio.h" 00022 00023 #include "LoRaMac.h" 00024 #include "Comissioning.h" 00025 #include "SerialDisplay.h" 00026 00027 #include "vt100.h" 00028 extern VT100 vt; 00029 #define MAJOR 0 00030 #define MINOR 1 00031 00032 char versionTimeDate[40]; 00033 void SerialDisplayMessage1(char *str); 00034 void SerialDisplayMessage2(char *str); 00035 00036 /*! 00037 * Join requests trials duty cycle. 00038 */ 00039 #define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000000 // 10 [s] value in us 00040 00041 /*! 00042 * Defines the application data transmission duty cycle. 5s, value in [us]. 00043 */ 00044 //#define APP_TX_DUTYCYCLE 5000000 00045 #define APP_TX_DUTYCYCLE 2000000 00046 00047 /*! 00048 * Defines a random delay for application data transmission duty cycle. 1s, 00049 * value in [us]. 00050 */ 00051 #define APP_TX_DUTYCYCLE_RND 1000000 00052 00053 /*! 00054 * Default mote datarate 00055 */ 00056 #define LORAWAN_DEFAULT_DATARATE DR_0 00057 00058 /*! 00059 * LoRaWAN confirmed messages 00060 */ 00061 #define LORAWAN_CONFIRMED_MSG_ON 1 00062 00063 /*! 00064 * LoRaWAN Adaptive Data Rate 00065 * 00066 * \remark Please note that when ADR is enabled the end-device should be static 00067 */ 00068 #define LORAWAN_ADR_ON 1 00069 00070 #if defined( USE_BAND_868 ) 00071 00072 #include "LoRaMacTest.h" 00073 00074 /*! 00075 * LoRaWAN ETSI duty cycle control enable/disable 00076 * 00077 * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes 00078 */ 00079 #define LORAWAN_DUTYCYCLE_ON true 00080 00081 #endif 00082 00083 /*! 00084 * LoRaWAN application port 00085 */ 00086 #define LORAWAN_APP_PORT 15 00087 00088 /*! 00089 * User application data buffer size 00090 */ 00091 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00092 //#define LORAWAN_APP_DATA_SIZE 6 00093 #define LORAWAN_APP_DATA_SIZE 12 00094 00095 #else 00096 #define LORAWAN_APP_DATA_SIZE 1 00097 00098 #endif 00099 00100 #if( OVER_THE_AIR_ACTIVATION != 0 ) 00101 00102 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI; 00103 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI; 00104 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY; 00105 00106 #else 00107 00108 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY; 00109 static uint8_t AppSKey[] = LORAWAN_APPSKEY; 00110 00111 /*! 00112 * Device address 00113 */ 00114 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS; 00115 00116 #endif 00117 00118 /*! 00119 * Application port 00120 */ 00121 static uint8_t AppPort = LORAWAN_APP_PORT; 00122 00123 /*! 00124 * User application data size 00125 */ 00126 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE; 00127 00128 /*! 00129 * User application data buffer size 00130 */ 00131 #define LORAWAN_APP_DATA_MAX_SIZE 64 00132 00133 /*! 00134 * User application data 00135 */ 00136 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE]; 00137 00138 /*! 00139 * Indicates if the node is sending confirmed or unconfirmed messages 00140 */ 00141 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00142 00143 /*! 00144 * Defines the application data transmission duty cycle 00145 */ 00146 static uint32_t TxDutyCycleTime; 00147 00148 /*! 00149 * Timer to handle the application data transmission duty cycle 00150 */ 00151 static TimerEvent_t TxNextPacketTimer; 00152 00153 #define LED_RED PTA1 00154 #define LED_YEL PTA2 00155 DigitalOut led1(LED_RED); 00156 DigitalOut led2(LED_YEL); 00157 //DigitalIn powerOn(PTC1); /* SW2 */ 00158 //DigitalIn killStatus(PTB17); /* SW3 */ 00159 00160 /*! 00161 * Specifies the state of the application LED 00162 */ 00163 static bool AppLedStateOn = false; 00164 volatile bool Led3StateChanged = false; 00165 /*! 00166 * Timer to handle the state of LED1 00167 */ 00168 static TimerEvent_t Led1Timer; 00169 volatile bool Led1State = false; 00170 volatile bool Led1StateChanged = false; 00171 /*! 00172 * Timer to handle the state of LED2 00173 */ 00174 static TimerEvent_t Led2Timer; 00175 volatile bool Led2State = false; 00176 volatile bool Led2StateChanged = false; 00177 00178 /*! 00179 * Indicates if a new packet can be sent 00180 */ 00181 static bool NextTx = true; 00182 00183 /*! 00184 * Device states 00185 */ 00186 static enum eDevicState 00187 { 00188 DEVICE_STATE_INIT, 00189 DEVICE_STATE_JOIN, 00190 DEVICE_STATE_SEND, 00191 DEVICE_STATE_CYCLE, 00192 DEVICE_STATE_SLEEP 00193 }DeviceState; 00194 00195 /*! 00196 * LoRaWAN compliance tests support data 00197 */ 00198 struct ComplianceTest_s 00199 { 00200 bool Running; 00201 uint8_t State; 00202 bool IsTxConfirmed; 00203 uint8_t AppPort; 00204 uint8_t AppDataSize; 00205 uint8_t *AppDataBuffer; 00206 uint16_t DownLinkCounter; 00207 bool LinkCheck; 00208 uint8_t DemodMargin; 00209 uint8_t NbGateways; 00210 }ComplianceTest; 00211 00212 /* 00213 * SerialDisplay managment variables 00214 */ 00215 00216 /*! 00217 * Indicates if the MAC layer network join status has changed. 00218 */ 00219 static bool IsNetworkJoinedStatusUpdate = false; 00220 00221 /*! 00222 * Strucure containing the Uplink status 00223 */ 00224 struct sLoRaMacUplinkStatus 00225 { 00226 uint8_t Acked; 00227 int8_t Datarate; 00228 uint16_t UplinkCounter; 00229 uint8_t Port; 00230 uint8_t *Buffer; 00231 uint8_t BufferSize; 00232 }LoRaMacUplinkStatus; 00233 volatile bool UplinkStatusUpdated = false; 00234 00235 /*! 00236 * Strucure containing the Downlink status 00237 */ 00238 struct sLoRaMacDownlinkStatus 00239 { 00240 int16_t Rssi; 00241 int8_t Snr; 00242 uint16_t DownlinkCounter; 00243 bool RxData; 00244 uint8_t Port; 00245 uint8_t *Buffer; 00246 uint8_t BufferSize; 00247 }LoRaMacDownlinkStatus; 00248 volatile bool DownlinkStatusUpdated = false; 00249 00250 void SerialDisplayRefresh( void ) 00251 { 00252 MibRequestConfirm_t mibReq; 00253 00254 SerialDisplayInit( ); 00255 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); 00256 00257 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00258 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); 00259 SerialDisplayUpdateDevAddr( DevAddr ); 00260 SerialDisplayUpdateKey( 12, NwkSKey ); 00261 SerialDisplayUpdateKey( 13, AppSKey ); 00262 #else 00263 SerialDisplayUpdateEui( 5, DevEui ); 00264 SerialDisplayUpdateEui( 6, AppEui ); 00265 SerialDisplayUpdateKey( 7, AppKey ); 00266 #endif 00267 00268 mibReq.Type = MIB_NETWORK_JOINED; 00269 LoRaMacMibGetRequestConfirm( &mibReq ); 00270 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); 00271 00272 SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); 00273 #if defined( USE_BAND_868 ) 00274 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); 00275 #else 00276 SerialDisplayUpdateDutyCycle( false ); 00277 #endif 00278 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); 00279 00280 SerialDisplayUpdateLedState( 3, AppLedStateOn ); 00281 00282 vt.SetCursorPos( 43, 0 ); 00283 sprintf(versionTimeDate,"V %d.%d %s %s",MAJOR,MINOR,__DATE__,__TIME__); 00284 vt.printf("%s",versionTimeDate); 00285 } 00286 00287 void SerialRxProcess( void ) 00288 { 00289 if( SerialDisplayReadable( ) == true ) 00290 { 00291 switch( SerialDisplayGetChar( ) ) 00292 { 00293 case 'R': 00294 case 'r': 00295 // Refresh Serial screen 00296 SerialDisplayRefresh( ); 00297 break; 00298 default: 00299 break; 00300 } 00301 } 00302 } 00303 00304 /*! 00305 * \brief Prepares the payload of the frame 00306 */ 00307 int randVoltage; 00308 int randKillStatus; 00309 int randPowerOn; 00310 int sendSignal; 00311 static void PrepareTxFrame( uint8_t port ) 00312 { 00313 char str[30]; 00314 00315 switch( port ) 00316 { 00317 case 15: 00318 { 00319 switch(sendSignal%3) 00320 { 00321 case 0: 00322 sprintf(str,"Voltage %2.2f",2.30 + (randVoltage%10 * .1)); 00323 randVoltage++; 00324 break; 00325 00326 case 1: 00327 sprintf(str,"KillStatus %d",(randKillStatus & 0x02)?1:0); 00328 randKillStatus++; 00329 break; 00330 00331 case 2: 00332 sprintf(str,"PowerOn %d",(randPowerOn & 0x04)?1:0); 00333 randPowerOn++; 00334 break; 00335 } 00336 sendSignal++; 00337 memcpy(AppData,str,strlen(str)); 00338 AppDataSize = strlen(str); 00339 #if 0 00340 AppData[0] = AppLedStateOn; 00341 if( IsTxConfirmed == true ) 00342 { 00343 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8; 00344 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter; 00345 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8; 00346 AppData[4] = LoRaMacDownlinkStatus.Rssi; 00347 AppData[5] = LoRaMacDownlinkStatus.Snr; 00348 } 00349 #endif 00350 } 00351 break; 00352 case 224: 00353 if( ComplianceTest.LinkCheck == true ) 00354 { 00355 ComplianceTest.LinkCheck = false; 00356 AppDataSize = 3; 00357 AppData[0] = 5; 00358 AppData[1] = ComplianceTest.DemodMargin; 00359 AppData[2] = ComplianceTest.NbGateways; 00360 ComplianceTest.State = 1; 00361 } 00362 else 00363 { 00364 switch( ComplianceTest.State ) 00365 { 00366 case 4: 00367 ComplianceTest.State = 1; 00368 break; 00369 case 1: 00370 AppDataSize = 2; 00371 AppData[0] = ComplianceTest.DownLinkCounter >> 8; 00372 AppData[1] = ComplianceTest.DownLinkCounter; 00373 break; 00374 } 00375 } 00376 break; 00377 default: 00378 break; 00379 } 00380 } 00381 00382 /*! 00383 * \brief Prepares the payload of the frame 00384 * 00385 * \retval [0: frame could be send, 1: error] 00386 */ 00387 static bool SendFrame( void ) 00388 { 00389 McpsReq_t mcpsReq; 00390 LoRaMacTxInfo_t txInfo; 00391 00392 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) 00393 { 00394 // Send empty frame in order to flush MAC commands 00395 mcpsReq.Type = MCPS_UNCONFIRMED; 00396 mcpsReq.Req.Unconfirmed.fBuffer = NULL; 00397 mcpsReq.Req.Unconfirmed.fBufferSize = 0; 00398 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; 00399 00400 LoRaMacUplinkStatus.Acked = false; 00401 LoRaMacUplinkStatus.Port = 0; 00402 LoRaMacUplinkStatus.Buffer = NULL; 00403 LoRaMacUplinkStatus.BufferSize = 0; 00404 SerialDisplayUpdateFrameType( false ); 00405 } 00406 else 00407 { 00408 LoRaMacUplinkStatus.Acked = false; 00409 LoRaMacUplinkStatus.Port = AppPort; 00410 LoRaMacUplinkStatus.Buffer = AppData; 00411 LoRaMacUplinkStatus.BufferSize = AppDataSize; 00412 SerialDisplayUpdateFrameType( IsTxConfirmed ); 00413 00414 if( IsTxConfirmed == false ) 00415 { 00416 mcpsReq.Type = MCPS_UNCONFIRMED; 00417 mcpsReq.Req.Unconfirmed.fPort = AppPort; 00418 mcpsReq.Req.Unconfirmed.fBuffer = AppData; 00419 mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize; 00420 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; 00421 } 00422 else 00423 { 00424 mcpsReq.Type = MCPS_CONFIRMED; 00425 mcpsReq.Req.Confirmed.fPort = AppPort; 00426 mcpsReq.Req.Confirmed.fBuffer = AppData; 00427 mcpsReq.Req.Confirmed.fBufferSize = AppDataSize; 00428 mcpsReq.Req.Confirmed.nbRetries = 8; 00429 mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE; 00430 } 00431 } 00432 00433 if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) 00434 { 00435 return false; 00436 } 00437 return true; 00438 } 00439 00440 /*! 00441 * \brief Function executed on TxNextPacket Timeout event 00442 */ 00443 static void OnTxNextPacketTimerEvent( void ) 00444 { 00445 MibRequestConfirm_t mibReq; 00446 LoRaMacStatus_t status; 00447 00448 TimerStop( &TxNextPacketTimer ); 00449 00450 mibReq.Type = MIB_NETWORK_JOINED; 00451 status = LoRaMacMibGetRequestConfirm( &mibReq ); 00452 00453 if( status == LORAMAC_STATUS_OK ) 00454 { 00455 if( mibReq.Param.IsNetworkJoined == true ) 00456 { 00457 DeviceState = DEVICE_STATE_SEND; 00458 NextTx = true; 00459 } 00460 else 00461 { 00462 DeviceState = DEVICE_STATE_JOIN; 00463 } 00464 } 00465 } 00466 00467 /*! 00468 * \brief Function executed on Led 1 Timeout event 00469 */ 00470 static void OnLed1TimerEvent( void ) 00471 { 00472 TimerStop( &Led1Timer ); 00473 // Switch LED 1 OFF 00474 Led1State = false; 00475 Led1StateChanged = true; 00476 00477 // char str[40]; 00478 // vt.SetCursorPos( 44, 0 ); 00479 // sprintf(str,"PowerOn: %X killStatus: %X",powerOn?1:0,killStatus?1:0); 00480 // vt.printf("%s",str); 00481 00482 } 00483 00484 /*! 00485 * \brief Function executed on Led 2 Timeout event 00486 */ 00487 static void OnLed2TimerEvent( void ) 00488 { 00489 TimerStop( &Led2Timer ); 00490 // Switch LED 2 OFF 00491 Led2State = false; 00492 Led2StateChanged = true; 00493 } 00494 00495 /*! 00496 * \brief MCPS-Confirm event function 00497 * 00498 * \param [IN] McpsConfirm - Pointer to the confirm structure, 00499 * containing confirm attributes. 00500 */ 00501 static void McpsConfirm( McpsConfirm_t *McpsConfirm ) 00502 { 00503 if( McpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00504 { 00505 switch( McpsConfirm->McpsRequest ) 00506 { 00507 case MCPS_UNCONFIRMED: 00508 { 00509 // Check Datarate 00510 // Check TxPower 00511 break; 00512 } 00513 case MCPS_CONFIRMED: 00514 { 00515 // Check Datarate 00516 // Check TxPower 00517 // Check AckReceived 00518 // Check NbRetries 00519 LoRaMacUplinkStatus.Acked = McpsConfirm->AckReceived; 00520 break; 00521 } 00522 case MCPS_PROPRIETARY: 00523 { 00524 break; 00525 } 00526 default: 00527 break; 00528 } 00529 LoRaMacUplinkStatus.Datarate = McpsConfirm->Datarate; 00530 LoRaMacUplinkStatus.UplinkCounter = McpsConfirm->UpLinkCounter; 00531 00532 UplinkStatusUpdated = true; 00533 } 00534 NextTx = true; 00535 } 00536 00537 /*! 00538 * \brief MCPS-Indication event function 00539 * 00540 * \param [IN] McpsIndication - Pointer to the indication structure, 00541 * containing indication attributes. 00542 */ 00543 static void McpsIndication( McpsIndication_t *McpsIndication ) 00544 { 00545 if( McpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) 00546 { 00547 return; 00548 } 00549 00550 switch( McpsIndication->McpsIndication ) 00551 { 00552 case MCPS_UNCONFIRMED: 00553 { 00554 break; 00555 } 00556 case MCPS_CONFIRMED: 00557 { 00558 break; 00559 } 00560 case MCPS_PROPRIETARY: 00561 { 00562 break; 00563 } 00564 case MCPS_MULTICAST: 00565 { 00566 break; 00567 } 00568 default: 00569 break; 00570 } 00571 00572 // Check Multicast 00573 // Check Port 00574 // Check Datarate 00575 // Check FramePending 00576 // Check Buffer 00577 // Check BufferSize 00578 // Check Rssi 00579 // Check Snr 00580 // Check RxSlot 00581 LoRaMacDownlinkStatus.Rssi = McpsIndication->Rssi; 00582 if( McpsIndication->Snr & 0x80 ) // The SNR sign bit is 1 00583 { 00584 // Invert and divide by 4 00585 LoRaMacDownlinkStatus.Snr = ( ( ~McpsIndication->Snr + 1 ) & 0xFF ) >> 2; 00586 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr; 00587 } 00588 else 00589 { 00590 // Divide by 4 00591 LoRaMacDownlinkStatus.Snr = ( McpsIndication->Snr & 0xFF ) >> 2; 00592 } 00593 LoRaMacDownlinkStatus.DownlinkCounter++; 00594 LoRaMacDownlinkStatus.RxData = McpsIndication->RxData; 00595 LoRaMacDownlinkStatus.Port = McpsIndication->Port; 00596 LoRaMacDownlinkStatus.Buffer = McpsIndication->Buffer; 00597 LoRaMacDownlinkStatus.BufferSize = McpsIndication->BufferSize; 00598 00599 if( ComplianceTest.Running == true ) 00600 { 00601 ComplianceTest.DownLinkCounter++; 00602 } 00603 00604 if( McpsIndication->RxData == true ) 00605 { 00606 switch( McpsIndication->Port ) 00607 { 00608 case 1: // The application LED can be controlled on port 1 or 2 00609 case 2: 00610 if( McpsIndication->BufferSize == 1 ) 00611 { 00612 AppLedStateOn = McpsIndication->Buffer[0] & 0x01; 00613 Led3StateChanged = true; 00614 } 00615 break; 00616 case 224: 00617 if( ComplianceTest.Running == false ) 00618 { 00619 // Check compliance test enable command (i) 00620 if( ( McpsIndication->BufferSize == 4 ) && 00621 ( McpsIndication->Buffer[0] == 0x01 ) && 00622 ( McpsIndication->Buffer[1] == 0x01 ) && 00623 ( McpsIndication->Buffer[2] == 0x01 ) && 00624 ( McpsIndication->Buffer[3] == 0x01 ) ) 00625 { 00626 IsTxConfirmed = false; 00627 AppPort = 224; 00628 AppDataSize = 2; 00629 ComplianceTest.DownLinkCounter = 0; 00630 ComplianceTest.LinkCheck = false; 00631 ComplianceTest.DemodMargin = 0; 00632 ComplianceTest.NbGateways = 0; 00633 ComplianceTest.Running = true; 00634 ComplianceTest.State = 1; 00635 00636 MibRequestConfirm_t mibReq; 00637 mibReq.Type = MIB_ADR; 00638 mibReq.Param.AdrEnable = true; 00639 LoRaMacMibSetRequestConfirm( &mibReq ); 00640 00641 #if defined( USE_BAND_868 ) 00642 LoRaMacTestSetDutyCycleOn( false ); 00643 #endif 00644 } 00645 } 00646 else 00647 { 00648 ComplianceTest.State = McpsIndication->Buffer[0]; 00649 switch( ComplianceTest.State ) 00650 { 00651 case 0: // Check compliance test disable command (ii) 00652 IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00653 AppPort = LORAWAN_APP_PORT; 00654 AppDataSize = LORAWAN_APP_DATA_SIZE; 00655 ComplianceTest.DownLinkCounter = 0; 00656 ComplianceTest.Running = false; 00657 00658 MibRequestConfirm_t mibReq; 00659 mibReq.Type = MIB_ADR; 00660 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 00661 LoRaMacMibSetRequestConfirm( &mibReq ); 00662 #if defined( USE_BAND_868 ) 00663 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 00664 #endif 00665 break; 00666 case 1: // (iii, iv) 00667 AppDataSize = 2; 00668 break; 00669 case 2: // Enable confirmed messages (v) 00670 IsTxConfirmed = true; 00671 ComplianceTest.State = 1; 00672 break; 00673 case 3: // Disable confirmed messages (vi) 00674 IsTxConfirmed = false; 00675 ComplianceTest.State = 1; 00676 break; 00677 case 4: // (vii) 00678 AppDataSize = McpsIndication->BufferSize; 00679 00680 AppData[0] = 4; 00681 for( uint8_t i = 1; i < AppDataSize; i++ ) 00682 { 00683 AppData[i] = McpsIndication->Buffer[i] + 1; 00684 } 00685 break; 00686 case 5: // (viii) 00687 { 00688 MlmeReq_t mlmeReq; 00689 mlmeReq.Type = MLME_LINK_CHECK; 00690 LoRaMacMlmeRequest( &mlmeReq ); 00691 } 00692 break; 00693 default: 00694 break; 00695 } 00696 } 00697 break; 00698 default: 00699 break; 00700 } 00701 } 00702 00703 // Switch LED 2 ON for each received downlink 00704 Led2State = true; 00705 Led2StateChanged = true; 00706 TimerStart( &Led2Timer ); 00707 DownlinkStatusUpdated = true; 00708 } 00709 00710 /*! 00711 * \brief MLME-Confirm event function 00712 * 00713 * \param [IN] MlmeConfirm - Pointer to the confirm structure, 00714 * containing confirm attributes. 00715 */ 00716 static void MlmeConfirm( MlmeConfirm_t *MlmeConfirm ) 00717 { 00718 if( MlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00719 { 00720 switch( MlmeConfirm->MlmeRequest ) 00721 { 00722 case MLME_JOIN: 00723 { 00724 // Status is OK, node has joined the network 00725 IsNetworkJoinedStatusUpdate = true; 00726 break; 00727 } 00728 case MLME_LINK_CHECK: 00729 { 00730 // Check DemodMargin 00731 // Check NbGateways 00732 if( ComplianceTest.Running == true ) 00733 { 00734 ComplianceTest.LinkCheck = true; 00735 ComplianceTest.DemodMargin = MlmeConfirm->DemodMargin; 00736 ComplianceTest.NbGateways = MlmeConfirm->NbGateways; 00737 } 00738 break; 00739 } 00740 default: 00741 break; 00742 } 00743 } 00744 NextTx = true; 00745 UplinkStatusUpdated = true; 00746 } 00747 00748 /** 00749 * Main application entry point. 00750 */ 00751 int main( void ) 00752 { 00753 char str[80]; 00754 00755 LoRaMacPrimitives_t LoRaMacPrimitives; 00756 LoRaMacCallback_t LoRaMacCallbacks; 00757 MibRequestConfirm_t mibReq; 00758 00759 led1 = 1; 00760 led2 = 1; 00761 BoardInit( ); /* set up timers and any other board initialization */ 00762 SerialDisplayInit( ); /* draw complete initial screen */ 00763 // while(1) 00764 // { 00765 // led1 = !led1; 00766 // for(int i=0;i<9000000;i++); 00767 // vt.printf("5"); 00768 // } 00769 DeviceState = DEVICE_STATE_INIT; /* set initial state to initilzation */ 00770 00771 sprintf(str,"SystemCoreClock: %d",SystemCoreClock); 00772 SerialDisplayMessage1(str); 00773 00774 while( 1 ) 00775 { 00776 SerialRxProcess( ); /* refresh screen if "r/R" hit */ 00777 if( IsNetworkJoinedStatusUpdate == true ) 00778 { 00779 IsNetworkJoinedStatusUpdate = false; 00780 mibReq.Type = MIB_NETWORK_JOINED; 00781 LoRaMacMibGetRequestConfirm( &mibReq ); 00782 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); 00783 } 00784 if( Led1StateChanged == true ) /* if LED changed update display and LED */ 00785 { 00786 Led1StateChanged = false; 00787 SerialDisplayUpdateLedState( 1, Led1State ); 00788 led1 = !Led1State; 00789 } 00790 if( Led2StateChanged == true ) /* if LED changed update display and LED */ 00791 { 00792 Led2StateChanged = false; 00793 SerialDisplayUpdateLedState( 2, Led2State ); 00794 led2 = !Led2State; 00795 } 00796 if( Led3StateChanged == true ) /* if LED changed update display and LED */ 00797 { 00798 Led3StateChanged = false; 00799 SerialDisplayUpdateLedState( 3, AppLedStateOn ); 00800 } 00801 if( UplinkStatusUpdated == true ) /* data sent changed so update the Uplink display */ 00802 { 00803 UplinkStatusUpdated = false; 00804 SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize ); 00805 } 00806 if( DownlinkStatusUpdated == true ) /* data reveived changed so update the Downlink display */ 00807 { 00808 DownlinkStatusUpdated = false; 00809 SerialDisplayUpdateLedState( 2, Led2State ); 00810 SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize ); 00811 } 00812 00813 switch( DeviceState ) /* handle the device state*/ 00814 { 00815 case DEVICE_STATE_INIT: /* initial state called on start up */ 00816 { 00817 /* initialize to static functions in this file and battery function*/ 00818 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; 00819 LoRaMacPrimitives.MacMcpsIndication = McpsIndication; 00820 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; 00821 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; 00822 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); 00823 00824 vt.SetCursorPos( 43, 0 ); 00825 sprintf(versionTimeDate,"V %d.%d %s %s Battery: %d",MAJOR,MINOR,__DATE__,__TIME__,LoRaMacCallbacks.GetBatteryLevel()); 00826 vt.printf("%s",versionTimeDate); 00827 00828 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); 00829 00830 TimerInit( &Led1Timer, OnLed1TimerEvent ); /* initialize led1 timer for 25 ms but do not start*/ 00831 TimerSetValue( &Led1Timer, 25000 ); 00832 00833 TimerInit( &Led2Timer, OnLed2TimerEvent ); /* initialize led2 timer for 25 ms but do not start*/ 00834 TimerSetValue( &Led2Timer, 25000 ); 00835 00836 mibReq.Type = MIB_ADR; 00837 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 00838 LoRaMacMibSetRequestConfirm( &mibReq ); /* set AdrEnable Paramter */ 00839 00840 mibReq.Type = MIB_PUBLIC_NETWORK; 00841 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; 00842 LoRaMacMibSetRequestConfirm( &mibReq ); /* set EnablePublicNetwork parameter */ 00843 00844 #if defined( USE_BAND_868 ) 00845 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 00846 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); 00847 #endif 00848 /* update the VT100 display */ 00849 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); 00850 SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); 00851 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); 00852 00853 LoRaMacDownlinkStatus.DownlinkCounter = 0; 00854 00855 DeviceState = DEVICE_STATE_JOIN; 00856 break; 00857 } 00858 case DEVICE_STATE_JOIN: 00859 { 00860 #if( OVER_THE_AIR_ACTIVATION != 0 ) 00861 MlmeReq_t mlmeReq; 00862 00863 mlmeReq.Type = MLME_JOIN; /* set up join command */ 00864 00865 mlmeReq.Req.Join.DevEui = DevEui; /* set up EUIs and key */ 00866 mlmeReq.Req.Join.AppEui = AppEui; 00867 mlmeReq.Req.Join.AppKey = AppKey; 00868 00869 if( NextTx == true ) 00870 { 00871 LoRaMacMlmeRequest( &mlmeReq ); /* request to join network */ 00872 } 00873 00874 /* update VT100 display with EUIs and key info */ 00875 SerialDisplayUpdateEui( 5, DevEui ); 00876 SerialDisplayUpdateEui( 6, AppEui ); 00877 SerialDisplayUpdateKey( 7, AppKey ); 00878 00879 // Schedule next packet transmission 00880 TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE; 00881 DeviceState = DEVICE_STATE_CYCLE; 00882 00883 #else 00884 mibReq.Type = MIB_NET_ID; 00885 mibReq.Param.NetID = LORAWAN_NETWORK_ID; 00886 LoRaMacMibSetRequestConfirm( &mibReq ); 00887 00888 mibReq.Type = MIB_DEV_ADDR; 00889 mibReq.Param.DevAddr = DevAddr; 00890 LoRaMacMibSetRequestConfirm( &mibReq ); 00891 00892 mibReq.Type = MIB_NWK_SKEY; 00893 mibReq.Param.NwkSKey = NwkSKey; 00894 LoRaMacMibSetRequestConfirm( &mibReq ); 00895 00896 mibReq.Type = MIB_APP_SKEY; 00897 mibReq.Param.AppSKey = AppSKey; 00898 LoRaMacMibSetRequestConfirm( &mibReq ); 00899 00900 mibReq.Type = MIB_NETWORK_JOINED; 00901 mibReq.Param.IsNetworkJoined = true; 00902 LoRaMacMibSetRequestConfirm( &mibReq ); 00903 00904 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); 00905 SerialDisplayUpdateDevAddr( DevAddr ); 00906 SerialDisplayUpdateKey( 12, NwkSKey ); 00907 SerialDisplayUpdateKey( 13, AppSKey ); 00908 00909 DeviceState = DEVICE_STATE_SEND; 00910 #endif 00911 IsNetworkJoinedStatusUpdate = true; 00912 break; 00913 } 00914 case DEVICE_STATE_SEND: 00915 { 00916 if( NextTx == true ) 00917 { 00918 SerialDisplayUpdateUplinkAcked( false ); 00919 SerialDisplayUpdateDonwlinkRxData( false ); 00920 PrepareTxFrame( AppPort ); 00921 00922 NextTx = SendFrame( ); 00923 00924 // Switch LED 1 ON 00925 Led1State = true; 00926 Led1StateChanged = true; 00927 TimerStart( &Led1Timer ); 00928 } 00929 if( ComplianceTest.Running == true ) 00930 { 00931 // Schedule next packet transmission as soon as possible 00932 TxDutyCycleTime = 1000; // 1 ms 00933 } 00934 else 00935 { 00936 // Schedule next packet transmission 00937 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 00938 } 00939 DeviceState = DEVICE_STATE_CYCLE; 00940 break; 00941 } 00942 case DEVICE_STATE_CYCLE: 00943 { 00944 // Schedule next packet transmission 00945 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); 00946 TimerStart( &TxNextPacketTimer ); 00947 00948 DeviceState = DEVICE_STATE_SLEEP; 00949 break; 00950 } 00951 case DEVICE_STATE_SLEEP: 00952 { 00953 // Wake up through events 00954 break; 00955 } 00956 default: 00957 { 00958 DeviceState = DEVICE_STATE_INIT; 00959 break; 00960 } 00961 } 00962 } 00963 }
Generated on Wed Jul 13 2022 20:47:11 by 1.7.2