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