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 32fc9c5..0000000 Binary files a/mcu_bin/dbg_000206_CoreCell_USB.bin and /dev/null differ 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;