v1.0.5
* HAL: Fixed packet timestamp issue which was "jumping in time" in specific conditions. * HAL: Workaround hardware issue when reading 32-bits registers (timestamp, nb bytes in RX buffer...) * HAL: Fixed potential endless loop in sx1302_tx_abort() in SPI access fails. * Packet Forwarder: Added global_conf.json.sx1250.US915 for US915 band * test_hal_rx: added command line to specify RSSI offset to be applied
This commit is contained in:
parent
81e748c904
commit
6291e62ef9
8 changed files with 240 additions and 68 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
1.0.4
|
1.0.5
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,15 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@struct timestamp_counter_s
|
@struct timestamp_counter_s
|
||||||
@brief context to maintain the internal counters (inst and pps trig) wrapping
|
@brief context to maintain the internal counters (inst and pps trig) rollover status
|
||||||
*/
|
*/
|
||||||
|
struct timestamp_info_s {
|
||||||
|
uint32_t counter_us_27bits_ref; /* reference value (last read) */
|
||||||
|
uint8_t counter_us_27bits_wrap; /* rollover/wrap status */
|
||||||
|
};
|
||||||
typedef struct timestamp_counter_s {
|
typedef struct timestamp_counter_s {
|
||||||
uint32_t counter_us_raw_27bits_inst_prev;
|
struct timestamp_info_s inst; /* holds current reference of the instantaneous counter */
|
||||||
uint32_t counter_us_raw_27bits_pps_prev;
|
struct timestamp_info_s pps; /* holds current reference of the pps-trigged counter */
|
||||||
uint8_t counter_us_raw_27bits_inst_wrap;
|
|
||||||
uint8_t counter_us_raw_27bits_pps_wrap;
|
|
||||||
} timestamp_counter_t;
|
} timestamp_counter_t;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
@ -85,6 +87,14 @@ void timestamp_counter_update(timestamp_counter_t * self, bool pps, uint32_t cnt
|
||||||
*/
|
*/
|
||||||
uint32_t timestamp_counter_expand(timestamp_counter_t * self, bool pps, uint32_t cnt_us);
|
uint32_t timestamp_counter_expand(timestamp_counter_t * self, bool pps, uint32_t cnt_us);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Convert the 27-bits packet timestamp to a 32-bits counter which wraps on a uint32_t.
|
||||||
|
@param self Pointer to the counter handler
|
||||||
|
@param cnt_us The packet 27-bits counter to be expanded
|
||||||
|
@return the 32-bits counter
|
||||||
|
*/
|
||||||
|
uint32_t timestamp_pkt_expand(timestamp_counter_t * self, uint32_t cnt_us);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Reads the SX1302 internal counter register, and return the 32-bits 1 MHz counter
|
@brief Reads the SX1302 internal counter register, and return the 32-bits 1 MHz counter
|
||||||
@param self Pointer to the counter handler
|
@param self Pointer to the counter handler
|
||||||
|
|
|
||||||
|
|
@ -1812,10 +1812,15 @@ int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p) {
|
||||||
timestamp_correction = 0;
|
timestamp_correction = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scale packet timestamp to 1 MHz (microseconds) */
|
/* Update counter reference / wrap status before expanding */
|
||||||
|
timestamp_counter_get(&counter_us, false);
|
||||||
|
|
||||||
|
/* Scale 32 MHz packet timestamp to 1 MHz (microseconds) */
|
||||||
p->count_us = pkt.timestamp_cnt / 32;
|
p->count_us = pkt.timestamp_cnt / 32;
|
||||||
|
|
||||||
/* Expand 27-bits counter to 32-bits counter, based on current wrapping status */
|
/* Expand 27-bits counter to 32-bits counter, based on current wrapping status */
|
||||||
p->count_us = timestamp_counter_expand(&counter_us, false, p->count_us);
|
p->count_us = timestamp_pkt_expand(&counter_us, p->count_us);
|
||||||
|
|
||||||
/* Packet timestamp corrected */
|
/* Packet timestamp corrected */
|
||||||
p->count_us = p->count_us - timestamp_correction;
|
p->count_us = p->count_us - timestamp_correction;
|
||||||
|
|
||||||
|
|
@ -1940,7 +1945,7 @@ uint8_t sx1302_tx_status(uint8_t rf_chain) {
|
||||||
|
|
||||||
err = lgw_reg_r(SX1302_REG_TX_TOP_TX_FSM_STATUS_TX_STATUS(rf_chain), &read_value);
|
err = lgw_reg_r(SX1302_REG_TX_TOP_TX_FSM_STATUS_TX_STATUS(rf_chain), &read_value);
|
||||||
if (err != LGW_REG_SUCCESS) {
|
if (err != LGW_REG_SUCCESS) {
|
||||||
printf("ERROR: Failed to read TX STATUS");
|
printf("ERROR: Failed to read TX STATUS\n");
|
||||||
return TX_STATUS_UNKNOWN;
|
return TX_STATUS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1967,13 +1972,20 @@ uint8_t sx1302_rx_status(uint8_t rf_chain) {
|
||||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
int sx1302_tx_abort(uint8_t rf_chain) {
|
int sx1302_tx_abort(uint8_t rf_chain) {
|
||||||
lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_IMMEDIATE(rf_chain), 0x00);
|
int err;
|
||||||
lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_DELAYED(rf_chain), 0x00);
|
uint8_t tx_status;
|
||||||
lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_GPS(rf_chain), 0x00);
|
|
||||||
|
err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_IMMEDIATE(rf_chain), 0x00);
|
||||||
|
err |= lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_DELAYED(rf_chain), 0x00);
|
||||||
|
err |= lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_GPS(rf_chain), 0x00);
|
||||||
|
if (err != LGW_REG_SUCCESS) {
|
||||||
|
printf("ERROR: Failed to stop TX trigger\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
wait_ms(1);
|
wait_ms(1);
|
||||||
} while (sx1302_tx_status(rf_chain) != TX_FREE);
|
} while ((tx_status = sx1302_tx_status(rf_chain)) != TX_FREE && tx_status != TX_STATUS_UNKNOWN);
|
||||||
|
|
||||||
return LGW_REG_SUCCESS;
|
return LGW_REG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,14 +132,23 @@ int rx_buffer_del(rx_buffer_t * self) {
|
||||||
int rx_buffer_fetch(rx_buffer_t * self) {
|
int rx_buffer_fetch(rx_buffer_t * self) {
|
||||||
int i, res;
|
int i, res;
|
||||||
uint8_t buff[2];
|
uint8_t buff[2];
|
||||||
|
int32_t msb;
|
||||||
|
|
||||||
/* Check input params */
|
/* Check input params */
|
||||||
CHECK_NULL(self);
|
CHECK_NULL(self);
|
||||||
|
|
||||||
/* Check if there is data in the FIFO */
|
/* Check if there is data in the FIFO */
|
||||||
lgw_reg_rb(SX1302_REG_RX_TOP_RX_BUFFER_NB_BYTES_MSB_RX_BUFFER_NB_BYTES, buff, sizeof buff);
|
lgw_reg_rb(SX1302_REG_RX_TOP_RX_BUFFER_NB_BYTES_MSB_RX_BUFFER_NB_BYTES, buff, sizeof buff);
|
||||||
self->buffer_size = (uint16_t)((buff[0] << 8) & 0xFF00);
|
/* Workaround concentrator chip issue:
|
||||||
self->buffer_size |= (uint16_t)((buff[1] << 0) & 0x00FF);
|
- read MSB again
|
||||||
|
- if MSB changed, read the full size gain
|
||||||
|
*/
|
||||||
|
lgw_reg_r(SX1302_REG_RX_TOP_RX_BUFFER_NB_BYTES_MSB_RX_BUFFER_NB_BYTES, &msb);
|
||||||
|
if (buff[0] != (uint8_t)msb) {
|
||||||
|
lgw_reg_rb(SX1302_REG_RX_TOP_RX_BUFFER_NB_BYTES_MSB_RX_BUFFER_NB_BYTES, buff, sizeof buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->buffer_size = (buff[0] << 8) | (buff[1] << 0);
|
||||||
|
|
||||||
/* Fetch bytes from fifo if any */
|
/* Fetch bytes from fifo if any */
|
||||||
if (self->buffer_size > 0) {
|
if (self->buffer_size > 0) {
|
||||||
|
|
@ -277,13 +286,6 @@ int rx_buffer_pop(rx_buffer_t * self, rx_packet_t * pkt) {
|
||||||
pkt->timestamp_cnt |= (uint32_t)((SX1302_PKT_TIMESTAMP_23_16(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 16) & 0x00FF0000);
|
pkt->timestamp_cnt |= (uint32_t)((SX1302_PKT_TIMESTAMP_23_16(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 16) & 0x00FF0000);
|
||||||
pkt->timestamp_cnt |= (uint32_t)((SX1302_PKT_TIMESTAMP_31_24(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 24) & 0xFF000000);
|
pkt->timestamp_cnt |= (uint32_t)((SX1302_PKT_TIMESTAMP_31_24(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 24) & 0xFF000000);
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Scale packet timestamp to 1 MHz (microseconds) */
|
|
||||||
pkt->timestamp_cnt /= 32;
|
|
||||||
/* Expand 27-bits counter to 32-bits counter, based on current wrapping status */
|
|
||||||
pkt->timestamp_cnt = timestamp_counter_expand(&counter_us, false, pkt->timestamp_cnt);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DEBUG_MSG ("-----------------\n");
|
DEBUG_MSG ("-----------------\n");
|
||||||
DEBUG_PRINTF(" modem: %u\n", pkt->modem_id);
|
DEBUG_PRINTF(" modem: %u\n", pkt->modem_id);
|
||||||
DEBUG_PRINTF(" chan: %u\n", pkt->rx_channel_in);
|
DEBUG_PRINTF(" chan: %u\n", pkt->rx_channel_in);
|
||||||
|
|
@ -323,7 +325,7 @@ int rx_buffer_pop(rx_buffer_t * self, rx_packet_t * pkt) {
|
||||||
/* Move buffer index toward next message */
|
/* Move buffer index toward next message */
|
||||||
self->buffer_index += (SX1302_PKT_HEAD_METADATA + pkt->rxbytenb_modem + SX1302_PKT_TAIL_METADATA + (2 * pkt->num_ts_metrics_stored));
|
self->buffer_index += (SX1302_PKT_HEAD_METADATA + pkt->rxbytenb_modem + SX1302_PKT_TAIL_METADATA + (2 * pkt->num_ts_metrics_stored));
|
||||||
|
|
||||||
/* Update the umber of packets currently stored in the rx_buffer */
|
/* Update the number of packets currently stored in the rx_buffer */
|
||||||
self->buffer_pkt_nb -= 1;
|
self->buffer_pkt_nb -= 1;
|
||||||
|
|
||||||
return LGW_REG_SUCCESS;
|
return LGW_REG_SUCCESS;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||||
|
|
||||||
#include <stdint.h> /* C99 types */
|
#include <stdint.h> /* C99 types */
|
||||||
#include <stdio.h> /* printf fprintf */
|
#include <stdio.h> /* printf fprintf */
|
||||||
|
#include <memory.h> /* memset */
|
||||||
|
|
||||||
#include "loragw_sx1302_timestamp.h"
|
#include "loragw_sx1302_timestamp.h"
|
||||||
#include "loragw_reg.h"
|
#include "loragw_reg.h"
|
||||||
|
|
@ -65,50 +66,28 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||||
|
|
||||||
void timestamp_counter_new(timestamp_counter_t * self) {
|
void timestamp_counter_new(timestamp_counter_t * self) {
|
||||||
self->counter_us_raw_27bits_inst_prev = 0;
|
memset(self, 0, sizeof(*self));
|
||||||
self->counter_us_raw_27bits_pps_prev = 0;
|
|
||||||
self->counter_us_raw_27bits_inst_wrap = 0;
|
|
||||||
self->counter_us_raw_27bits_pps_wrap = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
void timestamp_counter_delete(timestamp_counter_t * self) {
|
void timestamp_counter_delete(timestamp_counter_t * self) {
|
||||||
self->counter_us_raw_27bits_inst_prev = 0;
|
memset(self, 0, sizeof(*self));
|
||||||
self->counter_us_raw_27bits_pps_prev = 0;
|
|
||||||
self->counter_us_raw_27bits_inst_wrap = 0;
|
|
||||||
self->counter_us_raw_27bits_pps_wrap = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
void timestamp_counter_update(timestamp_counter_t * self, bool pps, uint32_t cnt) {
|
void timestamp_counter_update(timestamp_counter_t * self, bool pps, uint32_t cnt) {
|
||||||
uint32_t counter_us_raw_27bits_prev;
|
struct timestamp_info_s* tinfo = (pps == true) ? &self->pps : &self->inst;
|
||||||
uint8_t counter_us_raw_27bits_wrap;
|
|
||||||
|
|
||||||
/* Get the previous counter value and wrap status */
|
|
||||||
if (pps == true) {
|
|
||||||
counter_us_raw_27bits_prev = self->counter_us_raw_27bits_pps_prev;
|
|
||||||
counter_us_raw_27bits_wrap = self->counter_us_raw_27bits_pps_wrap;
|
|
||||||
} else {
|
|
||||||
counter_us_raw_27bits_prev = self->counter_us_raw_27bits_inst_prev;
|
|
||||||
counter_us_raw_27bits_wrap = self->counter_us_raw_27bits_inst_wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if counter has wrapped, and update wrap status if necessary */
|
/* Check if counter has wrapped, and update wrap status if necessary */
|
||||||
if (cnt < counter_us_raw_27bits_prev) {
|
if (cnt < tinfo->counter_us_27bits_ref) {
|
||||||
counter_us_raw_27bits_wrap += 1;
|
tinfo->counter_us_27bits_wrap += 1;
|
||||||
counter_us_raw_27bits_wrap = counter_us_raw_27bits_wrap % 32;
|
tinfo->counter_us_27bits_wrap %= 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store counter value and wrap status for next time */
|
/* Update counter reference */
|
||||||
if (pps == true) {
|
tinfo->counter_us_27bits_ref = cnt;
|
||||||
self->counter_us_raw_27bits_pps_prev = cnt;
|
|
||||||
self->counter_us_raw_27bits_pps_wrap = counter_us_raw_27bits_wrap;
|
|
||||||
} else {
|
|
||||||
self->counter_us_raw_27bits_inst_prev = cnt;
|
|
||||||
self->counter_us_raw_27bits_inst_wrap = counter_us_raw_27bits_wrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
@ -117,20 +96,42 @@ uint32_t timestamp_counter_get(timestamp_counter_t * self, bool pps) {
|
||||||
int x;
|
int x;
|
||||||
uint8_t buff[4];
|
uint8_t buff[4];
|
||||||
uint32_t counter_us_raw_27bits_now;
|
uint32_t counter_us_raw_27bits_now;
|
||||||
|
int32_t msb;
|
||||||
|
|
||||||
/* Get the 32MHz timestamp counter - 4 bytes */
|
/* Get the 32MHz timestamp counter - 4 bytes */
|
||||||
/* step of 31.25 ns */
|
x = lgw_reg_rb((pps == true) ? SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_MSB2_TIMESTAMP_PPS :
|
||||||
x = lgw_reg_rb((pps == true) ? SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_MSB2_TIMESTAMP_PPS : SX1302_REG_TIMESTAMP_TIMESTAMP_MSB2_TIMESTAMP, &buff[0], 4);
|
SX1302_REG_TIMESTAMP_TIMESTAMP_MSB2_TIMESTAMP,
|
||||||
|
&buff[0], 4);
|
||||||
if (x != LGW_REG_SUCCESS) {
|
if (x != LGW_REG_SUCCESS) {
|
||||||
printf("ERROR: Failed to get timestamp counter value\n");
|
printf("ERROR: Failed to get timestamp counter value\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
counter_us_raw_27bits_now = (uint32_t)((buff[0] << 24) & 0xFF000000);
|
/* Workaround concentrator chip issue:
|
||||||
counter_us_raw_27bits_now |= (uint32_t)((buff[1] << 16) & 0x00FF0000);
|
- read MSB again
|
||||||
counter_us_raw_27bits_now |= (uint32_t)((buff[2] << 8) & 0x0000FF00);
|
- if MSB changed, read the full counter gain
|
||||||
counter_us_raw_27bits_now |= (uint32_t)((buff[3] << 0) & 0x000000FF);
|
*/
|
||||||
counter_us_raw_27bits_now /= 32; /* scale to 1MHz */
|
x = lgw_reg_r((pps == true) ? SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_MSB2_TIMESTAMP_PPS :
|
||||||
|
SX1302_REG_TIMESTAMP_TIMESTAMP_MSB2_TIMESTAMP,
|
||||||
|
&msb);
|
||||||
|
if (x != LGW_REG_SUCCESS) {
|
||||||
|
printf("ERROR: Failed to get timestamp counter MSB value\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (buff[0] != (uint8_t)msb) {
|
||||||
|
x = lgw_reg_rb((pps == true) ? SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_MSB2_TIMESTAMP_PPS :
|
||||||
|
SX1302_REG_TIMESTAMP_TIMESTAMP_MSB2_TIMESTAMP,
|
||||||
|
&buff[0], 4);
|
||||||
|
if (x != LGW_REG_SUCCESS) {
|
||||||
|
printf("ERROR: Failed to get timestamp counter value\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
counter_us_raw_27bits_now = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3];
|
||||||
|
|
||||||
|
/* Scale to 1MHz */
|
||||||
|
counter_us_raw_27bits_now /= 32;
|
||||||
|
|
||||||
/* Update counter wrapping status */
|
/* Update counter wrapping status */
|
||||||
timestamp_counter_update(self, pps, counter_us_raw_27bits_now);
|
timestamp_counter_update(self, pps, counter_us_raw_27bits_now);
|
||||||
|
|
@ -142,13 +143,10 @@ uint32_t timestamp_counter_get(timestamp_counter_t * self, bool pps) {
|
||||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
uint32_t timestamp_counter_expand(timestamp_counter_t * self, bool pps, uint32_t cnt_us) {
|
uint32_t timestamp_counter_expand(timestamp_counter_t * self, bool pps, uint32_t cnt_us) {
|
||||||
|
struct timestamp_info_s* tinfo = (pps == true) ? &self->pps : &self->inst;
|
||||||
uint32_t counter_us_32bits;
|
uint32_t counter_us_32bits;
|
||||||
|
|
||||||
if (pps == true) {
|
counter_us_32bits = (tinfo->counter_us_27bits_wrap << 27) | cnt_us;
|
||||||
counter_us_32bits = (self->counter_us_raw_27bits_pps_wrap << 27) | cnt_us;
|
|
||||||
} else {
|
|
||||||
counter_us_32bits = (self->counter_us_raw_27bits_inst_wrap << 27) | cnt_us;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* DEBUG: to be enabled when running test_loragw_counter test application
|
/* DEBUG: to be enabled when running test_loragw_counter test application
|
||||||
|
|
@ -156,12 +154,41 @@ uint32_t timestamp_counter_expand(timestamp_counter_t * self, bool pps, uint32_t
|
||||||
> set datafile separator comma
|
> set datafile separator comma
|
||||||
> plot for [col=1:2:1] 'log_count.txt' using col with lines
|
> plot for [col=1:2:1] 'log_count.txt' using col with lines
|
||||||
*/
|
*/
|
||||||
printf("%u,%u,%u\n", cnt_us, counter_us_32bits, (pps == true) ? self->counter_us_raw_27bits_pps_wrap : self->counter_us_raw_27bits_inst_wrap);
|
printf("%u,%u,%u\n", cnt_us, counter_us_32bits, tinfo->counter_us_27bits_wrap);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return counter_us_32bits;
|
return counter_us_32bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
uint32_t timestamp_pkt_expand(timestamp_counter_t * self, uint32_t pkt_cnt_us) {
|
||||||
|
struct timestamp_info_s* tinfo = &self->inst;
|
||||||
|
uint32_t counter_us_32bits;
|
||||||
|
uint8_t wrap_status;
|
||||||
|
|
||||||
|
/* Check if counter has wrapped since the packet has been received in the sx1302 internal FIFO */
|
||||||
|
/* If the sx1302 counter was greater than the pkt timestamp, it means that the internal counter
|
||||||
|
hasn't rolled over since the packet has been received by the sx1302
|
||||||
|
case 1: --|-P--|----|--R-|----|--||-|----|-- : use current wrap status counter
|
||||||
|
case 2: --|-P-||-|-R--|-- : use previous wrap status counter
|
||||||
|
P : packet received in sx1302 internal FIFO
|
||||||
|
R : read packet from sx1302 internal FIFO
|
||||||
|
| : last update internal counter ref value.
|
||||||
|
||: sx1302 internal counter rollover (wrap)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Use current wrap counter or previous ? */
|
||||||
|
wrap_status = tinfo->counter_us_27bits_wrap - ((tinfo->counter_us_27bits_ref >= pkt_cnt_us) ? 0 : 1);
|
||||||
|
wrap_status &= 0x1F; /* [0..31] */
|
||||||
|
|
||||||
|
/* Expand packet counter */
|
||||||
|
counter_us_32bits = (wrap_status << 27) | pkt_cnt_us;
|
||||||
|
|
||||||
|
return counter_us_32bits;
|
||||||
|
}
|
||||||
|
|
||||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
int timestamp_counter_mode(bool enable_precision_ts, uint8_t max_ts_metrics, uint8_t nb_symbols) {
|
int timestamp_counter_mode(bool enable_precision_ts, uint8_t max_ts_metrics, uint8_t nb_symbols) {
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ void usage(void) {
|
||||||
printf(" -r <uint> Radio type (1255, 1257, 1250)\n");
|
printf(" -r <uint> Radio type (1255, 1257, 1250)\n");
|
||||||
printf(" -a <float> Radio A RX frequency in MHz\n");
|
printf(" -a <float> Radio A RX frequency in MHz\n");
|
||||||
printf(" -b <float> Radio B RX frequency in MHz\n");
|
printf(" -b <float> Radio B RX frequency in MHz\n");
|
||||||
|
printf(" -o <float> RSSI Offset to be applied in dB\n");
|
||||||
printf(" -n <uint> Number of packet received with CRC OK for each HAL start/stop loop\n");
|
printf(" -n <uint> Number of packet received with CRC OK for each HAL start/stop loop\n");
|
||||||
printf(" -z <uint> Size of the RX packet array to be passed to lgw_receive()\n");
|
printf(" -z <uint> Size of the RX packet array to be passed to lgw_receive()\n");
|
||||||
printf(" -m <uint> Channel frequency plan mode [0:LoRaWAN-like, 1:Same frequency for all channels (-400000Hz on RF0)]\n");
|
printf(" -m <uint> Channel frequency plan mode [0:LoRaWAN-like, 1:Same frequency for all channels (-400000Hz on RF0)]\n");
|
||||||
|
|
@ -99,6 +100,7 @@ int main(int argc, char **argv)
|
||||||
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE;
|
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE;
|
||||||
uint8_t max_rx_pkt = 16;
|
uint8_t max_rx_pkt = 16;
|
||||||
bool single_input_mode = false;
|
bool single_input_mode = false;
|
||||||
|
float rssi_offset = 0.0;
|
||||||
|
|
||||||
struct lgw_conf_board_s boardconf;
|
struct lgw_conf_board_s boardconf;
|
||||||
struct lgw_conf_rxrf_s rfconf;
|
struct lgw_conf_rxrf_s rfconf;
|
||||||
|
|
@ -138,7 +140,7 @@ int main(int argc, char **argv)
|
||||||
const uint8_t channel_rfchain_mode1[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
const uint8_t channel_rfchain_mode1[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
/* parse command line options */
|
/* parse command line options */
|
||||||
while ((i = getopt (argc, argv, "hja:b:k:r:n:z:m:")) != -1) {
|
while ((i = getopt (argc, argv, "hja:b:k:r:n:z:m:o:")) != -1) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 'h':
|
case 'h':
|
||||||
usage();
|
usage();
|
||||||
|
|
@ -220,6 +222,15 @@ int main(int argc, char **argv)
|
||||||
channel_mode = arg_u;
|
channel_mode = arg_u;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'o': /* <float> RSSI offset in dB */
|
||||||
|
i = sscanf(optarg, "%lf", &arg_d);
|
||||||
|
if (i != 1) {
|
||||||
|
printf("ERROR: argument parsing of -f argument. Use -h to print help\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
rssi_offset = (float)arg_d;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("ERROR: argument parsing\n");
|
printf("ERROR: argument parsing\n");
|
||||||
usage();
|
usage();
|
||||||
|
|
@ -254,6 +265,7 @@ int main(int argc, char **argv)
|
||||||
rfconf.enable = true;
|
rfconf.enable = true;
|
||||||
rfconf.freq_hz = fa;
|
rfconf.freq_hz = fa;
|
||||||
rfconf.type = radio_type;
|
rfconf.type = radio_type;
|
||||||
|
rfconf.rssi_offset = rssi_offset;
|
||||||
rfconf.tx_enable = false;
|
rfconf.tx_enable = false;
|
||||||
rfconf.single_input_mode = single_input_mode;
|
rfconf.single_input_mode = single_input_mode;
|
||||||
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
|
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
|
||||||
|
|
@ -265,6 +277,7 @@ int main(int argc, char **argv)
|
||||||
rfconf.enable = true;
|
rfconf.enable = true;
|
||||||
rfconf.freq_hz = fb;
|
rfconf.freq_hz = fb;
|
||||||
rfconf.type = radio_type;
|
rfconf.type = radio_type;
|
||||||
|
rfconf.rssi_offset = rssi_offset;
|
||||||
rfconf.tx_enable = false;
|
rfconf.tx_enable = false;
|
||||||
rfconf.single_input_mode = single_input_mode;
|
rfconf.single_input_mode = single_input_mode;
|
||||||
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
|
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
|
||||||
|
|
|
||||||
98
packet_forwarder/global_conf.json.sx1250.US915
Normal file
98
packet_forwarder/global_conf.json.sx1250.US915
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
"SX130x_conf": {
|
||||||
|
"spidev_path": "/dev/spidev0.0",
|
||||||
|
"lorawan_public": true,
|
||||||
|
"clksrc": 0,
|
||||||
|
"antenna_gain": 0, /* antenna gain, in dBi */
|
||||||
|
"full_duplex": false,
|
||||||
|
"precision_timestamp": {
|
||||||
|
"enable": false,
|
||||||
|
"max_ts_metrics": 255,
|
||||||
|
"nb_symbols": 1
|
||||||
|
},
|
||||||
|
"radio_0": {
|
||||||
|
"enable": true,
|
||||||
|
"type": "SX1250",
|
||||||
|
"freq": 904300000,
|
||||||
|
"rssi_offset": -215.4,
|
||||||
|
"rssi_tcomp": {"coeff_a": 0, "coeff_b": 0, "coeff_c": 20.41, "coeff_d": 2162.56, "coeff_e": 0},
|
||||||
|
"tx_enable": true,
|
||||||
|
"tx_freq_min": 923000000,
|
||||||
|
"tx_freq_max": 928000000,
|
||||||
|
"tx_gain_lut":[
|
||||||
|
{"rf_power": 12, "pa_gain": 0, "pwr_idx": 15},
|
||||||
|
{"rf_power": 13, "pa_gain": 0, "pwr_idx": 16},
|
||||||
|
{"rf_power": 14, "pa_gain": 0, "pwr_idx": 17},
|
||||||
|
{"rf_power": 15, "pa_gain": 0, "pwr_idx": 19},
|
||||||
|
{"rf_power": 16, "pa_gain": 0, "pwr_idx": 20},
|
||||||
|
{"rf_power": 17, "pa_gain": 0, "pwr_idx": 22},
|
||||||
|
{"rf_power": 18, "pa_gain": 1, "pwr_idx": 1},
|
||||||
|
{"rf_power": 19, "pa_gain": 1, "pwr_idx": 2},
|
||||||
|
{"rf_power": 20, "pa_gain": 1, "pwr_idx": 3},
|
||||||
|
{"rf_power": 21, "pa_gain": 1, "pwr_idx": 4},
|
||||||
|
{"rf_power": 22, "pa_gain": 1, "pwr_idx": 5},
|
||||||
|
{"rf_power": 23, "pa_gain": 1, "pwr_idx": 6},
|
||||||
|
{"rf_power": 24, "pa_gain": 1, "pwr_idx": 7},
|
||||||
|
{"rf_power": 25, "pa_gain": 1, "pwr_idx": 9},
|
||||||
|
{"rf_power": 26, "pa_gain": 1, "pwr_idx": 11},
|
||||||
|
{"rf_power": 27, "pa_gain": 1, "pwr_idx": 14}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"radio_1": {
|
||||||
|
"enable": true,
|
||||||
|
"type": "SX1250",
|
||||||
|
"freq": 905000000,
|
||||||
|
"rssi_offset": -215.4,
|
||||||
|
"rssi_tcomp": {"coeff_a": 0, "coeff_b": 0, "coeff_c": 20.41, "coeff_d": 2162.56, "coeff_e": 0},
|
||||||
|
"tx_enable": false
|
||||||
|
},
|
||||||
|
"chan_multiSF_0": {"enable": true, "radio": 0, "if": -400000}, /* Freq : 903.9 MHz*/
|
||||||
|
"chan_multiSF_1": {"enable": true, "radio": 0, "if": -200000}, /* Freq : 904.1 MHz*/
|
||||||
|
"chan_multiSF_2": {"enable": true, "radio": 0, "if": 0}, /* Freq : 904.3 MHz*/
|
||||||
|
"chan_multiSF_3": {"enable": true, "radio": 0, "if": 200000}, /* Freq : 904.5 MHz*/
|
||||||
|
"chan_multiSF_4": {"enable": true, "radio": 1, "if": -300000}, /* Freq : 904.7 MHz*/
|
||||||
|
"chan_multiSF_5": {"enable": true, "radio": 1, "if": -100000}, /* Freq : 904.9 MHz*/
|
||||||
|
"chan_multiSF_6": {"enable": true, "radio": 1, "if": 100000}, /* Freq : 905.1 MHz*/
|
||||||
|
"chan_multiSF_7": {"enable": true, "radio": 1, "if": 300000}, /* Freq : 905.3 MHz*/
|
||||||
|
"chan_Lora_std": {"enable": true, "radio": 0, "if": 300000, "bandwidth": 500000, "spread_factor": 8, /* Freq : 904.6 MHz*/
|
||||||
|
"implicit_hdr": false, "implicit_payload_length": 17, "implicit_crc_en": false, "implicit_coderate": 1},
|
||||||
|
"chan_FSK": {"enable": false, "radio": 1, "if": 300000, "bandwidth": 125000, "datarate": 50000} /* Freq : 868.8 MHz*/
|
||||||
|
},
|
||||||
|
|
||||||
|
"gateway_conf": {
|
||||||
|
"gateway_ID": "AA555A0000000000",
|
||||||
|
/* change with default server address/ports */
|
||||||
|
"server_address": "localhost",
|
||||||
|
"serv_port_up": 1730,
|
||||||
|
"serv_port_down": 1730,
|
||||||
|
/* adjust the following parameters for your network */
|
||||||
|
"keepalive_interval": 10,
|
||||||
|
"stat_interval": 30,
|
||||||
|
"push_timeout_ms": 100,
|
||||||
|
/* forward only valid packets */
|
||||||
|
"forward_crc_valid": true,
|
||||||
|
"forward_crc_error": false,
|
||||||
|
"forward_crc_disabled": false,
|
||||||
|
/* GPS configuration */
|
||||||
|
"gps_tty_path": "/dev/ttyS0",
|
||||||
|
/* GPS reference coordinates */
|
||||||
|
"ref_latitude": 0.0,
|
||||||
|
"ref_longitude": 0.0,
|
||||||
|
"ref_altitude": 0,
|
||||||
|
/* Beaconing parameters */
|
||||||
|
"beacon_period": 0, /* disable class B beacon */
|
||||||
|
"beacon_freq_hz": 869525000,
|
||||||
|
"beacon_datarate": 9,
|
||||||
|
"beacon_bw_hz": 125000,
|
||||||
|
"beacon_power": 14,
|
||||||
|
"beacon_infodesc": 0
|
||||||
|
},
|
||||||
|
|
||||||
|
"debug_conf": {
|
||||||
|
"ref_payload":[
|
||||||
|
{"id": "0xCAFE1234"},
|
||||||
|
{"id": "0xCAFE2345"}
|
||||||
|
],
|
||||||
|
"log_file": "loragw_hal.log"
|
||||||
|
}
|
||||||
|
}
|
||||||
10
readme.md
10
readme.md
|
|
@ -161,6 +161,16 @@ found in the `libtools` directory.
|
||||||
|
|
||||||
## 6. Changelog
|
## 6. Changelog
|
||||||
|
|
||||||
|
### v1.0.5 ###
|
||||||
|
|
||||||
|
* HAL: Fixed packet timestamp issue which was "jumping in time" in specific
|
||||||
|
conditions.
|
||||||
|
* HAL: Workaround hardware issue when reading 32-bits registers (timestamp, nb
|
||||||
|
bytes in RX buffer...)
|
||||||
|
* HAL: Fixed potential endless loop in sx1302_tx_abort() in SPI access fails.
|
||||||
|
* Packet Forwarder: Added global_conf.json.sx1250.US915 for US915 band
|
||||||
|
* test_hal_rx: added command line to specify RSSI offset to be applied
|
||||||
|
|
||||||
### v1.0.4 ###
|
### v1.0.4 ###
|
||||||
|
|
||||||
* Added missing LICENSE.TXT file
|
* Added missing LICENSE.TXT file
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue