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.
This commit is contained in:
parent
2c14708bdb
commit
05416800cd
7 changed files with 49 additions and 11 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
2.0.0
|
2.0.1
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ int timestamp_counter_mode(bool ftime_enable);
|
||||||
@param result_ftime A pointer to store the resulting fine timestamp
|
@param result_ftime A pointer to store the resulting fine timestamp
|
||||||
@return 0 if success, -1 otherwise
|
@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
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||||
#endif
|
#endif
|
||||||
#define CHECK_ERR(a) if(a==-1){return LGW_REG_ERROR;}
|
#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)
|
#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 sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p) {
|
||||||
int err;
|
int err;
|
||||||
int ifmod; /* type of if_chain/modem a packet was received by */
|
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;
|
uint16_t payload_crc16_calc;
|
||||||
uint8_t cr;
|
uint8_t cr;
|
||||||
int32_t timestamp_correction;
|
int32_t timestamp_correction;
|
||||||
|
|
@ -2065,14 +2068,32 @@ int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p) {
|
||||||
break;
|
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 */
|
/* 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);
|
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_received = false;
|
||||||
p->ftime = 0;
|
p->ftime = 0;
|
||||||
if ((pkt.num_ts_metrics_stored > 0) && (pkt.timing_set == true) && (p->status == STAT_CRC_OK)) {
|
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) {
|
if (err == 0) {
|
||||||
p->ftime_received = true;
|
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");
|
DEBUG_MSG("Note: preamble length adjusted to respect minimum FSK preamble size\n");
|
||||||
}
|
}
|
||||||
buff[0] = (uint8_t)(pkt_data->preamble >> 8);
|
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);
|
err = lgw_reg_wb(SX1302_REG_TX_TOP_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE(pkt_data->rf_chain), buff, 2);
|
||||||
CHECK_ERR(err);
|
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;
|
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 */
|
/* Number of 32MHz clock cycles */
|
||||||
return delay;
|
return delay;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
int i, x, timestamp_pps_idx, timestamp_pps_idx_next, timestamp_pps_idx_prev;
|
||||||
int32_t ftime_sum;
|
int32_t ftime_sum;
|
||||||
int32_t ftime[256];
|
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)) +
|
offset_preamble_hdr = 256 * (1 << sf) * (8 + 4 + (((sf == 5) || (sf == 6)) ? 2 : 0)) +
|
||||||
256 * ((1 << sf) / 4 - 1); /* 32e6 / 125e3 = 256 */
|
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 */
|
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 */
|
/* Shift the packet coarse timestamp which is used to get ref PPS counter */
|
||||||
|
|
|
||||||
Binary file not shown.
18
readme.md
18
readme.md
|
|
@ -26,7 +26,7 @@ more details.
|
||||||
Those programs are included in the project to provide examples on how to use
|
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.
|
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
|
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
|
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
|
## 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 ###
|
### v2.0.0 ###
|
||||||
|
|
||||||
> #### New features
|
> #### New features
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* Launch Spectral Scan on each channels */
|
/* Launch Spectral Scan on each channels */
|
||||||
for (j = 0; j < nb_channels; j++) {
|
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) {
|
if (x != 0) {
|
||||||
printf("ERROR: spectral scan start failed\n");
|
printf("ERROR: spectral scan start failed\n");
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue