Skip to content

Commit

Permalink
Fix #442: re-adjust window calcuations, expand jitter, fix clock erro…
Browse files Browse the repository at this point in the history
…r, so we arrive on-time
  • Loading branch information
terrillmoore committed Dec 30, 2019
1 parent 1752835 commit bf24989
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 22 deletions.
20 changes: 13 additions & 7 deletions src/lmic/lmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1476,16 +1476,22 @@ ostime_t LMICcore_adjustForDrift (ostime_t delay, ostime_t hsym, rxsyms_t rxsyms
// If the clock is slow, the window needs to open earlier in our time
// in order to open at or before the specified time (in real world),.
// Don't bother to round, as this is very fine-grained.
// and bear in mind that the delay is always
ostime_t drift = (ostime_t)(((int64_t)delay * clockerr) / MAX_CLOCK_ERROR);

// we add symbols if we're starting tx before the window.
rxoffset -= drift;

// if we're starting before the window, extend the number of symbols
// for timeout appropriately.
// calculate the additional rxsyms needed to hit the window nominally.
ostime_t const tsym = 2 * hsym;
ostime_t driftwin;
driftwin = 2 * drift;
if (rxoffset < 0)
rxsyms_in += (-rxoffset + 2 * hsym - 1) / (2 * hsym);
driftwin += -rxoffset;
// else we'll hit the window nominally.

rxsyms_in += (driftwin + tsym - 1) / tsym;

// reduce the rxoffset by the drift; this compensates for a slow clock;
// but it makes the rxtime too early by approximately `drift` if clock
// is fast.
rxoffset -= drift;

setRxsyms(rxsyms_in);

Expand Down
5 changes: 3 additions & 2 deletions src/lmic/lmic.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,14 @@ enum {
MAX_CLOCK_ERROR = 65536,
//! \brief maximum clock error that users can specify: 2000 ppm (0.2%).
//! \details This is the limit for clock error, unless LMIC_ENABLE_arbitrary_clock_error is set.
//! The default is 2,000 ppm, which is .002, or 0.2%. If your clock error is bigger,
//! The default is 4,000 ppm, which is .004, or 0.4%; this is what you get on an
//! STM32L0 running with the HSI oscillator after cal. If your clock error is bigger,
//! usually you want to calibrate it so that millis() and micros() are reasonably
//! accurate. Important: do not use clock error to compensate for late serving
//! of the LMIC. If you see that LMIC.radio.rxlate_count is increasing, you need
//! to adjust your application logic so the LMIC gets serviced promptly when a
//! Class A downlink (or beacon) is pending.
LMIC_kMaxClockError_ppm = 2000,
LMIC_kMaxClockError_ppm = 4000,
};

// callbacks for client alerts.
Expand Down
4 changes: 2 additions & 2 deletions src/lmic/oslmic.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,15 @@ void radio_monitor_rssi(ostime_t n, oslmic_radio_rssi_t *pRssi);
// to platform issues. It's specified in units of ostime_t. It must reflect
// platform jitter and latency, as well as the speed of the LMIC when running
// on this plaform.
#define RX_RAMPUP (us2osticks(2000))
#define RX_RAMPUP (us2osticks(10000))
#endif

#ifndef TX_RAMPUP
// TX_RAMPUP specifies the extra time we must allow to set up a TX event) due
// to platform issues. It's specified in units of ostime_t. It must reflect
// platform jitter and latency, as well as the speed of the LMIC when running
// on this plaform.
#define TX_RAMPUP (us2osticks(2000))
#define TX_RAMPUP (us2osticks(10000))
#endif

#ifndef OSTICKS_PER_SEC
Expand Down
27 changes: 16 additions & 11 deletions src/lmic/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,18 @@ static CONST_TABLE(u1_t, rxlorairqmask)[] = {
[RXMODE_RSSI] = 0x00,
};

//! \brief handle late RX events.
//! \param nLate is the number of `ostime_t` ticks that the event was late.
//! \details If nLate is non-zero, increment the count of events, totalize
//! the number of ticks late, and (if implemented) adjust the estimate of
//! what would be best to return from `os_getRadioRxRampup()`.
static void rxlate (u4_t nLate) {
if (nLate) {
LMIC.radio.rxlate_ticks += nLate;
++LMIC.radio.rxlate_count;
}
}

// start LoRa receiver (time=LMIC.rxtime, timeout=LMIC.rxsyms, result=LMIC.frame[LMIC.dataLen])
static void rxlora (u1_t rxmode) {
// select LoRa modem (from sleep mode)
Expand Down Expand Up @@ -966,13 +978,9 @@ static void rxlora (u1_t rxmode) {
// now instruct the radio to receive
if (rxmode == RXMODE_SINGLE) { // single rx
u4_t nLate = hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
LMICOS_logEventUint32("+Rx LoRa Single", nLate);
opmode(OPMODE_RX_SINGLE);
if (nLate)
{
++LMIC.radio.rxlate_count;
LMIC.radio.rxlate_ticks += nLate;
}
LMICOS_logEventUint32("+Rx LoRa Single", nLate);
rxlate(nLate);
#if LMIC_DEBUG_LEVEL > 0
ostime_t now = os_getTime();
LMIC_DEBUG_PRINTF("start single rx: now-rxtime: %"LMIC_PRId_ostime_t"\n", now - LMIC.rxtime);
Expand Down Expand Up @@ -1042,12 +1050,9 @@ static void rxfsk (u1_t rxmode) {
// now instruct the radio to receive
if (rxmode == RXMODE_SINGLE) {
u4_t nLate = hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
LMICOS_logEventUint32("+Rx FSK", nLate);
opmode(OPMODE_RX); // no single rx mode available in FSK
if (nLate) {
LMIC.radio.rxlate_ticks += nLate;
++LMIC.radio.rxlate_count;
}
LMICOS_logEventUint32("+Rx FSK", nLate);
rxlate(nLate);
} else {
LMICOS_logEvent("+Rx FSK Continuous");
opmode(OPMODE_RX);
Expand Down

0 comments on commit bf24989

Please sign in to comment.