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