From e1e48b492b6ee8027f5742f6bca28f9329b628a3 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 7 Dec 2018 12:47:06 +0200 Subject: [PATCH] Final cleanup and ASCII art for algorithm v2 Final code cleanup and adding ascii art for the version 2 of the algorithm. --- features/lorawan/lorastack/phy/LoRaPHY.cpp | 12 +-- features/lorawan/lorastack/phy/LoRaPHY.h | 85 ++++++++++++------- features/lorawan/mbed_lib.json | 2 +- .../lorawan/system/lorawan_data_structures.h | 7 +- 4 files changed, 63 insertions(+), 43 deletions(-) diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index 8f8c3b21f2..29414ee7aa 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -32,8 +32,8 @@ SPDX-License-Identifier: BSD-3-Clause #define BACKOFF_DC_1_HOUR 100 #define BACKOFF_DC_10_HOURS 1000 #define BACKOFF_DC_24_HOURS 10000 -#define MAX_PREAMBLE_LENGTH 8.0 -#define TICK_GRANULARITY_JITTER 1.0 +#define MAX_PREAMBLE_LENGTH 8.0f +#define TICK_GRANULARITY_JITTER 1.0f #define CHANNELS_IN_MASK 16 LoRaPHY::LoRaPHY() @@ -397,7 +397,7 @@ float LoRaPHY::compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth) float LoRaPHY::compute_symb_timeout_fsk(uint8_t phy_dr) { - return (8.0 / (float) phy_dr); // 1 symbol equals 1 byte + return (8.0f / (float) phy_dr); // 1 symbol equals 1 byte } @@ -420,11 +420,11 @@ void LoRaPHY::get_rx_window_params(float t_symb, uint8_t min_rx_symb, // Actual window offset in ms in response to timing error fudge factor and // radio wakeup/turned around time. - *window_offset = floor(target_rx_window_offset - error_fudge - MBED_CONF_LORA_WAKEUP_TIME); + *window_offset = floor(target_rx_window_offset - error_fudge - wakeup_time); // possible wait for next symbol start if we start inside the preamble float possible_wait_for_symb_start = MIN(t_symb, - ((2 * error_fudge) + MBED_CONF_LORA_WAKEUP_TIME + TICK_GRANULARITY_JITTER)); + ((2 * error_fudge) + wakeup_time + TICK_GRANULARITY_JITTER)); // how early we might start reception relative to transmit start (so negative if before transmit starts) float earliest_possible_start_time = *window_offset - error_fudge - TICK_GRANULARITY_JITTER; @@ -845,7 +845,7 @@ void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, rx_conf_params->frequency = phy_params.channels.channel_list[rx_conf_params->channel].frequency; } - get_rx_window_params(t_symbol, min_rx_symbols, (float) rx_error, RADIO_WAKEUP_TIME, + get_rx_window_params(t_symbol, min_rx_symbols, (float) rx_error, MBED_CONF_LORA_WAKEUP_TIME, &rx_conf_params->window_timeout, &rx_conf_params->window_offset, rx_conf_params->datarate); } diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index a81b5bc779..d6be36b1dc 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -202,40 +202,63 @@ public: /** Computing Receive Windows * - * For more details please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf + * The algorithm tries to calculate the length of receive windows (i.e., + * the minimum time it should remain to acquire a lock on the Preamble + * for synchronization) and the error offset which compensates for the system + * timing errors. Basic idea behind the algorithm is to optimize for the + * reception of last 'min_rx_symbols' symbols out of transmitted Premable + * symbols. The algorithm compensates for the clock drifts, tick granularity + * and system wake up time (from sleep state) by opening the window early for + * the lower SFs. For higher SFs, the symbol time is large enough that we can + * afford to open late (hence the positive offset). + * The table below shows the calculated values for SF7 to SF12 with 125 kHz + * bandwidth. * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | + * +----+-----+----------+---------+-------------------------+----------------------+-------------------------+ + * | SF | BW (kHz) | rx_error (ms) | wake_up (ms) | min_rx_symbols | window_timeout(symb) | window_offset(ms) | + * +----+-----+----------+---------+-------------------------+----------------------+-------------------------+ + * | 7 | 125 | 5 | 5 | 5 | 18 | -7 | + * | 8 | 125 | 5 | 5 | 5 | 10 | -4 | + * | 9 | 125 | 5 | 5 | 5 | 6 | 2 | + * | 10 | 125 | 5 | 5 | 5 | 6 | 14 | + * | 11 | 125 | 5 | 5 | 5 | 6 | 39 | + * | 12 | 125 | 5 | 5 | 5 | 6 | 88 | + * +----+-----+----------+---------+-------------------------+----------------------+-------------------------+ + * + * For example for SF7, the receive window will open at downlink start time + * plus the offset calculated and will remain open for the length window_timeout. + * + * Symbol time = 1.024 ms + * Downlink start: T = Tx + 1s (+/- 20 us) + * | + * | + * | + * | + * | + * +---+---+---+---+---+---+---+---+ + * | 8 Preamble Symbols | + * +---+---+---+---+---+---+---+---+ + * | RX Window start time = T +/- Offset + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * | | | | | | | | | | | | | | | | | | | + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * + * Similarly for SF12: + * + * Symbol time = 32.768 ms + * Downlink start: T = Tx + 1s (+/- 20 us) + * | + * | + * | + * | + * | * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | + * | 8 Preamble Symbols | * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol. + * | RX Window start time = T +/- Offset + * +---+---+---+---+---+---+ + * | | | | | | | + * +---+---+---+---+---+---+ */ /*! * Computes the RX window timeout and offset. diff --git a/features/lorawan/mbed_lib.json b/features/lorawan/mbed_lib.json index 967e7c8783..30e130b364 100644 --- a/features/lorawan/mbed_lib.json +++ b/features/lorawan/mbed_lib.json @@ -78,7 +78,7 @@ "value": 5 }, "downlink-preamble-length": { - "help": "Number of whole preamble symbols needed to have a firm lock on the signal. Default: 5 + 1", + "help": "Number of whole preamble symbols needed to have a firm lock on the signal.", "value": 5 }, "uplink-preamble-length": { diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index a6e14ed197..dafcb29ff1 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -44,9 +44,6 @@ typedef uint32_t lorawan_time_t; #endif -// Radio wake-up time from sleep - unit ms. -#define RADIO_WAKEUP_TIME 1.0 - /*! * Sets the length of the LoRaMAC footer field. * Mainly indicates the MIC field length. @@ -1259,8 +1256,8 @@ typedef struct { /*! * LoRaMac reception windows delay - * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME - * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME + * \remark normal frame: RxWindowXDelay = ReceiveDelayX - Offset + * join frame : RxWindowXDelay = JoinAcceptDelayX - Offset */ uint32_t rx_window1_delay; uint32_t rx_window2_delay;