![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
LoRaWAN-hello-world code for Tushar
Dependencies: mbed LoRaWAN-lib
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 5000 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 true 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 * Indicates if a new packet can be sent 00147 */ 00148 static bool NextTx = true; 00149 00150 /*! 00151 * Device states 00152 */ 00153 static enum eDeviceState 00154 { 00155 DEVICE_STATE_INIT, 00156 DEVICE_STATE_JOIN, 00157 DEVICE_STATE_SEND, 00158 DEVICE_STATE_CYCLE, 00159 DEVICE_STATE_SLEEP 00160 }DeviceState; 00161 00162 /*! 00163 * LoRaWAN compliance tests support data 00164 */ 00165 struct ComplianceTest_s 00166 { 00167 bool Running; 00168 uint8_t State; 00169 bool IsTxConfirmed; 00170 uint8_t AppPort; 00171 uint8_t AppDataSize; 00172 uint8_t *AppDataBuffer; 00173 uint16_t DownLinkCounter; 00174 bool LinkCheck; 00175 uint8_t DemodMargin; 00176 uint8_t NbGateways; 00177 }ComplianceTest; 00178 00179 /* 00180 * SerialDisplay managment variables 00181 */ 00182 00183 /*! 00184 * Indicates if the MAC layer network join status has changed. 00185 */ 00186 static bool IsNetworkJoinedStatusUpdate = false; 00187 00188 /*! 00189 * Strucure containing the Uplink status 00190 */ 00191 struct sLoRaMacUplinkStatus 00192 { 00193 uint8_t Acked; 00194 int8_t Datarate; 00195 uint16_t UplinkCounter; 00196 uint8_t Port; 00197 uint8_t *Buffer; 00198 uint8_t BufferSize; 00199 }LoRaMacUplinkStatus; 00200 volatile bool UplinkStatusUpdated = false; 00201 00202 /*! 00203 * Strucure containing the Downlink status 00204 */ 00205 struct sLoRaMacDownlinkStatus 00206 { 00207 int16_t Rssi; 00208 int8_t Snr; 00209 uint16_t DownlinkCounter; 00210 bool RxData; 00211 uint8_t Port; 00212 uint8_t *Buffer; 00213 uint8_t BufferSize; 00214 }LoRaMacDownlinkStatus; 00215 volatile bool DownlinkStatusUpdated = false; 00216 00217 00218 // Application Globals 00219 DigitalOut myled(D6); 00220 00221 00222 00223 void SerialDisplayRefresh( void ) 00224 { 00225 MibRequestConfirm_t mibReq; 00226 00227 SerialDisplayInit( ); 00228 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); 00229 00230 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00231 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); 00232 SerialDisplayUpdateDevAddr( DevAddr ); 00233 SerialDisplayUpdateKey( 12, NwkSKey ); 00234 SerialDisplayUpdateKey( 13, AppSKey ); 00235 #endif 00236 SerialDisplayUpdateEui( 5, DevEui ); 00237 SerialDisplayUpdateEui( 6, AppEui ); 00238 SerialDisplayUpdateKey( 7, AppKey ); 00239 00240 mibReq.Type = MIB_NETWORK_JOINED; 00241 LoRaMacMibGetRequestConfirm( &mibReq ); 00242 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); 00243 00244 SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); 00245 #if defined( USE_BAND_868 ) 00246 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); 00247 #else 00248 SerialDisplayUpdateDutyCycle( false ); 00249 #endif 00250 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); 00251 } 00252 00253 void SerialRxProcess( void ) 00254 { 00255 if( SerialDisplayReadable( ) == true ) 00256 { 00257 switch( SerialDisplayGetChar( ) ) 00258 { 00259 case 'R': 00260 case 'r': 00261 // Refresh Serial screen 00262 SerialDisplayRefresh( ); 00263 break; 00264 default: 00265 break; 00266 } 00267 } 00268 } 00269 00270 /*! 00271 * \brief Prepares the payload of the frame 00272 */ 00273 static void PrepareTxFrame( uint8_t port ) 00274 { 00275 switch( port ) 00276 { 00277 case 15: 00278 { 00279 AppData[0] = 0; 00280 if( IsTxConfirmed == true ) 00281 { 00282 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8; 00283 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter; 00284 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8; 00285 AppData[4] = LoRaMacDownlinkStatus.Rssi; 00286 AppData[5] = LoRaMacDownlinkStatus.Snr; 00287 } 00288 } 00289 break; 00290 case 224: 00291 if( ComplianceTest.LinkCheck == true ) 00292 { 00293 ComplianceTest.LinkCheck = false; 00294 AppDataSize = 3; 00295 AppData[0] = 5; 00296 AppData[1] = ComplianceTest.DemodMargin; 00297 AppData[2] = ComplianceTest.NbGateways; 00298 ComplianceTest.State = 1; 00299 } 00300 else 00301 { 00302 switch( ComplianceTest.State ) 00303 { 00304 case 4: 00305 ComplianceTest.State = 1; 00306 break; 00307 case 1: 00308 AppDataSize = 2; 00309 AppData[0] = ComplianceTest.DownLinkCounter >> 8; 00310 AppData[1] = ComplianceTest.DownLinkCounter; 00311 break; 00312 } 00313 } 00314 break; 00315 default: 00316 break; 00317 } 00318 } 00319 00320 /*! 00321 * \brief Prepares the payload of the frame 00322 * 00323 * \retval [0: frame could be send, 1: error] 00324 */ 00325 static bool SendFrame( void ) 00326 { 00327 McpsReq_t mcpsReq; 00328 LoRaMacTxInfo_t txInfo; 00329 00330 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) 00331 { 00332 // Send empty frame in order to flush MAC commands 00333 mcpsReq.Type = MCPS_UNCONFIRMED; 00334 mcpsReq.Req.Unconfirmed.fBuffer = NULL; 00335 mcpsReq.Req.Unconfirmed.fBufferSize = 0; 00336 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; 00337 00338 LoRaMacUplinkStatus.Acked = false; 00339 LoRaMacUplinkStatus.Port = 0; 00340 LoRaMacUplinkStatus.Buffer = NULL; 00341 LoRaMacUplinkStatus.BufferSize = 0; 00342 SerialDisplayUpdateFrameType( false ); 00343 } 00344 else 00345 { 00346 LoRaMacUplinkStatus.Acked = false; 00347 LoRaMacUplinkStatus.Port = AppPort; 00348 LoRaMacUplinkStatus.Buffer = AppData; 00349 LoRaMacUplinkStatus.BufferSize = AppDataSize; 00350 SerialDisplayUpdateFrameType( IsTxConfirmed ); 00351 00352 if( IsTxConfirmed == false ) 00353 { 00354 mcpsReq.Type = MCPS_UNCONFIRMED; 00355 mcpsReq.Req.Unconfirmed.fPort = AppPort; 00356 mcpsReq.Req.Unconfirmed.fBuffer = AppData; 00357 mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize; 00358 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; 00359 } 00360 else 00361 { 00362 mcpsReq.Type = MCPS_CONFIRMED; 00363 mcpsReq.Req.Confirmed.fPort = AppPort; 00364 mcpsReq.Req.Confirmed.fBuffer = AppData; 00365 mcpsReq.Req.Confirmed.fBufferSize = AppDataSize; 00366 mcpsReq.Req.Confirmed.NbTrials = 8; 00367 mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE; 00368 } 00369 } 00370 00371 if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) 00372 { 00373 return false; 00374 } 00375 return true; 00376 } 00377 00378 /*! 00379 * \brief Function executed on TxNextPacket Timeout event 00380 */ 00381 static void OnTxNextPacketTimerEvent( void ) 00382 { 00383 MibRequestConfirm_t mibReq; 00384 LoRaMacStatus_t status; 00385 00386 TimerStop( &TxNextPacketTimer ); 00387 00388 mibReq.Type = MIB_NETWORK_JOINED; 00389 status = LoRaMacMibGetRequestConfirm( &mibReq ); 00390 00391 if( status == LORAMAC_STATUS_OK ) 00392 { 00393 if( mibReq.Param.IsNetworkJoined == true ) 00394 { 00395 DeviceState = DEVICE_STATE_SEND; 00396 NextTx = true; 00397 } 00398 else 00399 { 00400 DeviceState = DEVICE_STATE_JOIN; 00401 } 00402 } 00403 } 00404 00405 00406 /*! 00407 * \brief MCPS-Confirm event function 00408 * 00409 * \param [IN] mcpsConfirm - Pointer to the confirm structure, 00410 * containing confirm attributes. 00411 */ 00412 static void McpsConfirm( McpsConfirm_t *mcpsConfirm ) 00413 { 00414 if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00415 { 00416 switch( mcpsConfirm->McpsRequest ) 00417 { 00418 case MCPS_UNCONFIRMED: 00419 { 00420 // Check Datarate 00421 // Check TxPower 00422 break; 00423 } 00424 case MCPS_CONFIRMED: 00425 { 00426 // Check Datarate 00427 // Check TxPower 00428 // Check AckReceived 00429 // Check NbTrials 00430 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived; 00431 break; 00432 } 00433 case MCPS_PROPRIETARY: 00434 { 00435 break; 00436 } 00437 default: 00438 break; 00439 } 00440 LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate; 00441 LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter; 00442 00443 UplinkStatusUpdated = true; 00444 } 00445 NextTx = true; 00446 } 00447 00448 /*! 00449 * \brief MCPS-Indication event function 00450 * 00451 * \param [IN] mcpsIndication - Pointer to the indication structure, 00452 * containing indication attributes. 00453 */ 00454 static void McpsIndication( McpsIndication_t *mcpsIndication ) 00455 { 00456 if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) 00457 { 00458 return; 00459 } 00460 00461 switch( mcpsIndication->McpsIndication ) 00462 { 00463 case MCPS_UNCONFIRMED: 00464 { 00465 break; 00466 } 00467 case MCPS_CONFIRMED: 00468 { 00469 break; 00470 } 00471 case MCPS_PROPRIETARY: 00472 { 00473 break; 00474 } 00475 case MCPS_MULTICAST: 00476 { 00477 break; 00478 } 00479 default: 00480 break; 00481 } 00482 00483 // Check Multicast 00484 // Check Port 00485 // Check Datarate 00486 // Check FramePending 00487 // Check Buffer 00488 // Check BufferSize 00489 // Check Rssi 00490 // Check Snr 00491 // Check RxSlot 00492 LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi; 00493 if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1 00494 { 00495 // Invert and divide by 4 00496 LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2; 00497 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr; 00498 } 00499 else 00500 { 00501 // Divide by 4 00502 LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2; 00503 } 00504 LoRaMacDownlinkStatus.DownlinkCounter++; 00505 LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData; 00506 LoRaMacDownlinkStatus.Port = mcpsIndication->Port; 00507 LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer; 00508 LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize; 00509 00510 if( ComplianceTest.Running == true ) 00511 { 00512 ComplianceTest.DownLinkCounter++; 00513 } 00514 00515 if( mcpsIndication->RxData == true ) 00516 { 00517 switch( mcpsIndication->Port ) 00518 { 00519 case 1: // The application LED can be controlled on port 1 or 2 00520 case 2: 00521 break; 00522 case 224: 00523 if( ComplianceTest.Running == false ) 00524 { 00525 // Check compliance test enable command (i) 00526 if( ( mcpsIndication->BufferSize == 4 ) && 00527 ( mcpsIndication->Buffer[0] == 0x01 ) && 00528 ( mcpsIndication->Buffer[1] == 0x01 ) && 00529 ( mcpsIndication->Buffer[2] == 0x01 ) && 00530 ( mcpsIndication->Buffer[3] == 0x01 ) ) 00531 { 00532 IsTxConfirmed = false; 00533 AppPort = 224; 00534 AppDataSize = 2; 00535 ComplianceTest.DownLinkCounter = 0; 00536 ComplianceTest.LinkCheck = false; 00537 ComplianceTest.DemodMargin = 0; 00538 ComplianceTest.NbGateways = 0; 00539 ComplianceTest.Running = true; 00540 ComplianceTest.State = 1; 00541 00542 MibRequestConfirm_t mibReq; 00543 mibReq.Type = MIB_ADR; 00544 mibReq.Param.AdrEnable = true; 00545 LoRaMacMibSetRequestConfirm( &mibReq ); 00546 00547 #if defined( USE_BAND_868 ) 00548 LoRaMacTestSetDutyCycleOn( false ); 00549 #endif 00550 } 00551 } 00552 else 00553 { 00554 ComplianceTest.State = mcpsIndication->Buffer[0]; 00555 switch( ComplianceTest.State ) 00556 { 00557 case 0: // Check compliance test disable command (ii) 00558 IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00559 AppPort = LORAWAN_APP_PORT; 00560 AppDataSize = LORAWAN_APP_DATA_SIZE; 00561 ComplianceTest.DownLinkCounter = 0; 00562 ComplianceTest.Running = false; 00563 00564 MibRequestConfirm_t mibReq; 00565 mibReq.Type = MIB_ADR; 00566 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 00567 LoRaMacMibSetRequestConfirm( &mibReq ); 00568 #if defined( USE_BAND_868 ) 00569 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 00570 #endif 00571 break; 00572 case 1: // (iii, iv) 00573 AppDataSize = 2; 00574 break; 00575 case 2: // Enable confirmed messages (v) 00576 IsTxConfirmed = true; 00577 ComplianceTest.State = 1; 00578 break; 00579 case 3: // Disable confirmed messages (vi) 00580 IsTxConfirmed = false; 00581 ComplianceTest.State = 1; 00582 break; 00583 case 4: // (vii) 00584 AppDataSize = mcpsIndication->BufferSize; 00585 00586 AppData[0] = 4; 00587 for( uint8_t i = 1; i < AppDataSize; i++ ) 00588 { 00589 AppData[i] = mcpsIndication->Buffer[i] + 1; 00590 } 00591 break; 00592 case 5: // (viii) 00593 { 00594 MlmeReq_t mlmeReq; 00595 mlmeReq.Type = MLME_LINK_CHECK; 00596 LoRaMacMlmeRequest( &mlmeReq ); 00597 } 00598 break; 00599 case 6: // (ix) 00600 { 00601 MlmeReq_t mlmeReq; 00602 00603 // Disable TestMode and revert back to normal operation 00604 IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00605 AppPort = LORAWAN_APP_PORT; 00606 AppDataSize = LORAWAN_APP_DATA_SIZE; 00607 ComplianceTest.DownLinkCounter = 0; 00608 ComplianceTest.Running = false; 00609 00610 MibRequestConfirm_t mibReq; 00611 mibReq.Type = MIB_ADR; 00612 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 00613 LoRaMacMibSetRequestConfirm( &mibReq ); 00614 #if defined( USE_BAND_868 ) 00615 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 00616 #endif 00617 00618 mlmeReq.Type = MLME_JOIN; 00619 00620 mlmeReq.Req.Join.DevEui = DevEui; 00621 mlmeReq.Req.Join.AppEui = AppEui; 00622 mlmeReq.Req.Join.AppKey = AppKey; 00623 mlmeReq.Req.Join.NbTrials = 3; 00624 00625 LoRaMacMlmeRequest( &mlmeReq ); 00626 DeviceState = DEVICE_STATE_SLEEP; 00627 } 00628 break; 00629 case 7: // (x) 00630 { 00631 if( mcpsIndication->BufferSize == 3 ) 00632 { 00633 MlmeReq_t mlmeReq; 00634 mlmeReq.Type = MLME_TXCW; 00635 mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] ); 00636 LoRaMacMlmeRequest( &mlmeReq ); 00637 } 00638 else if( mcpsIndication->BufferSize == 7 ) 00639 { 00640 MlmeReq_t mlmeReq; 00641 mlmeReq.Type = MLME_TXCW_1; 00642 mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] ); 00643 mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100; 00644 mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6]; 00645 LoRaMacMlmeRequest( &mlmeReq ); 00646 } 00647 ComplianceTest.State = 1; 00648 } 00649 break; 00650 default: 00651 break; 00652 } 00653 } 00654 break; 00655 default: 00656 break; 00657 } 00658 } 00659 00660 DownlinkStatusUpdated = true; 00661 } 00662 00663 /*! 00664 * \brief MLME-Confirm event function 00665 * 00666 * \param [IN] mlmeConfirm - Pointer to the confirm structure, 00667 * containing confirm attributes. 00668 */ 00669 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm ) 00670 { 00671 switch( mlmeConfirm->MlmeRequest ) 00672 { 00673 case MLME_JOIN: 00674 { 00675 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00676 { 00677 // Status is OK, node has joined the network 00678 IsNetworkJoinedStatusUpdate = true; 00679 DeviceState = DEVICE_STATE_SEND; 00680 } 00681 else 00682 { 00683 // Join was not successful. Try to join again 00684 DeviceState = DEVICE_STATE_JOIN; 00685 } 00686 break; 00687 } 00688 case MLME_LINK_CHECK: 00689 { 00690 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00691 { 00692 // Check DemodMargin 00693 // Check NbGateways 00694 if( ComplianceTest.Running == true ) 00695 { 00696 ComplianceTest.LinkCheck = true; 00697 ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin; 00698 ComplianceTest.NbGateways = mlmeConfirm->NbGateways; 00699 } 00700 } 00701 break; 00702 } 00703 default: 00704 break; 00705 } 00706 NextTx = true; 00707 UplinkStatusUpdated = true; 00708 } 00709 00710 void flash_builtin() { 00711 myled = 1; // turn the LED on (HIGH is the voltage level) 00712 wait(2); // wait for a second 00713 myled = 0; // turn the LED off by making the voltage LOW 00714 wait(1); 00715 } 00716 00717 /** 00718 * Main application entry point. 00719 */ 00720 Serial pc(SERIAL_TX, SERIAL_RX,115200); 00721 int MY_SetSysClock_PLL_HSE(void) 00722 { 00723 RCC_ClkInitTypeDef RCC_ClkInitStruct; 00724 RCC_OscInitTypeDef RCC_OscInitStruct; 00725 00726 /* Enable HSE and activate PLL with HSE as source */ 00727 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 00728 RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ 00729 00730 // PLLCLK = (8 MHz * 8)/2 = 32 MHz 00731 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 00732 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 00733 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; 00734 RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; 00735 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 00736 return (-1); // FAIL 00737 } 00738 00739 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ 00740 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); 00741 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 32 MHz 00742 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 32 MHz 00743 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 32 MHz 00744 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 32 MHz 00745 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { 00746 return (-2); // FAIL 00747 } 00748 00749 /* Enable HSE and activate PLL with HSE as source */ 00750 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI; 00751 RCC_OscInitStruct.HSIState = RCC_HSI_OFF; 00752 RCC_OscInitStruct.MSIState = RCC_MSI_OFF; 00753 RCC_OscInitStruct.HSI48State = RCC_HSI48_OFF; 00754 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 00755 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 00756 return (-3); // FAIL 00757 } 00758 00759 return 0; // OK 00760 } 00761 00762 void my_patch(void) 00763 { 00764 int retVal; 00765 00766 HAL_RCC_DeInit(); 00767 retVal = MY_SetSysClock_PLL_HSE(); 00768 if(retVal< 0) 00769 { 00770 // fail 00771 pc.printf("Failed to start HSE, ERR= %d\r\n", retVal); 00772 00773 // indicate error 00774 while(1) 00775 { 00776 myled = 1; 00777 wait(0.2); 00778 myled = 0; 00779 wait(0.5); 00780 } 00781 } 00782 } 00783 00784 int main( void ) 00785 { 00786 pc.printf("mbed-os-rev: %d.%d.%d lib-rev: %d\r\n", \ 00787 MBED_MAJOR_VERSION, MBED_MINOR_VERSION,MBED_PATCH_VERSION,MBED_LIBRARY_VERSION); 00788 pc.printf("BUILD= %s, SysClock= %d, RCC= %0X\r\n", __TIME__, SystemCoreClock, RCC->CR); 00789 my_patch(); 00790 pc.printf("NEW SysClock= %d, NEW RCC= %0X\r\n", SystemCoreClock, RCC->CR); 00791 00792 flash_builtin(); 00793 flash_builtin(); 00794 flash_builtin(); 00795 flash_builtin(); 00796 00797 LoRaMacPrimitives_t LoRaMacPrimitives; 00798 LoRaMacCallback_t LoRaMacCallbacks; 00799 MibRequestConfirm_t mibReq; 00800 00801 BoardInit( ); 00802 SerialDisplayInit( ); 00803 00804 SerialDisplayUpdateEui( 5, DevEui ); 00805 SerialDisplayUpdateEui( 6, AppEui ); 00806 SerialDisplayUpdateKey( 7, AppKey ); 00807 00808 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00809 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); 00810 SerialDisplayUpdateDevAddr( DevAddr ); 00811 SerialDisplayUpdateKey( 12, NwkSKey ); 00812 SerialDisplayUpdateKey( 13, AppSKey ); 00813 #endif 00814 00815 DeviceState = DEVICE_STATE_INIT; 00816 00817 while( 1 ) 00818 { 00819 SerialRxProcess( ); 00820 flash_builtin(); 00821 if( IsNetworkJoinedStatusUpdate == true ) 00822 { 00823 IsNetworkJoinedStatusUpdate = false; 00824 mibReq.Type = MIB_NETWORK_JOINED; 00825 LoRaMacMibGetRequestConfirm( &mibReq ); 00826 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); 00827 } 00828 if( UplinkStatusUpdated == true ) 00829 { 00830 UplinkStatusUpdated = false; 00831 SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize ); 00832 } 00833 if( DownlinkStatusUpdated == true ) 00834 { 00835 DownlinkStatusUpdated = false; 00836 SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize ); 00837 } 00838 00839 switch( DeviceState ) 00840 { 00841 case DEVICE_STATE_INIT: 00842 { 00843 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; 00844 LoRaMacPrimitives.MacMcpsIndication = McpsIndication; 00845 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; 00846 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; 00847 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); 00848 00849 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); 00850 00851 mibReq.Type = MIB_ADR; 00852 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 00853 LoRaMacMibSetRequestConfirm( &mibReq ); 00854 00855 mibReq.Type = MIB_PUBLIC_NETWORK; 00856 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; 00857 LoRaMacMibSetRequestConfirm( &mibReq ); 00858 00859 #if defined( USE_BAND_868 ) 00860 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 00861 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); 00862 00863 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 00864 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 ); 00865 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 ); 00866 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 ); 00867 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 ); 00868 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 ); 00869 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 ); 00870 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 ); 00871 00872 mibReq.Type = MIB_RX2_DEFAULT_CHANNEL; 00873 mibReq.Param.Rx2DefaultChannel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; 00874 LoRaMacMibSetRequestConfirm( &mibReq ); 00875 00876 mibReq.Type = MIB_RX2_CHANNEL; 00877 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; 00878 LoRaMacMibSetRequestConfirm( &mibReq ); 00879 #endif 00880 00881 #endif 00882 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); 00883 SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); 00884 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); 00885 00886 LoRaMacDownlinkStatus.DownlinkCounter = 0; 00887 00888 DeviceState = DEVICE_STATE_JOIN; 00889 break; 00890 } 00891 case DEVICE_STATE_JOIN: 00892 { 00893 #if( OVER_THE_AIR_ACTIVATION != 0 ) 00894 MlmeReq_t mlmeReq; 00895 00896 mlmeReq.Type = MLME_JOIN; 00897 00898 mlmeReq.Req.Join.DevEui = DevEui; 00899 mlmeReq.Req.Join.AppEui = AppEui; 00900 mlmeReq.Req.Join.AppKey = AppKey; 00901 00902 if( NextTx == true ) 00903 { 00904 LoRaMacMlmeRequest( &mlmeReq ); 00905 } 00906 DeviceState = DEVICE_STATE_SLEEP; 00907 #else 00908 mibReq.Type = MIB_NET_ID; 00909 mibReq.Param.NetID = LORAWAN_NETWORK_ID; 00910 LoRaMacMibSetRequestConfirm( &mibReq ); 00911 00912 mibReq.Type = MIB_DEV_ADDR; 00913 mibReq.Param.DevAddr = DevAddr; 00914 LoRaMacMibSetRequestConfirm( &mibReq ); 00915 00916 mibReq.Type = MIB_NWK_SKEY; 00917 mibReq.Param.NwkSKey = NwkSKey; 00918 LoRaMacMibSetRequestConfirm( &mibReq ); 00919 00920 mibReq.Type = MIB_APP_SKEY; 00921 mibReq.Param.AppSKey = AppSKey; 00922 LoRaMacMibSetRequestConfirm( &mibReq ); 00923 00924 mibReq.Type = MIB_NETWORK_JOINED; 00925 mibReq.Param.IsNetworkJoined = true; 00926 LoRaMacMibSetRequestConfirm( &mibReq ); 00927 00928 DeviceState = DEVICE_STATE_SEND; 00929 #endif 00930 IsNetworkJoinedStatusUpdate = true; 00931 break; 00932 } 00933 case DEVICE_STATE_SEND: 00934 { 00935 if( NextTx == true ) 00936 { 00937 SerialDisplayUpdateUplinkAcked( false ); 00938 SerialDisplayUpdateDonwlinkRxData( false ); 00939 PrepareTxFrame( AppPort ); 00940 00941 NextTx = SendFrame( ); 00942 } 00943 if( ComplianceTest.Running == true ) 00944 { 00945 // Schedule next packet transmission 00946 TxDutyCycleTime = 5000; // 5000 ms 00947 } 00948 else 00949 { 00950 // Schedule next packet transmission 00951 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 00952 } 00953 DeviceState = DEVICE_STATE_CYCLE; 00954 break; 00955 } 00956 case DEVICE_STATE_CYCLE: 00957 { 00958 DeviceState = DEVICE_STATE_SLEEP; 00959 00960 // Schedule next packet transmission 00961 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); 00962 TimerStart( &TxNextPacketTimer ); 00963 break; 00964 } 00965 case DEVICE_STATE_SLEEP: 00966 { 00967 // Wake up through events 00968 break; 00969 } 00970 default: 00971 { 00972 DeviceState = DEVICE_STATE_INIT; 00973 break; 00974 } 00975 } 00976 } 00977 }
Generated on Fri Jul 15 2022 08:41:07 by
![doxygen](doxygen.png)