IBM LoRa MAC in C (LMiC) mbed library port

Dependents:   lora-temperature LoRaWAN-lmic-app_HS LoRaWAN-lmic-app_huynh

LoRa WAN in C for sx1276 shield

Currently version 1.5


LoRaWAN network configuration for end-device

The following three pieces of information uniquely identifies end-device to network to allow over-the-air activation. These are stored in the end-device prior to join procedure.

AppEUI

Uniquely identifies application provider of end-device.

Least-significant byte first, 8 bytes, use reverse memcpy() to keep same order as shown on lora server.

example C code

static const u1_t APPEUI[8]  = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0C, 0x25, 0x00 };

This is copied into LMIC by os_getArtEui() callback function in application.

DevEUI

End-device ID, unique to each end-node.

Least-significant byte first, 8 bytes, use reverse memcpy() to keep same order as shown on lora server.

example C code

static const u1_t DEVEUI[8]  = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x25, 0x00 }; 

This is copied into LMIC by os_getDevEui() callback function in application.

AppKey (aka DevKey)

128-bit (16byte) AES key.

example C code

static const u1_t DEVKEY[16] = { 0xe4, 0x72, 0x71, 0xc5, 0xf5, 0x30, 0xa9, 0x9f, 0xcf, 0xc4, 0x0e, 0xab, 0xea, 0xd7, 0x19, 0x42 };

This is copied into LMIC by os_getDevKey() callback function in application.

Using over-the air activation, the end-device (LMIC) performs a join procedure every time it starts for first time, or has lost session context information. When join procedure has successfully completed, the end-device will have a network session key (NwkSKey) and an application session key (AppSKey), which are used for encryption and message integrity check.


US915 configuration with http://us01-iot.semtech.com/

  • log in to server
  • click on Applications
  • find your application and click it
  • go to configure motes
  • to create a mote, you may enter a new DevEUI
    • you may copy-paste the 16byte application key from an already existing mote, if you desire.
CHNL_HYBRID125KHz500KHz
defined valuechannelschannel
00 to 764
18 to 1565
216 to 2366
324 to 3167
432 to 3968
540 to 4769
648 to 5570
756 to 6371
undef0 to 6364 to 71
Committer:
mluis
Date:
Thu Nov 26 17:17:08 2015 +0000
Revision:
4:85b2b647cb64
Parent:
2:974cafbfb159
Merged branches

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:62d1edcc13d1 1 /*******************************************************************************
mluis 1:d3b7bde3995c 2 * Copyright (c) 2014-2015 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 1:d3b7bde3995c 57 #if defined(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 };
dudmuck 2:974cafbfb159 87 enum { DR_DNW2 = DR_SF12 };
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 1:d3b7bde3995c 91 enum { AIRTIME_BCN = 144384 }; // micros
mluis 0:62d1edcc13d1 92
mluis 1:d3b7bde3995c 93 enum {
mluis 1:d3b7bde3995c 94 // Beacon frame format EU SF9
mluis 1:d3b7bde3995c 95 OFF_BCN_NETID = 0,
mluis 1:d3b7bde3995c 96 OFF_BCN_TIME = 3,
mluis 1:d3b7bde3995c 97 OFF_BCN_CRC1 = 7,
mluis 1:d3b7bde3995c 98 OFF_BCN_INFO = 8,
mluis 1:d3b7bde3995c 99 OFF_BCN_LAT = 9,
mluis 1:d3b7bde3995c 100 OFF_BCN_LON = 12,
mluis 1:d3b7bde3995c 101 OFF_BCN_CRC2 = 15,
mluis 1:d3b7bde3995c 102 LEN_BCN = 17
mluis 1:d3b7bde3995c 103 };
mluis 1:d3b7bde3995c 104
mluis 1:d3b7bde3995c 105 #elif defined(CFG_us915) // =========================================
mluis 0:62d1edcc13d1 106
mluis 0:62d1edcc13d1 107 enum _dr_us915_t { DR_SF10=0, DR_SF9, DR_SF8, DR_SF7, DR_SF8C, DR_NONE,
mluis 1:d3b7bde3995c 108 // Devices behind a router:
mluis 1:d3b7bde3995c 109 DR_SF12CR=8, DR_SF11CR, DR_SF10CR, DR_SF9CR, DR_SF8CR, DR_SF7CR };
mluis 0:62d1edcc13d1 110 enum { DR_DFLTMIN = DR_SF8C };
mluis 0:62d1edcc13d1 111 enum { DR_PAGE = DR_PAGE_US915 };
mluis 0:62d1edcc13d1 112
mluis 0:62d1edcc13d1 113 // Default frequency plan for US 915MHz
mluis 0:62d1edcc13d1 114 enum { US915_125kHz_UPFBASE = 902300000,
mluis 0:62d1edcc13d1 115 US915_125kHz_UPFSTEP = 200000,
mluis 0:62d1edcc13d1 116 US915_500kHz_UPFBASE = 903000000,
mluis 0:62d1edcc13d1 117 US915_500kHz_UPFSTEP = 1600000,
mluis 0:62d1edcc13d1 118 US915_500kHz_DNFBASE = 923300000,
mluis 0:62d1edcc13d1 119 US915_500kHz_DNFSTEP = 600000
mluis 0:62d1edcc13d1 120 };
mluis 0:62d1edcc13d1 121 enum { US915_FREQ_MIN = 902000000,
mluis 0:62d1edcc13d1 122 US915_FREQ_MAX = 928000000 };
mluis 0:62d1edcc13d1 123
mluis 1:d3b7bde3995c 124 enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating)
mluis 0:62d1edcc13d1 125 enum { FREQ_PING = US915_500kHz_DNFBASE + CHNL_PING*US915_500kHz_DNFSTEP }; // default ping freq
mluis 0:62d1edcc13d1 126 enum { DR_PING = DR_SF10CR }; // default ping DR
mluis 1:d3b7bde3995c 127 enum { CHNL_DNW2 = 0 };
mluis 0:62d1edcc13d1 128 enum { FREQ_DNW2 = US915_500kHz_DNFBASE + CHNL_DNW2*US915_500kHz_DNFSTEP };
mluis 1:d3b7bde3995c 129 enum { DR_DNW2 = DR_SF12CR };
mluis 1:d3b7bde3995c 130 enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme)
mluis 0:62d1edcc13d1 131 enum { DR_BCN = DR_SF10CR };
mluis 1:d3b7bde3995c 132 enum { AIRTIME_BCN = 72192 }; // micros
mluis 1:d3b7bde3995c 133
mluis 1:d3b7bde3995c 134 enum {
mluis 1:d3b7bde3995c 135 // Beacon frame format US SF10
mluis 1:d3b7bde3995c 136 OFF_BCN_NETID = 0,
mluis 1:d3b7bde3995c 137 OFF_BCN_TIME = 3,
mluis 1:d3b7bde3995c 138 OFF_BCN_CRC1 = 7,
mluis 1:d3b7bde3995c 139 OFF_BCN_INFO = 9,
mluis 1:d3b7bde3995c 140 OFF_BCN_LAT = 10,
mluis 1:d3b7bde3995c 141 OFF_BCN_LON = 13,
mluis 1:d3b7bde3995c 142 OFF_BCN_RFU1 = 16,
mluis 1:d3b7bde3995c 143 OFF_BCN_CRC2 = 17,
mluis 1:d3b7bde3995c 144 LEN_BCN = 19
mluis 1:d3b7bde3995c 145 };
mluis 0:62d1edcc13d1 146
mluis 0:62d1edcc13d1 147 #endif // ===================================================
mluis 0:62d1edcc13d1 148
mluis 0:62d1edcc13d1 149 enum {
mluis 0:62d1edcc13d1 150 // Join Request frame format
mluis 0:62d1edcc13d1 151 OFF_JR_HDR = 0,
mluis 0:62d1edcc13d1 152 OFF_JR_ARTEUI = 1,
mluis 0:62d1edcc13d1 153 OFF_JR_DEVEUI = 9,
mluis 0:62d1edcc13d1 154 OFF_JR_DEVNONCE = 17,
mluis 0:62d1edcc13d1 155 OFF_JR_MIC = 19,
mluis 0:62d1edcc13d1 156 LEN_JR = 23
mluis 0:62d1edcc13d1 157 };
mluis 0:62d1edcc13d1 158 enum {
mluis 0:62d1edcc13d1 159 // Join Accept frame format
mluis 0:62d1edcc13d1 160 OFF_JA_HDR = 0,
mluis 0:62d1edcc13d1 161 OFF_JA_ARTNONCE = 1,
mluis 0:62d1edcc13d1 162 OFF_JA_NETID = 4,
mluis 0:62d1edcc13d1 163 OFF_JA_DEVADDR = 7,
mluis 0:62d1edcc13d1 164 OFF_JA_RFU = 11,
mluis 1:d3b7bde3995c 165 OFF_JA_DLSET = 11,
mluis 1:d3b7bde3995c 166 OFF_JA_RXDLY = 12,
mluis 1:d3b7bde3995c 167 OFF_CFLIST = 13,
mluis 0:62d1edcc13d1 168 LEN_JA = 17,
mluis 0:62d1edcc13d1 169 LEN_JAEXT = 17+16
mluis 0:62d1edcc13d1 170 };
mluis 0:62d1edcc13d1 171 enum {
mluis 0:62d1edcc13d1 172 // Data frame format
mluis 0:62d1edcc13d1 173 OFF_DAT_HDR = 0,
mluis 0:62d1edcc13d1 174 OFF_DAT_ADDR = 1,
mluis 0:62d1edcc13d1 175 OFF_DAT_FCT = 5,
mluis 0:62d1edcc13d1 176 OFF_DAT_SEQNO = 6,
mluis 0:62d1edcc13d1 177 OFF_DAT_OPTS = 8,
mluis 0:62d1edcc13d1 178 };
mluis 0:62d1edcc13d1 179 enum { MAX_LEN_PAYLOAD = MAX_LEN_FRAME-(int)OFF_DAT_OPTS-4 };
mluis 0:62d1edcc13d1 180 enum {
mluis 0:62d1edcc13d1 181 // Bitfields in frame format octet
mluis 0:62d1edcc13d1 182 HDR_FTYPE = 0xE0,
mluis 0:62d1edcc13d1 183 HDR_RFU = 0x1C,
mluis 0:62d1edcc13d1 184 HDR_MAJOR = 0x03
mluis 0:62d1edcc13d1 185 };
mluis 0:62d1edcc13d1 186 enum { HDR_FTYPE_DNFLAG = 0x20 }; // flags DN frame except for HDR_FTYPE_PROP
mluis 0:62d1edcc13d1 187 enum {
mluis 0:62d1edcc13d1 188 // Values of frame type bit field
mluis 0:62d1edcc13d1 189 HDR_FTYPE_JREQ = 0x00,
mluis 0:62d1edcc13d1 190 HDR_FTYPE_JACC = 0x20,
mluis 0:62d1edcc13d1 191 HDR_FTYPE_DAUP = 0x40, // data (unconfirmed) up
mluis 0:62d1edcc13d1 192 HDR_FTYPE_DADN = 0x60, // data (unconfirmed) dn
mluis 0:62d1edcc13d1 193 HDR_FTYPE_DCUP = 0x80, // data confirmed up
mluis 0:62d1edcc13d1 194 HDR_FTYPE_DCDN = 0xA0, // data confirmed dn
mluis 0:62d1edcc13d1 195 HDR_FTYPE_REJOIN = 0xC0, // rejoin for roaming
mluis 0:62d1edcc13d1 196 HDR_FTYPE_PROP = 0xE0
mluis 0:62d1edcc13d1 197 };
mluis 0:62d1edcc13d1 198 enum {
mluis 0:62d1edcc13d1 199 HDR_MAJOR_V1 = 0x00,
mluis 0:62d1edcc13d1 200 };
mluis 0:62d1edcc13d1 201 enum {
mluis 0:62d1edcc13d1 202 // Bitfields in frame control octet
mluis 0:62d1edcc13d1 203 FCT_ADREN = 0x80,
mluis 0:62d1edcc13d1 204 FCT_ADRARQ = 0x40,
mluis 0:62d1edcc13d1 205 FCT_ACK = 0x20,
mluis 1:d3b7bde3995c 206 FCT_MORE = 0x10, // also in DN direction: Class B indicator
mluis 0:62d1edcc13d1 207 FCT_OPTLEN = 0x0F,
mluis 0:62d1edcc13d1 208 };
mluis 0:62d1edcc13d1 209 enum {
mluis 1:d3b7bde3995c 210 // In UP direction: signals class B enabled
mluis 1:d3b7bde3995c 211 FCT_CLASSB = FCT_MORE
mluis 1:d3b7bde3995c 212 };
mluis 1:d3b7bde3995c 213 enum {
mluis 0:62d1edcc13d1 214 NWKID_MASK = (int)0xFE000000,
mluis 0:62d1edcc13d1 215 NWKID_BITS = 7
mluis 0:62d1edcc13d1 216 };
mluis 0:62d1edcc13d1 217
mluis 0:62d1edcc13d1 218 // MAC uplink commands downwlink too
mluis 0:62d1edcc13d1 219 enum {
mluis 0:62d1edcc13d1 220 // Class A
mluis 0:62d1edcc13d1 221 MCMD_LCHK_REQ = 0x02, // - link check request : -
mluis 0:62d1edcc13d1 222 MCMD_LADR_ANS = 0x03, // - link ADR answer : u1:7-3:RFU, 3/2/1: pow/DR/Ch ACK
mluis 0:62d1edcc13d1 223 MCMD_DCAP_ANS = 0x04, // - duty cycle answer : -
mluis 0:62d1edcc13d1 224 MCMD_DN2P_ANS = 0x05, // - 2nd DN slot status : u1:7-2:RFU 1/0:datarate/channel ack
mluis 0:62d1edcc13d1 225 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 226 MCMD_SNCH_ANS = 0x07, // - set new channel : u1: 7-2=RFU, 1/0:DR/freq ACK
mluis 0:62d1edcc13d1 227 // Class B
mluis 0:62d1edcc13d1 228 MCMD_PING_IND = 0x10, // - pingability indic : u1: 7=RFU, 6-4:interval, 3-0:datarate
mluis 0:62d1edcc13d1 229 MCMD_PING_ANS = 0x11, // - ack ping freq : u1: 7-1:RFU, 0:freq ok
mluis 0:62d1edcc13d1 230 MCMD_BCNI_REQ = 0x12, // - next beacon start : -
mluis 0:62d1edcc13d1 231 };
mluis 0:62d1edcc13d1 232
mluis 0:62d1edcc13d1 233 // MAC downlink commands
mluis 0:62d1edcc13d1 234 enum {
mluis 0:62d1edcc13d1 235 // Class A
mluis 0:62d1edcc13d1 236 MCMD_LCHK_ANS = 0x02, // link check answer : u1:margin 0-254,255=unknown margin / u1:gwcnt
mluis 0:62d1edcc13d1 237 MCMD_LADR_REQ = 0x03, // link ADR request : u1:DR/TXPow, u2:chmask, u1:chpage/repeat
mluis 0:62d1edcc13d1 238 MCMD_DCAP_REQ = 0x04, // duty cycle cap : u1:255 dead [7-4]:RFU, [3-0]:cap 2^-k
mluis 0:62d1edcc13d1 239 MCMD_DN2P_SET = 0x05, // 2nd DN window param: u1:7-4:RFU/3-0:datarate, u3:freq
mluis 0:62d1edcc13d1 240 MCMD_DEVS_REQ = 0x06, // device status req : -
mluis 0:62d1edcc13d1 241 MCMD_SNCH_REQ = 0x07, // set new channel : u1:chidx, u3:freq, u1:DRrange
mluis 0:62d1edcc13d1 242 // Class B
mluis 0:62d1edcc13d1 243 MCMD_PING_SET = 0x11, // set ping freq : u3: freq
mluis 1:d3b7bde3995c 244 MCMD_BCNI_ANS = 0x12, // next beacon start : u2: delay(in TUNIT millis), u1:channel
mluis 0:62d1edcc13d1 245 };
mluis 0:62d1edcc13d1 246
mluis 0:62d1edcc13d1 247 enum {
mluis 1:d3b7bde3995c 248 MCMD_BCNI_TUNIT = 30 // time unit of delay value in millis
mluis 1:d3b7bde3995c 249 };
mluis 1:d3b7bde3995c 250 enum {
mluis 0:62d1edcc13d1 251 MCMD_LADR_ANS_RFU = 0xF8, // RFU bits
mluis 0:62d1edcc13d1 252 MCMD_LADR_ANS_POWACK = 0x04, // 0=not supported power level
mluis 0:62d1edcc13d1 253 MCMD_LADR_ANS_DRACK = 0x02, // 0=unknown data rate
mluis 0:62d1edcc13d1 254 MCMD_LADR_ANS_CHACK = 0x01, // 0=unknown channel enabled
mluis 0:62d1edcc13d1 255 };
mluis 0:62d1edcc13d1 256 enum {
mluis 0:62d1edcc13d1 257 MCMD_DN2P_ANS_RFU = 0xFC, // RFU bits
mluis 0:62d1edcc13d1 258 MCMD_DN2P_ANS_DRACK = 0x02, // 0=unknown data rate
mluis 0:62d1edcc13d1 259 MCMD_DN2P_ANS_CHACK = 0x01, // 0=unknown channel enabled
mluis 0:62d1edcc13d1 260 };
mluis 0:62d1edcc13d1 261 enum {
mluis 0:62d1edcc13d1 262 MCMD_SNCH_ANS_RFU = 0xFC, // RFU bits
mluis 0:62d1edcc13d1 263 MCMD_SNCH_ANS_DRACK = 0x02, // 0=unknown data rate
mluis 0:62d1edcc13d1 264 MCMD_SNCH_ANS_FQACK = 0x01, // 0=rejected channel frequency
mluis 0:62d1edcc13d1 265 };
mluis 0:62d1edcc13d1 266 enum {
mluis 0:62d1edcc13d1 267 MCMD_PING_ANS_RFU = 0xFE,
mluis 0:62d1edcc13d1 268 MCMD_PING_ANS_FQACK = 0x01
mluis 0:62d1edcc13d1 269 };
mluis 0:62d1edcc13d1 270
mluis 0:62d1edcc13d1 271 enum {
mluis 0:62d1edcc13d1 272 MCMD_DEVS_EXT_POWER = 0x00, // external power supply
mluis 0:62d1edcc13d1 273 MCMD_DEVS_BATT_MIN = 0x01, // min battery value
mluis 0:62d1edcc13d1 274 MCMD_DEVS_BATT_MAX = 0xFE, // max battery value
mluis 0:62d1edcc13d1 275 MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level
mluis 0:62d1edcc13d1 276 };
mluis 0:62d1edcc13d1 277
mluis 0:62d1edcc13d1 278 // Bit fields byte#3 of MCMD_LADR_REQ payload
mluis 0:62d1edcc13d1 279 enum {
mluis 0:62d1edcc13d1 280 MCMD_LADR_CHP_125ON = 0x60, // special channel page enable, bits applied to 64..71
mluis 0:62d1edcc13d1 281 MCMD_LADR_CHP_125OFF = 0x70, // ditto
mluis 0:62d1edcc13d1 282 MCMD_LADR_N3RFU_MASK = 0x80,
mluis 0:62d1edcc13d1 283 MCMD_LADR_CHPAGE_MASK = 0xF0,
mluis 0:62d1edcc13d1 284 MCMD_LADR_REPEAT_MASK = 0x0F,
mluis 0:62d1edcc13d1 285 MCMD_LADR_REPEAT_1 = 0x01,
mluis 0:62d1edcc13d1 286 MCMD_LADR_CHPAGE_1 = 0x10
mluis 0:62d1edcc13d1 287 };
mluis 0:62d1edcc13d1 288 // Bit fields byte#0 of MCMD_LADR_REQ payload
mluis 0:62d1edcc13d1 289 enum {
mluis 0:62d1edcc13d1 290 MCMD_LADR_DR_MASK = 0xF0,
mluis 0:62d1edcc13d1 291 MCMD_LADR_POW_MASK = 0x0F,
mluis 0:62d1edcc13d1 292 MCMD_LADR_DR_SHIFT = 4,
mluis 0:62d1edcc13d1 293 MCMD_LADR_POW_SHIFT = 0,
mluis 1:d3b7bde3995c 294 #if defined(CFG_eu868)
mluis 0:62d1edcc13d1 295 MCMD_LADR_SF12 = DR_SF12<<4,
mluis 0:62d1edcc13d1 296 MCMD_LADR_SF11 = DR_SF11<<4,
mluis 0:62d1edcc13d1 297 MCMD_LADR_SF10 = DR_SF10<<4,
mluis 0:62d1edcc13d1 298 MCMD_LADR_SF9 = DR_SF9 <<4,
mluis 0:62d1edcc13d1 299 MCMD_LADR_SF8 = DR_SF8 <<4,
mluis 0:62d1edcc13d1 300 MCMD_LADR_SF7 = DR_SF7 <<4,
mluis 0:62d1edcc13d1 301 MCMD_LADR_SF7B = DR_SF7B<<4,
mluis 0:62d1edcc13d1 302 MCMD_LADR_FSK = DR_FSK <<4,
mluis 0:62d1edcc13d1 303
mluis 0:62d1edcc13d1 304 MCMD_LADR_20dBm = 0,
mluis 0:62d1edcc13d1 305 MCMD_LADR_14dBm = 1,
mluis 0:62d1edcc13d1 306 MCMD_LADR_11dBm = 2,
mluis 0:62d1edcc13d1 307 MCMD_LADR_8dBm = 3,
mluis 0:62d1edcc13d1 308 MCMD_LADR_5dBm = 4,
mluis 0:62d1edcc13d1 309 MCMD_LADR_2dBm = 5,
mluis 1:d3b7bde3995c 310 #elif defined(CFG_us915)
mluis 0:62d1edcc13d1 311 MCMD_LADR_SF10 = DR_SF10<<4,
mluis 0:62d1edcc13d1 312 MCMD_LADR_SF9 = DR_SF9 <<4,
mluis 0:62d1edcc13d1 313 MCMD_LADR_SF8 = DR_SF8 <<4,
mluis 0:62d1edcc13d1 314 MCMD_LADR_SF7 = DR_SF7 <<4,
mluis 0:62d1edcc13d1 315 MCMD_LADR_SF8C = DR_SF8C<<4,
mluis 0:62d1edcc13d1 316 MCMD_LADR_SF12CR = DR_SF12CR<<4,
mluis 0:62d1edcc13d1 317 MCMD_LADR_SF11CR = DR_SF11CR<<4,
mluis 0:62d1edcc13d1 318 MCMD_LADR_SF10CR = DR_SF10CR<<4,
mluis 0:62d1edcc13d1 319 MCMD_LADR_SF9CR = DR_SF9CR<<4,
mluis 0:62d1edcc13d1 320 MCMD_LADR_SF8CR = DR_SF8CR<<4,
mluis 0:62d1edcc13d1 321 MCMD_LADR_SF7CR = DR_SF7CR<<4,
mluis 0:62d1edcc13d1 322
mluis 0:62d1edcc13d1 323 MCMD_LADR_30dBm = 0,
mluis 0:62d1edcc13d1 324 MCMD_LADR_28dBm = 1,
mluis 0:62d1edcc13d1 325 MCMD_LADR_26dBm = 2,
mluis 0:62d1edcc13d1 326 MCMD_LADR_24dBm = 3,
mluis 0:62d1edcc13d1 327 MCMD_LADR_22dBm = 4,
mluis 0:62d1edcc13d1 328 MCMD_LADR_20dBm = 5,
mluis 0:62d1edcc13d1 329 MCMD_LADR_18dBm = 6,
mluis 0:62d1edcc13d1 330 MCMD_LADR_16dBm = 7,
mluis 0:62d1edcc13d1 331 MCMD_LADR_14dBm = 8,
mluis 0:62d1edcc13d1 332 MCMD_LADR_12dBm = 9,
mluis 0:62d1edcc13d1 333 MCMD_LADR_10dBm = 10
mluis 0:62d1edcc13d1 334 #endif
mluis 0:62d1edcc13d1 335 };
mluis 0:62d1edcc13d1 336
mluis 0:62d1edcc13d1 337 // Device address
mluis 0:62d1edcc13d1 338 typedef u4_t devaddr_t;
mluis 0:62d1edcc13d1 339
mluis 0:62d1edcc13d1 340 // RX quality (device)
mluis 0:62d1edcc13d1 341 enum { RSSI_OFF=64, SNR_SCALEUP=4 };
mluis 0:62d1edcc13d1 342
mluis 0:62d1edcc13d1 343 inline sf_t getSf (rps_t params) { return (sf_t)(params & 0x7); }
mluis 0:62d1edcc13d1 344 inline rps_t setSf (rps_t params, sf_t sf) { return (rps_t)((params & ~0x7) | sf); }
mluis 0:62d1edcc13d1 345 inline bw_t getBw (rps_t params) { return (bw_t)((params >> 3) & 0x3); }
mluis 0:62d1edcc13d1 346 inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); }
mluis 0:62d1edcc13d1 347 inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); }
mluis 0:62d1edcc13d1 348 inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); }
mluis 0:62d1edcc13d1 349 inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); }
mluis 0:62d1edcc13d1 350 inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); }
mluis 0:62d1edcc13d1 351 inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); }
mluis 0:62d1edcc13d1 352 inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); }
mluis 0:62d1edcc13d1 353 inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) {
mluis 0:62d1edcc13d1 354 return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8);
mluis 0:62d1edcc13d1 355 }
mluis 0:62d1edcc13d1 356 #define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8)))
mluis 0:62d1edcc13d1 357 // Two frames with params r1/r2 would interfere on air: same SFx + BWx
mluis 0:62d1edcc13d1 358 inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; }
mluis 0:62d1edcc13d1 359
mluis 0:62d1edcc13d1 360 extern const u1_t _DR2RPS_CRC[];
mluis 0:62d1edcc13d1 361 inline rps_t updr2rps (dr_t dr) { return (rps_t)_DR2RPS_CRC[dr+1]; }
mluis 0:62d1edcc13d1 362 inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); }
mluis 0:62d1edcc13d1 363 inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; }
mluis 0:62d1edcc13d1 364 inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; }
mluis 0:62d1edcc13d1 365 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 366 inline dr_t decDR (dr_t dr) { return _DR2RPS_CRC[dr ]==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate
mluis 0:62d1edcc13d1 367 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 368 inline bit_t validDR (dr_t dr) { return _DR2RPS_CRC[dr+1]!=ILLEGAL_RPS; } // in range
mluis 0:62d1edcc13d1 369 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 370
mluis 0:62d1edcc13d1 371 //
mluis 0:62d1edcc13d1 372 // BEG: Keep in sync with lorabase.hpp
mluis 0:62d1edcc13d1 373 // ================================================================================
mluis 0:62d1edcc13d1 374
mluis 0:62d1edcc13d1 375
mluis 0:62d1edcc13d1 376 // Convert between dBm values and power codes (MCMD_LADR_XdBm)
mluis 0:62d1edcc13d1 377 s1_t pow2dBm (u1_t mcmd_ladr_p1);
mluis 0:62d1edcc13d1 378 // Calculate airtime
mluis 0:62d1edcc13d1 379 ostime_t calcAirTime (rps_t rps, u1_t plen);
mluis 0:62d1edcc13d1 380 // Sensitivity at given SF/BW
mluis 0:62d1edcc13d1 381 int getSensitivity (rps_t rps);
mluis 0:62d1edcc13d1 382
mluis 0:62d1edcc13d1 383
mluis 0:62d1edcc13d1 384 #endif // _lorabase_h_