Fix ADR channel mask handling

Dependents:  

Fork of lmic_MOTE_L152RC by canuck lehead

Committer:
dkjendal
Date:
Thu Aug 25 16:53:47 2016 +0000
Revision:
14:f8a4a16a7df8
Parent:
8:0faa1bb768b5
Hybrid mode

Who changed what in which revision?

UserRevisionLine numberNew 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 //! @file
dudmuck 0:f2716e543d97 13 //! @brief LMIC API
dudmuck 0:f2716e543d97 14
dudmuck 0:f2716e543d97 15 #ifndef _lmic_h_
dudmuck 0:f2716e543d97 16 #define _lmic_h_
dudmuck 0:f2716e543d97 17
dudmuck 0:f2716e543d97 18 #include "oslmic.h"
dudmuck 0:f2716e543d97 19 #include "lorabase.h"
dudmuck 0:f2716e543d97 20
dudmuck 0:f2716e543d97 21 // LMIC version
dudmuck 0:f2716e543d97 22 #define LMIC_VERSION_MAJOR 1
dudmuck 0:f2716e543d97 23 #define LMIC_VERSION_MINOR 5
dudmuck 0:f2716e543d97 24 #define LMIC_VERSION_BUILD 1431528305
dudmuck 0:f2716e543d97 25
dudmuck 0:f2716e543d97 26 enum { MAX_FRAME_LEN = 64 }; //!< Library cap on max frame length
dudmuck 0:f2716e543d97 27 enum { TXCONF_ATTEMPTS = 8 }; //!< Transmit attempts for confirmed frames
dudmuck 0:f2716e543d97 28 enum { MAX_MISSED_BCNS = 20 }; // threshold for triggering rejoin requests
dudmuck 0:f2716e543d97 29 enum { MAX_RXSYMS = 100 }; // stop tracking beacon beyond this
dudmuck 0:f2716e543d97 30
dudmuck 0:f2716e543d97 31 enum { LINK_CHECK_CONT = 12 , // continue with this after reported dead link
dudmuck 0:f2716e543d97 32 LINK_CHECK_DEAD = 24 , // after this UP frames and no response from NWK assume link is dead
dudmuck 0:f2716e543d97 33 LINK_CHECK_INIT = -12 , // UP frame count until we inc datarate
dudmuck 0:f2716e543d97 34 LINK_CHECK_OFF =-128 }; // link check disabled
dudmuck 0:f2716e543d97 35
dudmuck 0:f2716e543d97 36 enum { TIME_RESYNC = 6*128 }; // secs
dudmuck 0:f2716e543d97 37 enum { TXRX_GUARD_ms = 6000 }; // msecs - don't start TX-RX transaction before beacon
dudmuck 0:f2716e543d97 38 enum { JOIN_GUARD_ms = 9000 }; // msecs - don't start Join Req/Acc transaction before beacon
dudmuck 0:f2716e543d97 39 enum { TXRX_BCNEXT_secs = 2 }; // secs - earliest start after beacon time
dudmuck 0:f2716e543d97 40 enum { RETRY_PERIOD_secs = 3 }; // secs - random period for retrying a confirmed send
dudmuck 0:f2716e543d97 41
dudmuck 0:f2716e543d97 42 #if defined(CFG_eu868) // EU868 spectrum ====================================================
dudmuck 0:f2716e543d97 43
dudmuck 0:f2716e543d97 44 enum { MAX_CHANNELS = 16 }; //!< Max supported channels
dudmuck 0:f2716e543d97 45 enum { MAX_BANDS = 4 };
dudmuck 0:f2716e543d97 46
dudmuck 0:f2716e543d97 47 enum { LIMIT_CHANNELS = (1<<4) }; // EU868 will never have more channels
dudmuck 0:f2716e543d97 48 //! \internal
dudmuck 0:f2716e543d97 49 struct band_t {
dudmuck 0:f2716e543d97 50 u2_t txcap; // duty cycle limitation: 1/txcap
dudmuck 0:f2716e543d97 51 s1_t txpow; // maximum TX power
dudmuck 0:f2716e543d97 52 u1_t lastchnl; // last used channel
dudmuck 0:f2716e543d97 53 ostime_t avail; // channel is blocked until this time
dudmuck 0:f2716e543d97 54 };
dudmuck 0:f2716e543d97 55 TYPEDEF_xref2band_t; //!< \internal
dudmuck 0:f2716e543d97 56
dudmuck 0:f2716e543d97 57 #elif defined(CFG_us915) // US915 spectrum =================================================
dudmuck 0:f2716e543d97 58
dudmuck 0:f2716e543d97 59 enum { MAX_XCHANNELS = 2 }; // extra channels in RAM, channels 0-71 are immutable
dudmuck 0:f2716e543d97 60 enum { MAX_TXPOW_125kHz = 30 };
dudmuck 0:f2716e543d97 61
dudmuck 0:f2716e543d97 62 #endif // ==========================================================================
dudmuck 0:f2716e543d97 63
dudmuck 0:f2716e543d97 64 // Keep in sync with evdefs.hpp::drChange
dudmuck 0:f2716e543d97 65 enum { DRCHG_SET, DRCHG_NOJACC, DRCHG_NOACK, DRCHG_NOADRACK, DRCHG_NWKCMD };
dudmuck 0:f2716e543d97 66 enum { KEEP_TXPOW = -128 };
dudmuck 0:f2716e543d97 67
dudmuck 0:f2716e543d97 68
dudmuck 0:f2716e543d97 69 //! \internal
dudmuck 0:f2716e543d97 70 struct rxsched_t {
dudmuck 0:f2716e543d97 71 u1_t dr;
dudmuck 0:f2716e543d97 72 u1_t intvExp; // 0..7
dudmuck 0:f2716e543d97 73 u1_t slot; // runs from 0 to 128
dudmuck 0:f2716e543d97 74 u1_t rxsyms;
dudmuck 0:f2716e543d97 75 ostime_t rxbase;
dudmuck 0:f2716e543d97 76 ostime_t rxtime; // start of next spot
dudmuck 0:f2716e543d97 77 u4_t freq;
dudmuck 0:f2716e543d97 78 };
dudmuck 0:f2716e543d97 79 TYPEDEF_xref2rxsched_t; //!< \internal
dudmuck 0:f2716e543d97 80
dudmuck 0:f2716e543d97 81
dudmuck 0:f2716e543d97 82 //! Parsing and tracking states of beacons.
dudmuck 0:f2716e543d97 83 enum { BCN_NONE = 0x00, //!< No beacon received
dudmuck 0:f2716e543d97 84 BCN_PARTIAL = 0x01, //!< Only first (common) part could be decoded (info,lat,lon invalid/previous)
dudmuck 0:f2716e543d97 85 BCN_FULL = 0x02, //!< Full beacon decoded
dudmuck 0:f2716e543d97 86 BCN_NODRIFT = 0x04, //!< No drift value measured yet
dudmuck 0:f2716e543d97 87 BCN_NODDIFF = 0x08 }; //!< No differential drift measured yet
dudmuck 0:f2716e543d97 88 //! Information about the last and previous beacons.
dudmuck 0:f2716e543d97 89 struct bcninfo_t {
dudmuck 0:f2716e543d97 90 ostime_t txtime; //!< Time when the beacon was sent
dudmuck 0:f2716e543d97 91 s1_t rssi; //!< Adjusted RSSI value of last received beacon
dudmuck 0:f2716e543d97 92 s1_t snr; //!< Scaled SNR value of last received beacon
dudmuck 0:f2716e543d97 93 u1_t flags; //!< Last beacon reception and tracking states. See BCN_* values.
dudmuck 0:f2716e543d97 94 u4_t time; //!< GPS time in seconds of last beacon (received or surrogate)
dudmuck 0:f2716e543d97 95 //
dudmuck 0:f2716e543d97 96 u1_t info; //!< Info field of last beacon (valid only if BCN_FULL set)
dudmuck 0:f2716e543d97 97 s4_t lat; //!< Lat field of last beacon (valid only if BCN_FULL set)
dudmuck 0:f2716e543d97 98 s4_t lon; //!< Lon field of last beacon (valid only if BCN_FULL set)
dudmuck 0:f2716e543d97 99 };
dudmuck 0:f2716e543d97 100
dudmuck 0:f2716e543d97 101 // purpose of receive window - lmic_t.rxState
dudmuck 0:f2716e543d97 102 enum { RADIO_RST=0, RADIO_TX=1, RADIO_RX=2, RADIO_RXON=3 };
dudmuck 0:f2716e543d97 103 // Netid values / lmic_t.netid
dudmuck 0:f2716e543d97 104 enum { NETID_NONE=(int)~0U, NETID_MASK=(int)0xFFFFFF };
dudmuck 0:f2716e543d97 105 // MAC operation modes (lmic_t.opmode).
dudmuck 0:f2716e543d97 106 enum { OP_NONE = 0x0000,
dudmuck 0:f2716e543d97 107 OP_SCAN = 0x0001, // radio scan to find a beacon
dudmuck 0:f2716e543d97 108 OP_TRACK = 0x0002, // track my networks beacon (netid)
dudmuck 0:f2716e543d97 109 OP_JOINING = 0x0004, // device joining in progress (blocks other activities)
dudmuck 0:f2716e543d97 110 OP_TXDATA = 0x0008, // TX user data (buffered in pendTxData)
dudmuck 0:f2716e543d97 111 OP_POLL = 0x0010, // send empty UP frame to ACK confirmed DN/fetch more DN data
dudmuck 0:f2716e543d97 112 OP_REJOIN = 0x0020, // occasionally send JOIN REQUEST
dudmuck 0:f2716e543d97 113 OP_SHUTDOWN = 0x0040, // prevent MAC from doing anything
dudmuck 0:f2716e543d97 114 OP_TXRXPEND = 0x0080, // TX/RX transaction pending
dudmuck 0:f2716e543d97 115 OP_RNDTX = 0x0100, // prevent TX lining up after a beacon
dudmuck 0:f2716e543d97 116 OP_PINGINI = 0x0200, // pingable is initialized and scheduling active
dudmuck 0:f2716e543d97 117 OP_PINGABLE = 0x0400, // we're pingable
dudmuck 0:f2716e543d97 118 OP_NEXTCHNL = 0x0800, // find a new channel
dudmuck 0:f2716e543d97 119 OP_LINKDEAD = 0x1000, // link was reported as dead
dudmuck 0:f2716e543d97 120 OP_TESTMODE = 0x2000, // developer test mode
dudmuck 0:f2716e543d97 121 };
dudmuck 0:f2716e543d97 122 // TX-RX transaction flags - report back to user
dudmuck 0:f2716e543d97 123 enum { TXRX_ACK = 0x80, // confirmed UP frame was acked
dudmuck 0:f2716e543d97 124 TXRX_NACK = 0x40, // confirmed UP frame was not acked
dudmuck 0:f2716e543d97 125 TXRX_NOPORT = 0x20, // set if a frame with a port was RXed, clr if no frame/no port
dudmuck 0:f2716e543d97 126 TXRX_PORT = 0x10, // set if a frame with a port was RXed, LMIC.frame[LMIC.dataBeg-1] => port
dudmuck 0:f2716e543d97 127 TXRX_DNW1 = 0x01, // received in 1st DN slot
dudmuck 0:f2716e543d97 128 TXRX_DNW2 = 0x02, // received in 2dn DN slot
dudmuck 0:f2716e543d97 129 TXRX_PING = 0x04 }; // received in a scheduled RX slot
dudmuck 0:f2716e543d97 130 // Event types for event callback
dudmuck 0:f2716e543d97 131 enum _ev_t { EV_SCAN_TIMEOUT=1, EV_BEACON_FOUND,
dudmuck 0:f2716e543d97 132 EV_BEACON_MISSED, EV_BEACON_TRACKED, EV_JOINING,
dudmuck 0:f2716e543d97 133 EV_JOINED, EV_RFU1, EV_JOIN_FAILED, EV_REJOIN_FAILED,
dudmuck 0:f2716e543d97 134 EV_TXCOMPLETE, EV_LOST_TSYNC, EV_RESET,
dudmuck 0:f2716e543d97 135 EV_RXCOMPLETE, EV_LINK_DEAD, EV_LINK_ALIVE };
dudmuck 0:f2716e543d97 136 typedef enum _ev_t ev_t;
dudmuck 0:f2716e543d97 137
dudmuck 0:f2716e543d97 138
dudmuck 0:f2716e543d97 139 struct lmic_t {
dudmuck 0:f2716e543d97 140 // Radio settings TX/RX (also accessed by HAL)
dudmuck 0:f2716e543d97 141 ostime_t txend;
dudmuck 0:f2716e543d97 142 ostime_t rxtime;
dudmuck 0:f2716e543d97 143 u4_t freq;
dudmuck 0:f2716e543d97 144 s1_t rssi;
dudmuck 0:f2716e543d97 145 s1_t snr;
dudmuck 0:f2716e543d97 146 rps_t rps;
dudmuck 0:f2716e543d97 147 u1_t rxsyms;
dudmuck 0:f2716e543d97 148 u1_t dndr;
dudmuck 0:f2716e543d97 149 s1_t txpow; // dBm
dudmuck 5:e4ba433f0ac1 150 s1_t txpow_limit; // dBm maximum permitted
dudmuck 0:f2716e543d97 151
dudmuck 0:f2716e543d97 152 osjob_t osjob;
dudmuck 0:f2716e543d97 153
dudmuck 0:f2716e543d97 154 // Channel scheduling
dudmuck 0:f2716e543d97 155 #if defined(CFG_eu868)
dudmuck 0:f2716e543d97 156 band_t bands[MAX_BANDS];
dudmuck 0:f2716e543d97 157 u4_t channelFreq[MAX_CHANNELS];
dudmuck 0:f2716e543d97 158 u2_t channelDrMap[MAX_CHANNELS];
dudmuck 0:f2716e543d97 159 u2_t channelMap;
dudmuck 0:f2716e543d97 160 #elif defined(CFG_us915)
dudmuck 0:f2716e543d97 161 u4_t xchFreq[MAX_XCHANNELS]; // extra channel frequencies (if device is behind a repeater)
dudmuck 0:f2716e543d97 162 u2_t xchDrMap[MAX_XCHANNELS]; // extra channel datarate ranges ---XXX: ditto
dudmuck 0:f2716e543d97 163 u2_t channelMap[(72+MAX_XCHANNELS+15)/16]; // enabled bits
dudmuck 0:f2716e543d97 164 u2_t chRnd; // channel randomizer
dudmuck 0:f2716e543d97 165 #endif
dudmuck 0:f2716e543d97 166 u1_t txChnl; // channel for next TX
dudmuck 0:f2716e543d97 167 u1_t globalDutyRate; // max rate: 1/2^k
dudmuck 0:f2716e543d97 168 ostime_t globalDutyAvail; // time device can send again
dudmuck 0:f2716e543d97 169
dudmuck 0:f2716e543d97 170 u4_t netid; // current network id (~0 - none)
dudmuck 0:f2716e543d97 171 u2_t opmode;
dudmuck 0:f2716e543d97 172 u1_t upRepeat; // configured up repeat
dudmuck 0:f2716e543d97 173 s1_t adrTxPow; // ADR adjusted TX power
dudmuck 0:f2716e543d97 174 u1_t datarate; // current data rate
dudmuck 0:f2716e543d97 175 u1_t errcr; // error coding rate (used for TX only)
dudmuck 0:f2716e543d97 176 u1_t rejoinCnt; // adjustment for rejoin datarate
dudmuck 8:0faa1bb768b5 177 u1_t joinBlock; // during join attempt: current channel block
dudmuck 8:0faa1bb768b5 178 u1_t joinBlockChnl; // during join attempt: current 125KHz channel
dudmuck 0:f2716e543d97 179 s2_t drift; // last measured drift
dudmuck 0:f2716e543d97 180 s2_t lastDriftDiff;
dudmuck 0:f2716e543d97 181 s2_t maxDriftDiff;
dudmuck 0:f2716e543d97 182
dudmuck 0:f2716e543d97 183 u1_t pendTxPort;
dudmuck 0:f2716e543d97 184 u1_t pendTxConf; // confirmed data
dudmuck 0:f2716e543d97 185 u1_t pendTxLen; // +0x80 = confirmed
dudmuck 0:f2716e543d97 186 u1_t pendTxData[MAX_LEN_PAYLOAD];
dudmuck 0:f2716e543d97 187
dudmuck 0:f2716e543d97 188 u2_t devNonce; // last generated nonce
dudmuck 0:f2716e543d97 189 u1_t nwkKey[16]; // network session key
dudmuck 0:f2716e543d97 190 u1_t artKey[16]; // application router session key
dudmuck 0:f2716e543d97 191 devaddr_t devaddr;
dudmuck 0:f2716e543d97 192 u4_t seqnoDn; // device level down stream seqno
dudmuck 0:f2716e543d97 193 u4_t seqnoUp;
dudmuck 0:f2716e543d97 194
dudmuck 0:f2716e543d97 195 u1_t dnConf; // dn frame confirm pending: LORA::FCT_ACK or 0
dudmuck 0:f2716e543d97 196 s1_t adrAckReq; // counter until we reset data rate (0=off)
dudmuck 0:f2716e543d97 197 u1_t adrChanged;
dudmuck 0:f2716e543d97 198
dudmuck 0:f2716e543d97 199 u1_t margin;
dudmuck 0:f2716e543d97 200 bit_t ladrAns; // link adr adapt answer pending
dudmuck 0:f2716e543d97 201 bit_t devsAns; // device status answer pending
dudmuck 0:f2716e543d97 202 u1_t adrEnabled;
dudmuck 0:f2716e543d97 203 u1_t moreData; // NWK has more data pending
dudmuck 0:f2716e543d97 204 bit_t dutyCapAns; // have to ACK duty cycle settings
dudmuck 0:f2716e543d97 205 u1_t snchAns; // answer set new channel
dudmuck 0:f2716e543d97 206 // 2nd RX window (after up stream)
dudmuck 0:f2716e543d97 207 u1_t dn2Dr;
dudmuck 0:f2716e543d97 208 u4_t dn2Freq;
dudmuck 0:f2716e543d97 209 u1_t dn2Ans; // 0=no answer pend, 0x80+ACKs
dudmuck 0:f2716e543d97 210
dudmuck 0:f2716e543d97 211 // Class B state
dudmuck 0:f2716e543d97 212 u1_t missedBcns; // unable to track last N beacons
dudmuck 0:f2716e543d97 213 u1_t bcninfoTries; // how often to try (scan mode only)
dudmuck 0:f2716e543d97 214 u1_t pingSetAns; // answer set cmd and ACK bits
dudmuck 0:f2716e543d97 215 rxsched_t ping; // pingable setup
dudmuck 0:f2716e543d97 216
dudmuck 0:f2716e543d97 217 // Public part of MAC state
dudmuck 0:f2716e543d97 218 u1_t txCnt;
dudmuck 0:f2716e543d97 219 u1_t txrxFlags; // transaction flags (TX-RX combo)
dudmuck 0:f2716e543d97 220 u1_t dataBeg; // 0 or start of data (dataBeg-1 is port)
dudmuck 0:f2716e543d97 221 u1_t dataLen; // 0 no data or zero length data, >0 byte count of data
dudmuck 0:f2716e543d97 222 u1_t frame[MAX_LEN_FRAME];
dudmuck 0:f2716e543d97 223
dudmuck 0:f2716e543d97 224 u1_t bcnChnl;
dudmuck 0:f2716e543d97 225 u1_t bcnRxsyms; //
dudmuck 0:f2716e543d97 226 ostime_t bcnRxtime;
dudmuck 0:f2716e543d97 227 bcninfo_t bcninfo; // Last received beacon info
dudmuck 0:f2716e543d97 228 };
dudmuck 0:f2716e543d97 229 //! \var struct lmic_t LMIC
dudmuck 0:f2716e543d97 230 //! The state of LMIC MAC layer is encapsulated in this variable.
dudmuck 0:f2716e543d97 231 DECLARE_LMIC; //!< \internal
dudmuck 0:f2716e543d97 232
dudmuck 0:f2716e543d97 233 //! Construct a bit map of allowed datarates from drlo to drhi (both included).
dudmuck 0:f2716e543d97 234 #define DR_RANGE_MAP(drlo,drhi) (((u2_t)0xFFFF<<(drlo)) & ((u2_t)0xFFFF>>(15-(drhi))))
dudmuck 0:f2716e543d97 235 #if defined(CFG_eu868)
dudmuck 0:f2716e543d97 236 enum { BAND_MILLI=0, BAND_CENTI=1, BAND_DECI=2, BAND_AUX=3 };
dudmuck 0:f2716e543d97 237 bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap);
dudmuck 0:f2716e543d97 238 #endif
dudmuck 0:f2716e543d97 239 bit_t LMIC_setupChannel (u1_t channel, u4_t freq, u2_t drmap, s1_t band);
dudmuck 0:f2716e543d97 240 void LMIC_disableChannel (u1_t channel);
dudmuck 0:f2716e543d97 241
dudmuck 0:f2716e543d97 242 void LMIC_setDrTxpow (dr_t dr, s1_t txpow); // set default/start DR/txpow
dudmuck 0:f2716e543d97 243 void LMIC_setAdrMode (bit_t enabled); // set ADR mode (if mobile turn off)
dudmuck 0:f2716e543d97 244 bit_t LMIC_startJoining (void);
dudmuck 0:f2716e543d97 245
dudmuck 0:f2716e543d97 246 void LMIC_shutdown (void);
dudmuck 0:f2716e543d97 247 void LMIC_init (void);
dudmuck 0:f2716e543d97 248 void LMIC_reset (void);
dudmuck 0:f2716e543d97 249 void LMIC_clrTxData (void);
dudmuck 0:f2716e543d97 250 void LMIC_setTxData (void);
dudmuck 0:f2716e543d97 251 int LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed);
dudmuck 0:f2716e543d97 252 void LMIC_sendAlive (void);
dudmuck 0:f2716e543d97 253
dudmuck 0:f2716e543d97 254 bit_t LMIC_enableTracking (u1_t tryBcnInfo);
dudmuck 0:f2716e543d97 255 void LMIC_disableTracking (void);
dudmuck 0:f2716e543d97 256
dudmuck 0:f2716e543d97 257 void LMIC_stopPingable (void);
dudmuck 0:f2716e543d97 258 void LMIC_setPingable (u1_t intvExp);
dudmuck 0:f2716e543d97 259 void LMIC_tryRejoin (void);
dudmuck 0:f2716e543d97 260
dudmuck 0:f2716e543d97 261 void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
dudmuck 0:f2716e543d97 262 void LMIC_setLinkCheckMode (bit_t enabled);
dudmuck 0:f2716e543d97 263
dudmuck 8:0faa1bb768b5 264 void LMIC_reverse_memcpy(u1_t *dst, const u1_t *src, size_t len);
dudmuck 0:f2716e543d97 265 // Special APIs - for development or testing
dudmuck 0:f2716e543d97 266 // !!!See implementation for caveats!!!
dudmuck 0:f2716e543d97 267
dudmuck 0:f2716e543d97 268 #endif // _lmic_h_