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:
Tue Mar 31 13:36:56 2015 +0000
Revision:
1:d3b7bde3995c
Parent:
0:62d1edcc13d1
Child:
2:974cafbfb159
Updated LMiC to release v1.4 (http://www.zurich.ibm.com/pdf/lrsc/lmic-release-v1.4.zip)

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