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