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