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