LMIC lib Lora OTA device for Everynet
Fork of LMiC-10secs by
Embed:
(wiki syntax)
Show/hide line numbers
lorabase.h
00001 /******************************************************************************* 00002 * Copyright (c) 2014-2015 IBM Corporation. 00003 * All rights reserved. This program and the accompanying materials 00004 * are made available under the terms of the Eclipse Public License v1.0 00005 * which accompanies this distribution, and is available at 00006 * http://www.eclipse.org/legal/epl-v10.html 00007 * 00008 * Contributors: 00009 * IBM Zurich Research Lab - initial API, implementation and documentation 00010 *******************************************************************************/ 00011 00012 #ifndef _lorabase_h_ 00013 #define _lorabase_h_ 00014 00015 // ================================================================================ 00016 // BEG: Keep in sync with lorabase.hpp 00017 // 00018 00019 enum _cr_t { CR_4_5=0, CR_4_6, CR_4_7, CR_4_8 }; 00020 enum _sf_t { FSK=0, SF7, SF8, SF9, SF10, SF11, SF12, SFrfu }; 00021 enum _bw_t { BW125=0, BW250, BW500, BWrfu }; 00022 typedef u1_t cr_t; 00023 typedef u1_t sf_t; 00024 typedef u1_t bw_t; 00025 typedef u1_t dr_t; 00026 // Radio parameter set (encodes SF/BW/CR/IH/NOCRC) 00027 typedef u2_t rps_t; 00028 TYPEDEF_xref2rps_t; 00029 00030 enum { ILLEGAL_RPS = 0xFF }; 00031 enum { DR_PAGE_EU868 = 0x00 }; 00032 enum { DR_PAGE_US915 = 0x10 }; 00033 00034 // Global maximum frame length 00035 enum { STD_PREAMBLE_LEN = 8 }; 00036 //enum { MAX_LEN_FRAME = 96 }; 00037 enum { MAX_LEN_FRAME = 64 }; 00038 enum { LEN_DEVNONCE = 2 }; 00039 enum { LEN_ARTNONCE = 3 }; 00040 enum { LEN_NETID = 3 }; 00041 enum { DELAY_JACC1 = 5 }; // in secs 00042 enum { DELAY_DNW1 = 1 }; // in secs down window #1 00043 enum { DELAY_EXTDNW2 = 1 }; // in secs 00044 enum { DELAY_JACC2 = DELAY_JACC1+(int)DELAY_EXTDNW2 }; // in secs 00045 enum { DELAY_DNW2 = DELAY_DNW1 +(int)DELAY_EXTDNW2 }; // in secs down window #1 00046 enum { BCN_INTV_exp = 7 }; 00047 enum { BCN_INTV_sec = 1<<BCN_INTV_exp }; 00048 enum { BCN_INTV_ms = BCN_INTV_sec*1000L }; 00049 enum { BCN_INTV_us = BCN_INTV_ms*1000L }; 00050 enum { BCN_RESERVE_ms = 2120 }; // space reserved for beacon and NWK management 00051 enum { BCN_GUARD_ms = 3000 }; // end of beacon period to prevent interference with beacon 00052 enum { BCN_SLOT_SPAN_ms = 30 }; // 2^12 reception slots a this span 00053 enum { BCN_WINDOW_ms = BCN_INTV_ms-(int)BCN_GUARD_ms-(int)BCN_RESERVE_ms }; 00054 enum { BCN_RESERVE_us = 2120000 }; 00055 enum { BCN_GUARD_us = 3000000 }; 00056 enum { BCN_SLOT_SPAN_us = 30000 }; 00057 00058 #if defined(CFG_eu868) // ============================================== 00059 00060 enum _dr_eu868_t { DR_SF12=0, DR_SF11, DR_SF10, DR_SF9, DR_SF8, DR_SF7, DR_SF7B, DR_FSK, DR_NONE }; 00061 enum { DR_DFLTMIN = DR_SF7 }; 00062 enum { DR_PAGE = DR_PAGE_EU868 }; 00063 00064 // Default frequency plan for EU 868MHz ISM band 00065 // Bands: 00066 // g1 : 1% 14dBm 00067 // g2 : 0.1% 14dBm 00068 // g3 : 10% 27dBm 00069 // freq band datarates 00070 enum { EU868_F1 = 868100000, // g1 SF7-12 00071 EU868_F2 = 868300000, // g1 SF7-12 FSK SF7/250 00072 EU868_F3 = 868500000, // g1 SF7-12 00073 EU868_F4 = 868850000, // g2 SF7-12 00074 EU868_F5 = 869050000, // g2 SF7-12 00075 EU868_F6 = 869525000, // g3 SF7-12 00076 EU868_J4 = 864100000, // g2 SF7-12 used during join 00077 EU868_J5 = 864300000, // g2 SF7-12 ditto 00078 EU868_J6 = 864500000, // g2 SF7-12 ditto 00079 }; 00080 enum { EU868_FREQ_MIN = 863000000, 00081 EU868_FREQ_MAX = 870000000 }; 00082 00083 enum { CHNL_PING = 5 }; 00084 enum { FREQ_PING = EU868_F6 }; // default ping freq 00085 enum { DR_PING = SF9 }; // default ping DR 00086 enum { CHNL_DNW2 = 5 }; 00087 enum { FREQ_DNW2 = EU868_F6 }; 00088 enum { DR_DNW2 = DR_SF9 }; // changed from LoRaWAN specification. 00089 // Default value is DR_SF12 00090 enum { CHNL_BCN = 5 }; 00091 enum { FREQ_BCN = EU868_F6 }; 00092 enum { DR_BCN = DR_SF9 }; 00093 enum { AIRTIME_BCN = 144384 }; // micros 00094 00095 enum { 00096 // Beacon frame format EU SF9 00097 OFF_BCN_NETID = 0, 00098 OFF_BCN_TIME = 3, 00099 OFF_BCN_CRC1 = 7, 00100 OFF_BCN_INFO = 8, 00101 OFF_BCN_LAT = 9, 00102 OFF_BCN_LON = 12, 00103 OFF_BCN_CRC2 = 15, 00104 LEN_BCN = 17 00105 }; 00106 00107 #elif defined(CFG_us915) // ========================================= 00108 00109 enum _dr_us915_t { DR_SF10=0, DR_SF9, DR_SF8, DR_SF7, DR_SF8C, DR_NONE, 00110 // Devices behind a router: 00111 DR_SF12CR=8, DR_SF11CR, DR_SF10CR, DR_SF9CR, DR_SF8CR, DR_SF7CR }; 00112 enum { DR_DFLTMIN = DR_SF8C }; 00113 enum { DR_PAGE = DR_PAGE_US915 }; 00114 00115 // Default frequency plan for US 915MHz 00116 enum { US915_125kHz_UPFBASE = 902300000, 00117 US915_125kHz_UPFSTEP = 200000, 00118 US915_500kHz_UPFBASE = 903000000, 00119 US915_500kHz_UPFSTEP = 1600000, 00120 US915_500kHz_DNFBASE = 923300000, 00121 US915_500kHz_DNFSTEP = 600000 00122 }; 00123 enum { US915_FREQ_MIN = 902000000, 00124 US915_FREQ_MAX = 928000000 }; 00125 00126 enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating) 00127 enum { FREQ_PING = US915_500kHz_DNFBASE + CHNL_PING*US915_500kHz_DNFSTEP }; // default ping freq 00128 enum { DR_PING = DR_SF10CR }; // default ping DR 00129 enum { CHNL_DNW2 = 0 }; 00130 enum { FREQ_DNW2 = US915_500kHz_DNFBASE + CHNL_DNW2*US915_500kHz_DNFSTEP }; 00131 enum { DR_DNW2 = DR_SF12CR }; 00132 enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme) 00133 enum { DR_BCN = DR_SF10CR }; 00134 enum { AIRTIME_BCN = 72192 }; // micros 00135 00136 enum { 00137 // Beacon frame format US SF10 00138 OFF_BCN_NETID = 0, 00139 OFF_BCN_TIME = 3, 00140 OFF_BCN_CRC1 = 7, 00141 OFF_BCN_INFO = 9, 00142 OFF_BCN_LAT = 10, 00143 OFF_BCN_LON = 13, 00144 OFF_BCN_RFU1 = 16, 00145 OFF_BCN_CRC2 = 17, 00146 LEN_BCN = 19 00147 }; 00148 00149 #endif // =================================================== 00150 00151 enum { 00152 // Join Request frame format 00153 OFF_JR_HDR = 0, 00154 OFF_JR_ARTEUI = 1, 00155 OFF_JR_DEVEUI = 9, 00156 OFF_JR_DEVNONCE = 17, 00157 OFF_JR_MIC = 19, 00158 LEN_JR = 23 00159 }; 00160 enum { 00161 // Join Accept frame format 00162 OFF_JA_HDR = 0, 00163 OFF_JA_ARTNONCE = 1, 00164 OFF_JA_NETID = 4, 00165 OFF_JA_DEVADDR = 7, 00166 OFF_JA_RFU = 11, 00167 OFF_JA_DLSET = 11, 00168 OFF_JA_RXDLY = 12, 00169 OFF_CFLIST = 13, 00170 LEN_JA = 17, 00171 LEN_JAEXT = 17+16 00172 }; 00173 enum { 00174 // Data frame format 00175 OFF_DAT_HDR = 0, 00176 OFF_DAT_ADDR = 1, 00177 OFF_DAT_FCT = 5, 00178 OFF_DAT_SEQNO = 6, 00179 OFF_DAT_OPTS = 8, 00180 }; 00181 enum { MAX_LEN_PAYLOAD = MAX_LEN_FRAME-(int)OFF_DAT_OPTS-4 }; 00182 enum { 00183 // Bitfields in frame format octet 00184 HDR_FTYPE = 0xE0, 00185 HDR_RFU = 0x1C, 00186 HDR_MAJOR = 0x03 00187 }; 00188 enum { HDR_FTYPE_DNFLAG = 0x20 }; // flags DN frame except for HDR_FTYPE_PROP 00189 enum { 00190 // Values of frame type bit field 00191 HDR_FTYPE_JREQ = 0x00, 00192 HDR_FTYPE_JACC = 0x20, 00193 HDR_FTYPE_DAUP = 0x40, // data (unconfirmed) up 00194 HDR_FTYPE_DADN = 0x60, // data (unconfirmed) dn 00195 HDR_FTYPE_DCUP = 0x80, // data confirmed up 00196 HDR_FTYPE_DCDN = 0xA0, // data confirmed dn 00197 HDR_FTYPE_REJOIN = 0xC0, // rejoin for roaming 00198 HDR_FTYPE_PROP = 0xE0 00199 }; 00200 enum { 00201 HDR_MAJOR_V1 = 0x00, 00202 }; 00203 enum { 00204 // Bitfields in frame control octet 00205 FCT_ADREN = 0x80, 00206 FCT_ADRARQ = 0x40, 00207 FCT_ACK = 0x20, 00208 FCT_MORE = 0x10, // also in DN direction: Class B indicator 00209 FCT_OPTLEN = 0x0F, 00210 }; 00211 enum { 00212 // In UP direction: signals class B enabled 00213 FCT_CLASSB = FCT_MORE 00214 }; 00215 enum { 00216 NWKID_MASK = (int)0xFE000000, 00217 NWKID_BITS = 7 00218 }; 00219 00220 // MAC uplink commands downwlink too 00221 enum { 00222 // Class A 00223 MCMD_LCHK_REQ = 0x02, // - link check request : - 00224 MCMD_LADR_ANS = 0x03, // - link ADR answer : u1:7-3:RFU, 3/2/1: pow/DR/Ch ACK 00225 MCMD_DCAP_ANS = 0x04, // - duty cycle answer : - 00226 MCMD_DN2P_ANS = 0x05, // - 2nd DN slot status : u1:7-2:RFU 1/0:datarate/channel ack 00227 MCMD_DEVS_ANS = 0x06, // - device status ans : u1:battery 0,1-254,255=?, u1:7-6:RFU,5-0:margin(-32..31) 00228 MCMD_SNCH_ANS = 0x07, // - set new channel : u1: 7-2=RFU, 1/0:DR/freq ACK 00229 // Class B 00230 MCMD_PING_IND = 0x10, // - pingability indic : u1: 7=RFU, 6-4:interval, 3-0:datarate 00231 MCMD_PING_ANS = 0x11, // - ack ping freq : u1: 7-1:RFU, 0:freq ok 00232 MCMD_BCNI_REQ = 0x12, // - next beacon start : - 00233 }; 00234 00235 // MAC downlink commands 00236 enum { 00237 // Class A 00238 MCMD_LCHK_ANS = 0x02, // link check answer : u1:margin 0-254,255=unknown margin / u1:gwcnt 00239 MCMD_LADR_REQ = 0x03, // link ADR request : u1:DR/TXPow, u2:chmask, u1:chpage/repeat 00240 MCMD_DCAP_REQ = 0x04, // duty cycle cap : u1:255 dead [7-4]:RFU, [3-0]:cap 2^-k 00241 MCMD_DN2P_SET = 0x05, // 2nd DN window param: u1:7-4:RFU/3-0:datarate, u3:freq 00242 MCMD_DEVS_REQ = 0x06, // device status req : - 00243 MCMD_SNCH_REQ = 0x07, // set new channel : u1:chidx, u3:freq, u1:DRrange 00244 // Class B 00245 MCMD_PING_SET = 0x11, // set ping freq : u3: freq 00246 MCMD_BCNI_ANS = 0x12, // next beacon start : u2: delay(in TUNIT millis), u1:channel 00247 }; 00248 00249 enum { 00250 MCMD_BCNI_TUNIT = 30 // time unit of delay value in millis 00251 }; 00252 enum { 00253 MCMD_LADR_ANS_RFU = 0xF8, // RFU bits 00254 MCMD_LADR_ANS_POWACK = 0x04, // 0=not supported power level 00255 MCMD_LADR_ANS_DRACK = 0x02, // 0=unknown data rate 00256 MCMD_LADR_ANS_CHACK = 0x01, // 0=unknown channel enabled 00257 }; 00258 enum { 00259 MCMD_DN2P_ANS_RFU = 0xFC, // RFU bits 00260 MCMD_DN2P_ANS_DRACK = 0x02, // 0=unknown data rate 00261 MCMD_DN2P_ANS_CHACK = 0x01, // 0=unknown channel enabled 00262 }; 00263 enum { 00264 MCMD_SNCH_ANS_RFU = 0xFC, // RFU bits 00265 MCMD_SNCH_ANS_DRACK = 0x02, // 0=unknown data rate 00266 MCMD_SNCH_ANS_FQACK = 0x01, // 0=rejected channel frequency 00267 }; 00268 enum { 00269 MCMD_PING_ANS_RFU = 0xFE, 00270 MCMD_PING_ANS_FQACK = 0x01 00271 }; 00272 00273 enum { 00274 MCMD_DEVS_EXT_POWER = 0x00, // external power supply 00275 MCMD_DEVS_BATT_MIN = 0x01, // min battery value 00276 MCMD_DEVS_BATT_MAX = 0xFE, // max battery value 00277 MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level 00278 }; 00279 00280 // Bit fields byte#3 of MCMD_LADR_REQ payload 00281 enum { 00282 MCMD_LADR_CHP_125ON = 0x60, // special channel page enable, bits applied to 64..71 00283 MCMD_LADR_CHP_125OFF = 0x70, // ditto 00284 MCMD_LADR_N3RFU_MASK = 0x80, 00285 MCMD_LADR_CHPAGE_MASK = 0xF0, 00286 MCMD_LADR_REPEAT_MASK = 0x0F, 00287 MCMD_LADR_REPEAT_1 = 0x01, 00288 MCMD_LADR_CHPAGE_1 = 0x10 00289 }; 00290 // Bit fields byte#0 of MCMD_LADR_REQ payload 00291 enum { 00292 MCMD_LADR_DR_MASK = 0xF0, 00293 MCMD_LADR_POW_MASK = 0x0F, 00294 MCMD_LADR_DR_SHIFT = 4, 00295 MCMD_LADR_POW_SHIFT = 0, 00296 #if defined(CFG_eu868) 00297 MCMD_LADR_SF12 = DR_SF12<<4, 00298 MCMD_LADR_SF11 = DR_SF11<<4, 00299 MCMD_LADR_SF10 = DR_SF10<<4, 00300 MCMD_LADR_SF9 = DR_SF9 <<4, 00301 MCMD_LADR_SF8 = DR_SF8 <<4, 00302 MCMD_LADR_SF7 = DR_SF7 <<4, 00303 MCMD_LADR_SF7B = DR_SF7B<<4, 00304 MCMD_LADR_FSK = DR_FSK <<4, 00305 00306 MCMD_LADR_20dBm = 0, 00307 MCMD_LADR_14dBm = 1, 00308 MCMD_LADR_11dBm = 2, 00309 MCMD_LADR_8dBm = 3, 00310 MCMD_LADR_5dBm = 4, 00311 MCMD_LADR_2dBm = 5, 00312 #elif defined(CFG_us915) 00313 MCMD_LADR_SF10 = DR_SF10<<4, 00314 MCMD_LADR_SF9 = DR_SF9 <<4, 00315 MCMD_LADR_SF8 = DR_SF8 <<4, 00316 MCMD_LADR_SF7 = DR_SF7 <<4, 00317 MCMD_LADR_SF8C = DR_SF8C<<4, 00318 MCMD_LADR_SF12CR = DR_SF12CR<<4, 00319 MCMD_LADR_SF11CR = DR_SF11CR<<4, 00320 MCMD_LADR_SF10CR = DR_SF10CR<<4, 00321 MCMD_LADR_SF9CR = DR_SF9CR<<4, 00322 MCMD_LADR_SF8CR = DR_SF8CR<<4, 00323 MCMD_LADR_SF7CR = DR_SF7CR<<4, 00324 00325 MCMD_LADR_30dBm = 0, 00326 MCMD_LADR_28dBm = 1, 00327 MCMD_LADR_26dBm = 2, 00328 MCMD_LADR_24dBm = 3, 00329 MCMD_LADR_22dBm = 4, 00330 MCMD_LADR_20dBm = 5, 00331 MCMD_LADR_18dBm = 6, 00332 MCMD_LADR_16dBm = 7, 00333 MCMD_LADR_14dBm = 8, 00334 MCMD_LADR_12dBm = 9, 00335 MCMD_LADR_10dBm = 10 00336 #endif 00337 }; 00338 00339 // Device address 00340 typedef u4_t devaddr_t; 00341 00342 // RX quality (device) 00343 enum { RSSI_OFF=64, SNR_SCALEUP=4 }; 00344 00345 inline sf_t getSf (rps_t params) { return (sf_t)(params & 0x7); } 00346 inline rps_t setSf (rps_t params, sf_t sf) { return (rps_t)((params & ~0x7) | sf); } 00347 inline bw_t getBw (rps_t params) { return (bw_t)((params >> 3) & 0x3); } 00348 inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); } 00349 inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); } 00350 inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); } 00351 inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); } 00352 inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); } 00353 inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); } 00354 inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); } 00355 inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) { 00356 return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8); 00357 } 00358 #define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8))) 00359 // Two frames with params r1/r2 would interfere on air: same SFx + BWx 00360 inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; } 00361 00362 extern const u1_t _DR2RPS_CRC[]; 00363 inline rps_t updr2rps (dr_t dr) { return (rps_t)_DR2RPS_CRC[dr+1]; } 00364 inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); } 00365 inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; } 00366 inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; } 00367 inline dr_t incDR (dr_t dr) { return _DR2RPS_CRC[dr+2]==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate 00368 inline dr_t decDR (dr_t dr) { return _DR2RPS_CRC[dr ]==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate 00369 inline dr_t assertDR (dr_t dr) { return _DR2RPS_CRC[dr+1]==ILLEGAL_RPS ? DR_DFLTMIN : dr; } // force into a valid DR 00370 inline bit_t validDR (dr_t dr) { return _DR2RPS_CRC[dr+1]!=ILLEGAL_RPS; } // in range 00371 inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; } // decrease data rate by n steps 00372 00373 // 00374 // BEG: Keep in sync with lorabase.hpp 00375 // ================================================================================ 00376 00377 00378 // Convert between dBm values and power codes (MCMD_LADR_XdBm) 00379 s1_t pow2dBm (u1_t mcmd_ladr_p1); 00380 // Calculate airtime 00381 ostime_t calcAirTime (rps_t rps, u1_t plen); 00382 // Sensitivity at given SF/BW 00383 int getSensitivity (rps_t rps); 00384 00385 00386 #endif // _lorabase_h_
Generated on Thu Jul 14 2022 20:56:52 by 1.7.2