summaryrefslogtreecommitdiff
path: root/src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_us915.c
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2021-09-23 22:22:47 +0200
committerDaniel Friesel <derf@finalrewind.org>2021-09-23 22:22:47 +0200
commit8578e1ea7d078b60864b084094dbb02b6cac99c3 (patch)
tree19a02eef376f5b89c7044c48dcc0c0f43ea9d416 /src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_us915.c
parent30a29dcd0d064ab8403a9afb32c59800bb346840 (diff)
Import partially adapted MCCI LoRaWAN LMIC library. Needs further work.
Diffstat (limited to 'src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_us915.c')
-rw-r--r--src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_us915.c269
1 files changed, 269 insertions, 0 deletions
diff --git a/src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_us915.c b/src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_us915.c
new file mode 100644
index 0000000..0cbf852
--- /dev/null
+++ b/src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_us915.c
@@ -0,0 +1,269 @@
+/*
+* Copyright (c) 2014-2016 IBM Corporation.
+* Copyright (c) 2017, 2019-2021 MCCI Corporation.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the <organization> nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define LMIC_DR_LEGACY 0
+
+#include "lmic_bandplan.h"
+
+#if defined(CFG_us915)
+// ================================================================================
+//
+// BEG: US915 related stuff
+//
+
+CONST_TABLE(u1_t, _DR2RPS_CRC)[] = {
+ ILLEGAL_RPS, // [-1]
+ MAKERPS(SF10, BW125, CR_4_5, 0, 0), // [0]
+ MAKERPS(SF9 , BW125, CR_4_5, 0, 0), // [1]
+ MAKERPS(SF8 , BW125, CR_4_5, 0, 0), // [2]
+ MAKERPS(SF7 , BW125, CR_4_5, 0, 0), // [3]
+ MAKERPS(SF8 , BW500, CR_4_5, 0, 0), // [4]
+ ILLEGAL_RPS , // [5]
+ ILLEGAL_RPS , // [6]
+ ILLEGAL_RPS , // [7]
+ MAKERPS(SF12, BW500, CR_4_5, 0, 0), // [8]
+ MAKERPS(SF11, BW500, CR_4_5, 0, 0), // [9]
+ MAKERPS(SF10, BW500, CR_4_5, 0, 0), // [10]
+ MAKERPS(SF9 , BW500, CR_4_5, 0, 0), // [11]
+ MAKERPS(SF8 , BW500, CR_4_5, 0, 0), // [12]
+ MAKERPS(SF7 , BW500, CR_4_5, 0, 0), // [13]
+ ILLEGAL_RPS // [14]
+};
+
+bit_t
+LMICus915_validDR(dr_t dr) {
+ // use subtract here to avoid overflow
+ if (dr >= LENOF_TABLE(_DR2RPS_CRC) - 2)
+ return 0;
+ return TABLE_GET_U1(_DR2RPS_CRC, dr+1)!=ILLEGAL_RPS;
+}
+
+static CONST_TABLE(u1_t, maxFrameLens)[] = {
+ 19+5, 61+5, 133+5, 250+5, 250+5, 0, 0,0,
+ 61+5, 133+5, 250+5, 250+5, 250+5, 250+5
+ };
+
+uint8_t LMICus915_maxFrameLen(uint8_t dr) {
+ if (dr < LENOF_TABLE(maxFrameLens))
+ return TABLE_GET_U1(maxFrameLens, dr);
+ else
+ return 0;
+}
+
+int8_t LMICus915_pow2dbm(uint8_t mcmd_ladr_p1) {
+ if ((mcmd_ladr_p1 & MCMD_LinkADRReq_POW_MASK) >
+ ((LMIC_LORAWAN_SPEC_VERSION < LMIC_LORAWAN_SPEC_VERSION_1_0_3)
+ ? US915_LinkAdrReq_POW_MAX_1_0_2
+ : US915_LinkAdrReq_POW_MAX_1_0_3))
+ return -128;
+ else
+ return ((s1_t)(US915_TX_MAX_DBM - (((mcmd_ladr_p1)&MCMD_LinkADRReq_POW_MASK)<<1)));
+}
+
+static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = {
+ us2osticksRound(128 << 5), // DR_SF10 DR_SF12CR
+ us2osticksRound(128 << 4), // DR_SF9 DR_SF11CR
+ us2osticksRound(128 << 3), // DR_SF8 DR_SF10CR
+ us2osticksRound(128 << 2), // DR_SF7 DR_SF9CR
+ us2osticksRound(128 << 1), // DR_SF8C DR_SF8CR
+ us2osticksRound(128 << 0) // ------ DR_SF7CR
+};
+
+ostime_t LMICus915_dr2hsym(uint8_t dr) {
+ return TABLE_GET_OSTIME(DR2HSYM_osticks, (dr) & 7); // map DR_SFnCR -> 0-6
+}
+
+
+
+u4_t LMICus915_convFreq(xref2cu1_t ptr) {
+ u4_t freq = (os_rlsbf4(ptr - 1) >> 8) * 100;
+ if (freq < US915_FREQ_MIN || freq > US915_FREQ_MAX)
+ freq = 0;
+ return freq;
+}
+
+///
+/// \brief query number of default channels.
+///
+/// For US, we have no programmable channels; all channels
+/// are fixed. Return the total channel count.
+///
+u1_t LMIC_queryNumDefaultChannels() {
+ return 64 + 8;
+}
+
+///
+/// \brief LMIC_setupChannel for US915
+///
+/// \note there are no progammable channels for US915, so this API
+/// always returns FALSE.
+///
+bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
+ LMIC_API_PARAMETER(chidx);
+ LMIC_API_PARAMETER(freq);
+ LMIC_API_PARAMETER(drmap);
+ LMIC_API_PARAMETER(band);
+
+ return 0; // channels 0..71 are hardwired
+}
+
+bit_t LMIC_disableChannel(u1_t channel) {
+ bit_t result = 0;
+ if (channel < 72) {
+ if (ENABLED_CHANNEL(channel)) {
+ result = 1;
+ if (IS_CHANNEL_125khz(channel))
+ LMIC.activeChannels125khz--;
+ else if (IS_CHANNEL_500khz(channel))
+ LMIC.activeChannels500khz--;
+ }
+ LMIC.channelMap[channel >> 4] &= ~(1 << (channel & 0xF));
+ }
+ return result;
+}
+
+bit_t LMIC_enableChannel(u1_t channel) {
+ bit_t result = 0;
+ if (channel < 72) {
+ if (!ENABLED_CHANNEL(channel)) {
+ result = 1;
+ if (IS_CHANNEL_125khz(channel))
+ LMIC.activeChannels125khz++;
+ else if (IS_CHANNEL_500khz(channel))
+ LMIC.activeChannels500khz++;
+ }
+ LMIC.channelMap[channel >> 4] |= (1 << (channel & 0xF));
+ }
+ return result;
+}
+
+bit_t LMIC_enableSubBand(u1_t band) {
+ ASSERT(band < 8);
+ u1_t start = band * 8;
+ u1_t end = start + 8;
+ bit_t result = 0;
+
+ // enable all eight 125 kHz channels in this subband
+ for (int channel = start; channel < end; ++channel)
+ result |= LMIC_enableChannel(channel);
+
+ // there's a single 500 kHz channel associated with
+ // each group of 8 125 kHz channels. Enable it, too.
+ result |= LMIC_enableChannel(64 + band);
+ return result;
+}
+
+bit_t LMIC_disableSubBand(u1_t band) {
+ ASSERT(band < 8);
+ u1_t start = band * 8;
+ u1_t end = start + 8;
+ bit_t result = 0;
+
+ // disable all eight 125 kHz channels in this subband
+ for (int channel = start; channel < end; ++channel)
+ result |= LMIC_disableChannel(channel);
+
+ // there's a single 500 kHz channel associated with
+ // each group of 8 125 kHz channels. Disable it, too.
+ result |= LMIC_disableChannel(64 + band);
+ return result;
+}
+
+bit_t LMIC_selectSubBand(u1_t band) {
+ bit_t result = 0;
+
+ ASSERT(band < 8);
+ for (int b = 0; b<8; ++b) {
+ if (band == b)
+ result |= LMIC_enableSubBand(b);
+ else
+ result |= LMIC_disableSubBand(b);
+ }
+ return result;
+}
+
+void LMICus915_updateTx(ostime_t txbeg) {
+ u1_t chnl = LMIC.txChnl;
+ if (chnl < 64) {
+ LMIC.freq = US915_125kHz_UPFBASE + chnl*US915_125kHz_UPFSTEP;
+ if (LMIC.activeChannels125khz >= 50)
+ LMIC.txpow = 30;
+ else
+ LMIC.txpow = 21;
+ } else {
+ // at 500kHz bandwidth, we're allowed more power.
+ LMIC.txpow = 26;
+ LMIC.freq = US915_500kHz_UPFBASE + (chnl - 64)*US915_500kHz_UPFSTEP;
+ }
+
+ // Update global duty cycle stats
+ if (LMIC.globalDutyRate != 0) {
+ ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen);
+ LMIC.globalDutyAvail = txbeg + (airtime << LMIC.globalDutyRate);
+ }
+}
+
+#if !defined(DISABLE_BEACONS)
+void LMICus915_setBcnRxParams(void) {
+ LMIC.dataLen = 0;
+ LMIC.freq = US915_500kHz_DNFBASE + LMIC.bcnChnl * US915_500kHz_DNFSTEP;
+ LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN), 1), LEN_BCN);
+}
+#endif // !DISABLE_BEACONS
+
+// set the Rx1 dndr, rps.
+void LMICus915_setRx1Params(void) {
+ u1_t const txdr = LMIC.dndr;
+ u1_t candidateDr;
+ LMIC.freq = US915_500kHz_DNFBASE + (LMIC.txChnl & 0x7) * US915_500kHz_DNFSTEP;
+ if ( /* TX datarate */txdr < LORAWAN_DR4)
+ candidateDr = txdr + 10 - LMIC.rx1DrOffset;
+ else
+ candidateDr = LORAWAN_DR13 - LMIC.rx1DrOffset;
+
+ if (candidateDr < LORAWAN_DR8)
+ candidateDr = LORAWAN_DR8;
+ else if (candidateDr > LORAWAN_DR13)
+ candidateDr = LORAWAN_DR13;
+
+ LMIC.dndr = candidateDr;
+ LMIC.rps = dndr2rps(LMIC.dndr);
+}
+
+void LMICus915_initJoinLoop(void) {
+ LMICuslike_initJoinLoop();
+
+ // initialize the adrTxPower.
+ LMIC.adrTxPow = 20; // dBm
+}
+
+//
+// END: US915 related stuff
+//
+// ================================================================================
+#endif