From 05416800cd3f3681db49201fe4335835ef91c1a2 Mon Sep 17 00:00:00 2001 From: Michael Coracin Date: Fri, 18 Dec 2020 11:11:19 +0100 Subject: [PATCH] v2.0.1 > #### Updates The fine timestamping feature has been fully validated with this release. > #### Changes * HAL: Adjusted the freq_offset field of received packets, to take into account the channel IF resolution error. * HAL: Refined the fine timestamp offset compared to Gateway v2, by taking into account the frequency offset of the received packet. * HAL: Fixed the preamble length for FSK downlinks * MCU: Removed the binary compiled in debug mode. * util_spectral_scan: actually use the nb_scan input argument which was ignored. --- VERSION | 2 +- libloragw/inc/loragw_sx1302_timestamp.h | 2 +- libloragw/src/loragw_sx1302.c | 31 +++++++++++++++++++----- libloragw/src/loragw_sx1302_timestamp.c | 5 +++- mcu_bin/dbg_000206_CoreCell_USB.bin | Bin 56112 -> 0 bytes readme.md | 18 +++++++++++++- util_spectral_scan/src/spectral_scan.c | 2 +- 7 files changed, 49 insertions(+), 11 deletions(-) delete mode 100644 mcu_bin/dbg_000206_CoreCell_USB.bin diff --git a/VERSION b/VERSION index 227cea2..38f77a6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 +2.0.1 diff --git a/libloragw/inc/loragw_sx1302_timestamp.h b/libloragw/inc/loragw_sx1302_timestamp.h index 4e4b5fd..cd16ab8 100644 --- a/libloragw/inc/loragw_sx1302_timestamp.h +++ b/libloragw/inc/loragw_sx1302_timestamp.h @@ -141,7 +141,7 @@ int timestamp_counter_mode(bool ftime_enable); @param result_ftime A pointer to store the resulting fine timestamp @return 0 if success, -1 otherwise */ -int precise_timestamp_calculate(uint8_t ts_metrics_nb, const int8_t * ts_metrics, uint32_t pkt_coarse_tmst, uint8_t sf, int32_t if_freq_hz, uint32_t * result_ftime); +int precise_timestamp_calculate(uint8_t ts_metrics_nb, const int8_t * ts_metrics, uint32_t pkt_coarse_tmst, uint8_t sf, int32_t if_freq_hz, double pkt_freq_error, uint32_t * result_ftime); #endif diff --git a/libloragw/src/loragw_sx1302.c b/libloragw/src/loragw_sx1302.c index 9a3c7ee..aa330cd 100644 --- a/libloragw/src/loragw_sx1302.c +++ b/libloragw/src/loragw_sx1302.c @@ -49,7 +49,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project #endif #define CHECK_ERR(a) if(a==-1){return LGW_REG_ERROR;} -#define IF_HZ_TO_REG(f) ((f << 5) / 15625) +#define IF_HZ_TO_REG(f) ((f * 32) / 15625) #define SX1302_FREQ_TO_REG(f) (uint32_t)((uint64_t)f * (1 << 18) / 32000000U) @@ -1897,6 +1897,9 @@ int sx1302_fetch(uint8_t * nb_pkt) { int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p) { int err; int ifmod; /* type of if_chain/modem a packet was received by */ + int32_t if_freq_hz; + int32_t if_freq_error; + double pkt_freq_error; uint16_t payload_crc16_calc; uint8_t cr; int32_t timestamp_correction; @@ -2065,14 +2068,32 @@ int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p) { break; } + /* Adjust the frequency offset with channel IF frequency error: + When the channel IF frequency has been configured, a precision error may have been introduced + due to the register precision. We calculate this error here, and adjust the returned frequency error + accordingly. */ + if_freq_hz = context->if_chain_cfg[p->if_chain].freq_hz; /* The IF frequency set in the registers, is the offset from the zero IF. */ + if_freq_error = if_freq_hz - (IF_HZ_TO_REG(if_freq_hz) * 15625 / 32); /* The error corresponds to how many Hz are missing to get to actual 0 IF. */ + /* Example to better understand what we get here: + - For a channel set to IF 400000Hz + - The IF frequency register will actually be set to 399902Hz due to its resolution + - This means that the modem, to shift to 0 IF, will apply -399902, instead of -400000. + - This means that the modem will be centered +98hz above the real 0 IF + - As the freq_offset given is supposed to be relative to the 0 IF, we add this resolution error to it */ + p->freq_offset += if_freq_error; + /* Get timestamp correction to be applied to count_us */ timestamp_correction = timestamp_counter_correction(context, p->bandwidth, p->datarate, p->coderate, pkt.crc_en, pkt.rxbytenb_modem, RX_DFT_PEAK_MODE_AUTO); - /* Compute fine timestmap for packets coming from the modem optimized for fine timestamping, if CRC is OK */ + /* Compute fine timestamp for packets coming from the modem optimized for fine timestamping, if CRC is OK */ p->ftime_received = false; p->ftime = 0; if ((pkt.num_ts_metrics_stored > 0) && (pkt.timing_set == true) && (p->status == STAT_CRC_OK)) { - err = precise_timestamp_calculate(pkt.num_ts_metrics_stored, &pkt.timestamp_avg[0], pkt.timestamp_cnt, pkt.rx_rate_sf, context->if_chain_cfg[p->if_chain].freq_hz, &(p->ftime)); + /* The actual packet frequency error compared to the channel frequency, need to compute the ftime */ + pkt_freq_error = ((double)(p->freq_hz + p->freq_offset) / (double)(p->freq_hz)) - 1.0; + + /* Compute the fine timestamp */ + err = precise_timestamp_calculate(pkt.num_ts_metrics_stored, &pkt.timestamp_avg[0], pkt.timestamp_cnt, pkt.rx_rate_sf, context->if_chain_cfg[p->if_chain].freq_hz, pkt_freq_error, &(p->ftime)); if (err == 0) { p->ftime_received = true; } @@ -2691,7 +2712,7 @@ int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut, DEBUG_MSG("Note: preamble length adjusted to respect minimum FSK preamble size\n"); } buff[0] = (uint8_t)(pkt_data->preamble >> 8); - buff[1] = (uint8_t)(pkt_data->preamble >> 8); + buff[1] = (uint8_t)(pkt_data->preamble >> 0); err = lgw_reg_wb(SX1302_REG_TX_TOP_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE(pkt_data->rf_chain), buff, 2); CHECK_ERR(err); @@ -2798,8 +2819,6 @@ double sx1302_dc_notch_delay(double if_freq_khz) { delay = 1.7e-6 * pow(if_freq_khz, 4) + 2.4e-6 * pow(if_freq_khz, 3) - 0.0101 * pow(if_freq_khz, 2) - 0.01275 * if_freq_khz + 10.2922; } - printf("SX1302: DC notch filter delay : %f\n", delay); - /* Number of 32MHz clock cycles */ return delay; } diff --git a/libloragw/src/loragw_sx1302_timestamp.c b/libloragw/src/loragw_sx1302_timestamp.c index dc49c37..effeaa0 100644 --- a/libloragw/src/loragw_sx1302_timestamp.c +++ b/libloragw/src/loragw_sx1302_timestamp.c @@ -475,7 +475,7 @@ int32_t timestamp_counter_correction(lgw_context_t * context, uint8_t bandwidth, /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -int precise_timestamp_calculate(uint8_t ts_metrics_nb, const int8_t * ts_metrics, uint32_t timestamp_cnt, uint8_t sf, int32_t if_freq_hz, uint32_t * result_ftime) { +int precise_timestamp_calculate(uint8_t ts_metrics_nb, const int8_t * ts_metrics, uint32_t timestamp_cnt, uint8_t sf, int32_t if_freq_hz, double pkt_freq_error, uint32_t * result_ftime) { int i, x, timestamp_pps_idx, timestamp_pps_idx_next, timestamp_pps_idx_prev; int32_t ftime_sum; int32_t ftime[256]; @@ -504,6 +504,9 @@ int precise_timestamp_calculate(uint8_t ts_metrics_nb, const int8_t * ts_metrics offset_preamble_hdr = 256 * (1 << sf) * (8 + 4 + (((sf == 5) || (sf == 6)) ? 2 : 0)) + 256 * ((1 << sf) / 4 - 1); /* 32e6 / 125e3 = 256 */ + /* Take the packet frequency error in account in the offset */ + offset_preamble_hdr += ((double)offset_preamble_hdr * pkt_freq_error + 0.5); + timestamp_cnt_end_of_preamble = timestamp_cnt - offset_preamble_hdr + 2138; /* 2138 is the number of 32MHz clock cycle offset b/w GW_V2 and SX1303 decimation/filtering group delay */ /* Shift the packet coarse timestamp which is used to get ref PPS counter */ diff --git a/mcu_bin/dbg_000206_CoreCell_USB.bin b/mcu_bin/dbg_000206_CoreCell_USB.bin deleted file mode 100644 index 32fc9c5b2d2dc4de8742174984143cbe4931ef1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56112 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 Mmd>cf%@_Rs7h%S)+yDRo diff --git a/readme.md b/readme.md index ac396a7..c3fed49 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ more details. Those programs are included in the project to provide examples on how to use the HAL library, and to help the system builder test different parts of it. -### 2.1. packet_frowarder ### +### 2.1. packet_forwarder ### The packet forwarder is a program running on the host of a Lora gateway that forwards RF packets receive by the concentrator to a server through a IP/UDP @@ -191,6 +191,22 @@ found in the `libtools` directory. ## 7. Changelog +### v2.0.1 ### + +> #### Updates + +The fine timestamping feature has been fully validated with this release. + +> #### Changes + +* HAL: Adjusted the freq_offset field of received packets, to take into account +the channel IF resolution error. +* HAL: Refined the fine timestamp offset compared to Gateway v2, by taking into +account the frequency offset of the received packet. +* HAL: Fixed the preamble length for FSK downlinks +* MCU: Removed the binary compiled in debug mode. +* util_spectral_scan: actually use the nb_scan input argument which was ignored. + ### v2.0.0 ### > #### New features diff --git a/util_spectral_scan/src/spectral_scan.c b/util_spectral_scan/src/spectral_scan.c index 0c48248..b9f336e 100644 --- a/util_spectral_scan/src/spectral_scan.c +++ b/util_spectral_scan/src/spectral_scan.c @@ -285,7 +285,7 @@ int main(int argc, char **argv) /* Launch Spectral Scan on each channels */ for (j = 0; j < nb_channels; j++) { - x = lgw_spectral_scan_start(freq_hz, 2000); + x = lgw_spectral_scan_start(freq_hz, nb_scan); if (x != 0) { printf("ERROR: spectral scan start failed\n"); continue;