Bootcamp_Final
Fork of LoRaWAN-grove-cayenne by
Embed:
(wiki syntax)
Show/hide line numbers
sensorDemoVT100.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2018 Semtech 00008 00009 Description: LoRaMac classB device implementation 00010 00011 License: Revised BSD License, see LICENSE.TXT file include in the project 00012 00013 */ 00014 00015 #include "LoRaMac1v1.h" 00016 #include "SerialDisplay.h" 00017 #include "LoRaMacString.h" 00018 #ifdef ENABLE_VT100 00019 00020 /*! 00021 * Defines the application data transmission duty cycle. 5s, value in [ms]. 00022 */ 00023 #define APP_TX_DUTYCYCLE_us 8000000 00024 00025 /*! 00026 * Defines a random delay for application data transmission duty cycle. 1s, 00027 * value in [ms]. 00028 */ 00029 #define APP_TX_DUTYCYCLE_RND_us 2000000 00030 00031 /*! 00032 * Default datarate 00033 */ 00034 00035 #if defined( USE_BAND_ARIB_8CH ) 00036 #define LORAWAN_DEFAULT_DATARATE DR_3 00037 #else 00038 #define LORAWAN_DEFAULT_DATARATE DR_0 00039 #endif 00040 00041 /*! 00042 * LoRaWAN confirmed messages 00043 */ 00044 #define LORAWAN_CONFIRMED_MSG_ON false 00045 00046 /*! 00047 * LoRaWAN Adaptive Data Rate 00048 * 00049 * \remark Please note that when ADR is enabled the end-device should be static 00050 */ 00051 #define LORAWAN_ADR_ON 1 00052 00053 #if defined( USE_BAND_868 ) 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 2 00082 00083 /*! 00084 * User application data buffer size 00085 */ 00086 #define LORAWAN_APP_DATA_SIZE 3 00087 00088 00089 #ifdef LORAWAN_JOIN_EUI 00090 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI; 00091 static const uint8_t JoinEui[] = LORAWAN_JOIN_EUI; 00092 static const uint8_t NwkKey[] = LORAWAN_ROOT_NWKKEY; 00093 #ifdef LORAWAN_ROOT_APPKEY 00094 static const uint8_t AppKey[] = LORAWAN_ROOT_APPKEY; 00095 #endif 00096 #else 00097 static const uint8_t FNwkSIntKey[] = LORAWAN_FNwkSIntKey; 00098 static const uint8_t AppSKey[] = LORAWAN_APPSKEY; 00099 static const uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS; 00100 #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey) 00101 static const uint8_t SNwkSIntKey[] = LORAWAN_SNwkSIntKey; 00102 static const uint8_t NwkSEncKey[] = LORAWAN_NwkSEncKey; 00103 #endif 00104 #endif 00105 00106 /*! 00107 * Application port 00108 */ 00109 static uint8_t AppPort = LORAWAN_APP_PORT; 00110 00111 /*! 00112 * User application data size 00113 */ 00114 static uint8_t gAppDataSize = LORAWAN_APP_DATA_SIZE; 00115 00116 /*! 00117 * User application data buffer size 00118 */ 00119 #define LORAWAN_APP_DATA_MAX_SIZE 64 00120 00121 /*! 00122 * User application data 00123 */ 00124 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE]; 00125 00126 /*! 00127 * Indicates if the node is sending confirmed or unconfirmed messages 00128 */ 00129 static uint8_t gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00130 00131 /*! 00132 * Timer to handle the application data transmission duty cycle 00133 * 00134 */ 00135 LowPowerTimeout tx_timeout; 00136 00137 /*! 00138 * Indicates if a new packet can be sent 00139 */ 00140 static volatile struct { 00141 uint8_t gmi : 1; 00142 uint8_t gmc : 1; 00143 } flags; 00144 00145 /*! 00146 * Device states 00147 */ 00148 volatile enum eDevicState 00149 { 00150 /* 0 */ DEVICE_STATE_INIT = 0, 00151 /* 1 */ DEVICE_STATE_SEND, 00152 /* 2 */ DEVICE_STATE_TRIGGER, 00153 /* 3 */ DEVICE_STATE_SLEEP, 00154 #ifdef LORAWAN_JOIN_EUI 00155 /* 4 */ DEVICE_STATE_JOIN, 00156 /* 5 */ DEVICE_STATE_JOIN_OK 00157 #endif /* LORAWAN_JOIN_EUI */ 00158 } DeviceState, WakeUpState; 00159 00160 #if defined(TARGET_MOTE_L152RC) && !defined(TARGET_FF_ARDUINO) 00161 #define TARGET_FF_ARDUINO 00162 #endif 00163 00164 #if defined(TARGET_FF_ARDUINO) 00165 #ifdef TARGET_DISCO_L072CZ_LRWAN1 00166 #define LED_GREEN LED1 00167 #define LED_RED2 LED2 // next to LD7 00168 #define LED_BLUE LED3 00169 #define LED_RED4 LED4 00170 InterruptIn button_pin(USER_BUTTON); 00171 #define BUTTON_PRESSED 0 00172 DigitalOut extLed(LED_RED4); 00173 AnalogIn ain_temp(PA_0); 00174 #else 00175 InterruptIn button_pin(D8); 00176 #define BUTTON_PRESSED 1 00177 DigitalOut extLed(D15); 00178 AnalogIn ain_pot(A1); 00179 AnalogIn ain_temp(A3); 00180 #endif 00181 #endif /* TARGET_FF_ARDUINO */ 00182 00183 #if defined(TARGET_FF_MORPHO) && !defined(TARGET_DISCO_L072CZ_LRWAN1) 00184 #define JUMPER_ENABLE 00185 #endif /* */ 00186 00187 #ifdef JUMPER_ENABLE 00188 #define TX_INTERVAL_US 15000000 00189 DigitalOut jumper_out(PC_10); 00190 InterruptIn jumper_in(PC_12); 00191 #endif /* JUMPER_ENABLE */ 00192 00193 uint8_t c_ch; 00194 us_timestamp_t buttonStartAt; 00195 #ifdef TARGET_DISCO_L072CZ_LRWAN1 00196 PwmOut pwm(PA_0); 00197 #elif defined(TARGET_FF_ARDUINO) 00198 PwmOut pwm(PB_11); 00199 #endif /* TARGET_DISCO_L072CZ_LRWAN1 */ 00200 volatile int cayenne_ack_ch; 00201 00202 /*! 00203 * LoRaWAN compliance tests support data 00204 */ 00205 struct ComplianceTest_s 00206 { 00207 bool Running; 00208 uint8_t State; 00209 bool IsTxConfirmed; 00210 uint8_t AppPort; 00211 uint8_t AppDataSize; 00212 uint8_t *AppDataBuffer; 00213 uint16_t DownLinkCounter; 00214 bool LinkCheck; 00215 uint8_t DemodMargin; 00216 uint8_t NbGateways; 00217 }ComplianceTest; 00218 00219 McpsIndication_t gmi; 00220 00221 McpsConfirm_t gmc; 00222 00223 #ifdef JUMPER_ENABLE 00224 void autoUplink() 00225 { 00226 if (jumper_in.read() == 1) { 00227 tx_timeout.attach_us(autoUplink, TX_INTERVAL_US); 00228 } 00229 00230 c_ch = 0xff; 00231 DeviceState = DEVICE_STATE_SEND; 00232 } 00233 00234 void jumper_callback() 00235 { 00236 tx_timeout.attach_us(autoUplink, TX_INTERVAL_US); 00237 } 00238 #endif /* JUMPER_ENABLE */ 00239 00240 static void 00241 clearIndications() 00242 { 00243 vt.SetCursorPos(ROW_MCPS_CONF, 1); 00244 vt.printf("\e[K"); 00245 vt.SetCursorPos(ROW_MCPS_IND, 1); 00246 vt.printf("\e[K"); 00247 vt.SetCursorPos(ROW_MLME_IND, 1); 00248 vt.printf("\e[K"); 00249 vt.SetCursorPos(ROW_MLME_CONF, 1); 00250 vt.printf("\e[K"); 00251 00252 vt.SetCursorPos(ROW_MIC+3, 1); 00253 vt.printf("\e[K"); 00254 } 00255 00256 #define LPP_DIGITAL_INPUT 0 // 1 byte 00257 #define LPP_DIGITAL_OUTPUT 1 // 1 byte 00258 #define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed 00259 #define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed 00260 #define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned 00261 #define LPP_PRESENCE 102 // 1 byte, 1 00262 #define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed 00263 #define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned 00264 #define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G 00265 #define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned 00266 #define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s 00267 #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m 00268 00269 00270 // Data ID + Data Type + Data Size 00271 #define LPP_DIGITAL_INPUT_SIZE 3 00272 #define LPP_DIGITAL_OUTPUT_SIZE 3 00273 #define LPP_ANALOG_INPUT_SIZE 4 00274 #define LPP_ANALOG_OUTPUT_SIZE 4 00275 #define LPP_LUMINOSITY_SIZE 4 00276 #define LPP_PRESENCE_SIZE 3 00277 #define LPP_TEMPERATURE_SIZE 4 00278 #define LPP_RELATIVE_HUMIDITY_SIZE 3 00279 #define LPP_ACCELEROMETER_SIZE 8 00280 #define LPP_BAROMETRIC_PRESSURE_SIZE 4 00281 #define LPP_GYROMETER_SIZE 8 00282 #define LPP_GPS_SIZE 11 00283 00284 #define CAYENNE_CH_DOUT 2 00285 #define CAYENNE_CH_AOUT 3 00286 #define CAYENNE_CH_TEMP 0 00287 #ifndef TARGET_DISCO_L072CZ_LRWAN1 00288 #define CAYENNE_CH_POT 1 00289 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */ 00290 #define CAYENNE_CH_DIN 4 00291 00292 00293 const unsigned R0 = 100000; 00294 const unsigned B = 4275; 00295 volatile bool dout_downlink; 00296 00297 /*! 00298 * \brief Prepares the payload of the frame 00299 */ 00300 static void PrepareTxFrame( uint8_t port ) 00301 { 00302 uint16_t u16, rot; 00303 float t, f, R; 00304 static uint8_t seq; 00305 00306 if (c_ch != 0xff) { 00307 gAppDataSize = 0; 00308 AppData[gAppDataSize++] = c_ch; 00309 switch (c_ch) { 00310 case CAYENNE_CH_TEMP: 00311 AppData[gAppDataSize++] = LPP_TEMPERATURE; 00312 u16 = ain_temp.read_u16() >> 4; 00313 R = 4096.0 / u16 - 1.0; 00314 R = R0 * R; 00315 t = 1.0/(log(R/R0)/B+1/298.15)-273.15; 00316 u16 = t * 10; // 0.1C per bit 00317 AppData[gAppDataSize++] = u16 >> 8; 00318 AppData[gAppDataSize++] = u16; 00319 break; 00320 #ifndef TARGET_DISCO_L072CZ_LRWAN1 00321 case CAYENNE_CH_POT: 00322 AppData[gAppDataSize++] = LPP_ANALOG_INPUT; 00323 u16 = ain_pot.read_u16(); // pot (rotary angle) 00324 f = u16 / 198.6; // scale 65535/3.3 to 0.01v per bit 00325 rot = (uint16_t) f; 00326 AppData[gAppDataSize++] = rot >> 8; 00327 AppData[gAppDataSize++] = rot; 00328 break; 00329 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */ 00330 case CAYENNE_CH_DOUT: 00331 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT; 00332 AppData[gAppDataSize++] = extLed.read(); 00333 break; 00334 case CAYENNE_CH_AOUT: 00335 AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT; 00336 u16 = pwm.read() * 100; 00337 AppData[gAppDataSize++] = u16 >> 8; 00338 AppData[gAppDataSize++] = u16; 00339 break; 00340 } 00341 return; 00342 } else if (cayenne_ack_ch != -1) { 00343 switch (cayenne_ack_ch) { 00344 case CAYENNE_CH_DOUT: 00345 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT; 00346 AppData[gAppDataSize++] = extLed.read(); 00347 break; 00348 case CAYENNE_CH_AOUT: 00349 AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT; 00350 u16 = pwm.read() * 100; 00351 AppData[gAppDataSize++] = u16 >> 8; 00352 AppData[gAppDataSize++] = u16; 00353 break; 00354 } 00355 cayenne_ack_ch = -1; 00356 } 00357 00358 while (button_pin.read() == BUTTON_PRESSED) { 00359 us_timestamp_t duration = LoRaMacReadTimer() - buttonStartAt; 00360 if (duration > 1000000) { 00361 gAppDataSize = 0; 00362 AppData[gAppDataSize++] = CAYENNE_CH_DOUT; 00363 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT; 00364 AppData[gAppDataSize++] = extLed.read(); 00365 return; 00366 } 00367 } 00368 00369 switch( port ) { 00370 case LORAWAN_APP_PORT: 00371 gAppDataSize = 0; 00372 AppData[gAppDataSize++] = CAYENNE_CH_TEMP; 00373 AppData[gAppDataSize++] = LPP_TEMPERATURE; 00374 00375 //vt.SetCursorPos( ROW_END-1, 1 ); 00376 00377 u16 = ain_temp.read_u16() >> 4; 00378 //vt.printf("0x%03x ", u16); 00379 R = 4096.0 / u16 - 1.0; 00380 R = R0 * R; 00381 t = 1.0/(log(R/R0)/B+1/298.15)-273.15; 00382 //vt.printf("%.1fC\e[K", t); 00383 u16 = t * 10; // 0.1C per bit 00384 AppData[gAppDataSize++] = u16 >> 8; 00385 AppData[gAppDataSize++] = u16; 00386 #ifndef TARGET_DISCO_L072CZ_LRWAN1 00387 AppData[gAppDataSize++] = CAYENNE_CH_POT; 00388 AppData[gAppDataSize++] = LPP_ANALOG_INPUT; 00389 u16 = ain_pot.read_u16(); // pot (rotary angle) 00390 f = u16 / 198.6; // scale 65535/3.3 to 0.01v per bit 00391 rot = (uint16_t) f; 00392 AppData[gAppDataSize++] = rot >> 8; 00393 AppData[gAppDataSize++] = rot; 00394 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */ 00395 00396 /* limited packet size: either ack downlink, or send sequence number */ 00397 if (dout_downlink) { 00398 AppData[gAppDataSize++] = CAYENNE_CH_DOUT; 00399 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT; 00400 AppData[gAppDataSize++] = extLed.read(); 00401 dout_downlink = false; 00402 } else { 00403 AppData[gAppDataSize++] = CAYENNE_CH_DIN; 00404 AppData[gAppDataSize++] = LPP_DIGITAL_INPUT; 00405 AppData[gAppDataSize++] = seq++; 00406 } 00407 break; 00408 case 224: 00409 if( ComplianceTest.LinkCheck == true ) { 00410 ComplianceTest.LinkCheck = false; 00411 gAppDataSize = 3; 00412 AppData[0] = 5; 00413 AppData[1] = ComplianceTest.DemodMargin; 00414 AppData[2] = ComplianceTest.NbGateways; 00415 ComplianceTest.State = 1; 00416 } else { 00417 switch( ComplianceTest.State ) { 00418 case 4: 00419 ComplianceTest.State = 1; 00420 break; 00421 case 1: 00422 gAppDataSize = 2; 00423 AppData[0] = ComplianceTest.DownLinkCounter >> 8; 00424 AppData[1] = ComplianceTest.DownLinkCounter; 00425 break; 00426 } 00427 } 00428 break; 00429 default: 00430 break; 00431 } 00432 } 00433 00434 00435 /*! 00436 * \brief Prepares the payload of the frame 00437 * 00438 * \retval [0: frame could be send, 1: error] 00439 */ 00440 static LoRaMacStatus_t SendFrame(bool IsTxConfirmed, uint8_t AppDataSize) 00441 { 00442 LoRaMacStatus_t status; 00443 char str[64]; 00444 McpsReq_t mcpsReq; 00445 LoRaMacTxInfo_t txInfo; 00446 00447 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) 00448 { 00449 // Send empty frame in order to flush MAC commands 00450 mcpsReq.Type = MCPS_UNCONFIRMED; 00451 mcpsReq.Req.fBuffer = NULL; 00452 mcpsReq.Req.fBufferSize = 0; 00453 mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE; 00454 } 00455 else 00456 { 00457 SerialDisplayUpdateFrameType(IsTxConfirmed); 00458 if( IsTxConfirmed == false ) 00459 { 00460 mcpsReq.Type = MCPS_UNCONFIRMED; 00461 mcpsReq.Req.fPort = AppPort; 00462 mcpsReq.Req.fBuffer = AppData; 00463 mcpsReq.Req.fBufferSize = AppDataSize; 00464 mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE; 00465 } 00466 else 00467 { 00468 mcpsReq.Type = MCPS_CONFIRMED; 00469 mcpsReq.Req.fPort = AppPort; 00470 mcpsReq.Req.fBuffer = AppData; 00471 mcpsReq.Req.fBufferSize = AppDataSize; 00472 mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE; 00473 } 00474 } 00475 00476 clearIndications(); 00477 status = LoRaMacMcpsRequest( &mcpsReq ); 00478 if (status == LORAMAC_STATUS_OK) { 00479 SerialDisplayUplink(mcpsReq.Req.fPort, AppData, mcpsReq.Req.fBufferSize); 00480 vt.SetCursorPos( ROW_END, 1 ); 00481 vt.printf("sendFrame() OK %u\e[K", AppDataSize); 00482 } else { 00483 LoRaMacStatus_to_string(status, str); 00484 vt.SetCursorPos( ROW_END, 1 ); 00485 vt.printf("sendFrame() %s rx%d\e[K", str, LoRaMacGetRxSlot()); 00486 } 00487 00488 return status; 00489 } // ..SendFrame() 00490 00491 /*! 00492 * \brief MCPS-Confirm event function 00493 * 00494 * \param [IN] mcpsConfirm - Pointer to the confirm structure, 00495 * containing confirm attributes. 00496 */ 00497 static void McpsConfirm( const McpsConfirm_t *mcpsConfirm ) 00498 { 00499 char str[64]; 00500 00501 vt.SetCursorPos( ROW_MCPS_CONF, 1); 00502 vt.printf("McpsConfirm up:%uhz ", mcpsConfirm->UpLinkFreqHz); 00503 LoRaMacEventInfoStatus_to_string(mcpsConfirm->Status, str); 00504 if (mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) 00505 vt.printf("%s \e[K", str); 00506 else 00507 vt.printf("\e[31m%s\e[0m \e[K", str); 00508 00509 if (mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) 00510 { 00511 switch( mcpsConfirm->McpsRequest ) 00512 { 00513 case MCPS_UNCONFIRMED: 00514 { 00515 // Check Datarate 00516 // Check TxPower 00517 break; 00518 } 00519 case MCPS_CONFIRMED: 00520 { 00521 // Check Datarate 00522 // Check TxPower 00523 // Check AckReceived 00524 // Check NbTrials 00525 //LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived; 00526 break; 00527 } 00528 case MCPS_PROPRIETARY: 00529 { 00530 break; 00531 } 00532 default: 00533 break; 00534 } 00535 } else { 00536 /* fail */ 00537 } 00538 memcpy(&gmc, mcpsConfirm, sizeof(McpsConfirm_t)); 00539 flags.gmc = true; 00540 00541 DeviceState = DEVICE_STATE_TRIGGER; 00542 } // ..McpsConfirm() 00543 00544 00545 /*! 00546 * \brief MCPS-Indication event function 00547 * 00548 * \param [IN] mcpsIndication - Pointer to the indication structure, 00549 * containing indication attributes. 00550 */ 00551 static void McpsIndication( const McpsIndication_t *mcpsIndication ) 00552 { 00553 char str[64]; 00554 00555 memcpy(&gmi, mcpsIndication, sizeof(McpsIndication_t)); 00556 flags.gmi = true; 00557 00558 vt.SetCursorPos(ROW_MCPS_CONF, 1); 00559 vt.printf("\e[K"); // clear stale mcpsconf if retrying 00560 00561 vt.SetCursorPos( ROW_MCPS_IND, 0); 00562 vt.printf("McpsIndication rx%d ADR_ACK_CNT:%u ", mcpsIndication->RxSlot, mcpsIndication->ADR_ACK_CNT); 00563 if (mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK) 00564 { 00565 LoRaMacEventInfoStatus_to_string(mcpsIndication->Status, str); 00566 vt.printf("\e[31m%s\e[0m\e[K", str); 00567 return; 00568 } 00569 vt.printf("OK\e[K"); 00570 00571 switch( mcpsIndication->McpsIndication ) 00572 { 00573 case MCPS_UNCONFIRMED: 00574 { 00575 break; 00576 } 00577 case MCPS_CONFIRMED: 00578 { 00579 /* ack sent by mac layer */ 00580 break; 00581 } 00582 case MCPS_PROPRIETARY: 00583 { 00584 break; 00585 } 00586 case MCPS_MULTICAST: 00587 { 00588 break; 00589 } 00590 default: 00591 break; 00592 } 00593 00594 // Check Multicast 00595 // Check Port 00596 // Check Datarate 00597 // Check FramePending 00598 // Check Buffer 00599 // Check BufferSize 00600 // Check Rssi 00601 // Check Snr 00602 // Check RxSlot 00603 00604 00605 if( ComplianceTest.Running == true ) 00606 { 00607 ComplianceTest.DownLinkCounter++; 00608 } 00609 00610 if( mcpsIndication->RxData == true ) 00611 { 00612 unsigned n; 00613 for (n = 0; n < mcpsIndication->BufferSize; n += 4) { 00614 uint16_t val = mcpsIndication->Buffer[n+1] << 8; 00615 val += mcpsIndication->Buffer[n+2]; 00616 cayenne_ack_ch = mcpsIndication->Buffer[n]; 00617 switch (mcpsIndication->Buffer[n]) { 00618 case CAYENNE_CH_DOUT: 00619 extLed.write(val); 00620 dout_downlink = true; 00621 break; 00622 case CAYENNE_CH_AOUT: 00623 pwm.write(val / 100.0); 00624 break; 00625 default: 00626 break; 00627 } 00628 } 00629 00630 switch( mcpsIndication->Port ) 00631 { 00632 case 1: // The application LED can be controlled on port 1 or 2 00633 case 2: 00634 break; 00635 case 224: 00636 if( ComplianceTest.Running == false ) 00637 { 00638 // Check compliance test enable command (i) 00639 if( ( mcpsIndication->BufferSize == 4 ) && 00640 ( mcpsIndication->Buffer[0] == 0x01 ) && 00641 ( mcpsIndication->Buffer[1] == 0x01 ) && 00642 ( mcpsIndication->Buffer[2] == 0x01 ) && 00643 ( mcpsIndication->Buffer[3] == 0x01 ) ) 00644 { 00645 gIsTxConfirmed = false; 00646 AppPort = 224; 00647 gAppDataSize = 2; 00648 ComplianceTest.DownLinkCounter = 0; 00649 ComplianceTest.LinkCheck = false; 00650 ComplianceTest.DemodMargin = 0; 00651 ComplianceTest.NbGateways = 0; 00652 ComplianceTest.Running = true; 00653 ComplianceTest.State = 1; 00654 00655 MibRequestConfirm_t mibReq; 00656 mibReq.Type = MIB_ADR; 00657 mibReq.Param.AdrEnable = true; 00658 LoRaMacMibSetRequestConfirm( &mibReq ); 00659 00660 #if defined( USE_BAND_868 ) 00661 DutyCycleOn = false; 00662 #endif 00663 } 00664 } 00665 else 00666 { 00667 ComplianceTest.State = mcpsIndication->Buffer[0]; 00668 switch( ComplianceTest.State ) 00669 { 00670 case 0: // Check compliance test disable command (ii) 00671 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00672 AppPort = LORAWAN_APP_PORT; 00673 gAppDataSize = LORAWAN_APP_DATA_SIZE; 00674 ComplianceTest.DownLinkCounter = 0; 00675 ComplianceTest.Running = false; 00676 00677 MibRequestConfirm_t mibReq; 00678 mibReq.Type = MIB_ADR; 00679 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 00680 LoRaMacMibSetRequestConfirm( &mibReq ); 00681 #if defined( USE_BAND_868 ) 00682 DutyCycleOn = LORAWAN_DUTYCYCLE_ON; 00683 #endif 00684 break; 00685 case 1: // (iii, iv) 00686 gAppDataSize = 2; 00687 break; 00688 case 2: // Enable confirmed messages (v) 00689 gIsTxConfirmed = true; 00690 ComplianceTest.State = 1; 00691 break; 00692 case 3: // Disable confirmed messages (vi) 00693 gIsTxConfirmed = false; 00694 ComplianceTest.State = 1; 00695 break; 00696 case 4: // (vii) 00697 gAppDataSize = mcpsIndication->BufferSize; 00698 00699 AppData[0] = 4; 00700 for( uint8_t i = 1; i < gAppDataSize; i++ ) 00701 { 00702 AppData[i] = mcpsIndication->Buffer[i] + 1; 00703 } 00704 break; 00705 case 5: // (viii) 00706 { 00707 MlmeReq_t mlmeReq; 00708 mlmeReq.Type = MLME_LINK_CHECK; 00709 LoRaMacMlmeRequest( &mlmeReq ); 00710 } 00711 break; 00712 case 6: // (ix) 00713 { 00714 #ifdef LORAWAN_JOIN_EUI 00715 MlmeReq_t mlmeReq = {}; 00716 00717 // Disable TestMode and revert back to normal operation 00718 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; 00719 AppPort = LORAWAN_APP_PORT; 00720 gAppDataSize = LORAWAN_APP_DATA_SIZE; 00721 ComplianceTest.DownLinkCounter = 0; 00722 ComplianceTest.Running = false; 00723 00724 MibRequestConfirm_t mibReq; 00725 mibReq.Type = MIB_ADR; 00726 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 00727 LoRaMacMibSetRequestConfirm( &mibReq ); 00728 #if defined( USE_BAND_868 ) 00729 DutyCycleOn = LORAWAN_DUTYCYCLE_ON; 00730 #endif 00731 00732 mlmeReq.Type = MLME_JOIN; 00733 00734 mlmeReq.Req.Join.DevEui = DevEui; 00735 mlmeReq.Req.Join.JoinEui = JoinEui; 00736 mlmeReq.Req.Join.NwkKey = NwkKey; 00737 #ifdef LORAWAN_ROOT_APPKEY 00738 mlmeReq.Req.Join.AppKey = AppKey; 00739 #endif /* LORAWAN_ROOT_APPKEY */ 00740 00741 LoRaMacMlmeRequest( &mlmeReq ); 00742 #endif /* LORAWAN_JOIN_EUI */ 00743 DeviceState = DEVICE_STATE_SLEEP; 00744 } 00745 break; 00746 case 7: // Switch end device Class 00747 { 00748 MlmeReq_t mlmeReq; 00749 00750 mlmeReq.Type = MLME_SWITCH_CLASS; 00751 00752 // CLASS_A = 0, CLASS_B = 1, CLASS_C = 2 00753 mlmeReq.Req.SwitchClass.Class = ( DeviceClass_t )mcpsIndication->Buffer[1]; 00754 00755 LoRaMacMlmeRequest( &mlmeReq ); 00756 00757 PrepareTxFrame( AppPort ); 00758 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize); 00759 } 00760 break; 00761 case 8: // Send PingSlotInfoReq 00762 { 00763 MlmeReq_t mlmeReq; 00764 00765 mlmeReq.Type = MLME_PING_SLOT_INFO; 00766 00767 mlmeReq.Req.PingSlotInfo.Value = mcpsIndication->Buffer[1]; 00768 00769 LoRaMacMlmeRequest( &mlmeReq ); 00770 PrepareTxFrame( AppPort ); 00771 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize); 00772 } 00773 break; 00774 case 9: // Send BeaconTimingReq 00775 { 00776 MlmeReq_t mlmeReq; 00777 00778 mlmeReq.Type = MLME_BEACON_TIMING; 00779 00780 LoRaMacMlmeRequest( &mlmeReq ); 00781 PrepareTxFrame( AppPort ); 00782 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize); 00783 } 00784 break; 00785 default: 00786 break; 00787 } 00788 } 00789 break; 00790 default: 00791 break; 00792 } 00793 00794 } 00795 00796 } // ..McpsIndication() 00797 00798 #ifdef LORAWAN_JOIN_EUI 00799 void 00800 join(uint8_t tries) 00801 { 00802 char str[64]; 00803 LoRaMacStatus_t status; 00804 MlmeReq_t mlmeReq = { }; 00805 00806 mlmeReq.Type = MLME_JOIN; 00807 00808 clearIndications(); 00809 #ifdef LORAWAN_ROOT_APPKEY 00810 mlmeReq.Req.Join.AppKey = AppKey; 00811 #endif 00812 mlmeReq.Req.Join.DevEui = DevEui; 00813 mlmeReq.Req.Join.JoinEui = JoinEui; 00814 mlmeReq.Req.Join.NwkKey = NwkKey; 00815 mlmeReq.Req.Join.NbTrials = tries; 00816 status = LoRaMacMlmeRequest( &mlmeReq ); 00817 if (status != LORAMAC_STATUS_OK) { 00818 LoRaMacStatus_to_string(status, str); 00819 } else 00820 extLed = 1; 00821 } 00822 #endif /* LORAWAN_JOIN_EUI */ 00823 00824 /*! 00825 * \brief MLME-Confirm event function 00826 * 00827 * \param [IN] mlmeConfirm - Pointer to the confirm structure, 00828 * containing confirm attributes. 00829 */ 00830 static void MlmeConfirm( const MlmeConfirm_t *mlmeConfirm ) 00831 { 00832 char str[64]; 00833 static uint8_t failCnt = 0; 00834 00835 vt.SetCursorPos(ROW_MLME_CONF, 1); 00836 Mlme_to_string(mlmeConfirm->MlmeRequest, str); 00837 vt.printf("MlmeConfirm %s ", str); 00838 LoRaMacEventInfoStatus_to_string(mlmeConfirm->Status, str); 00839 if (mlmeConfirm->Status != LORAMAC_EVENT_INFO_STATUS_OK) 00840 vt.printf("\e[31m%s \e[0m \e[K", str); 00841 else 00842 vt.printf("%s \e[K", str); 00843 00844 #if defined(LORAWAN_ROOT_APPKEY) && defined(LORAWAN_JOIN_EUI) 00845 /* 1v1 joinNonce is incrementing non-volatile value */ 00846 if (mlmeConfirm->MlmeRequest == MLME_JOIN) { 00847 vt.printf(" rxJoinNonce:%u vs %u", 00848 mlmeConfirm->fields.join.rxJoinNonce, 00849 mlmeConfirm->fields.join.myJoinNonce 00850 ); 00851 } 00852 #endif /* LORAWAN_ROOT_APPKEY */ 00853 00854 if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) 00855 { 00856 failCnt = 0; 00857 switch (mlmeConfirm->MlmeRequest) 00858 { 00859 #ifdef LORAWAN_JOIN_EUI 00860 case MLME_JOIN: 00861 { 00862 // Status is OK, node has joined the network 00863 /* collect any mac cmds from server until expected channel mask */ 00864 extLed = 0; 00865 DeviceState = DEVICE_STATE_JOIN_OK; 00866 break; 00867 } 00868 #endif /* LORAWAN_JOIN_EUI*/ 00869 case MLME_LINK_CHECK: 00870 { 00871 // Check DemodMargin 00872 // Check NbGateways 00873 if( ComplianceTest.Running == true ) 00874 { 00875 ComplianceTest.LinkCheck = true; 00876 ComplianceTest.DemodMargin = mlmeConfirm->fields.link.DemodMargin; 00877 ComplianceTest.NbGateways = mlmeConfirm->fields.link.NbGateways; 00878 } 00879 break; 00880 } 00881 case MLME_TIME_REQ: 00882 break; 00883 default: 00884 /* TODO: handle unknown MLME request */ 00885 DeviceState = DEVICE_STATE_SLEEP; 00886 break; 00887 } 00888 } 00889 else // not ok... 00890 { 00891 failCnt++; 00892 00893 #ifdef LORAWAN_JOIN_EUI 00894 if (failCnt > 5) { 00895 join(1); 00896 return; 00897 } 00898 #endif 00899 00900 switch( mlmeConfirm->MlmeRequest ) 00901 { 00902 #ifdef LORAWAN_JOIN_EUI 00903 case MLME_JOIN: 00904 { 00905 // Join failed, restart join procedure 00906 break; 00907 } 00908 #endif /* LORAWAN_JOIN_EUI */ 00909 case MLME_LINK_CHECK: 00910 DeviceState = DEVICE_STATE_SLEEP; 00911 break; 00912 #ifdef LORAWAN_JOIN_EUI 00913 case MLME_REJOIN_0: 00914 break; 00915 case MLME_REJOIN_2: 00916 break; 00917 case MLME_TIME_REQ: 00918 break; 00919 #endif /* LORAWAN_JOIN_EUI */ 00920 default: 00921 DeviceState = DEVICE_STATE_SLEEP; 00922 break; 00923 } 00924 } 00925 } // ..MlmeConfirm 00926 00927 static void MlmeIndication( const MlmeIndication_t *MlmeIndication ) 00928 { 00929 char str[48]; 00930 MibRequestConfirm_t mibReq; 00931 00932 vt.SetCursorPos(ROW_MLME_IND, 1); 00933 Mlme_to_string(MlmeIndication->MlmeIndication, str); 00934 vt.printf("MlmeIndication %s %08x ", str, RCC->CSR); 00935 LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str); 00936 if (MlmeIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK) 00937 vt.printf("\e[31m%s \e[0m \e[K", str); 00938 else 00939 vt.printf("%s \e[K", str); 00940 00941 switch( MlmeIndication->MlmeIndication ) 00942 { 00943 case MLME_SWITCH_CLASS: 00944 { 00945 /* mac gave up on beacon */ 00946 mibReq.Type = MIB_DEVICE_CLASS; 00947 mibReq.Param.Class = CLASS_A; 00948 LoRaMacMibSetRequestConfirm( &mibReq ); 00949 00950 // Switch to class A again 00951 DeviceState = DEVICE_STATE_SLEEP; // class-B manual switch 00952 break; 00953 } 00954 case MLME_BEACON: 00955 { 00956 LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str); 00957 break; 00958 00959 } 00960 #ifdef LORAWAN_JOIN_EUI 00961 case MLME_JOIN: 00962 vt.printf("%uhz try%u", MlmeIndication->freqHz, MlmeIndication->JoinRequestTrials); 00963 break; 00964 #endif /* !LORAWAN_JOIN_EUI */ 00965 default: 00966 break; 00967 } 00968 00969 } // ..MlmeIndication() 00970 00971 uint8_t periodicity; 00972 00973 void SerialDisplayRefresh( void ) 00974 { 00975 #ifdef LORAWAN_JOIN_EUI 00976 MibRequestConfirm_t mibReq; 00977 #endif 00978 00979 SerialDisplayInit( ); 00980 #ifdef LORAWAN_JOIN_EUI 00981 SerialDisplayUpdateActivationMode(true); 00982 SerialDisplayUpdateEui( ROW_DEVEUI, DevEui); 00983 SerialDisplayUpdateEui( ROW_JOINEUI, JoinEui); 00984 SerialDisplayUpdateKey( ROW_NWKKEY, NwkKey); 00985 00986 #ifdef LORAWAN_ROOT_APPKEY 00987 SerialDisplayUpdateKey(ROW_APPKEY, AppKey); 00988 #endif 00989 00990 mibReq.Type = MIB_NETWORK_JOINED; 00991 LoRaMacMibGetRequestConfirm( &mibReq ); 00992 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); 00993 #else 00994 //SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); 00995 SerialDisplayUpdateDevAddr( DevAddr ); 00996 SerialDisplayUpdateKey( ROW_FNwkSIntKey, FNwkSIntKey); 00997 SerialDisplayUpdateKey( ROW_AppSKey, AppSKey ); 00998 #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey) 00999 SerialDisplayUpdateKey(ROW_NwkSEncKey, NwkSEncKey); 01000 SerialDisplayUpdateKey(ROW_SNwkSIntKey, SNwkSIntKey); 01001 #endif /* 1v1 ABP */ 01002 01003 vt.SetCursorPos( ROW_END, 1 ); 01004 vt.printf("FCntUp:%08x", eeprom_read(EEPROM_FCNTUP)); 01005 vt.printf(" AFCntDown:%08x", get_fcntdwn(true)); 01006 vt.printf(" NFCntDown:%08x", get_fcntdwn(false)); 01007 #endif 01008 01009 01010 SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); 01011 #if defined( USE_BAND_868 ) 01012 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); 01013 #else 01014 SerialDisplayUpdateDutyCycle( false ); 01015 #endif 01016 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); 01017 01018 //SerialDisplayUpdateLedState( 3, AppLedStateOn ); 01019 } 01020 01021 void SerialRxProcess( void ) 01022 { 01023 LoRaMacStatus_t status; 01024 MlmeReq_t mlmeReq; 01025 #ifndef LORAWAN_JOIN_EUI 01026 static uint8_t icnt = 0; 01027 #endif 01028 01029 if( SerialDisplayReadable( ) == true ) { 01030 char ch = SerialDisplayGetChar(); 01031 #ifndef LORAWAN_JOIN_EUI 01032 if (ch == 'I') { 01033 if (++icnt == 3) { 01034 vt.SetCursorPos( ROW_END, 1 ); 01035 vt.printf("reset-fcnts\e[K"); 01036 eeprom_clear(EEPROM_AFCNTDWN); 01037 eeprom_clear(EEPROM_NFCNTDWN); 01038 eeprom_clear(EEPROM_FCNTUP); 01039 } 01040 } else 01041 icnt = 0; 01042 #endif /* !LORAWAN_JOIN_EUI */ 01043 01044 if ( ch >= '0' && ch <= '9') { 01045 c_ch = ch - '0'; 01046 DeviceState = DEVICE_STATE_SEND; 01047 return; 01048 } 01049 switch( ch ) { 01050 case 'R': 01051 case 'r': 01052 // Refresh Serial screen 01053 SerialDisplayRefresh( ); 01054 break; 01055 case 'L': 01056 clearIndications(); 01057 mlmeReq.Type = MLME_LINK_CHECK; 01058 status = LoRaMacMlmeRequest( &mlmeReq ); 01059 if (status == LORAMAC_STATUS_OK) 01060 SendFrame(0, false); 01061 break; 01062 #ifdef LORAWAN_JOIN_EUI 01063 case 'j': 01064 DeviceState = DEVICE_STATE_JOIN; 01065 break; 01066 #endif 01067 default: 01068 break; 01069 } 01070 } 01071 } 01072 01073 static void button_isr() 01074 { 01075 c_ch = 0xff; 01076 DeviceState = DEVICE_STATE_SEND; 01077 buttonStartAt = LoRaMacReadTimer(); 01078 } 01079 01080 static const LoRaMacPrimitives_t LoRaMacPrimitives = { 01081 McpsConfirm, 01082 McpsIndication, 01083 MlmeConfirm, 01084 MlmeIndication 01085 }; 01086 01087 static const LoRaMacCallback_t LoRaMacCallbacks = { 01088 BoardGetBatteryLevel, 01089 NULL 01090 }; 01091 01092 /** 01093 * Main application entry point. 01094 */ 01095 int main() 01096 { 01097 LoRaMacStatus_t status; 01098 MibRequestConfirm_t mibReq; 01099 01100 DeviceState = DEVICE_STATE_INIT; 01101 01102 if (sleep_manager_can_deep_sleep()) 01103 sleep_manager_lock_deep_sleep(); // prevent deep sleep 01104 01105 #ifdef JUMPER_ENABLE 01106 jumper_out = 1; 01107 jumper_in.mode(PullDown); 01108 jumper_in.rise(jumper_callback); 01109 // Q: does InterruptIn.rise() call immediately if already high? 01110 if (jumper_in.read()) 01111 jumper_callback(); // A: probably not 01112 #endif /* JUMPER_ENABLE */ 01113 01114 while( 1 ) 01115 { 01116 SerialRxProcess( ); 01117 01118 if (flags.gmi) { 01119 flags.gmi = false; 01120 SerialDisplayMcpsIndication(&gmi); 01121 } 01122 01123 if (flags.gmc) { 01124 flags.gmc = false; 01125 SerialDisplayMcpsConfirm(&gmc); 01126 } 01127 01128 switch( DeviceState ) 01129 { 01130 case DEVICE_STATE_INIT: 01131 { 01132 status = LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); 01133 if (LORAMAC_STATUS_OK != status) { 01134 char str[48]; 01135 LoRaMacStatus_to_string(status, str); 01136 vt.SetCursorPos(1, 1); 01137 vt.printf("MacInit: %s\e[K", str); 01138 for (;;) asm("nop"); 01139 } 01140 01141 pwm.period(1.0 / 60); 01142 cayenne_ack_ch = -1; 01143 c_ch = 0xff; 01144 button_pin.mode(PullDown); 01145 #ifdef TARGET_DISCO_L072CZ_LRWAN1 01146 button_pin.fall(button_isr); 01147 #else 01148 button_pin.rise(button_isr); 01149 #endif 01150 01151 mibReq.Type = MIB_ADR; 01152 mibReq.Param.AdrEnable = LORAWAN_ADR_ON; 01153 LoRaMacMibSetRequestConfirm( &mibReq ); 01154 01155 mibReq.Type = MIB_PUBLIC_NETWORK; 01156 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; 01157 LoRaMacMibSetRequestConfirm( &mibReq ); 01158 01159 #if defined( USE_BAND_868 ) 01160 DutyCycleOn = LORAWAN_DUTYCYCLE_ON ; 01161 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 01162 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 ); 01163 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 ); 01164 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 ); 01165 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 ); 01166 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 ); 01167 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 ); 01168 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 ); 01169 01170 mibReq.Type = MIB_RX2_CHANNEL; 01171 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; 01172 LoRaMacMibSetRequestConfirm( &mibReq ); 01173 #endif 01174 01175 #endif 01176 01177 SerialDisplayRefresh(); 01178 #ifdef LORAWAN_JOIN_EUI 01179 01180 #ifndef SENETCO /* for senet, use network provided DevEUI */ 01181 // Initialize LoRaMac device unique ID 01182 //HardwareIDtoDevEUI(DevEui); 01183 #ifdef LORAWAN_ROOT_APPKEY 01184 // inverted DevEui provisioned as v1.1 on server (non-inv = lorawan1v0) 01185 for (int i = 0; i < 8; i++) 01186 DevEui[i] ^= 0xff; 01187 #endif /* LORAWAN_ROOT_APPKEY */ 01188 #endif /* !SENETCO */ 01189 SerialDisplayUpdateEui( 5, DevEui ); 01190 DeviceState = DEVICE_STATE_JOIN; 01191 #else /* ABP... */ 01192 01193 mibReq.Type = MIB_DEV_ADDR; 01194 mibReq.Param.DevAddr = DevAddr; 01195 LoRaMacMibSetRequestConfirm( &mibReq ); 01196 SerialDisplayUpdateDevAddr(DevAddr); 01197 01198 mibReq.Type = MIB_APP_SKEY; 01199 mibReq.Param.key = AppSKey; 01200 LoRaMacMibSetRequestConfirm( &mibReq ); 01201 SerialDisplayUpdateKey(ROW_AppSKey, AppSKey); 01202 01203 #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey) 01204 /* lorawan 1v1 ABP */ 01205 mibReq.Type = MIB_NwkSEncKey; 01206 mibReq.Param.key = NwkSEncKey; 01207 LoRaMacMibSetRequestConfirm( &mibReq ); 01208 SerialDisplayUpdateKey(ROW_NwkSEncKey, NwkSEncKey); 01209 01210 mibReq.Type = MIB_SNwkSIntKey; 01211 mibReq.Param.key = SNwkSIntKey; 01212 LoRaMacMibSetRequestConfirm( &mibReq ); 01213 SerialDisplayUpdateKey(ROW_SNwkSIntKey, SNwkSIntKey); 01214 01215 mibReq.Type = MIB_FNwkSIntKey; 01216 mibReq.Param.key = FNwkSIntKey; 01217 LoRaMacMibSetRequestConfirm( &mibReq ); 01218 SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key); 01219 #else 01220 /* lorawan 1v0 ABP */ 01221 mibReq.Type = MIB_NwkSKey; 01222 mibReq.Param.key = FNwkSIntKey; 01223 LoRaMacMibSetRequestConfirm( &mibReq ); 01224 SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key); 01225 #endif 01226 01227 DeviceState = DEVICE_STATE_TRIGGER; 01228 #endif /* !LORAWAN_JOIN_EUI */ 01229 break; 01230 } 01231 #ifdef LORAWAN_JOIN_EUI 01232 case DEVICE_STATE_JOIN: 01233 { 01234 join(8); 01235 DeviceState = DEVICE_STATE_SLEEP; 01236 break; 01237 } 01238 case DEVICE_STATE_JOIN_OK: 01239 MibRequestConfirm_t mibReq; 01240 mibReq.Type = MIB_NETWORK_JOINED; 01241 LoRaMacMibGetRequestConfirm( &mibReq ); 01242 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); 01243 mibReq.Type = MIB_DEV_ADDR; 01244 LoRaMacMibGetRequestConfirm( &mibReq ); 01245 SerialDisplayUpdateDevAddr(mibReq.Param.DevAddr); 01246 mibReq.Type = MIB_FNwkSIntKey; 01247 LoRaMacMibGetRequestConfirm( &mibReq ); 01248 SerialDisplayUpdateKey( ROW_FNwkSIntKey, mibReq.Param.key ); 01249 mibReq.Type = MIB_APP_SKEY; 01250 LoRaMacMibGetRequestConfirm( &mibReq ); 01251 SerialDisplayUpdateKey( ROW_AppSKey, mibReq.Param.key ); 01252 01253 #ifdef LORAWAN_ROOT_APPKEY 01254 mibReq.Type = MIB_SNwkSIntKey; 01255 LoRaMacMibGetRequestConfirm( &mibReq ); 01256 SerialDisplayUpdateKey(ROW_SNwkSIntKey, mibReq.Param.key); 01257 mibReq.Type = MIB_NwkSEncKey; 01258 LoRaMacMibGetRequestConfirm( &mibReq ); 01259 SerialDisplayUpdateKey(ROW_NwkSEncKey, mibReq.Param.key); 01260 #endif /* LORAWAN_ROOT_APPKEY */ 01261 DeviceState = DEVICE_STATE_TRIGGER; 01262 break; 01263 #endif /* LORAWAN_JOIN_EUI */ 01264 case DEVICE_STATE_SEND: 01265 SerialDisplayUpdateUplinkAcked( false ); 01266 SerialDisplayUpdateDonwlinkRxData( false ); 01267 PrepareTxFrame( AppPort ); 01268 status = SendFrame(gIsTxConfirmed, gAppDataSize); 01269 if (status == LORAMAC_STATUS_OK) { 01270 /* McpsConfirm or McpsIndication callback will continue */ 01271 DeviceState = DEVICE_STATE_SLEEP; 01272 } else 01273 DeviceState = DEVICE_STATE_TRIGGER; 01274 break; 01275 case DEVICE_STATE_SLEEP: 01276 { 01277 // Wake up through events 01278 sleep_manager_sleep_auto(); 01279 break; 01280 } 01281 case DEVICE_STATE_TRIGGER: 01282 /* wait button ISR */ 01283 sleep_manager_sleep_auto(); 01284 break; 01285 default: 01286 DeviceState = DEVICE_STATE_INIT; 01287 break; 01288 } // ..switch( DeviceState ) 01289 01290 LoRaMacUserContext(); 01291 } // ..while( 1 ) 01292 } 01293 #endif /* ENABLE_VT100 */
Generated on Thu Jul 14 2022 03:03:44 by 1.7.2