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_MOTE_L152RC by
lorabase.h@13:097c74da6ffe, 2016-08-11 (annotated)
- Committer:
- dkjendal
- Date:
- Thu Aug 11 15:45:21 2016 +0000
- Revision:
- 13:097c74da6ffe
- Parent:
- 0:f2716e543d97
Fix ADR channel mask handling
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| dudmuck | 0:f2716e543d97 | 1 | /******************************************************************************* |
| dudmuck | 0:f2716e543d97 | 2 | * Copyright (c) 2014-2015 IBM Corporation. |
| dudmuck | 0:f2716e543d97 | 3 | * All rights reserved. This program and the accompanying materials |
| dudmuck | 0:f2716e543d97 | 4 | * are made available under the terms of the Eclipse Public License v1.0 |
| dudmuck | 0:f2716e543d97 | 5 | * which accompanies this distribution, and is available at |
| dudmuck | 0:f2716e543d97 | 6 | * http://www.eclipse.org/legal/epl-v10.html |
| dudmuck | 0:f2716e543d97 | 7 | * |
| dudmuck | 0:f2716e543d97 | 8 | * Contributors: |
| dudmuck | 0:f2716e543d97 | 9 | * IBM Zurich Research Lab - initial API, implementation and documentation |
| dudmuck | 0:f2716e543d97 | 10 | *******************************************************************************/ |
| dudmuck | 0:f2716e543d97 | 11 | |
| dudmuck | 0:f2716e543d97 | 12 | #ifndef _lorabase_h_ |
| dudmuck | 0:f2716e543d97 | 13 | #define _lorabase_h_ |
| dudmuck | 0:f2716e543d97 | 14 | |
| dudmuck | 0:f2716e543d97 | 15 | #include "config.h" |
| dudmuck | 0:f2716e543d97 | 16 | // ================================================================================ |
| dudmuck | 0:f2716e543d97 | 17 | // BEG: Keep in sync with lorabase.hpp |
| dudmuck | 0:f2716e543d97 | 18 | // |
| dudmuck | 0:f2716e543d97 | 19 | |
| dudmuck | 0:f2716e543d97 | 20 | enum _cr_t { CR_4_5=0, CR_4_6, CR_4_7, CR_4_8 }; |
| dudmuck | 0:f2716e543d97 | 21 | enum _sf_t { FSK=0, SF7, SF8, SF9, SF10, SF11, SF12, SFrfu }; |
| dudmuck | 0:f2716e543d97 | 22 | enum _bw_t { BW125=0, BW250, BW500, BWrfu }; |
| dudmuck | 0:f2716e543d97 | 23 | typedef u1_t cr_t; |
| dudmuck | 0:f2716e543d97 | 24 | typedef u1_t sf_t; |
| dudmuck | 0:f2716e543d97 | 25 | typedef u1_t bw_t; |
| dudmuck | 0:f2716e543d97 | 26 | typedef u1_t dr_t; |
| dudmuck | 0:f2716e543d97 | 27 | // Radio parameter set (encodes SF/BW/CR/IH/NOCRC) |
| dudmuck | 0:f2716e543d97 | 28 | typedef u2_t rps_t; |
| dudmuck | 0:f2716e543d97 | 29 | TYPEDEF_xref2rps_t; |
| dudmuck | 0:f2716e543d97 | 30 | |
| dudmuck | 0:f2716e543d97 | 31 | enum { ILLEGAL_RPS = 0xFF }; |
| dudmuck | 0:f2716e543d97 | 32 | enum { DR_PAGE_EU868 = 0x00 }; |
| dudmuck | 0:f2716e543d97 | 33 | enum { DR_PAGE_US915 = 0x10 }; |
| dudmuck | 0:f2716e543d97 | 34 | |
| dudmuck | 0:f2716e543d97 | 35 | // Global maximum frame length |
| dudmuck | 0:f2716e543d97 | 36 | enum { STD_PREAMBLE_LEN = 8 }; |
| dudmuck | 0:f2716e543d97 | 37 | enum { MAX_LEN_FRAME = 64 }; |
| dudmuck | 0:f2716e543d97 | 38 | enum { LEN_DEVNONCE = 2 }; |
| dudmuck | 0:f2716e543d97 | 39 | enum { LEN_ARTNONCE = 3 }; |
| dudmuck | 0:f2716e543d97 | 40 | enum { LEN_NETID = 3 }; |
| dudmuck | 0:f2716e543d97 | 41 | enum { DELAY_JACC1 = 5 }; // in secs |
| dudmuck | 0:f2716e543d97 | 42 | enum { DELAY_DNW1 = 1 }; // in secs down window #1 |
| dudmuck | 0:f2716e543d97 | 43 | enum { DELAY_EXTDNW2 = 1 }; // in secs |
| dudmuck | 0:f2716e543d97 | 44 | enum { DELAY_JACC2 = DELAY_JACC1+(int)DELAY_EXTDNW2 }; // in secs |
| dudmuck | 0:f2716e543d97 | 45 | enum { DELAY_DNW2 = DELAY_DNW1 +(int)DELAY_EXTDNW2 }; // in secs down window #1 |
| dudmuck | 0:f2716e543d97 | 46 | enum { BCN_INTV_exp = 7 }; |
| dudmuck | 0:f2716e543d97 | 47 | enum { BCN_INTV_sec = 1<<BCN_INTV_exp }; |
| dudmuck | 0:f2716e543d97 | 48 | enum { BCN_INTV_ms = BCN_INTV_sec*1000L }; |
| dudmuck | 0:f2716e543d97 | 49 | enum { BCN_INTV_us = BCN_INTV_ms*1000L }; |
| dudmuck | 0:f2716e543d97 | 50 | enum { BCN_RESERVE_ms = 2120 }; // space reserved for beacon and NWK management |
| dudmuck | 0:f2716e543d97 | 51 | enum { BCN_GUARD_ms = 3000 }; // end of beacon period to prevent interference with beacon |
| dudmuck | 0:f2716e543d97 | 52 | enum { BCN_SLOT_SPAN_ms = 30 }; // 2^12 reception slots a this span |
| dudmuck | 0:f2716e543d97 | 53 | enum { BCN_WINDOW_ms = BCN_INTV_ms-(int)BCN_GUARD_ms-(int)BCN_RESERVE_ms }; |
| dudmuck | 0:f2716e543d97 | 54 | enum { BCN_RESERVE_us = 2120000 }; |
| dudmuck | 0:f2716e543d97 | 55 | enum { BCN_GUARD_us = 3000000 }; |
| dudmuck | 0:f2716e543d97 | 56 | enum { BCN_SLOT_SPAN_us = 30000 }; |
| dudmuck | 0:f2716e543d97 | 57 | |
| dudmuck | 0:f2716e543d97 | 58 | #if defined(CFG_eu868) // ============================================== |
| dudmuck | 0:f2716e543d97 | 59 | |
| dudmuck | 0:f2716e543d97 | 60 | enum _dr_eu868_t { DR_SF12=0, DR_SF11, DR_SF10, DR_SF9, DR_SF8, DR_SF7, DR_SF7B, DR_FSK, DR_NONE }; |
| dudmuck | 0:f2716e543d97 | 61 | enum { DR_DFLTMIN = DR_SF7 }; |
| dudmuck | 0:f2716e543d97 | 62 | enum { DR_PAGE = DR_PAGE_EU868 }; |
| dudmuck | 0:f2716e543d97 | 63 | |
| dudmuck | 0:f2716e543d97 | 64 | // Default frequency plan for EU 868MHz ISM band |
| dudmuck | 0:f2716e543d97 | 65 | // Bands: |
| dudmuck | 0:f2716e543d97 | 66 | // g1 : 1% 14dBm |
| dudmuck | 0:f2716e543d97 | 67 | // g2 : 0.1% 14dBm |
| dudmuck | 0:f2716e543d97 | 68 | // g3 : 10% 27dBm |
| dudmuck | 0:f2716e543d97 | 69 | // freq band datarates |
| dudmuck | 0:f2716e543d97 | 70 | enum { EU868_F1 = 868100000, // g1 SF7-12 |
| dudmuck | 0:f2716e543d97 | 71 | EU868_F2 = 868300000, // g1 SF7-12 FSK SF7/250 |
| dudmuck | 0:f2716e543d97 | 72 | EU868_F3 = 868500000, // g1 SF7-12 |
| dudmuck | 0:f2716e543d97 | 73 | EU868_F4 = 868850000, // g2 SF7-12 |
| dudmuck | 0:f2716e543d97 | 74 | EU868_F5 = 869050000, // g2 SF7-12 |
| dudmuck | 0:f2716e543d97 | 75 | EU868_F6 = 869525000, // g3 SF7-12 |
| dudmuck | 0:f2716e543d97 | 76 | EU868_J4 = 864100000, // g2 SF7-12 used during join |
| dudmuck | 0:f2716e543d97 | 77 | EU868_J5 = 864300000, // g2 SF7-12 ditto |
| dudmuck | 0:f2716e543d97 | 78 | EU868_J6 = 864500000, // g2 SF7-12 ditto |
| dudmuck | 0:f2716e543d97 | 79 | }; |
| dudmuck | 0:f2716e543d97 | 80 | enum { EU868_FREQ_MIN = 863000000, |
| dudmuck | 0:f2716e543d97 | 81 | EU868_FREQ_MAX = 870000000 }; |
| dudmuck | 0:f2716e543d97 | 82 | |
| dudmuck | 0:f2716e543d97 | 83 | enum { CHNL_PING = 5 }; |
| dudmuck | 0:f2716e543d97 | 84 | enum { FREQ_PING = EU868_F6 }; // default ping freq |
| dudmuck | 0:f2716e543d97 | 85 | enum { DR_PING = SF9 }; // default ping DR |
| dudmuck | 0:f2716e543d97 | 86 | enum { CHNL_DNW2 = 5 }; |
| dudmuck | 0:f2716e543d97 | 87 | enum { FREQ_DNW2 = EU868_F6 }; |
| dudmuck | 0:f2716e543d97 | 88 | enum { DR_DNW2 = DR_SF12 }; |
| dudmuck | 0:f2716e543d97 | 89 | enum { CHNL_BCN = 5 }; |
| dudmuck | 0:f2716e543d97 | 90 | enum { FREQ_BCN = EU868_F6 }; |
| dudmuck | 0:f2716e543d97 | 91 | enum { DR_BCN = DR_SF9 }; |
| dudmuck | 0:f2716e543d97 | 92 | enum { AIRTIME_BCN = 144384 }; // micros |
| dudmuck | 0:f2716e543d97 | 93 | |
| dudmuck | 0:f2716e543d97 | 94 | enum { |
| dudmuck | 0:f2716e543d97 | 95 | // Beacon frame format EU SF9 |
| dudmuck | 0:f2716e543d97 | 96 | OFF_BCN_NETID = 0, |
| dudmuck | 0:f2716e543d97 | 97 | OFF_BCN_TIME = 3, |
| dudmuck | 0:f2716e543d97 | 98 | OFF_BCN_CRC1 = 7, |
| dudmuck | 0:f2716e543d97 | 99 | OFF_BCN_INFO = 8, |
| dudmuck | 0:f2716e543d97 | 100 | OFF_BCN_LAT = 9, |
| dudmuck | 0:f2716e543d97 | 101 | OFF_BCN_LON = 12, |
| dudmuck | 0:f2716e543d97 | 102 | OFF_BCN_CRC2 = 15, |
| dudmuck | 0:f2716e543d97 | 103 | LEN_BCN = 17 |
| dudmuck | 0:f2716e543d97 | 104 | }; |
| dudmuck | 0:f2716e543d97 | 105 | |
| dudmuck | 0:f2716e543d97 | 106 | #elif defined(CFG_us915) // ========================================= |
| dudmuck | 0:f2716e543d97 | 107 | |
| dudmuck | 0:f2716e543d97 | 108 | enum _dr_us915_t { DR_SF10=0, DR_SF9, DR_SF8, DR_SF7, DR_SF8C, DR_NONE, |
| dudmuck | 0:f2716e543d97 | 109 | // Devices behind a router: |
| dudmuck | 0:f2716e543d97 | 110 | DR_SF12CR=8, DR_SF11CR, DR_SF10CR, DR_SF9CR, DR_SF8CR, DR_SF7CR }; |
| dudmuck | 0:f2716e543d97 | 111 | enum { DR_DFLTMIN = DR_SF8C }; |
| dudmuck | 0:f2716e543d97 | 112 | enum { DR_PAGE = DR_PAGE_US915 }; |
| dudmuck | 0:f2716e543d97 | 113 | |
| dudmuck | 0:f2716e543d97 | 114 | // Default frequency plan for US 915MHz |
| dudmuck | 0:f2716e543d97 | 115 | enum { US915_125kHz_UPFBASE = 902300000, |
| dudmuck | 0:f2716e543d97 | 116 | US915_125kHz_UPFSTEP = 200000, |
| dudmuck | 0:f2716e543d97 | 117 | US915_500kHz_UPFBASE = 903000000, |
| dudmuck | 0:f2716e543d97 | 118 | US915_500kHz_UPFSTEP = 1600000, |
| dudmuck | 0:f2716e543d97 | 119 | US915_500kHz_DNFBASE = 923300000, |
| dudmuck | 0:f2716e543d97 | 120 | US915_500kHz_DNFSTEP = 600000 |
| dudmuck | 0:f2716e543d97 | 121 | }; |
| dudmuck | 0:f2716e543d97 | 122 | enum { US915_FREQ_MIN = 902000000, |
| dudmuck | 0:f2716e543d97 | 123 | US915_FREQ_MAX = 928000000 }; |
| dudmuck | 0:f2716e543d97 | 124 | |
| dudmuck | 0:f2716e543d97 | 125 | enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating) |
| dudmuck | 0:f2716e543d97 | 126 | enum { FREQ_PING = US915_500kHz_DNFBASE + CHNL_PING*US915_500kHz_DNFSTEP }; // default ping freq |
| dudmuck | 0:f2716e543d97 | 127 | enum { DR_PING = DR_SF10CR }; // default ping DR |
| dudmuck | 0:f2716e543d97 | 128 | enum { CHNL_DNW2 = 0 }; |
| dudmuck | 0:f2716e543d97 | 129 | enum { FREQ_DNW2 = US915_500kHz_DNFBASE + CHNL_DNW2*US915_500kHz_DNFSTEP }; |
| dudmuck | 0:f2716e543d97 | 130 | enum { DR_DNW2 = DR_SF12CR }; |
| dudmuck | 0:f2716e543d97 | 131 | enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme) |
| dudmuck | 0:f2716e543d97 | 132 | enum { DR_BCN = DR_SF10CR }; |
| dudmuck | 0:f2716e543d97 | 133 | enum { AIRTIME_BCN = 72192 }; // micros |
| dudmuck | 0:f2716e543d97 | 134 | |
| dudmuck | 0:f2716e543d97 | 135 | enum { |
| dudmuck | 0:f2716e543d97 | 136 | // Beacon frame format US SF10 |
| dudmuck | 0:f2716e543d97 | 137 | OFF_BCN_NETID = 0, |
| dudmuck | 0:f2716e543d97 | 138 | OFF_BCN_TIME = 3, |
| dudmuck | 0:f2716e543d97 | 139 | OFF_BCN_CRC1 = 7, |
| dudmuck | 0:f2716e543d97 | 140 | OFF_BCN_INFO = 9, |
| dudmuck | 0:f2716e543d97 | 141 | OFF_BCN_LAT = 10, |
| dudmuck | 0:f2716e543d97 | 142 | OFF_BCN_LON = 13, |
| dudmuck | 0:f2716e543d97 | 143 | OFF_BCN_RFU1 = 16, |
| dudmuck | 0:f2716e543d97 | 144 | OFF_BCN_CRC2 = 17, |
| dudmuck | 0:f2716e543d97 | 145 | LEN_BCN = 19 |
| dudmuck | 0:f2716e543d97 | 146 | }; |
| dudmuck | 0:f2716e543d97 | 147 | |
| dudmuck | 0:f2716e543d97 | 148 | #endif // =================================================== |
| dudmuck | 0:f2716e543d97 | 149 | |
| dudmuck | 0:f2716e543d97 | 150 | enum { |
| dudmuck | 0:f2716e543d97 | 151 | // Join Request frame format |
| dudmuck | 0:f2716e543d97 | 152 | OFF_JR_HDR = 0, |
| dudmuck | 0:f2716e543d97 | 153 | OFF_JR_ARTEUI = 1, |
| dudmuck | 0:f2716e543d97 | 154 | OFF_JR_DEVEUI = 9, |
| dudmuck | 0:f2716e543d97 | 155 | OFF_JR_DEVNONCE = 17, |
| dudmuck | 0:f2716e543d97 | 156 | OFF_JR_MIC = 19, |
| dudmuck | 0:f2716e543d97 | 157 | LEN_JR = 23 |
| dudmuck | 0:f2716e543d97 | 158 | }; |
| dudmuck | 0:f2716e543d97 | 159 | enum { |
| dudmuck | 0:f2716e543d97 | 160 | // Join Accept frame format |
| dudmuck | 0:f2716e543d97 | 161 | OFF_JA_HDR = 0, |
| dudmuck | 0:f2716e543d97 | 162 | OFF_JA_ARTNONCE = 1, |
| dudmuck | 0:f2716e543d97 | 163 | OFF_JA_NETID = 4, |
| dudmuck | 0:f2716e543d97 | 164 | OFF_JA_DEVADDR = 7, |
| dudmuck | 0:f2716e543d97 | 165 | OFF_JA_RFU = 11, |
| dudmuck | 0:f2716e543d97 | 166 | OFF_JA_DLSET = 11, |
| dudmuck | 0:f2716e543d97 | 167 | OFF_JA_RXDLY = 12, |
| dudmuck | 0:f2716e543d97 | 168 | OFF_CFLIST = 13, |
| dudmuck | 0:f2716e543d97 | 169 | LEN_JA = 17, |
| dudmuck | 0:f2716e543d97 | 170 | LEN_JAEXT = 17+16 |
| dudmuck | 0:f2716e543d97 | 171 | }; |
| dudmuck | 0:f2716e543d97 | 172 | enum { |
| dudmuck | 0:f2716e543d97 | 173 | // Data frame format |
| dudmuck | 0:f2716e543d97 | 174 | OFF_DAT_HDR = 0, |
| dudmuck | 0:f2716e543d97 | 175 | OFF_DAT_ADDR = 1, |
| dudmuck | 0:f2716e543d97 | 176 | OFF_DAT_FCT = 5, |
| dudmuck | 0:f2716e543d97 | 177 | OFF_DAT_SEQNO = 6, |
| dudmuck | 0:f2716e543d97 | 178 | OFF_DAT_OPTS = 8, |
| dudmuck | 0:f2716e543d97 | 179 | }; |
| dudmuck | 0:f2716e543d97 | 180 | enum { MAX_LEN_PAYLOAD = MAX_LEN_FRAME-(int)OFF_DAT_OPTS-4 }; |
| dudmuck | 0:f2716e543d97 | 181 | enum { |
| dudmuck | 0:f2716e543d97 | 182 | // Bitfields in frame format octet |
| dudmuck | 0:f2716e543d97 | 183 | HDR_FTYPE = 0xE0, |
| dudmuck | 0:f2716e543d97 | 184 | HDR_RFU = 0x1C, |
| dudmuck | 0:f2716e543d97 | 185 | HDR_MAJOR = 0x03 |
| dudmuck | 0:f2716e543d97 | 186 | }; |
| dudmuck | 0:f2716e543d97 | 187 | enum { HDR_FTYPE_DNFLAG = 0x20 }; // flags DN frame except for HDR_FTYPE_PROP |
| dudmuck | 0:f2716e543d97 | 188 | enum { |
| dudmuck | 0:f2716e543d97 | 189 | // Values of frame type bit field |
| dudmuck | 0:f2716e543d97 | 190 | HDR_FTYPE_JREQ = 0x00, |
| dudmuck | 0:f2716e543d97 | 191 | HDR_FTYPE_JACC = 0x20, |
| dudmuck | 0:f2716e543d97 | 192 | HDR_FTYPE_DAUP = 0x40, // data (unconfirmed) up |
| dudmuck | 0:f2716e543d97 | 193 | HDR_FTYPE_DADN = 0x60, // data (unconfirmed) dn |
| dudmuck | 0:f2716e543d97 | 194 | HDR_FTYPE_DCUP = 0x80, // data confirmed up |
| dudmuck | 0:f2716e543d97 | 195 | HDR_FTYPE_DCDN = 0xA0, // data confirmed dn |
| dudmuck | 0:f2716e543d97 | 196 | HDR_FTYPE_REJOIN = 0xC0, // rejoin for roaming |
| dudmuck | 0:f2716e543d97 | 197 | HDR_FTYPE_PROP = 0xE0 |
| dudmuck | 0:f2716e543d97 | 198 | }; |
| dudmuck | 0:f2716e543d97 | 199 | enum { |
| dudmuck | 0:f2716e543d97 | 200 | HDR_MAJOR_V1 = 0x00, |
| dudmuck | 0:f2716e543d97 | 201 | }; |
| dudmuck | 0:f2716e543d97 | 202 | enum { |
| dudmuck | 0:f2716e543d97 | 203 | // Bitfields in frame control octet |
| dudmuck | 0:f2716e543d97 | 204 | FCT_ADREN = 0x80, |
| dudmuck | 0:f2716e543d97 | 205 | FCT_ADRARQ = 0x40, |
| dudmuck | 0:f2716e543d97 | 206 | FCT_ACK = 0x20, |
| dudmuck | 0:f2716e543d97 | 207 | FCT_MORE = 0x10, // also in DN direction: Class B indicator |
| dudmuck | 0:f2716e543d97 | 208 | FCT_OPTLEN = 0x0F, |
| dudmuck | 0:f2716e543d97 | 209 | }; |
| dudmuck | 0:f2716e543d97 | 210 | enum { |
| dudmuck | 0:f2716e543d97 | 211 | // In UP direction: signals class B enabled |
| dudmuck | 0:f2716e543d97 | 212 | FCT_CLASSB = FCT_MORE |
| dudmuck | 0:f2716e543d97 | 213 | }; |
| dudmuck | 0:f2716e543d97 | 214 | enum { |
| dudmuck | 0:f2716e543d97 | 215 | NWKID_MASK = (int)0xFE000000, |
| dudmuck | 0:f2716e543d97 | 216 | NWKID_BITS = 7 |
| dudmuck | 0:f2716e543d97 | 217 | }; |
| dudmuck | 0:f2716e543d97 | 218 | |
| dudmuck | 0:f2716e543d97 | 219 | // MAC uplink commands downwlink too |
| dudmuck | 0:f2716e543d97 | 220 | enum { |
| dudmuck | 0:f2716e543d97 | 221 | // Class A |
| dudmuck | 0:f2716e543d97 | 222 | MCMD_LCHK_REQ = 0x02, // - link check request : - |
| dudmuck | 0:f2716e543d97 | 223 | MCMD_LADR_ANS = 0x03, // - link ADR answer : u1:7-3:RFU, 3/2/1: pow/DR/Ch ACK |
| dudmuck | 0:f2716e543d97 | 224 | MCMD_DCAP_ANS = 0x04, // - duty cycle answer : - |
| dudmuck | 0:f2716e543d97 | 225 | MCMD_DN2P_ANS = 0x05, // - 2nd DN slot status : u1:7-2:RFU 1/0:datarate/channel ack |
| dudmuck | 0:f2716e543d97 | 226 | MCMD_DEVS_ANS = 0x06, // - device status ans : u1:battery 0,1-254,255=?, u1:7-6:RFU,5-0:margin(-32..31) |
| dudmuck | 0:f2716e543d97 | 227 | MCMD_SNCH_ANS = 0x07, // - set new channel : u1: 7-2=RFU, 1/0:DR/freq ACK |
| dudmuck | 0:f2716e543d97 | 228 | // Class B |
| dudmuck | 0:f2716e543d97 | 229 | MCMD_PING_IND = 0x10, // - pingability indic : u1: 7=RFU, 6-4:interval, 3-0:datarate |
| dudmuck | 0:f2716e543d97 | 230 | MCMD_PING_ANS = 0x11, // - ack ping freq : u1: 7-1:RFU, 0:freq ok |
| dudmuck | 0:f2716e543d97 | 231 | MCMD_BCNI_REQ = 0x12, // - next beacon start : - |
| dudmuck | 0:f2716e543d97 | 232 | }; |
| dudmuck | 0:f2716e543d97 | 233 | |
| dudmuck | 0:f2716e543d97 | 234 | // MAC downlink commands |
| dudmuck | 0:f2716e543d97 | 235 | enum { |
| dudmuck | 0:f2716e543d97 | 236 | // Class A |
| dudmuck | 0:f2716e543d97 | 237 | MCMD_LCHK_ANS = 0x02, // link check answer : u1:margin 0-254,255=unknown margin / u1:gwcnt |
| dudmuck | 0:f2716e543d97 | 238 | MCMD_LADR_REQ = 0x03, // link ADR request : u1:DR/TXPow, u2:chmask, u1:chpage/repeat |
| dudmuck | 0:f2716e543d97 | 239 | MCMD_DCAP_REQ = 0x04, // duty cycle cap : u1:255 dead [7-4]:RFU, [3-0]:cap 2^-k |
| dudmuck | 0:f2716e543d97 | 240 | MCMD_DN2P_SET = 0x05, // 2nd DN window param: u1:7-4:RFU/3-0:datarate, u3:freq |
| dudmuck | 0:f2716e543d97 | 241 | MCMD_DEVS_REQ = 0x06, // device status req : - |
| dudmuck | 0:f2716e543d97 | 242 | MCMD_SNCH_REQ = 0x07, // set new channel : u1:chidx, u3:freq, u1:DRrange |
| dudmuck | 0:f2716e543d97 | 243 | // Class B |
| dudmuck | 0:f2716e543d97 | 244 | MCMD_PING_SET = 0x11, // set ping freq : u3: freq |
| dudmuck | 0:f2716e543d97 | 245 | MCMD_BCNI_ANS = 0x12, // next beacon start : u2: delay(in TUNIT millis), u1:channel |
| dudmuck | 0:f2716e543d97 | 246 | }; |
| dudmuck | 0:f2716e543d97 | 247 | |
| dudmuck | 0:f2716e543d97 | 248 | enum { |
| dudmuck | 0:f2716e543d97 | 249 | MCMD_BCNI_TUNIT = 30 // time unit of delay value in millis |
| dudmuck | 0:f2716e543d97 | 250 | }; |
| dudmuck | 0:f2716e543d97 | 251 | enum { |
| dudmuck | 0:f2716e543d97 | 252 | MCMD_LADR_ANS_RFU = 0xF8, // RFU bits |
| dudmuck | 0:f2716e543d97 | 253 | MCMD_LADR_ANS_POWACK = 0x04, // 0=not supported power level |
| dudmuck | 0:f2716e543d97 | 254 | MCMD_LADR_ANS_DRACK = 0x02, // 0=unknown data rate |
| dudmuck | 0:f2716e543d97 | 255 | MCMD_LADR_ANS_CHACK = 0x01, // 0=unknown channel enabled |
| dudmuck | 0:f2716e543d97 | 256 | }; |
| dudmuck | 0:f2716e543d97 | 257 | enum { |
| dudmuck | 0:f2716e543d97 | 258 | MCMD_DN2P_ANS_RFU = 0xFC, // RFU bits |
| dudmuck | 0:f2716e543d97 | 259 | MCMD_DN2P_ANS_DRACK = 0x02, // 0=unknown data rate |
| dudmuck | 0:f2716e543d97 | 260 | MCMD_DN2P_ANS_CHACK = 0x01, // 0=unknown channel enabled |
| dudmuck | 0:f2716e543d97 | 261 | }; |
| dudmuck | 0:f2716e543d97 | 262 | enum { |
| dudmuck | 0:f2716e543d97 | 263 | MCMD_SNCH_ANS_RFU = 0xFC, // RFU bits |
| dudmuck | 0:f2716e543d97 | 264 | MCMD_SNCH_ANS_DRACK = 0x02, // 0=unknown data rate |
| dudmuck | 0:f2716e543d97 | 265 | MCMD_SNCH_ANS_FQACK = 0x01, // 0=rejected channel frequency |
| dudmuck | 0:f2716e543d97 | 266 | }; |
| dudmuck | 0:f2716e543d97 | 267 | enum { |
| dudmuck | 0:f2716e543d97 | 268 | MCMD_PING_ANS_RFU = 0xFE, |
| dudmuck | 0:f2716e543d97 | 269 | MCMD_PING_ANS_FQACK = 0x01 |
| dudmuck | 0:f2716e543d97 | 270 | }; |
| dudmuck | 0:f2716e543d97 | 271 | |
| dudmuck | 0:f2716e543d97 | 272 | enum { |
| dudmuck | 0:f2716e543d97 | 273 | MCMD_DEVS_EXT_POWER = 0x00, // external power supply |
| dudmuck | 0:f2716e543d97 | 274 | MCMD_DEVS_BATT_MIN = 0x01, // min battery value |
| dudmuck | 0:f2716e543d97 | 275 | MCMD_DEVS_BATT_MAX = 0xFE, // max battery value |
| dudmuck | 0:f2716e543d97 | 276 | MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level |
| dudmuck | 0:f2716e543d97 | 277 | }; |
| dudmuck | 0:f2716e543d97 | 278 | |
| dudmuck | 0:f2716e543d97 | 279 | // Bit fields byte#3 of MCMD_LADR_REQ payload |
| dudmuck | 0:f2716e543d97 | 280 | enum { |
| dudmuck | 0:f2716e543d97 | 281 | MCMD_LADR_CHP_125ON = 0x60, // special channel page enable, bits applied to 64..71 |
| dudmuck | 0:f2716e543d97 | 282 | MCMD_LADR_CHP_125OFF = 0x70, // ditto |
| dudmuck | 0:f2716e543d97 | 283 | MCMD_LADR_N3RFU_MASK = 0x80, |
| dudmuck | 0:f2716e543d97 | 284 | MCMD_LADR_CHPAGE_MASK = 0xF0, |
| dudmuck | 0:f2716e543d97 | 285 | MCMD_LADR_REPEAT_MASK = 0x0F, |
| dudmuck | 0:f2716e543d97 | 286 | MCMD_LADR_REPEAT_1 = 0x01, |
| dudmuck | 0:f2716e543d97 | 287 | MCMD_LADR_CHPAGE_1 = 0x10 |
| dudmuck | 0:f2716e543d97 | 288 | }; |
| dudmuck | 0:f2716e543d97 | 289 | // Bit fields byte#0 of MCMD_LADR_REQ payload |
| dudmuck | 0:f2716e543d97 | 290 | enum { |
| dudmuck | 0:f2716e543d97 | 291 | MCMD_LADR_DR_MASK = 0xF0, |
| dudmuck | 0:f2716e543d97 | 292 | MCMD_LADR_POW_MASK = 0x0F, |
| dudmuck | 0:f2716e543d97 | 293 | MCMD_LADR_DR_SHIFT = 4, |
| dudmuck | 0:f2716e543d97 | 294 | MCMD_LADR_POW_SHIFT = 0, |
| dudmuck | 0:f2716e543d97 | 295 | #if defined(CFG_eu868) |
| dudmuck | 0:f2716e543d97 | 296 | MCMD_LADR_SF12 = DR_SF12<<4, |
| dudmuck | 0:f2716e543d97 | 297 | MCMD_LADR_SF11 = DR_SF11<<4, |
| dudmuck | 0:f2716e543d97 | 298 | MCMD_LADR_SF10 = DR_SF10<<4, |
| dudmuck | 0:f2716e543d97 | 299 | MCMD_LADR_SF9 = DR_SF9 <<4, |
| dudmuck | 0:f2716e543d97 | 300 | MCMD_LADR_SF8 = DR_SF8 <<4, |
| dudmuck | 0:f2716e543d97 | 301 | MCMD_LADR_SF7 = DR_SF7 <<4, |
| dudmuck | 0:f2716e543d97 | 302 | MCMD_LADR_SF7B = DR_SF7B<<4, |
| dudmuck | 0:f2716e543d97 | 303 | MCMD_LADR_FSK = DR_FSK <<4, |
| dudmuck | 0:f2716e543d97 | 304 | |
| dudmuck | 0:f2716e543d97 | 305 | MCMD_LADR_20dBm = 0, |
| dudmuck | 0:f2716e543d97 | 306 | MCMD_LADR_14dBm = 1, |
| dudmuck | 0:f2716e543d97 | 307 | MCMD_LADR_11dBm = 2, |
| dudmuck | 0:f2716e543d97 | 308 | MCMD_LADR_8dBm = 3, |
| dudmuck | 0:f2716e543d97 | 309 | MCMD_LADR_5dBm = 4, |
| dudmuck | 0:f2716e543d97 | 310 | MCMD_LADR_2dBm = 5, |
| dudmuck | 0:f2716e543d97 | 311 | #elif defined(CFG_us915) |
| dudmuck | 0:f2716e543d97 | 312 | MCMD_LADR_SF10 = DR_SF10<<4, |
| dudmuck | 0:f2716e543d97 | 313 | MCMD_LADR_SF9 = DR_SF9 <<4, |
| dudmuck | 0:f2716e543d97 | 314 | MCMD_LADR_SF8 = DR_SF8 <<4, |
| dudmuck | 0:f2716e543d97 | 315 | MCMD_LADR_SF7 = DR_SF7 <<4, |
| dudmuck | 0:f2716e543d97 | 316 | MCMD_LADR_SF8C = DR_SF8C<<4, |
| dudmuck | 0:f2716e543d97 | 317 | MCMD_LADR_SF12CR = DR_SF12CR<<4, |
| dudmuck | 0:f2716e543d97 | 318 | MCMD_LADR_SF11CR = DR_SF11CR<<4, |
| dudmuck | 0:f2716e543d97 | 319 | MCMD_LADR_SF10CR = DR_SF10CR<<4, |
| dudmuck | 0:f2716e543d97 | 320 | MCMD_LADR_SF9CR = DR_SF9CR<<4, |
| dudmuck | 0:f2716e543d97 | 321 | MCMD_LADR_SF8CR = DR_SF8CR<<4, |
| dudmuck | 0:f2716e543d97 | 322 | MCMD_LADR_SF7CR = DR_SF7CR<<4, |
| dudmuck | 0:f2716e543d97 | 323 | |
| dudmuck | 0:f2716e543d97 | 324 | MCMD_LADR_30dBm = 0, |
| dudmuck | 0:f2716e543d97 | 325 | MCMD_LADR_28dBm = 1, |
| dudmuck | 0:f2716e543d97 | 326 | MCMD_LADR_26dBm = 2, |
| dudmuck | 0:f2716e543d97 | 327 | MCMD_LADR_24dBm = 3, |
| dudmuck | 0:f2716e543d97 | 328 | MCMD_LADR_22dBm = 4, |
| dudmuck | 0:f2716e543d97 | 329 | MCMD_LADR_20dBm = 5, |
| dudmuck | 0:f2716e543d97 | 330 | MCMD_LADR_18dBm = 6, |
| dudmuck | 0:f2716e543d97 | 331 | MCMD_LADR_16dBm = 7, |
| dudmuck | 0:f2716e543d97 | 332 | MCMD_LADR_14dBm = 8, |
| dudmuck | 0:f2716e543d97 | 333 | MCMD_LADR_12dBm = 9, |
| dudmuck | 0:f2716e543d97 | 334 | MCMD_LADR_10dBm = 10 |
| dudmuck | 0:f2716e543d97 | 335 | #endif |
| dudmuck | 0:f2716e543d97 | 336 | }; |
| dudmuck | 0:f2716e543d97 | 337 | |
| dudmuck | 0:f2716e543d97 | 338 | // Device address |
| dudmuck | 0:f2716e543d97 | 339 | typedef u4_t devaddr_t; |
| dudmuck | 0:f2716e543d97 | 340 | |
| dudmuck | 0:f2716e543d97 | 341 | // RX quality (device) |
| dudmuck | 0:f2716e543d97 | 342 | enum { RSSI_OFF=64, SNR_SCALEUP=4 }; |
| dudmuck | 0:f2716e543d97 | 343 | |
| dudmuck | 0:f2716e543d97 | 344 | inline sf_t getSf (rps_t params) { return (sf_t)(params & 0x7); } |
| dudmuck | 0:f2716e543d97 | 345 | inline rps_t setSf (rps_t params, sf_t sf) { return (rps_t)((params & ~0x7) | sf); } |
| dudmuck | 0:f2716e543d97 | 346 | inline bw_t getBw (rps_t params) { return (bw_t)((params >> 3) & 0x3); } |
| dudmuck | 0:f2716e543d97 | 347 | inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); } |
| dudmuck | 0:f2716e543d97 | 348 | inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); } |
| dudmuck | 0:f2716e543d97 | 349 | inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); } |
| dudmuck | 0:f2716e543d97 | 350 | inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); } |
| dudmuck | 0:f2716e543d97 | 351 | inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); } |
| dudmuck | 0:f2716e543d97 | 352 | inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); } |
| dudmuck | 0:f2716e543d97 | 353 | inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); } |
| dudmuck | 0:f2716e543d97 | 354 | inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) { |
| dudmuck | 0:f2716e543d97 | 355 | return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8); |
| dudmuck | 0:f2716e543d97 | 356 | } |
| dudmuck | 0:f2716e543d97 | 357 | #define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8))) |
| dudmuck | 0:f2716e543d97 | 358 | // Two frames with params r1/r2 would interfere on air: same SFx + BWx |
| dudmuck | 0:f2716e543d97 | 359 | inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; } |
| dudmuck | 0:f2716e543d97 | 360 | |
| dudmuck | 0:f2716e543d97 | 361 | extern const u1_t _DR2RPS_CRC[]; |
| dudmuck | 0:f2716e543d97 | 362 | inline rps_t updr2rps (dr_t dr) { return (rps_t)_DR2RPS_CRC[dr+1]; } |
| dudmuck | 0:f2716e543d97 | 363 | inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); } |
| dudmuck | 0:f2716e543d97 | 364 | inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; } |
| dudmuck | 0:f2716e543d97 | 365 | inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; } |
| dudmuck | 0:f2716e543d97 | 366 | inline dr_t incDR (dr_t dr) { return _DR2RPS_CRC[dr+2]==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate |
| dudmuck | 0:f2716e543d97 | 367 | inline dr_t decDR (dr_t dr) { return _DR2RPS_CRC[dr ]==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate |
| dudmuck | 0:f2716e543d97 | 368 | inline dr_t assertDR (dr_t dr) { return _DR2RPS_CRC[dr+1]==ILLEGAL_RPS ? DR_DFLTMIN : dr; } // force into a valid DR |
| dudmuck | 0:f2716e543d97 | 369 | inline bit_t validDR (dr_t dr) { return _DR2RPS_CRC[dr+1]!=ILLEGAL_RPS; } // in range |
| dudmuck | 0:f2716e543d97 | 370 | inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; } // decrease data rate by n steps |
| dudmuck | 0:f2716e543d97 | 371 | |
| dudmuck | 0:f2716e543d97 | 372 | // |
| dudmuck | 0:f2716e543d97 | 373 | // BEG: Keep in sync with lorabase.hpp |
| dudmuck | 0:f2716e543d97 | 374 | // ================================================================================ |
| dudmuck | 0:f2716e543d97 | 375 | |
| dudmuck | 0:f2716e543d97 | 376 | |
| dudmuck | 0:f2716e543d97 | 377 | // Convert between dBm values and power codes (MCMD_LADR_XdBm) |
| dudmuck | 0:f2716e543d97 | 378 | s1_t pow2dBm (u1_t mcmd_ladr_p1); |
| dudmuck | 0:f2716e543d97 | 379 | // Calculate airtime |
| dudmuck | 0:f2716e543d97 | 380 | ostime_t calcAirTime (rps_t rps, u1_t plen); |
| dudmuck | 0:f2716e543d97 | 381 | // Sensitivity at given SF/BW |
| dudmuck | 0:f2716e543d97 | 382 | int getSensitivity (rps_t rps); |
| dudmuck | 0:f2716e543d97 | 383 | |
| dudmuck | 0:f2716e543d97 | 384 | |
| dudmuck | 0:f2716e543d97 | 385 | #endif // _lorabase_h_ |

