diff --git a/README.md b/README.md index ec1f0519..9e8b8092 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,15 @@ The following configuration variables are available. ### Selecting the LoRaWAN Version -This library implements V1.0.3 of the LoRaWAN specification. However, it can also be used with V1.0.2. The only significant change when selecting V1.0.2 is that the US accepted power range in MAC commands is 10 dBm to 30 dBm; whereas in V1.0.3 the accepted range 2 dBm to 30 dBm. +This library implements V1.0.3 of the LoRaWAN specification. However, it can also be used with V1.0.2rB (revision B). Two significant changes have been identified between the versions: + +#### US Power Range + +In V1.0.2, the US accepted power range in MAC commands is 10 dBm to 30 dBm; whereas in V1.0.3 the accepted range 2 dBm to 30 dBm. + +#### AU915 Data Rate (DR)/Spreading Factor (SF), TxParamSetupReq and CFList + +In V1.0.2, the JoinReq data rate for OTAA is DR0 (SF12). This is been changed to DR2 (SF10) in V1.0.3. Furthermore, the TxParamSetupReq MAC command is not implemented, nor is the optional CFlist appended to the JoinAccept message. The default LoRaWAN version, if no version is explicitly selected, is V1.0.3. diff --git a/examples/ttn-otaa/ttn-otaa.ino b/examples/ttn-otaa/ttn-otaa.ino index fbbf0879..7b7bc621 100644 --- a/examples/ttn-otaa/ttn-otaa.ino +++ b/examples/ttn-otaa/ttn-otaa.ino @@ -237,6 +237,9 @@ void setup() { // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); + // TTN uses the 2nd sub-band (channels 8-15) (sub-band 1 when counting from 0). + LMIC_selectSubBand(1); + // Start job (sending automatically starts OTAA too) do_send(&sendjob); } diff --git a/project_config/lmic_project_config.h b/project_config/lmic_project_config.h index 620afbf5..f42723d4 100644 --- a/project_config/lmic_project_config.h +++ b/project_config/lmic_project_config.h @@ -1,13 +1,17 @@ // project-specific definitions //#define CFG_eu868 1 -#define CFG_us915 1 +//#define CFG_us915 1 //#define CFG_au915 1 //#define CFG_as923 1 -// #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP /* for as923-JP; also define CFG_as923 */ +//#define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP /* for as923-JP; also define CFG_as923 */ //#define CFG_kr920 1 //#define CFG_in866 1 -#define CFG_sx1276_radio 1 +//#define CFG_sx1276_radio 1 //#define CFG_sx1261_radio 1 //#define CFG_sx1262_radio 1 //#define ARDUINO_heltec_wifi_lora_32_V3 -//#define LMIC_USE_INTERRUPTS \ No newline at end of file +//#define LMIC_USE_INTERRUPTS +//#define LMIC_LORAWAN_SPEC_VERSION LMIC_LORAWAN_SPEC_VERSION_1_0_2 +//#define LMIC_LORAWAN_SPEC_VERSION LMIC_LORAWAN_SPEC_VERSION_1_0_3 +//#define LMIC_DEBUG_LEVEL 1 +//#define LMIC_DEBUG_LEVEL 2 \ No newline at end of file diff --git a/src/lmic/lmic_au915.c b/src/lmic/lmic_au915.c index 301cfc7b..357ec0fe 100644 --- a/src/lmic/lmic_au915.c +++ b/src/lmic/lmic_au915.c @@ -73,25 +73,36 @@ static CONST_TABLE(u1_t, maxFrameLens_dwell1)[] = { static bit_t LMICau915_getUplinkDwellBit() { + #if LMIC_LORAWAN_SPEC_VERSION <= LMIC_LORAWAN_SPEC_VERSION_1_0_2 + return 0; + #else // if uninitialized, return default. - if (LMIC.txParam == 0xFF) { - return AU915_INITIAL_TxParam_UplinkDwellTime; - } - return (LMIC.txParam & MCMD_TxParam_TxDWELL_MASK) != 0; + if (LMIC.txParam == 0xFF) { + return AU915_INITIAL_TxParam_UplinkDwellTime; + } + return (LMIC.txParam & MCMD_TxParam_TxDWELL_MASK) != 0; + #endif } uint8_t LMICau915_maxFrameLen(uint8_t dr) { - if (LMICau915_getUplinkDwellBit()) { + #if LMIC_LORAWAN_SPEC_VERSION <= LMIC_LORAWAN_SPEC_VERSION_1_0_2 if (dr < LENOF_TABLE(maxFrameLens_dwell0)) return TABLE_GET_U1(maxFrameLens_dwell0, dr); else return 0; - } else { + #else + if (LMICau915_getUplinkDwellBit()) { + if (dr < LENOF_TABLE(maxFrameLens_dwell0)) + return TABLE_GET_U1(maxFrameLens_dwell0, dr); + else + return 0; + } else { if (dr < LENOF_TABLE(maxFrameLens_dwell1)) - return TABLE_GET_U1(maxFrameLens_dwell1, dr); + return TABLE_GET_U1(maxFrameLens_dwell1, dr); else - return 0; - } + return 0; + } + #endif } // from LoRaWAN 5.8: mapping from txParam to MaxEIRP @@ -100,6 +111,9 @@ static CONST_TABLE(s1_t, TXMAXEIRP)[16] = { }; static int8_t LMICau915_getMaxEIRP(uint8_t mcmd_txparam) { + #if LMIC_LORAWAN_SPEC_VERSION <= LMIC_LORAWAN_SPEC_VERSION_1_0_2 + return 0; + #else // if uninitialized, return default. if (mcmd_txparam == 0xFF) return AU915_TX_EIRP_MAX_DBM; @@ -109,14 +123,19 @@ static int8_t LMICau915_getMaxEIRP(uint8_t mcmd_txparam) { (mcmd_txparam & MCMD_TxParam_MaxEIRP_MASK) >> MCMD_TxParam_MaxEIRP_SHIFT ); + #endif } int8_t LMICau915_pow2dbm(uint8_t mcmd_ladr_p1) { - if ((mcmd_ladr_p1 & MCMD_LinkADRReq_POW_MASK) == MCMD_LinkADRReq_POW_MASK) - return -128; - else { - return ((s1_t)(LMICau915_getMaxEIRP(LMIC.txParam) - (((mcmd_ladr_p1)&MCMD_LinkADRReq_POW_MASK)<<1))); - } + #if LMIC_LORAWAN_SPEC_VERSION <= LMIC_LORAWAN_SPEC_VERSION_1_0_2 + return 0; + #else + if ((mcmd_ladr_p1 & MCMD_LinkADRReq_POW_MASK) == MCMD_LinkADRReq_POW_MASK) + return -128; + else { + return ((s1_t)(LMICau915_getMaxEIRP(LMIC.txParam) - (((mcmd_ladr_p1)&MCMD_LinkADRReq_POW_MASK)<<1))); + } + #endif } static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = { @@ -256,7 +275,12 @@ bit_t LMIC_selectSubBand(u1_t band) { void LMICau915_updateTx(ostime_t txbeg) { u1_t chnl = LMIC.txChnl; - LMIC.txpow = LMICau915_getMaxEIRP(LMIC.txParam); + LMIC.txpow = 30; + + #if LMIC_LORAWAN_SPEC_VERSION > LMIC_LORAWAN_SPEC_VERSION_1_0_2 + LMIC.txpow = LMICau915_getMaxEIRP(LMIC.txParam); + #endif + if (chnl < 64) { LMIC.freq = AU915_125kHz_UPFBASE + chnl*AU915_125kHz_UPFSTEP; } else { @@ -273,9 +297,13 @@ void LMICau915_updateTx(ostime_t txbeg) { ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen); globalDutyDelay = txbeg + (airtime << LMIC.globalDutyRate); } - if (LMICau915_getUplinkDwellBit(LMIC.txParam)) { - dwellDelay = AU915_UPLINK_DWELL_TIME_osticks; - } + + #if LMIC_LORAWAN_SPEC_VERSION > LMIC_LORAWAN_SPEC_VERSION_1_0_2 + if (LMICau915_getUplinkDwellBit(LMIC.txParam)) { + dwellDelay = AU915_UPLINK_DWELL_TIME_osticks; + } + #endif + if (dwellDelay > globalDutyDelay) { globalDutyDelay = dwellDelay; } @@ -314,10 +342,11 @@ void LMICau915_setRx1Params(void) { void LMICau915_initJoinLoop(void) { // LMIC.txParam is set to 0xFF by the central code at init time. LMICuslike_initJoinLoop(); - // initialize the adrTxPower. - LMIC.adrTxPow = LMICau915_getMaxEIRP(LMIC.txParam); // dBm - + LMIC.adrTxPow = 30; // dBm + #if LMIC_LORAWAN_SPEC_VERSION > LMIC_LORAWAN_SPEC_VERSION_1_0_2 + LMIC.adrTxPow = LMICau915_getMaxEIRP(LMIC.txParam); // dBm + #endif } // diff --git a/src/lmic/lmic_bandplan_au915.h b/src/lmic/lmic_bandplan_au915.h index 78637799..1175e9ac 100644 --- a/src/lmic/lmic_bandplan_au915.h +++ b/src/lmic/lmic_bandplan_au915.h @@ -31,7 +31,12 @@ // preconditions for lmic_us_like.h #define LMICuslike_getFirst500kHzDR() (LORAWAN_DR6) -#define LMICuslike_getJoin125kHzDR() (LORAWAN_DR2) + +#if LMIC_LORAWAN_SPEC_VERSION <= LMIC_LORAWAN_SPEC_VERSION_1_0_2 + #define LMICuslike_getJoin125kHzDR() (LORAWAN_DR0) +#else + #define LMICuslike_getJoin125kHzDR() (LORAWAN_DR2) +#endif #ifndef _lmic_us_like_h_ # include "lmic_us_like.h" @@ -48,8 +53,11 @@ int8_t LMICau915_pow2dbm(uint8_t mcmd_ladr_p1); ostime_t LMICau915_dr2hsym(uint8_t dr); #define dr2hsym(dr) LMICau915_dr2hsym(dr) - -#define LMICbandplan_getInitialDrJoin() (LORAWAN_DR2) +#if LMIC_LORAWAN_SPEC_VERSION <= LMIC_LORAWAN_SPEC_VERSION_1_0_2 + #define LMICbandplan_getInitialDrJoin() (LORAWAN_DR0) +#else + #define LMICbandplan_getInitialDrJoin() (LORAWAN_DR2) +#endif void LMICau915_initJoinLoop(void); #define LMICbandplan_initJoinLoop() LMICau915_initJoinLoop() diff --git a/src/lmic/lmic_us_like.h b/src/lmic/lmic_us_like.h index f3e8bfca..feb5495a 100644 --- a/src/lmic/lmic_us_like.h +++ b/src/lmic/lmic_us_like.h @@ -63,8 +63,12 @@ LMICuslike_isValidBeacon1(const uint8_t *d) { // provide a default LMICbandplan_joinAcceptChannelClear() #define LMICbandplan_joinAcceptChannelClear() do { } while (0) -/// \brief there's a CFList on joins for US-like plans -#define LMICbandplan_hasJoinCFlist() (1) +/// \brief Indicates whether a Join CFList is included for US-like band plans based on LoRaWAN spec version. +#if LMIC_LORAWAN_SPEC_VERSION <= LMIC_LORAWAN_SPEC_VERSION_1_0_2 + #define LMICbandplan_hasJoinCFlist() (0) +#else + #define LMICbandplan_hasJoinCFlist() (1) +#endif /// \brief process CFLists from JoinAccept for EU-like regions void LMICuslike_processJoinAcceptCFList(void);