LMiC LoRa Semtech + Nucleo

Dependents:   LoRaWAN-lmic-app

Fork of LMiC by Semtech

Committer:
mluis
Date:
Thu Jan 22 12:50:49 2015 +0000
Revision:
0:62d1edcc13d1
Child:
1:d3b7bde3995c
Porting of IBM LoRa MAC in C (LMiC) to the mbed platform.

Who changed what in which revision?

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