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