Update to latest version of mcci-catena/arduino-lmic library

This commit is contained in:
Manuel Bleichenbacher 2018-10-21 23:28:25 +02:00
parent 4baa7a9a4c
commit 2e351ada9a
15 changed files with 257 additions and 104 deletions

View File

@ -142,4 +142,4 @@ u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) {
return 0;
}
#endif // !defined(USE_ORIGINAL_AES)
#endif // !defined(USE_ORIGINAL_AES)

View File

@ -347,7 +347,7 @@ static bool hal_wait(wait_open_e wait_option)
if (wait_option != WAIT_FOR_TIMER)
hal_disarm_timer();
hal_enterCriticalSection();
radio_irq_handler(item.ev, item.time);
radio_irq_handler_v2(item.ev, item.time);
hal_leaveCriticalSection();
if (wait_option != WAIT_FOR_TIMER)
return true;

120
src/lmic/lmic.c Executable file → Normal file
View File

@ -47,9 +47,10 @@ static void startScan (void);
#endif
static inline void initTxrxFlags(const char *func, u1_t mask) {
LMIC_DEBUG2_PARAMETER(func);
#if LMIC_DEBUG_LEVEL > 1
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: %s txrxFlags %#02x --> %02x\n", (unsigned)os_getTime(), func, LMIC.txrxFlags, mask);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": %s txrxFlags %#02x --> %02x\n", os_getTime(), func, LMIC.txrxFlags, mask);
#endif
LMIC.txrxFlags = mask;
}
@ -273,30 +274,6 @@ ostime_t calcAirTime (rps_t rps, u1_t plen) {
return (((ostime_t)tmp << sfx) * OSTICKS_PER_SEC + div/2) / div;
}
extern inline rps_t updr2rps (dr_t dr);
extern inline rps_t dndr2rps (dr_t dr);
extern inline int isFasterDR (dr_t dr1, dr_t dr2);
extern inline int isSlowerDR (dr_t dr1, dr_t dr2);
extern inline dr_t incDR (dr_t dr);
extern inline dr_t decDR (dr_t dr);
// ttn-esp32 change: remove unused function creating warning
//extern inline dr_t assertDR (dr_t dr);
extern inline dr_t validDR (dr_t dr);
extern inline dr_t lowerDR (dr_t dr, u1_t n);
extern inline sf_t getSf (rps_t params);
extern inline rps_t setSf (rps_t params, sf_t sf);
extern inline bw_t getBw (rps_t params);
extern inline rps_t setBw (rps_t params, bw_t cr);
extern inline cr_t getCr (rps_t params);
extern inline rps_t setCr (rps_t params, cr_t cr);
extern inline int getNocrc (rps_t params);
extern inline rps_t setNocrc (rps_t params, int nocrc);
extern inline int getIh (rps_t params);
extern inline rps_t setIh (rps_t params, int ih);
extern inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc);
extern inline int sameSfBw (rps_t r1, rps_t r2);
// END LORA
// ================================================================================
@ -416,6 +393,8 @@ static void txDelay (ostime_t reftime, u1_t secSpan) {
void LMICcore_setDrJoin (u1_t reason, u1_t dr) {
LMIC_EV_PARAMETER(reason);
EV(drChange, INFO, (e_.reason = reason,
e_.deveui = MAIN::CDEV->getEui(),
e_.dr = dr|DR_PAGE,
@ -428,6 +407,8 @@ void LMICcore_setDrJoin (u1_t reason, u1_t dr) {
static void setDrTxpow (u1_t reason, u1_t dr, s1_t pow) {
LMIC_EV_PARAMETER(reason);
EV(drChange, INFO, (e_.reason = reason,
e_.deveui = MAIN::CDEV->getEui(),
e_.dr = dr|DR_PAGE,
@ -464,6 +445,8 @@ void LMIC_setPingable (u1_t intvExp) {
#endif // !DISABLE_PING
static void runEngineUpdate (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
engineUpdate();
}
@ -478,6 +461,8 @@ static void reportEvent (ev_t ev) {
static void runReset (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
// Disable session
LMIC_reset();
#if !defined(DISABLE_JOIN)
@ -596,9 +581,8 @@ scan_mac_cmds(
// of contiguous commands (whatever that means), and ignore the
// data rate, NbTrans (uprpt) and txPow until the last one.
#if LMIC_DEBUG_LEVEL > 0
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: LinkAdrReq: p1:%02x chmap:%04x chpage:%02x uprt:%02x ans:%02x\n",
(unsigned)os_getTime(), p1, chmap, chpage, uprpt, LMIC.ladrAns
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": LinkAdrReq: p1:%02x chmap:%04x chpage:%02x uprt:%02x ans:%02x\n",
os_getTime(), p1, chmap, chpage, uprpt, LMIC.ladrAns
);
#endif /* LMIC_DEBUG_LEVEL */
@ -760,8 +744,7 @@ static bit_t decodeFrame (void) {
e_.info2 = hdr + (dlen<<8)));
norx:
#if LMIC_DEBUG_LEVEL > 0
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: Invalid downlink, window=%s\n", (unsigned)os_getTime(), window);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": Invalid downlink, window=%s\n", os_getTime(), window);
#endif
LMIC.dataLen = 0;
return 0;
@ -853,8 +836,7 @@ static bit_t decodeFrame (void) {
#if LMIC_DEBUG_LEVEL > 0
// Process OPTS
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: process options (olen=%#x)\n", (unsigned)os_getTime(), olen);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": process options (olen=%#x)\n", os_getTime(), olen);
#endif
xref2u1_t opts = &d[OFF_DAT_OPTS];
@ -873,17 +855,15 @@ static bit_t decodeFrame (void) {
if (port == 0) {
// this is a mac command. scan the options.
#if LMIC_DEBUG_LEVEL > 0
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: process mac commands for port 0 (olen=%#x)\n", (unsigned)os_getTime(), pend-poff);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": process mac commands for port 0 (olen=%#x)\n", os_getTime(), pend-poff);
#endif
int optendindex = scan_mac_cmds(d+poff, pend-poff);
if (optendindex != pend-poff) {
#if LMIC_DEBUG_LEVEL > 0
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF(
"%u: error processing mac commands for port 0 "
"%"LMIC_PRId_ostime_t": error processing mac commands for port 0 "
"(len=%#x, optendindex=%#x)\n",
(unsigned)os_getTime(), pend-poff, optendindex
os_getTime(), pend-poff, optendindex
);
#endif
}
@ -918,8 +898,7 @@ static bit_t decodeFrame (void) {
e_.info = seqno,
e_.info2 = ackup));
#if LMIC_DEBUG_LEVEL > 1
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: ??ack error ack=%d txCnt=%d\n", (unsigned)os_getTime(), ackup, LMIC.txCnt);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": ??ack error ack=%d txCnt=%d\n", os_getTime(), ackup, LMIC.txCnt);
#endif
}
@ -936,8 +915,7 @@ static bit_t decodeFrame (void) {
LMIC.dataLen = pend-poff;
}
#if LMIC_DEBUG_LEVEL > 0
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: Received downlink, window=%s, port=%d, ack=%d, txrxFlags=%#x\n", (unsigned)os_getTime(), window, port, ackup, LMIC.txrxFlags);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": Received downlink, window=%s, port=%d, ack=%d, txrxFlags=%#x\n", os_getTime(), window, port, ackup, LMIC.txrxFlags);
#endif
return 1;
}
@ -986,7 +964,7 @@ static void schedRx12 (ostime_t delay, osjobcb_t func, u1_t dr) {
// (again note that hsym is half a sumbol time, so no /2 needed)
LMIC.rxtime = LMIC.txend + delay + PAMBL_SYMS * hsym - LMIC.rxsyms * hsym;
LMIC_X_DEBUG_PRINTF("%lu: sched Rx12 %lu\n", os_getTime(), LMIC.rxtime - RX_RAMPUP);
LMIC_X_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": sched Rx12 %"LMIC_PRId_ostime_t"\n", os_getTime(), LMIC.rxtime - RX_RAMPUP);
os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func);
}
@ -1029,6 +1007,8 @@ static void txDone (ostime_t delay, osjobcb_t func) {
#if !defined(DISABLE_JOIN)
static void onJoinFailed (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
// Notify app - must call LMIC_reset() to stop joining
// otherwise join procedure continues.
reportEvent(EV_JOIN_FAILED);
@ -1081,8 +1061,9 @@ static bit_t processJoinAccept (void) {
}
u1_t hdr = LMIC.frame[0];
u1_t dlen = LMIC.dataLen;
// ttn-esp32 change: suppress warning
u4_t __attribute__((unused)) mic = os_rlsbf4(&LMIC.frame[dlen-4]); // safe before modified by encrypt!
u4_t mic = os_rlsbf4(&LMIC.frame[dlen-4]); // safe before modified by encrypt!
LMIC_EV_VARIABLE(mic); // only used by EV().
if( (dlen != LEN_JA && dlen != LEN_JAEXT)
|| (hdr & (HDR_FTYPE|HDR_MAJOR)) != (HDR_FTYPE_JACC|HDR_MAJOR_V1) ) {
EV(specCond, ERR, (e_.reason = EV::specCond_t::UNEXPECTED_FRAME,
@ -1119,8 +1100,7 @@ static bit_t processJoinAccept (void) {
if( freq ) {
LMIC_setupChannel(chidx, freq, 0, -1);
#if LMIC_DEBUG_LEVEL > 1
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: Setup channel, idx=%d, freq=%lu\n", (unsigned)os_getTime(), chidx, (unsigned long)freq);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": Setup channel, idx=%d, freq=%"PRIu32"\n", os_getTime(), chidx, freq);
#endif
}
}
@ -1172,6 +1152,8 @@ static bit_t processJoinAccept (void) {
static void processRx2Jacc (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
if( LMIC.dataLen == 0 ) {
initTxrxFlags(__func__, 0); // nothing in 1st/2nd DN slot
}
@ -1180,23 +1162,31 @@ static void processRx2Jacc (xref2osjob_t osjob) {
static void setupRx2Jacc (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
LMIC.osjob.func = FUNC_ADDR(processRx2Jacc);
setupRx2();
}
static void processRx1Jacc (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
if( LMIC.dataLen == 0 || !processJoinAccept() )
schedRx12(DELAY_JACC2_osticks, FUNC_ADDR(setupRx2Jacc), LMIC.dn2Dr);
}
static void setupRx1Jacc (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
setupRx1(FUNC_ADDR(processRx1Jacc));
}
static void jreqDone (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
txDone(DELAY_JACC1_osticks, FUNC_ADDR(setupRx1Jacc));
}
@ -1208,10 +1198,14 @@ static void jreqDone (xref2osjob_t osjob) {
static bit_t processDnData(void);
static void processRx2DnDataDelay (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
processDnData();
}
static void processRx2DnData (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
if( LMIC.dataLen == 0 ) {
initTxrxFlags(__func__, 0); // nothing in 1st/2nd DN slot
// Delay callback processing to avoid up TX while gateway is txing our missed frame!
@ -1226,23 +1220,31 @@ static void processRx2DnData (xref2osjob_t osjob) {
static void setupRx2DnData (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
LMIC.osjob.func = FUNC_ADDR(processRx2DnData);
setupRx2();
}
static void processRx1DnData (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
if( LMIC.dataLen == 0 || !processDnData() )
schedRx12(sec2osticks(LMIC.rxDelay +(int)DELAY_EXTDNW2), FUNC_ADDR(setupRx2DnData), LMIC.dn2Dr);
}
static void setupRx1DnData (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
setupRx1(FUNC_ADDR(processRx1DnData));
}
static void updataDone (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
txDone(sec2osticks(LMIC.rxDelay), FUNC_ADDR(setupRx1DnData));
}
@ -1387,7 +1389,9 @@ static void buildDataFrame (void) {
#if !defined(DISABLE_BEACONS)
// Callback from HAL during scan mode or when job timer expires.
static void onBcnRx (xref2osjob_t job) {
static void onBcnRx (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
// If we arrive via job timer make sure to put radio to rest.
os_radio(RADIO_RST);
os_clearCallback(&LMIC.osjob);
@ -1508,6 +1512,8 @@ static void buildJoinRequest (u1_t ftype) {
}
static void startJoining (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
reportEvent(EV_JOINING);
}
@ -1541,6 +1547,8 @@ bit_t LMIC_startJoining (void) {
#if !defined(DISABLE_PING)
static void processPingRx (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
if( LMIC.dataLen != 0 ) {
initTxrxFlags(__func__, TXRX_PING);
if( decodeFrame() ) {
@ -1622,6 +1630,8 @@ static bit_t processDnData (void) {
#if !defined(DISABLE_BEACONS)
static void processBeacon (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
ostime_t lasttx = LMIC.bcninfo.txtime; // save here - decodeBeacon might overwrite
u1_t flags = LMIC.bcninfo.flags;
ev_t ev;
@ -1683,6 +1693,8 @@ static void processBeacon (xref2osjob_t osjob) {
static void startRxBcn (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
LMIC.osjob.func = FUNC_ADDR(processBeacon);
os_radio(RADIO_RX);
}
@ -1691,6 +1703,8 @@ static void startRxBcn (xref2osjob_t osjob) {
#if !defined(DISABLE_PING)
static void startRxPing (xref2osjob_t osjob) {
LMIC_API_PARAMETER(osjob);
LMIC.osjob.func = FUNC_ADDR(processPingRx);
os_radio(RADIO_RX);
}
@ -1700,8 +1714,7 @@ static void startRxPing (xref2osjob_t osjob) {
// Decide what to do next for the MAC layer of a device
static void engineUpdate (void) {
#if LMIC_DEBUG_LEVEL > 0
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("%u: engineUpdate, opmode=0x%x\n", (unsigned)os_getTime(), LMIC.opmode);
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": engineUpdate, opmode=0x%x\n", os_getTime(), LMIC.opmode);
#endif
// Check for ongoing state: scan or TX/RX transaction
if( (LMIC.opmode & (OP_SCAN|OP_TXRXPEND|OP_SHUTDOWN)) != 0 )
@ -1715,9 +1728,10 @@ static void engineUpdate (void) {
#endif // !DISABLE_JOIN
ostime_t now = os_getTime();
// ttn-esp32 change: suppress unused variable warning
ostime_t __attribute__((unused)) rxtime = 0;
ostime_t rxtime = 0;
ostime_t txbeg = 0;
// ttn-esp32: suppress unused variable
LMIC_UNREFERENCED_VARIABLE(rxtime);
#if !defined(DISABLE_BEACONS)
if( (LMIC.opmode & OP_TRACK) != 0 ) {
@ -1861,7 +1875,7 @@ static void engineUpdate (void) {
e_.eui = MAIN::CDEV->getEui(),
e_.info = osticks2ms(txbeg-now),
e_.info2 = LMIC.seqnoUp-1));
LMIC_X_DEBUG_PRINTF("%lu: next engine update in %lu\n", now, txbeg-TX_RAMPUP);
LMIC_X_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": next engine update in %"LMIC_PRId_ostime_t"\n", now, txbeg-TX_RAMPUP);
os_setTimedCallback(&LMIC.osjob, txbeg-TX_RAMPUP, FUNC_ADDR(runEngineUpdate));
}

3
src/lmic/lmic.h Executable file → Normal file
View File

@ -61,6 +61,7 @@
# else // ndef LMIC_DEBUG_PRINTF_FN
// if there's no other info, just use printf. In a pure Arduino environment,
// that's what will happen.
# include <stdio.h>
# define LMIC_DEBUG_PRINTF(f, ...) printf(f, ## __VA_ARGS__)
# endif // ndef LMIC_DEBUG_PRINTF_FN
# endif // ndef LMIC_DEBUG_PRINTF
@ -104,7 +105,7 @@ extern "C"{
#define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, local) \
(((major) << 24u) | ((minor) << 16u) | ((patch) << 8u) | (local))
#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 2, 1, 0)
#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 2, 2, 0)
#define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \
(((v) >> 24u) & 0xFFu)

6
src/lmic/lmic_as923.c Executable file → Normal file
View File

@ -76,11 +76,15 @@ static CONST_TABLE(u1_t, maxFrameLens_dwell1)[] = {
static uint8_t
LMICas923_getUplinkDwellBit(uint8_t mcmd_txparam) {
LMIC_API_PARAMETER(mcmd_txparam);
return (LMIC.txParam & MCMD_TxParam_TxDWELL_MASK) != 0;
}
static uint8_t
LMICas923_getDownlinkDwellBit(uint8_t mcmd_txparam) {
LMIC_API_PARAMETER(mcmd_txparam);
return (LMIC.txParam & MCMD_TxParam_RxDWELL_MASK) != 0;
}
@ -164,6 +168,8 @@ static CONST_TABLE(u4_t, iniChannelFreq)[NUM_DEFAULT_CHANNELS] = {
// as923 ignores join, becuase the channel setup is the same either way.
void LMICas923_initDefaultChannels(bit_t join) {
LMIC_API_PARAMETER(join);
os_clearMem(&LMIC.channelFreq, sizeof(LMIC.channelFreq));
os_clearMem(&LMIC.channelDrMap, sizeof(LMIC.channelDrMap));
os_clearMem(&LMIC.bands, sizeof(LMIC.bands));

5
src/lmic/lmic_au921.c Executable file → Normal file
View File

@ -101,6 +101,11 @@ u4_t LMICau921_convFreq(xref2cu1_t ptr) {
// au921: no support for xchannels.
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; // all channels are hardwired.
}

1
src/lmic/lmic_config_preconditions.h Executable file → Normal file
View File

@ -55,6 +55,7 @@ Revision history:
//
// otherwise the lmic_project_config.h from the ../../project_config directory will be used.
#ifndef ARDUINO_LMIC_PROJECT_CONFIG_H
// ttn-esp32: different configuration concept
# define ARDUINO_LMIC_PROJECT_CONFIG_H ../esp_idf_lmic_config.h
#endif

3
src/lmic/lmic_eu_like.c Executable file → Normal file
View File

@ -33,9 +33,11 @@
#if CFG_LMIC_EU_like
void LMIC_enableSubBand(u1_t band) {
LMIC_API_PARAMETER(band);
}
void LMIC_disableSubBand(u1_t band) {
LMIC_API_PARAMETER(band);
}
void LMIC_disableChannel(u1_t channel) {
@ -46,6 +48,7 @@ void LMIC_disableChannel(u1_t channel) {
// this is a no-op provided for compatibilty
void LMIC_enableChannel(u1_t channel) {
LMIC_API_PARAMETER(channel);
}
u1_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap) {

2
src/lmic/lmic_in866.c Executable file → Normal file
View File

@ -95,6 +95,8 @@ static CONST_TABLE(u4_t, iniChannelFreq)[NUM_DEFAULT_CHANNELS] = {
// india ignores join, becuase the channel setup is the same either way.
void LMICin866_initDefaultChannels(bit_t join) {
LMIC_API_PARAMETER(join);
os_clearMem(&LMIC.channelFreq, sizeof(LMIC.channelFreq));
os_clearMem(&LMIC.channelDrMap, sizeof(LMIC.channelDrMap));
os_clearMem(&LMIC.bands, sizeof(LMIC.bands));

2
src/lmic/lmic_us915.c Executable file → Normal file
View File

@ -87,6 +87,8 @@ u4_t LMICus915_convFreq(xref2cu1_t ptr) {
}
bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
LMIC_API_PARAMETER(band);
if (chidx < 72 || chidx >= 72 + MAX_XCHANNELS)
return 0; // channels 0..71 are hardwired
LMIC.xchFreq[chidx - 72] = freq;

6
src/lmic/lmic_us_like.c Executable file → Normal file
View File

@ -71,12 +71,18 @@ static void setNextChannel(uint start, uint end, uint count) {
bit_t LMIC_setupBand(u1_t bandidx, s1_t txpow, u2_t txcap) {
LMIC_API_PARAMETER(bandidx);
LMIC_API_PARAMETER(txpow);
LMIC_API_PARAMETER(txcap);
// nothing; just succeed.
return 1;
}
void LMICuslike_initDefaultChannels(bit_t fJoin) {
LMIC_API_PARAMETER(fJoin);
// things work the same for join as normal.
for (u1_t i = 0; i<4; i++)
LMIC.channelMap[i] = 0xFFFF;

43
src/lmic/lorabase.h Executable file → Normal file
View File

@ -583,34 +583,33 @@ typedef u4_t devaddr_t;
// RX quality (device)
enum { RSSI_OFF=64, SNR_SCALEUP=4 };
inline sf_t getSf (rps_t params) { return (sf_t)(params & 0x7); }
inline rps_t setSf (rps_t params, sf_t sf) { return (rps_t)((params & ~0x7) | sf); }
inline bw_t getBw (rps_t params) { return (bw_t)((params >> 3) & 0x3); }
inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); }
inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); }
inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); }
inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); }
inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); }
inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); }
inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); }
inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) {
static inline sf_t getSf (rps_t params) { return (sf_t)(params & 0x7); }
static inline rps_t setSf (rps_t params, sf_t sf) { return (rps_t)((params & ~0x7) | sf); }
static inline bw_t getBw (rps_t params) { return (bw_t)((params >> 3) & 0x3); }
static inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); }
static inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); }
static inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); }
static inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); }
static inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); }
static inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); }
static inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); }
static inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) {
return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8);
}
#define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8)))
// Two frames with params r1/r2 would interfere on air: same SFx + BWx
inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; }
static inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; }
extern CONST_TABLE(u1_t, _DR2RPS_CRC)[];
inline rps_t updr2rps (dr_t dr) { return (rps_t)TABLE_GET_U1(_DR2RPS_CRC, dr+1); }
inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); }
inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; }
inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; }
inline dr_t incDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+2)==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate
inline dr_t decDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr )==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate
// ttn-esp32 change: remove unused function creating warning
//inline dr_t assertDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)==ILLEGAL_RPS ? DR_DFLTMIN : dr; } // force into a valid DR
inline bit_t validDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)!=ILLEGAL_RPS; } // in range
inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; } // decrease data rate by n steps
static inline rps_t updr2rps (dr_t dr) { return (rps_t)TABLE_GET_U1(_DR2RPS_CRC, dr+1); }
static inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); }
static inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; }
static inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; }
static inline dr_t incDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+2)==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate
static inline dr_t decDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr )==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate
static inline dr_t assertDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)==ILLEGAL_RPS ? (dr_t)DR_DFLTMIN : dr; } // force into a valid DR
static inline bit_t validDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)!=ILLEGAL_RPS; } // in range
static inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; } // decrease data rate by n steps
//
// BEG: Keep in sync with lorabase.hpp

7
src/lmic/oslmic.c Executable file → Normal file
View File

@ -71,8 +71,11 @@ static int unlinkjob (osjob_t** pnext, osjob_t* job) {
// clear scheduled job
void os_clearCallback (osjob_t* job) {
hal_disableIRQs();
// ttn-esp32 change: suppress error 'value computed is not used'
int __attribute__((unused)) res = unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job);
// if it's not in the scheduled jobs, look in the runnable...
if (! unlinkjob(&OS.scheduledjobs, job))
unlinkjob(&OS.runnablejobs, job);
hal_enableIRQs();
}

127
src/lmic/oslmic.h Executable file → Normal file
View File

@ -75,6 +75,14 @@ typedef const u1_t* xref2cu1_t;
typedef u1_t* xref2u1_t;
typedef s4_t ostime_t;
// int32_t == s4_t is long on some platforms; and someday
// we will want 64-bit ostime_t. So, we will use a macro for the
// print formatting of ostime_t.
#ifndef LMIC_PRId_ostime_t
# include <inttypes.h>
# define LMIC_PRId_ostime_t PRId32
#endif
#define TYPEDEF_xref2rps_t typedef rps_t* xref2rps_t
#define TYPEDEF_xref2rxsched_t typedef rxsched_t* xref2rxsched_t
#define TYPEDEF_xref2chnldef_t typedef chnldef_t* xref2chnldef_t
@ -83,6 +91,105 @@ typedef s4_t ostime_t;
#define SIZEOFEXPR(x) sizeof(x)
//----------------------------------------------------------------------------
// Annotations to avoid various "unused" warnings. These must appear as a
// statement in the function body; the macro annotates the variable to quiet
// compiler warnings. The way this is done is compiler-specific, and so these
// definitions are fall-backs, which might be overridden.
//
// Although these are all similar, we don't want extra macro expansions,
// so we define each one explicitly rather than relying on a common macro.
//----------------------------------------------------------------------------
// signal that a parameter is intentionally unused.
#ifndef LMIC_UNREFERENCED_PARAMETER
# define LMIC_UNREFERENCED_PARAMETER(v) do { (void) (v); } while (0)
#endif
// an API parameter is a parameter that is required by an API definition, but
// happens to be unreferenced in this implementation. This is a stronger
// assertion than LMIC_UNREFERENCED_PARAMETER(): this parameter is here
// becuase of an API contract, but we have no use for it in this function.
#ifndef LMIC_API_PARAMETER
# define LMIC_API_PARAMETER(v) do { (void) (v); } while (0)
#endif
// an intentionally-unreferenced variable.
#ifndef LMIC_UNREFERENCED_VARIABLE
# define LMIC_UNREFERENCED_VARIABLE(v) do { (void) (v); } while (0)
#endif
// we have three (!) debug levels (LMIC_DEBUG_LEVEL > 0, LMIC_DEBUG_LEVEL > 1,
// and LMIC_X_DEBUG_LEVEL > 0. In each case we might have parameters or
// or varables that are only refereneced at the target debug level.
// Parameter referenced only if debugging at level > 0.
#ifndef LMIC_DEBUG1_PARAMETER
# if LMIC_DEBUG_LEVEL > 0
# define LMIC_DEBUG1_PARAMETER(v) do { ; } while (0)
# else
# define LMIC_DEBUG1_PARAMETER(v) do { (void) (v); } while (0)
# endif
#endif
// variable referenced only if debugging at level > 0
#ifndef LMIC_DEBUG1_VARIABLE
# if LMIC_DEBUG_LEVEL > 0
# define LMIC_DEBUG1_VARIABLE(v) do { ; } while (0)
# else
# define LMIC_DEBUG1_VARIABLE(v) do { (void) (v); } while (0)
# endif
#endif
// parameter referenced only if debugging at level > 1
#ifndef LMIC_DEBUG2_PARAMETER
# if LMIC_DEBUG_LEVEL > 1
# define LMIC_DEBUG2_PARAMETER(v) do { ; } while (0)
# else
# define LMIC_DEBUG2_PARAMETER(v) do { (void) (v); } while (0)
# endif
#endif
// variable referenced only if debugging at level > 1
#ifndef LMIC_DEBUG2_VARIABLE
# if LMIC_DEBUG_LEVEL > 1
# define LMIC_DEBUG2_VARIABLE(v) do { ; } while (0)
# else
# define LMIC_DEBUG2_VARIABLE(v) do { (void) (v); } while (0)
# endif
#endif
// parameter referenced only if LMIC_X_DEBUG_LEVEL > 0
#ifndef LMIC_X_DEBUG_PARAMETER
# if LMIC_X_DEBUG_LEVEL > 0
# define LMIC_X_DEBUG_PARAMETER(v) do { ; } while (0)
# else
# define LMIC_X_DEBUG_PARAMETER(v) do { (void) (v); } while (0)
# endif
#endif
// variable referenced only if LMIC_X_DEBUG_LEVEL > 0
#ifndef LMIC_X_DEBUG_VARIABLE
# if LMIC_X_DEBUG_LEVEL > 0
# define LMIC_X_DEBUG_VARIABLE(v) do { ; } while (0)
# else
# define LMIC_X_DEBUG_VARIABLE(v) do { (void) (v); } while (0)
# endif
#endif
// parameter referenced only if EV() macro is enabled (which it never is)
// TODO(tmm@mcci.com) take out the EV() framework as it reuqires C++, and
// this code is really C-99 to its bones.
#ifndef LMIC_EV_PARAMETER
# define LMIC_EV_PARAMETER(v) do { (void) (v); } while (0)
#endif
// variable referenced only if EV() macro is defined.
#ifndef LMIC_EV_VARIABLE
# define LMIC_EV_VARIABLE(v) do { (void) (v); } while (0)
#endif
#define ON_LMIC_EVENT(ev) onEvent(ev)
#define DECL_ON_LMIC_EVENT void onEvent(ev_t e)
@ -108,8 +215,8 @@ struct oslmic_radio_rssi_s {
};
int radio_init (void);
// ttn-esp32 extension: time parameter for radio_irq_handler
void radio_irq_handler (u1_t dio, ostime_t now);
void radio_irq_handler (u1_t dio);
void radio_irq_handler_v2 (u1_t dio, ostime_t tref);
void os_init (void);
int os_init_ex (const void *pPinMap);
void os_runloop (void);
@ -258,7 +365,7 @@ u2_t os_crc16 (xref2cu1_t d, uint len);
// progmem using pgm_read_xx, or accesses memory directly when the
// index is a constant so gcc can optimize it away;
#define TABLE_GETTER(postfix, type, pgm_type) \
inline type table_get ## postfix(const type *table, size_t index) { \
static inline type table_get ## postfix(const type *table, size_t index) { \
if (__builtin_constant_p(table[index])) \
return table[index]; \
return pgm_read_ ## pgm_type(&table[index]); \
@ -278,13 +385,13 @@ u2_t os_crc16 (xref2cu1_t d, uint len);
// For AVR, store constants in PROGMEM, saving on RAM usage
#define CONST_TABLE(type, name) const type PROGMEM RESOLVE_TABLE(name)
#else
inline u1_t table_get_u1(const u1_t *table, size_t index) { return table[index]; }
inline s1_t table_get_s1(const s1_t *table, size_t index) { return table[index]; }
inline u2_t table_get_u2(const u2_t *table, size_t index) { return table[index]; }
inline s2_t table_get_s2(const s2_t *table, size_t index) { return table[index]; }
inline u4_t table_get_u4(const u4_t *table, size_t index) { return table[index]; }
inline s4_t table_get_s4(const s4_t *table, size_t index) { return table[index]; }
inline ostime_t table_get_ostime(const ostime_t *table, size_t index) { return table[index]; }
static inline u1_t table_get_u1(const u1_t *table, size_t index) { return table[index]; }
static inline s1_t table_get_s1(const s1_t *table, size_t index) { return table[index]; }
static inline u2_t table_get_u2(const u2_t *table, size_t index) { return table[index]; }
static inline s2_t table_get_s2(const s2_t *table, size_t index) { return table[index]; }
static inline u4_t table_get_u4(const u4_t *table, size_t index) { return table[index]; }
static inline s4_t table_get_s4(const s4_t *table, size_t index) { return table[index]; }
static inline ostime_t table_get_ostime(const ostime_t *table, size_t index) { return table[index]; }
// Declare a table
#define CONST_TABLE(type, name) const type RESOLVE_TABLE(name)

32
src/lmic/radio.c Executable file → Normal file
View File

@ -567,9 +567,8 @@ static void txlora () {
u1_t sf = getSf(LMIC.rps) + 6; // 1 == SF7
u1_t bw = getBw(LMIC.rps);
u1_t cr = getCr(LMIC.rps);
// ttn-esp32 change: fix printf for for ostime_t and freq
LMIC_DEBUG_PRINTF("%u: TXMODE, freq=%u, len=%d, SF=%d, BW=%d, CR=4/%d, IH=%d\n",
(unsigned)os_getTime(), LMIC.freq, LMIC.dataLen, sf,
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": TXMODE, freq=%"PRIu32", len=%d, SF=%d, BW=%d, CR=4/%d, IH=%d\n",
os_getTime(), LMIC.freq, LMIC.dataLen, sf,
bw == BW125 ? 125 : (bw == BW250 ? 250 : 500),
cr == CR_4_5 ? 5 : (cr == CR_4_6 ? 6 : (cr == CR_4_7 ? 7 : 8)),
getIh(LMIC.rps)
@ -675,8 +674,7 @@ static void rxlora (u1_t rxmode) {
opmode(OPMODE_RX_SINGLE);
#if LMIC_DEBUG_LEVEL > 0
ostime_t now = os_getTime();
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("start single rx: now-rxtime: %u\n", (unsigned)(now - LMIC.rxtime));
LMIC_DEBUG_PRINTF("start single rx: now-rxtime: %"LMIC_PRId_ostime_t"\n", now - LMIC.rxtime);
#endif
} else { // continous rx (scan or rssi)
opmode(OPMODE_RX);
@ -689,9 +687,8 @@ static void rxlora (u1_t rxmode) {
u1_t sf = getSf(LMIC.rps) + 6; // 1 == SF7
u1_t bw = getBw(LMIC.rps);
u1_t cr = getCr(LMIC.rps);
// ttn-esp32 change: fix printf for for ostime_t and freq
LMIC_DEBUG_PRINTF("%u: %s, freq=%u, SF=%d, BW=%d, CR=4/%d, IH=%d\n",
(unsigned)os_getTime(),
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": %s, freq=%"PRIu32", SF=%d, BW=%d, CR=4/%d, IH=%d\n",
os_getTime(),
rxmode == RXMODE_SINGLE ? "RXMODE_SINGLE" : (rxmode == RXMODE_SCAN ? "RXMODE_SCAN" : "UNKNOWN_RX"),
LMIC.freq, sf,
bw == BW125 ? 125 : (bw == BW250 ? 250 : 500),
@ -937,9 +934,17 @@ static CONST_TABLE(u2_t, LORA_RXDONE_FIXUP)[] = {
// called by hal ext IRQ handler
// (radio goes to stanby mode after tx/rx operations)
// ttn-esp32 change: additional time paramter
void radio_irq_handler (u1_t dio, ostime_t now) {
void radio_irq_handler (u1_t dio) {
radio_irq_handler_v2(dio, os_getTime());
}
void radio_irq_handler_v2 (u1_t dio, ostime_t now) {
LMIC_API_PARAMETER(dio);
#if CFG_TxContinuousMode
// in continuous mode, we don't use the now parameter.
LMIC_UNREFERENCED_PARAMETER(now);
// clear radio IRQ flags
writeReg(LORARegIrqFlags, 0xFF);
u1_t p = readReg(LORARegFifoAddrPtr);
@ -949,8 +954,7 @@ void radio_irq_handler (u1_t dio, ostime_t now) {
opmode(OPMODE_TX);
return;
#else /* ! CFG_TxContinuousMode */
// ttn-esp32 change: use provided time parameter
// ostime_t now = os_getTime();
#if LMIC_DEBUG_LEVEL > 0
ostime_t const entry = now;
#endif
@ -983,8 +987,8 @@ void radio_irq_handler (u1_t dio, ostime_t now) {
LMIC.dataLen = 0;
#if LMIC_DEBUG_LEVEL > 0
ostime_t now2 = os_getTime();
// ttn-esp32 change: fix printf for for ostime_t
LMIC_DEBUG_PRINTF("rxtimeout: entry: %u rxtime: %u entry-rxtime: %d now-entry: %d rxtime-txend: %d\n", (unsigned)entry, (unsigned)LMIC.rxtime, entry - LMIC.rxtime, now2 - entry, LMIC.rxtime-LMIC.txend);
LMIC_DEBUG_PRINTF("rxtimeout: entry: %"LMIC_PRId_ostime_t" rxtime: %"LMIC_PRId_ostime_t" entry-rxtime: %"LMIC_PRId_ostime_t" now-entry: %"LMIC_PRId_ostime_t" rxtime-txend: %"LMIC_PRId_ostime_t"\n", entry,
LMIC.rxtime, entry - LMIC.rxtime, now2 - entry, LMIC.rxtime-LMIC.txend);
#endif
}
// mask all radio IRQs