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.
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 #define LORAWAN_APP_DATA_SIZE 41 00087 00088 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI; 00089 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI; 00090 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY; 00091 00092 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00093 00094 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY; 00095 static uint8_t AppSKey[] = LORAWAN_APPSKEY; 00096 00097 /*! 00098 * Device address 00099 */ 00100 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS; 00101 00102 #endif 00103 00104 /*! 00105 * Application port 00106 */ 00107 static uint8_t AppPort = LORAWAN_APP_PORT; 00108 00109 /*! 00110 * User application data size 00111 */ 00112 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE; 00113 00114 /*! 00115 * User application data buffer size 00116 */ 00117 #define LORAWAN_APP_DATA_MAX_SIZE 64 00118 00119 /*! 00120 * User application data 00121 */ 00122 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE]; 00123 00124 /*! 00125 * Indicates if the node is sending confirmed or unconfirmed messages 00126 */ 00127 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00128 00129 /*! 00130 * Defines the application data transmission duty cycle 00131 */ 00132 static uint32_t TxDutyCycleTime; 00133 00134 /*! 00135 * Timer to handle the application data transmission duty cycle 00136 */ 00137 static TimerEvent_t TxNextPacketTimer; 00138 00139 /*! 00140 * SOME APPLICATION PARAMETERS 00141 */ 00142 00143 DigitalOut myled(D7); 00144 00145 DigitalOut relayPin(D6); 00146 AnalogIn BAT_PIN(A2); 00147 AnalogIn LIGHT_1_PIN(A1); 00148 AnalogIn LIGHT_2_PIN(A5); 00149 AnalogIn RH_PIN(PC_2); 00150 AnalogIn VCE_PIN(PB_1); 00151 00152 /* 00153 D7 == Green 00154 D8 == Blue 00155 */ 00156 00157 DigitalOut myGreenLed(D7); // ON = Lora Connected 00158 DigitalOut myBlueLed(D8); // Blink twice = Sends data or increments counter value Pelase proceed 00159 00160 InterruptIn button1(USER_BUTTON); 00161 volatile bool button1_pressed = false; // Used in the main loop 00162 volatile bool button1_enabled = true; // Used for debouncing 00163 Timeout button1_timeout; // Used for debouncing 00164 int press_count; 00165 Timeout buttonOptions_timeout; // Used for determining number of presses 00166 00167 unsigned int time_window = 5; // Default 3600 seconds in an hour 00168 unsigned long long_interval = 31557600; // Default 31557600 seconds in a year 00169 unsigned int hb_interval = 43200; // Default 86400 seconds in a day 00170 unsigned long test_interval = 2592000; // Default 2592000 seconds in a month 00171 00172 time_t next_stest; 00173 time_t next_ltest; 00174 00175 uint8_t hb_data[5]; 00176 uint8_t tdata[10]; 00177 00178 uint8_t *data; 00179 uint8_t data_len; 00180 00181 bool running_test; 00182 bool joining; 00183 // bool received_downlink; 00184 00185 time_t current_time; 00186 00187 unsigned long last_hb; 00188 unsigned long test_start; 00189 00190 uint8_t measurements[5]; 00191 00192 unsigned long test_duration; 00193 00194 /*! 00195 * Specifies the state of the application LED 00196 */ 00197 static bool AppLedStateOn = false; 00198 volatile bool Led3StateChanged = false; 00199 /*! 00200 * Timer to handle the state of LED1 00201 */ 00202 static TimerEvent_t Led1Timer; 00203 volatile bool Led1State = false; 00204 volatile bool Led1StateChanged = false; 00205 /*! 00206 * Timer to handle the state of LED2 00207 */ 00208 static TimerEvent_t Led2Timer; 00209 volatile bool Led2State = false; 00210 volatile bool Led2StateChanged = false; 00211 00212 enum GreenLedState_e{ 00213 GREEN_LED_STATE_INIT=0, 00214 GREEN_LED_STATE_JOINING, 00215 GREEN_LED_STATE_JOINED 00216 }GreenLedState; 00217 volatile uint32_t GreenLedTickCounter=0; 00218 00219 volatile bool BatteryLowFlag = true; 00220 00221 volatile uint32_t GreenLedJoiningCounter=0; 00222 00223 static TimerEvent_t GreenLedTimer; 00224 static void OnGreenLedTimerEvent( void ) 00225 { 00226 MibRequestConfirm_t mibReq; 00227 LoRaMacStatus_t status; 00228 00229 if(BatteryLowFlag == true) 00230 { 00231 myGreenLed = 0; // OFF 00232 } 00233 else 00234 { 00235 // battery ok 00236 GreenLedTickCounter++; 00237 switch(GreenLedState) 00238 { 00239 case GREEN_LED_STATE_INIT: 00240 { 00241 GreenLedState = GREEN_LED_STATE_JOINING; 00242 } 00243 break; 00244 00245 case GREEN_LED_STATE_JOINING: 00246 { 00247 GreenLedJoiningCounter++; 00248 if((GreenLedJoiningCounter % 2) == 0) 00249 { 00250 GreenLedJoiningCounter = 0; 00251 myGreenLed = !myGreenLed; // toggle 00252 00253 // check if we have joined the network 00254 mibReq.Type = MIB_NETWORK_JOINED ; 00255 status = LoRaMacMibGetRequestConfirm( &mibReq ); 00256 if( status == LORAMAC_STATUS_OK ) 00257 { 00258 if( mibReq.Param .IsNetworkJoined == true ) 00259 { 00260 GreenLedState = GREEN_LED_STATE_JOINED; 00261 } 00262 } 00263 } 00264 } 00265 break; 00266 00267 case GREEN_LED_STATE_JOINED: 00268 { 00269 myGreenLed = 1; 00270 } 00271 break; 00272 } 00273 } 00274 } 00275 00276 static TimerEvent_t BatteryCheckTimer; 00277 volatile bool BatteryCheckFlag=false; 00278 static void OnBatteryCheckTimerEvent( void ) 00279 { 00280 BatteryCheckFlag = true; 00281 } 00282 00283 /*! 00284 * Indicates if a new packet can be sent 00285 */ 00286 static bool NextTx = true; 00287 00288 /*! 00289 * Device states 00290 */ 00291 00292 00293 // Application Globals 00294 00295 00296 00297 00298 00299 static enum eDeviceState 00300 { 00301 DEVICE_STATE_INIT, 00302 DEVICE_STATE_JOIN, 00303 DEVICE_STATE_SEND, 00304 DEVICE_STATE_CYCLE, 00305 DEVICE_STATE_SLEEP 00306 }DeviceState; 00307 00308 static enum eMessageType 00309 { 00310 MESSAGE_TYPE_HB, 00311 MESSAGE_TYPE_SHORT_TEST, 00312 MESSAGE_TYPE_LONG_TEST 00313 }MessageType; 00314 00315 /*! 00316 * LoRaWAN compliance tests support data 00317 */ 00318 struct ComplianceTest_s 00319 { 00320 bool Running; 00321 uint8_t State; 00322 bool IsTxConfirmed; 00323 uint8_t AppPort; 00324 uint8_t AppDataSize; 00325 uint8_t *AppDataBuffer; 00326 uint16_t DownLinkCounter; 00327 bool LinkCheck; 00328 uint8_t DemodMargin; 00329 uint8_t NbGateways; 00330 }ComplianceTest; 00331 00332 /* 00333 * SerialDisplay managment variables 00334 */ 00335 00336 /*! 00337 * Indicates if the MAC layer network join status has changed. 00338 */ 00339 static bool IsNetworkJoinedStatusUpdate = false; 00340 00341 /*! 00342 * Strucure containing the Uplink status 00343 */ 00344 struct sLoRaMacUplinkStatus 00345 { 00346 uint8_t Acked; 00347 int8_t Datarate; 00348 uint16_t UplinkCounter; 00349 uint8_t Port; 00350 uint8_t *Buffer; 00351 uint8_t BufferSize; 00352 }LoRaMacUplinkStatus; 00353 volatile bool UplinkStatusUpdated = false; 00354 00355 /*! 00356 * Strucure containing the Downlink status 00357 */ 00358 struct sLoRaMacDownlinkStatus 00359 { 00360 int16_t Rssi; 00361 int8_t Snr; 00362 uint16_t DownlinkCounter; 00363 bool RxData; 00364 uint8_t Port; 00365 uint8_t *Buffer; 00366 uint8_t BufferSize; 00367 }LoRaMacDownlinkStatus; 00368 volatile bool DownlinkStatusUpdated = false; 00369 00370 void SerialDisplayRefresh( void ) 00371 { 00372 MibRequestConfirm_t mibReq; 00373 00374 SerialDisplayInit( ); 00375 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); 00376 00377 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00378 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); 00379 SerialDisplayUpdateDevAddr( DevAddr ); 00380 SerialDisplayUpdateKey( 12, NwkSKey ); 00381 SerialDisplayUpdateKey( 13, AppSKey ); 00382 #endif 00383 SerialDisplayUpdateEui( 5, DevEui ); 00384 SerialDisplayUpdateEui( 6, AppEui ); 00385 SerialDisplayUpdateKey( 7, AppKey ); 00386 00387 mibReq.Type = MIB_NETWORK_JOINED ; 00388 LoRaMacMibGetRequestConfirm( &mibReq ); 00389 SerialDisplayUpdateNetworkIsJoined( mibReq.Param .IsNetworkJoined ); 00390 00391 SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); 00392 #if defined( USE_BAND_868 ) 00393 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); 00394 #else 00395 SerialDisplayUpdateDutyCycle( false ); 00396 #endif 00397 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); 00398 00399 SerialDisplayUpdateLedState( 3, AppLedStateOn ); 00400 } 00401 00402 void SerialRxProcess( void ) 00403 { 00404 if( SerialDisplayReadable( ) == true ) 00405 { 00406 switch( SerialDisplayGetChar( ) ) 00407 { 00408 case 'R': 00409 case 'r': 00410 // Refresh Serial screen 00411 SerialDisplayRefresh( ); 00412 break; 00413 default: 00414 break; 00415 } 00416 } 00417 } 00418 00419 // Enables button when bouncing is over 00420 void button1_enabled_cb(void) 00421 { 00422 button1_enabled = true; 00423 } 00424 00425 // ISR handling button pressed event 00426 void button1_onpressed_cb(void) 00427 { 00428 if (button1_enabled) { // Disabled while the button is bouncing 00429 button1_enabled = false; 00430 button1_pressed = true; // To be read by the main loop 00431 button1_timeout.attach(callback(button1_enabled_cb), 0.2); // Debounce time 200 ms 00432 } 00433 } 00434 00435 // **************************** COMMUNICATION PACKET DEFINITION METHODS ******************************** // 00436 00437 void heartbeat_message(uint8_t *hb_data, uint8_t *current_date) { 00438 hb_data[0] = 0xD2; 00439 memcpy(hb_data+1, current_date, 4); 00440 } 00441 00442 void short_test_result(uint8_t *tdata, uint8_t *test_start_date, uint8_t *measurements) { 00443 tdata[0] = 0xD7; 00444 memcpy(tdata+1, test_start_date, 4); 00445 memcpy(tdata+5, measurements, 5); 00446 } 00447 00448 void long_test_result(uint8_t *tdata, uint8_t *test_start_date, uint8_t *measurements) { 00449 tdata[0] = 0xD8; 00450 memcpy(tdata+1, test_start_date, 4); 00451 memcpy(tdata+5, measurements, 5); 00452 } 00453 00454 /*! 00455 * \brief Prepares the payload of the frame 00456 */ 00457 static void PrepareTxFrame( uint8_t port ) 00458 { 00459 switch( port ) 00460 { 00461 case 15: 00462 { 00463 switch ( MessageType ) 00464 { 00465 case MESSAGE_TYPE_HB: 00466 { 00467 AppDataSize = 5; 00468 heartbeat_message(AppData, (uint8_t *)¤t_time); 00469 break; 00470 } 00471 case MESSAGE_TYPE_SHORT_TEST: 00472 { 00473 AppDataSize = 10; 00474 short_test_result(AppData, (uint8_t *)¤t_time, measurements); 00475 break; 00476 } 00477 case MESSAGE_TYPE_LONG_TEST: 00478 { 00479 AppDataSize = 10; 00480 long_test_result(AppData, (uint8_t *)¤t_time, measurements); 00481 break; 00482 } 00483 default: 00484 { 00485 AppDataSize = 5; 00486 heartbeat_message(AppData, (uint8_t *)¤t_time); 00487 break; 00488 } 00489 } 00490 } 00491 break; 00492 case 224: 00493 if( ComplianceTest.LinkCheck == true ) 00494 { 00495 ComplianceTest.LinkCheck = false; 00496 AppDataSize = 3; 00497 AppData[0] = 5; 00498 AppData[1] = ComplianceTest.DemodMargin; 00499 AppData[2] = ComplianceTest.NbGateways; 00500 ComplianceTest.State = 1; 00501 } 00502 else 00503 { 00504 switch( ComplianceTest.State ) 00505 { 00506 case 4: 00507 ComplianceTest.State = 1; 00508 break; 00509 case 1: 00510 AppDataSize = 2; 00511 AppData[0] = ComplianceTest.DownLinkCounter >> 8; 00512 AppData[1] = ComplianceTest.DownLinkCounter; 00513 break; 00514 } 00515 } 00516 break; 00517 default: 00518 break; 00519 } 00520 } 00521 00522 /*! 00523 * \brief Prepares the payload of the frame 00524 * 00525 * \retval [0: frame could be send, 1: error] 00526 */ 00527 static bool SendFrame( void ) 00528 { 00529 McpsReq_t mcpsReq; 00530 LoRaMacTxInfo_t txInfo; 00531 00532 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) 00533 { 00534 // Send empty frame in order to flush MAC commands 00535 mcpsReq.Type = MCPS_UNCONFIRMED ; 00536 mcpsReq.Req.Unconfirmed .fBuffer = NULL; 00537 mcpsReq.Req.Unconfirmed .fBufferSize = 0; 00538 mcpsReq.Req.Unconfirmed .Datarate = LORAWAN_DEFAULT_DATARATE; 00539 00540 LoRaMacUplinkStatus.Acked = false; 00541 LoRaMacUplinkStatus.Port = 0; 00542 LoRaMacUplinkStatus.Buffer = NULL; 00543 LoRaMacUplinkStatus.BufferSize = 0; 00544 SerialDisplayUpdateFrameType( false ); 00545 // SerialDisplayPrintDebugStatus( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) ); 00546 00547 } 00548 else 00549 { 00550 LoRaMacUplinkStatus.Acked = false; 00551 LoRaMacUplinkStatus.Port = AppPort; 00552 LoRaMacUplinkStatus.Buffer = AppData; 00553 LoRaMacUplinkStatus.BufferSize = AppDataSize; 00554 SerialDisplayUpdateFrameType( IsTxConfirmed ); 00555 00556 if( IsTxConfirmed == false ) 00557 { 00558 mcpsReq.Type = MCPS_UNCONFIRMED ; 00559 mcpsReq.Req.Unconfirmed .fPort = AppPort; 00560 mcpsReq.Req.Unconfirmed .fBuffer = AppData; 00561 mcpsReq.Req.Unconfirmed .fBufferSize = AppDataSize; 00562 mcpsReq.Req.Unconfirmed .Datarate = LORAWAN_DEFAULT_DATARATE; 00563 } 00564 else 00565 { 00566 mcpsReq.Type = MCPS_CONFIRMED ; 00567 mcpsReq.Req.Confirmed .fPort = AppPort; 00568 mcpsReq.Req.Confirmed .fBuffer = AppData; 00569 mcpsReq.Req.Confirmed .fBufferSize = AppDataSize; 00570 mcpsReq.Req.Confirmed .NbTrials = 8; 00571 mcpsReq.Req.Confirmed .Datarate = LORAWAN_DEFAULT_DATARATE; 00572 } 00573 } 00574 00575 if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) 00576 { 00577 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) 00578 { 00579 return true; 00580 } 00581 return false; 00582 } 00583 return true; 00584 } 00585 00586 /*! 00587 * \brief Function executed on TxNextPacket Timeout event 00588 */ 00589 static void OnTxNextPacketTimerEvent( void ) 00590 { 00591 MibRequestConfirm_t mibReq; 00592 LoRaMacStatus_t status; 00593 00594 TimerStop( &TxNextPacketTimer ); 00595 00596 mibReq.Type = MIB_NETWORK_JOINED ; 00597 status = LoRaMacMibGetRequestConfirm( &mibReq ); 00598 00599 if( status == LORAMAC_STATUS_OK ) 00600 { 00601 if( mibReq.Param .IsNetworkJoined == true ) 00602 { 00603 DeviceState = DEVICE_STATE_SEND; 00604 NextTx = true; 00605 } 00606 else 00607 { 00608 DeviceState = DEVICE_STATE_JOIN; 00609 } 00610 } 00611 } 00612 00613 /*! 00614 * \brief Function executed on Led 1 Timeout event 00615 */ 00616 static void OnLed1TimerEvent( void ) 00617 { 00618 TimerStop( &Led1Timer ); 00619 // Switch LED 1 OFF 00620 Led1State = false; 00621 Led1StateChanged = true; 00622 } 00623 00624 /*! 00625 * \brief Function executed on Led 2 Timeout event 00626 */ 00627 static void OnLed2TimerEvent( void ) 00628 { 00629 TimerStop( &Led2Timer ); 00630 // Switch LED 2 OFF 00631 Led2State = false; 00632 Led2StateChanged = true; 00633 } 00634 00635 /*! 00636 * \brief MCPS-Confirm event function 00637 * 00638 * \param [IN] mcpsConfirm - Pointer to the confirm structure, 00639 * containing confirm attributes. 00640 */ 00641 static void McpsConfirm( McpsConfirm_t *mcpsConfirm ) 00642 { 00643 if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00644 { 00645 switch( mcpsConfirm->McpsRequest ) 00646 { 00647 case MCPS_UNCONFIRMED : 00648 { 00649 // Check Datarate 00650 // Check TxPower 00651 break; 00652 } 00653 case MCPS_CONFIRMED : 00654 { 00655 // Check Datarate 00656 // Check TxPower 00657 // Check AckReceived 00658 // Check NbTrials 00659 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived ; 00660 break; 00661 } 00662 case MCPS_PROPRIETARY : 00663 { 00664 break; 00665 } 00666 default: 00667 break; 00668 } 00669 LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate ; 00670 LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter ; 00671 00672 // Switch LED 1 ON 00673 Led1State = true; 00674 Led1StateChanged = true; 00675 TimerStart( &Led1Timer ); 00676 00677 UplinkStatusUpdated = true; 00678 } 00679 NextTx = true; 00680 } 00681 00682 /*! 00683 * \brief MCPS-Indication event function 00684 * 00685 * \param [IN] mcpsIndication - Pointer to the indication structure, 00686 * containing indication attributes. 00687 */ 00688 static void McpsIndication( McpsIndication_t *mcpsIndication ) 00689 { 00690 if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) 00691 { 00692 return; 00693 } 00694 00695 switch( mcpsIndication->McpsIndication ) 00696 { 00697 case MCPS_UNCONFIRMED : 00698 { 00699 break; 00700 } 00701 case MCPS_CONFIRMED : 00702 { 00703 break; 00704 } 00705 case MCPS_PROPRIETARY : 00706 { 00707 break; 00708 } 00709 case MCPS_MULTICAST : 00710 { 00711 break; 00712 } 00713 default: 00714 break; 00715 } 00716 00717 // Check Multicast 00718 // Check Port 00719 // Check Datarate 00720 // Check FramePending 00721 // Check Buffer 00722 // Check BufferSize 00723 // Check Rssi 00724 // Check Snr 00725 // Check RxSlot 00726 LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi ; 00727 if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1 00728 { 00729 // Invert and divide by 4 00730 LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2; 00731 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr; 00732 } 00733 else 00734 { 00735 // Divide by 4 00736 LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2; 00737 } 00738 LoRaMacDownlinkStatus.DownlinkCounter++; 00739 LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData ; 00740 LoRaMacDownlinkStatus.Port = mcpsIndication->Port ; 00741 LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer ; 00742 LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize ; 00743 00744 if( ComplianceTest.Running == true ) 00745 { 00746 ComplianceTest.DownLinkCounter++; 00747 } 00748 00749 if( mcpsIndication->RxData == true ) 00750 { 00751 switch( mcpsIndication->Port ) 00752 { 00753 case 1: // The application LED can be controlled on port 1 or 2 00754 case 2: 00755 if( mcpsIndication->BufferSize == 1 ) 00756 { 00757 AppLedStateOn = mcpsIndication->Buffer [0] & 0x01; 00758 Led3StateChanged = true; 00759 } 00760 break; 00761 case 224: 00762 if( ComplianceTest.Running == false ) 00763 { 00764 // Check compliance test enable command (i) 00765 if( ( mcpsIndication->BufferSize == 4 ) && 00766 ( mcpsIndication->Buffer [0] == 0x01 ) && 00767 ( mcpsIndication->Buffer [1] == 0x01 ) && 00768 ( mcpsIndication->Buffer [2] == 0x01 ) && 00769 ( mcpsIndication->Buffer [3] == 0x01 ) ) 00770 { 00771 IsTxConfirmed = false; 00772 AppPort = 224; 00773 AppDataSize = 2; 00774 ComplianceTest.DownLinkCounter = 0; 00775 ComplianceTest.LinkCheck = false; 00776 ComplianceTest.DemodMargin = 0; 00777 ComplianceTest.NbGateways = 0; 00778 ComplianceTest.Running = true; 00779 ComplianceTest.State = 1; 00780 00781 MibRequestConfirm_t mibReq; 00782 mibReq.Type = MIB_ADR ; 00783 mibReq.Param .AdrEnable = true; 00784 LoRaMacMibSetRequestConfirm( &mibReq ); 00785 00786 #if defined( USE_BAND_868 ) 00787 LoRaMacTestSetDutyCycleOn( false ); 00788 #endif 00789 } 00790 } 00791 else 00792 { 00793 ComplianceTest.State = mcpsIndication->Buffer [0]; 00794 switch( ComplianceTest.State ) 00795 { 00796 case 0: // Check compliance test disable command (ii) 00797 IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00798 AppPort = LORAWAN_APP_PORT; 00799 AppDataSize = LORAWAN_APP_DATA_SIZE; 00800 ComplianceTest.DownLinkCounter = 0; 00801 ComplianceTest.Running = false; 00802 00803 MibRequestConfirm_t mibReq; 00804 mibReq.Type = MIB_ADR ; 00805 mibReq.Param .AdrEnable = LORAWAN_ADR_ON; 00806 LoRaMacMibSetRequestConfirm( &mibReq ); 00807 #if defined( USE_BAND_868 ) 00808 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 00809 #endif 00810 break; 00811 case 1: // (iii, iv) 00812 AppDataSize = 2; 00813 break; 00814 case 2: // Enable confirmed messages (v) 00815 IsTxConfirmed = true; 00816 ComplianceTest.State = 1; 00817 break; 00818 case 3: // Disable confirmed messages (vi) 00819 IsTxConfirmed = false; 00820 ComplianceTest.State = 1; 00821 break; 00822 case 4: // (vii) 00823 AppDataSize = mcpsIndication->BufferSize ; 00824 00825 AppData[0] = 4; 00826 for( uint8_t i = 1; i < AppDataSize; i++ ) 00827 { 00828 AppData[i] = mcpsIndication->Buffer [i] + 1; 00829 } 00830 break; 00831 case 5: // (viii) 00832 { 00833 MlmeReq_t mlmeReq; 00834 mlmeReq.Type = MLME_LINK_CHECK ; 00835 LoRaMacMlmeRequest( &mlmeReq ); 00836 } 00837 break; 00838 case 6: // (ix) 00839 { 00840 MlmeReq_t mlmeReq; 00841 00842 // Disable TestMode and revert back to normal operation 00843 IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00844 AppPort = LORAWAN_APP_PORT; 00845 AppDataSize = LORAWAN_APP_DATA_SIZE; 00846 ComplianceTest.DownLinkCounter = 0; 00847 ComplianceTest.Running = false; 00848 00849 MibRequestConfirm_t mibReq; 00850 mibReq.Type = MIB_ADR ; 00851 mibReq.Param .AdrEnable = LORAWAN_ADR_ON; 00852 LoRaMacMibSetRequestConfirm( &mibReq ); 00853 #if defined( USE_BAND_868 ) 00854 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 00855 #endif 00856 00857 mlmeReq.Type = MLME_JOIN ; 00858 00859 mlmeReq.Req.Join .DevEui = DevEui; 00860 mlmeReq.Req.Join .AppEui = AppEui; 00861 mlmeReq.Req.Join .AppKey = AppKey; 00862 mlmeReq.Req.Join .NbTrials = 3; 00863 00864 LoRaMacMlmeRequest( &mlmeReq ); 00865 DeviceState = DEVICE_STATE_SLEEP; 00866 } 00867 break; 00868 case 7: // (x) 00869 { 00870 if( mcpsIndication->BufferSize == 3 ) 00871 { 00872 MlmeReq_t mlmeReq; 00873 mlmeReq.Type = MLME_TXCW ; 00874 mlmeReq.Req.TxCw .Timeout = ( uint16_t )( ( mcpsIndication->Buffer [1] << 8 ) | mcpsIndication->Buffer [2] ); 00875 LoRaMacMlmeRequest( &mlmeReq ); 00876 } 00877 else if( mcpsIndication->BufferSize == 7 ) 00878 { 00879 MlmeReq_t mlmeReq; 00880 mlmeReq.Type = MLME_TXCW_1 ; 00881 mlmeReq.Req.TxCw .Timeout = ( uint16_t )( ( mcpsIndication->Buffer [1] << 8 ) | mcpsIndication->Buffer [2] ); 00882 mlmeReq.Req.TxCw .Frequency = ( uint32_t )( ( mcpsIndication->Buffer [3] << 16 ) | ( mcpsIndication->Buffer [4] << 8 ) | mcpsIndication->Buffer [5] ) * 100; 00883 mlmeReq.Req.TxCw .Power = mcpsIndication->Buffer [6]; 00884 LoRaMacMlmeRequest( &mlmeReq ); 00885 } 00886 ComplianceTest.State = 1; 00887 } 00888 break; 00889 default: 00890 break; 00891 } 00892 } 00893 break; 00894 default: 00895 break; 00896 } 00897 } 00898 00899 // Switch LED 2 ON for each received downlink 00900 Led2State = true; 00901 Led2StateChanged = true; 00902 TimerStart( &Led2Timer ); 00903 DownlinkStatusUpdated = true; 00904 } 00905 00906 /*! 00907 * \brief MLME-Confirm event function 00908 * 00909 * \param [IN] mlmeConfirm - Pointer to the confirm structure, 00910 * containing confirm attributes. 00911 */ 00912 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm ) 00913 { 00914 switch( mlmeConfirm->MlmeRequest ) 00915 { 00916 case MLME_JOIN : 00917 { 00918 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00919 { 00920 // Status is OK, node has joined the network 00921 IsNetworkJoinedStatusUpdate = true; 00922 DeviceState = DEVICE_STATE_SEND; 00923 00924 00925 MessageType = MESSAGE_TYPE_HB; 00926 joining = false; 00927 next_stest = current_time + 5; 00928 next_ltest = current_time + long_interval; 00929 } 00930 else 00931 { 00932 // Join was not successful. Try to join again 00933 DeviceState = DEVICE_STATE_JOIN; 00934 } 00935 break; 00936 } 00937 case MLME_LINK_CHECK : 00938 { 00939 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) 00940 { 00941 // Check DemodMargin 00942 // Check NbGateways 00943 if( ComplianceTest.Running == true ) 00944 { 00945 ComplianceTest.LinkCheck = true; 00946 ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin ; 00947 ComplianceTest.NbGateways = mlmeConfirm->NbGateways ; 00948 } 00949 } 00950 break; 00951 } 00952 default: 00953 break; 00954 } 00955 NextTx = true; 00956 UplinkStatusUpdated = true; 00957 } 00958 00959 00960 // **************************** TEST METHODS ******************************** // 00961 00962 void startTest(uint8_t *measurements) { 00963 00964 // Determine test length 00965 switch (MessageType) 00966 { 00967 case MESSAGE_TYPE_SHORT_TEST: 00968 test_duration = 30; 00969 break; 00970 case MESSAGE_TYPE_LONG_TEST: 00971 test_duration = 5400; 00972 break; 00973 default: 00974 test_duration = 0; 00975 break; 00976 } 00977 00978 // Start test 00979 relayPin = 1; 00980 AppLedStateOn = 1; 00981 Led3StateChanged = true; 00982 00983 // Measure voltage preval 00984 float battery_reading = BAT_PIN.read()*1000; 00985 measurements[0] = (uint8_t) rintf(battery_reading/10); 00986 } 00987 00988 void endTest(uint8_t *measurements) { 00989 // Measure endvals 00990 float battery_reading = BAT_PIN.read()*1000; 00991 int vce_reading = VCE_PIN.read()*1000; 00992 int light_1_reading = LIGHT_1_PIN.read()*1000 - vce_reading; 00993 int light_2_reading = LIGHT_2_PIN.read()*1000 - vce_reading; 00994 int rh_reading = RH_PIN.read()*1000 - vce_reading; 00995 00996 measurements[1] = (uint8_t) rintf(battery_reading/10); 00997 measurements[2] = (uint8_t) (light_1_reading/2); 00998 measurements[3] = (uint8_t) (light_2_reading/2); 00999 measurements[4] = (uint8_t) (rh_reading/2); 01000 01001 // End test // 01002 relayPin = 0; 01003 AppLedStateOn = 0; 01004 Led3StateChanged = true; 01005 } 01006 01007 void button_options_handler(void) 01008 { 01009 if (press_count >= 4) { 01010 // Run long test if 4 or more clicks 01011 MessageType = MESSAGE_TYPE_LONG_TEST; 01012 01013 startTest(measurements); 01014 01015 running_test = true; 01016 test_start = current_time; 01017 } 01018 if (press_count == 2 || press_count == 3) { 01019 // Run short test if 2 or 3 clicks 01020 MessageType = MESSAGE_TYPE_SHORT_TEST; 01021 01022 startTest(measurements); 01023 01024 running_test = true; 01025 test_start = current_time; 01026 } 01027 01028 // Reset count 01029 press_count = 0; 01030 } 01031 01032 /** 01033 * Main application entry point. 01034 */ 01035 Serial pc(SERIAL_TX, SERIAL_RX,115200); 01036 int MY_SetSysClock_PLL_HSE(void) 01037 { 01038 RCC_ClkInitTypeDef RCC_ClkInitStruct; 01039 RCC_OscInitTypeDef RCC_OscInitStruct; 01040 01041 /* configure RTC clock for HSE */ 01042 SET_BIT(PWR->CR, PWR_CR_DBP); // enable RTC register access as they are in backup domain 01043 __HAL_RCC_BACKUPRESET_FORCE(); // force reset RTC subsystem 01044 __HAL_RCC_BACKUPRESET_RELEASE(); 01045 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_HSE_DIV8); // HSE=8MHZ and RTC clock input is 1MHz(when using HSE as source) 01046 01047 /* Enable HSE and activate PLL with HSE as source */ 01048 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 01049 RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ 01050 01051 // PLLCLK = (8 MHz * 8)/2 = 32 MHz 01052 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 01053 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 01054 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; 01055 RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; 01056 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 01057 return (-1); // FAIL 01058 } 01059 01060 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ 01061 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); 01062 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 32 MHz 01063 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 32 MHz 01064 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 32 MHz 01065 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 32 MHz 01066 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { 01067 return (-2); // FAIL 01068 } 01069 01070 /* Enable HSE and activate PLL with HSE as source */ 01071 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI; 01072 RCC_OscInitStruct.HSIState = RCC_HSI_OFF; 01073 RCC_OscInitStruct.MSIState = RCC_MSI_OFF; 01074 RCC_OscInitStruct.HSI48State = RCC_HSI48_OFF; 01075 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 01076 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 01077 return (-3); // FAIL 01078 } 01079 01080 // enable rtc hardware 01081 __HAL_RCC_RTC_ENABLE(); 01082 wait(1.0); 01083 01084 return 0; // OK 01085 } 01086 01087 void my_patch(void) 01088 { 01089 int retVal; 01090 01091 // Put device into default clock, i.e using MSI = 2MHz 01092 HAL_RCC_DeInit(); 01093 01094 // Enable HSE clock 01095 retVal = MY_SetSysClock_PLL_HSE(); 01096 if(retVal< 0) 01097 { 01098 // fail 01099 //pc.printf("Failed to start HSE, ERR= %d\r\n", retVal); 01100 01101 // indicate error 01102 while(1) 01103 { 01104 myled = 1; 01105 wait(0.2); 01106 myled = 0; 01107 wait(0.5); 01108 } 01109 } 01110 } 01111 01112 int main( void ) 01113 { 01114 pc.printf("BUILD: %s mbed-os-rev: %d.%d.%d lib-rev: %d\r\n", \ 01115 __TIME__, MBED_MAJOR_VERSION, MBED_MINOR_VERSION,MBED_PATCH_VERSION,MBED_LIBRARY_VERSION); 01116 pc.printf("OLD: SysClock= %d RCC= %08X CSR= %08X CIER= %08X\r\n", SystemCoreClock, RCC->CR, RCC->CSR, RCC->CIER); 01117 my_patch(); 01118 pc.printf("\r\nNEW: SysClock= %d RCC= %08X CSR= %08X CIER= %08X\r\n", SystemCoreClock, RCC->CR, RCC->CSR, RCC->CIER); 01119 01120 wait(3); 01121 LoRaMacPrimitives_t LoRaMacPrimitives; 01122 LoRaMacCallback_t LoRaMacCallbacks; 01123 MibRequestConfirm_t mibReq; 01124 01125 BoardInit( ); 01126 SerialDisplayInit( ); 01127 01128 SerialDisplayUpdateEui( 5, DevEui ); 01129 SerialDisplayUpdateEui( 6, AppEui ); 01130 SerialDisplayUpdateKey( 7, AppKey ); 01131 01132 #if( OVER_THE_AIR_ACTIVATION == 0 ) 01133 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); 01134 SerialDisplayUpdateDevAddr( DevAddr ); 01135 SerialDisplayUpdateKey( 12, NwkSKey ); 01136 SerialDisplayUpdateKey( 13, AppSKey ); 01137 #endif 01138 01139 DeviceState = DEVICE_STATE_INIT; 01140 set_time(1514764800); 01141 relayPin = 0; 01142 01143 running_test = false; 01144 joining = true; 01145 //received_downlink = false; 01146 time_t start_time = time(NULL); 01147 01148 last_hb = start_time; 01149 01150 //button1.mode(PullUp); // Activate pull-up 01151 button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event 01152 AppLedStateOn = 0; 01153 Led3StateChanged = true; 01154 01155 myGreenLed = 0; // INITIAL OFF 01156 GreenLedState = GREEN_LED_STATE_INIT; 01157 TimerInit( &GreenLedTimer, OnGreenLedTimerEvent ); 01158 TimerSetValue( &GreenLedTimer, 100 ); 01159 TimerStart( &GreenLedTimer ); 01160 01161 TimerInit( &BatteryCheckTimer, OnBatteryCheckTimerEvent ); 01162 TimerSetValue( &BatteryCheckTimer, 100 ); // 100msec 01163 TimerStart( &BatteryCheckTimer ); 01164 01165 while( 1 ) 01166 { 01167 current_time = time(NULL); 01168 SerialRxProcess( ); 01169 if( IsNetworkJoinedStatusUpdate == true ) 01170 { 01171 IsNetworkJoinedStatusUpdate = false; 01172 mibReq.Type = MIB_NETWORK_JOINED ; 01173 LoRaMacMibGetRequestConfirm( &mibReq ); 01174 SerialDisplayUpdateNetworkIsJoined( mibReq.Param .IsNetworkJoined ); 01175 } 01176 if( Led1StateChanged == true ) 01177 { 01178 Led1StateChanged = false; 01179 SerialDisplayUpdateLedState( 1, Led1State ); 01180 } 01181 if( Led2StateChanged == true ) 01182 { 01183 Led2StateChanged = false; 01184 SerialDisplayUpdateLedState( 2, Led2State ); 01185 } 01186 if( Led3StateChanged == true ) 01187 { 01188 Led3StateChanged = false; 01189 SerialDisplayUpdateLedState( 3, AppLedStateOn ); 01190 } 01191 if( UplinkStatusUpdated == true ) 01192 { 01193 UplinkStatusUpdated = false; 01194 SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize ); 01195 } 01196 if( DownlinkStatusUpdated == true ) 01197 { 01198 DownlinkStatusUpdated = false; 01199 SerialDisplayUpdateLedState( 2, Led2State ); 01200 SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize ); 01201 } 01202 01203 if( BatteryCheckFlag == true) 01204 { 01205 BatteryCheckFlag = false; 01206 01207 // Measure voltage preval 01208 float battery_reading = BAT_PIN.read()*3300*2; 01209 // pc.printf("VBAT= %d", (int)battery_reading); 01210 01211 // Setting min value 2.0V so if relay button is pressed without battery Green LED will be OFF. 01212 // Set max value 4.45V as this voltage is seen at the battery pin. 01213 if((battery_reading < 2000)||(battery_reading > 4450)) 01214 { 01215 BatteryLowFlag = true; 01216 } 01217 else 01218 { 01219 BatteryLowFlag = false; 01220 } 01221 } 01222 01223 switch( DeviceState ) 01224 { 01225 case DEVICE_STATE_INIT: 01226 { 01227 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; 01228 LoRaMacPrimitives.MacMcpsIndication = McpsIndication; 01229 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; 01230 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; 01231 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); 01232 01233 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); 01234 01235 TimerInit( &Led1Timer, OnLed1TimerEvent ); 01236 TimerSetValue( &Led1Timer, 25 ); 01237 01238 TimerInit( &Led2Timer, OnLed2TimerEvent ); 01239 TimerSetValue( &Led2Timer, 25 ); 01240 01241 mibReq.Type = MIB_ADR ; 01242 mibReq.Param .AdrEnable = LORAWAN_ADR_ON; 01243 LoRaMacMibSetRequestConfirm( &mibReq ); 01244 01245 mibReq.Type = MIB_PUBLIC_NETWORK ; 01246 mibReq.Param .EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; 01247 LoRaMacMibSetRequestConfirm( &mibReq ); 01248 01249 // Limiting to just 2nd subband of 8 channels 01250 static uint16_t GatewayChannelsMask[] = {0xFF00, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000}; 01251 mibReq.Type = MIB_CHANNELS_DEFAULT_MASK ; 01252 mibReq.Param .ChannelsDefaultMask = GatewayChannelsMask; 01253 LoRaMacMibSetRequestConfirm( &mibReq ); 01254 01255 mibReq.Type = MIB_CHANNELS_MASK ; 01256 mibReq.Param .ChannelsMask = GatewayChannelsMask; 01257 LoRaMacMibSetRequestConfirm( &mibReq ); 01258 01259 01260 #if defined( USE_BAND_868 ) 01261 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); 01262 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); 01263 01264 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 01265 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 ); 01266 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 ); 01267 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 ); 01268 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 ); 01269 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 ); 01270 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 ); 01271 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 ); 01272 01273 mibReq.Type = MIB_RX2_DEFAULT_CHANNEL ; 01274 mibReq.Param .Rx2DefaultChannel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; 01275 LoRaMacMibSetRequestConfirm( &mibReq ); 01276 01277 mibReq.Type = MIB_RX2_CHANNEL ; 01278 mibReq.Param .Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; 01279 LoRaMacMibSetRequestConfirm( &mibReq ); 01280 #endif 01281 01282 #endif 01283 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); 01284 SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); 01285 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); 01286 01287 LoRaMacDownlinkStatus.DownlinkCounter = 0; 01288 01289 DeviceState = DEVICE_STATE_JOIN; 01290 break; 01291 } 01292 case DEVICE_STATE_JOIN: 01293 { 01294 #if( OVER_THE_AIR_ACTIVATION != 0 ) 01295 MlmeReq_t mlmeReq; 01296 01297 mlmeReq.Type = MLME_JOIN ; 01298 01299 mlmeReq.Req.Join .DevEui = DevEui; 01300 mlmeReq.Req.Join .AppEui = AppEui; 01301 mlmeReq.Req.Join .AppKey = AppKey; 01302 01303 if( NextTx == true ) 01304 { 01305 LoRaMacMlmeRequest( &mlmeReq ); 01306 } 01307 DeviceState = DEVICE_STATE_SLEEP; 01308 #else 01309 mibReq.Type = MIB_NET_ID ; 01310 mibReq.Param .NetID = LORAWAN_NETWORK_ID; 01311 LoRaMacMibSetRequestConfirm( &mibReq ); 01312 01313 mibReq.Type = MIB_DEV_ADDR ; 01314 mibReq.Param .DevAddr = DevAddr; 01315 LoRaMacMibSetRequestConfirm( &mibReq ); 01316 01317 mibReq.Type = MIB_NWK_SKEY ; 01318 mibReq.Param .NwkSKey = NwkSKey; 01319 LoRaMacMibSetRequestConfirm( &mibReq ); 01320 01321 mibReq.Type = MIB_APP_SKEY ; 01322 mibReq.Param .AppSKey = AppSKey; 01323 LoRaMacMibSetRequestConfirm( &mibReq ); 01324 01325 mibReq.Type = MIB_NETWORK_JOINED ; 01326 mibReq.Param .IsNetworkJoined = true; 01327 LoRaMacMibSetRequestConfirm( &mibReq ); 01328 01329 DeviceState = DEVICE_STATE_SEND; 01330 #endif 01331 IsNetworkJoinedStatusUpdate = true; 01332 break; 01333 } 01334 case DEVICE_STATE_SEND: 01335 { 01336 if( NextTx == true ) 01337 { 01338 SerialDisplayUpdateUplinkAcked( false ); 01339 SerialDisplayUpdateDonwlinkRxData( false ); 01340 PrepareTxFrame( AppPort ); 01341 01342 NextTx = SendFrame( ); 01343 } 01344 if( ComplianceTest.Running == true ) 01345 { 01346 // Schedule next packet transmission 01347 TxDutyCycleTime = 5000; // 5000 ms 01348 } 01349 else 01350 { 01351 // Schedule next packet transmission 01352 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 01353 } 01354 01355 if ( NextTx == true ) 01356 { 01357 DeviceState = DEVICE_STATE_SLEEP; 01358 01359 // Schedule next packet transmission 01360 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); 01361 TimerStart( &TxNextPacketTimer ); 01362 01363 // char my_str[17] = "Scheduled Resend"; 01364 // SerialDisplayPrintDebugLine( my_str, 17 ); 01365 } 01366 else 01367 { 01368 DeviceState = DEVICE_STATE_CYCLE; 01369 } 01370 01371 break; 01372 } 01373 case DEVICE_STATE_CYCLE: 01374 { 01375 // DeviceState = DEVICE_STATE_SLEEP; 01376 01377 // Schedule next packet transmission 01378 // TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); 01379 // TimerStart( &TxNextPacketTimer ); 01380 01381 01382 01383 // Is a test is running 01384 if (running_test) { 01385 // If it is 01386 01387 //check if it's time to end the test 01388 if (current_time - test_start >= test_duration) { 01389 endTest(measurements); 01390 // sendResult(measurements, ttype); 01391 DeviceState = DEVICE_STATE_SEND; 01392 last_hb = current_time; 01393 01394 // Set the times for the next tests 01395 switch ( MessageType ) 01396 { 01397 case MESSAGE_TYPE_SHORT_TEST: 01398 { 01399 next_stest = test_start + test_interval; 01400 break; 01401 } 01402 default: 01403 { 01404 // If long test, reset both test types, 01405 // to prevent two tests at the same time 01406 next_stest = test_start + test_interval; 01407 next_ltest = test_start + long_interval; 01408 break; 01409 } 01410 } 01411 01412 running_test = false; 01413 } 01414 } else { 01415 // If it isn't 01416 01417 // check if downlink action is required 01418 01419 //if (received_downlink == true) { 01420 // dl_handler(received_data); 01421 //} 01422 01423 //check if button is pressed 01424 if (button1_pressed) { // Set when button is pressed 01425 if (press_count == 0) { 01426 buttonOptions_timeout.attach(callback(button_options_handler), 2); // Debounce time 300 ms 01427 } 01428 button1_pressed = false; 01429 press_count++; 01430 } 01431 01432 //check if it's time to run a test 01433 if (current_time >= next_stest || current_time >= next_ltest) { 01434 01435 // Check what kind of test to run 01436 if (current_time >= next_ltest) { 01437 MessageType = MESSAGE_TYPE_LONG_TEST; 01438 } else { 01439 MessageType = MESSAGE_TYPE_SHORT_TEST; 01440 } 01441 01442 startTest(measurements); 01443 01444 running_test = true; 01445 test_start = current_time; 01446 01447 01448 //check if it's time for a heartbeat 01449 } else if (current_time - last_hb >= hb_interval) { 01450 // sendHb(); 01451 DeviceState = DEVICE_STATE_SEND; 01452 MessageType = MESSAGE_TYPE_HB; 01453 last_hb = current_time; 01454 } 01455 } 01456 01457 01458 break; 01459 } 01460 case DEVICE_STATE_SLEEP: 01461 { 01462 // Wake up through events 01463 break; 01464 } 01465 default: 01466 { 01467 DeviceState = DEVICE_STATE_INIT; 01468 break; 01469 } 01470 } 01471 } 01472 }
Generated on Thu Jul 14 2022 04:57:38 by
1.7.2