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