From 5942224602c5ee14469db6605b48a6fc57ff7a18 Mon Sep 17 00:00:00 2001 From: Michael Coracin Date: Fri, 20 Sep 2019 11:06:37 +0200 Subject: [PATCH] v1.0.3 * HAL: Fixed scheduled downlink time precision by taking the tx start delay into account. * HAL: Fixed timestamp correction calculation for BW250 & BW500 * HAL: Fixed possible buffer overflow in lgw_receive() function * HAL: Keep packet received in RX buffer when the buffer allocated to receive the packets is too small. Remaining packets will be fetched on the next lgw_receive calls (aligned on SX1301 behaviour). --- VERSION | 2 +- libloragw/inc/loragw_sx1302.h | 26 ++----- libloragw/inc/loragw_sx1302_rx.h | 26 +++---- libloragw/inc/loragw_sx1302_timestamp.h | 23 +++--- libloragw/src/loragw_hal.c | 53 +++++++------- libloragw/src/loragw_sx1302.c | 52 +++++++++----- libloragw/src/loragw_sx1302_rx.c | 30 +++++++- libloragw/src/loragw_sx1302_timestamp.c | 21 ++---- libloragw/tst/test_loragw_hal_rx.c | 96 ++++++++++++++++++++----- readme.md | 10 +++ 10 files changed, 217 insertions(+), 122 deletions(-) diff --git a/VERSION b/VERSION index 6d7de6e..21e8796 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.2 +1.0.3 diff --git a/libloragw/inc/loragw_sx1302.h b/libloragw/inc/loragw_sx1302.h index e71f99c..f0a0a60 100644 --- a/libloragw/inc/loragw_sx1302.h +++ b/libloragw/inc/loragw_sx1302.h @@ -350,28 +350,15 @@ void sx1302_arb_print_debug_stats(void); uint16_t sx1302_lora_payload_crc(const uint8_t * data, uint8_t size); /** -@brief TODO -@param TODO -@return TODO -*/ -uint16_t sx1302_rx_buffer_read_ptr_addr(void); - -/** -@brief TODO -@param TODO -@return TODO -*/ -uint16_t sx1302_rx_buffer_write_ptr_addr(void); - -/** -@brief Check if any data to be fetched from the SX1302 RX buffer and fetch it if any. -@param nb_bytes A pointer to allocated memory to hold the number of bytes fetched +@brief Get the number of packets available in rx_buffer and fetch data from ... +@brief ... the SX1302 if rx_buffer is empty. +@param nb_pkt A pointer to allocated memory to hold the number of packet fetched @return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise */ -int sx1302_fetch(uint16_t * nb_bytes); +int sx1302_fetch(uint8_t * nb_pkt); /** -@brief Parse and return the next packet available in the fetched RX buffer. +@brief Parse and return the next packet available in rx_buffer. @param context Gateway configuration context @param p The structure to get the packet parsed @return LGW_REG_SUCCESS if a packet could be parsed, LGW_REG_ERROR otherwise @@ -384,9 +371,10 @@ int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p); @param radio_type The type of radio for this RF chain @param modulation The modulation used for the TX @param bandwidth The bandwidth used for the TX +@param delay The TX start delay calculated and applied @return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise */ -int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uint8_t modulation, uint8_t bandwidth); +int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uint8_t modulation, uint8_t bandwidth, uint16_t * delay); /** @brief Compute the offset to be applied on RSSI for temperature compensation diff --git a/libloragw/inc/loragw_sx1302_rx.h b/libloragw/inc/loragw_sx1302_rx.h index 8953cf5..a8cca03 100644 --- a/libloragw/inc/loragw_sx1302_rx.h +++ b/libloragw/inc/loragw_sx1302_rx.h @@ -72,36 +72,38 @@ typedef struct rx_buffer_s { uint8_t buffer[4096]; /*!> byte array to hald the data fetched from the RX buffer */ uint16_t buffer_size; /*!> The number of bytes currently stored in the buffer */ int buffer_index; /*!> Current parsing index in the buffer */ + uint8_t buffer_pkt_nb; } rx_buffer_t; /* -------------------------------------------------------------------------- */ /* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */ /** -@brief TODO -@param TODO -@return TODO +@brief Initialize the rx_buffer instance +@param self A pointer to a rx_buffer handler +@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise */ int rx_buffer_new(rx_buffer_t * self); /** -@brief TODO -@param TODO -@return TODO +@brief Reset the rx_buffer instance +@param self A pointer to a rx_buffer handler +@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise */ int rx_buffer_del(rx_buffer_t * self); /** -@brief TODO -@param TODO -@return TODO +@brief Fetch packets from the SX1302 internal RX buffer, and count packets available. +@param self A pointer to a rx_buffer handler +@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise */ int rx_buffer_fetch(rx_buffer_t * self); /** -@brief TODO -@param TODO -@return TODO +@brief Parse the rx_buffer and return the first packet available in the given structure. +@param self A pointer to a rx_buffer handler +@param pkt A pointer to the structure to receive the packet parsed +@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise */ int rx_buffer_pop(rx_buffer_t * self, rx_packet_t * pkt); diff --git a/libloragw/inc/loragw_sx1302_timestamp.h b/libloragw/inc/loragw_sx1302_timestamp.h index 92c9245..4e11a62 100644 --- a/libloragw/inc/loragw_sx1302_timestamp.h +++ b/libloragw/inc/loragw_sx1302_timestamp.h @@ -54,16 +54,16 @@ typedef struct timestamp_counter_s { /* --- PUBLIC FUNCTIONS ----------------------------------------------------- */ /** -@brief TODO -@param TODO -@return TODO +@brief Initialize the timestamp_counter instance +@param self Pointer to the counter handler +@return N/A */ void timestamp_counter_new(timestamp_counter_t * self); /** -@brief TODO -@param TODO -@return TODO +@brief Reset the timestamp_counter instance +@param self Pointer to the counter handler +@return N/A */ void timestamp_counter_delete(timestamp_counter_t * self); @@ -106,9 +106,14 @@ uint32_t timestamp_counter_get(timestamp_counter_t * self, bool pps); uint32_t timestamp_counter_correction(int ifmod, uint8_t bandwidth, uint8_t datarate, uint8_t coderate, uint32_t crc_en, uint16_t payload_length); /** -@brief TODO -@param TODO -@return TODO +@brief Configure the SX1302 to output legacy timestamp or precision timestamp +@note Legacy timestamp gives a timestamp latched at the end of the packet +@note Precision timestamp gives a timestamp latched at the end of the header +@note and additionally supplies metrics every N symbols troughout the payload. +@param enable_precision_ts A boolean to enable precision timestamp output. +@param max_ts_metrics The number of timestamp metrics to be returned when precision timestamp is enabled +@param nb_symbols The sampling rate of timestamp metrics +@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise */ int timestamp_counter_mode(bool enable_precision_ts, uint8_t max_ts_metrics, uint8_t nb_symbols); diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c index 672c879..a09016a 100644 --- a/libloragw/src/loragw_hal.c +++ b/libloragw/src/loragw_hal.c @@ -31,6 +31,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project #include #include /* symlink, unlink */ #include +#include #include "loragw_reg.h" #include "loragw_hal.h" @@ -451,7 +452,7 @@ int lgw_rxif_setconf(uint8_t if_chain, struct lgw_conf_rxif_s * conf) { CONTEXT_FSK.sync_word_size = conf->sync_word_size; CONTEXT_FSK.sync_word = conf->sync_word; } - DEBUG_PRINTF("Note: FSK if_chain %d configuration; en:%d freq:%d bw:%d dr:%d (%d real dr) sync:0x%0*llX\n", if_chain, + DEBUG_PRINTF("Note: FSK if_chain %d configuration; en:%d freq:%d bw:%d dr:%d (%d real dr) sync:0x%0*" PRIu64 "\n", if_chain, CONTEXT_IF_CHAIN[if_chain].enable, CONTEXT_IF_CHAIN[if_chain].freq_hz, CONTEXT_FSK.bandwidth, @@ -772,9 +773,9 @@ int lgw_stop(void) { int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { int res; - uint16_t sz = 0; + uint8_t nb_pkt_fetched = 0; uint16_t nb_pkt_found = 0; - uint16_t nb_pkt_dropped = 0; + uint16_t nb_pkt_left = 0; float current_temperature, rssi_temperature_offset; /* Check that AGC/ARB firmwares are not corrupted, and update internal counter */ @@ -785,48 +786,46 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { } /* Get packets from SX1302, if any */ - res = sx1302_fetch(&sz); + res = sx1302_fetch(&nb_pkt_fetched); if (res != LGW_REG_SUCCESS) { printf("ERROR: failed to fetch packets from SX1302\n"); return LGW_HAL_ERROR; } - if (sz == 0) { + if (nb_pkt_fetched == 0) { return 0; } + if (nb_pkt_fetched > max_pkt) { + nb_pkt_left = nb_pkt_fetched - max_pkt; + printf("WARNING: not enough space allocated, fetched %d packet(s), %d will be left in RX buffer\n", nb_pkt_fetched, nb_pkt_left); + } - /* Get the current temperature for further RSSI compensation : TODO */ + /* Apply RSSI temperature compensation */ res = stts751_get_temperature(ts_fd, ts_addr, ¤t_temperature); if (res != LGW_I2C_SUCCESS) { printf("ERROR: failed to get current temperature\n"); return LGW_HAL_ERROR; } - DEBUG_PRINTF("INFO: current temperature is %f C\n", current_temperature); /* Iterate on the RX buffer to get parsed packets */ - res = LGW_REG_SUCCESS; - while ((res == LGW_REG_SUCCESS) && (nb_pkt_found <= max_pkt)) { + for (nb_pkt_found = 0; nb_pkt_found < ((nb_pkt_fetched <= max_pkt) ? nb_pkt_fetched : max_pkt); nb_pkt_found++) { + /* Get packet and move to next one */ res = sx1302_parse(&lgw_context, &pkt_data[nb_pkt_found]); - if (res == LGW_REG_SUCCESS) { - /* we found a packet and parsed it */ - if ((nb_pkt_found + 1) > max_pkt) { - printf("WARNING: no space left, dropping packet\n"); - nb_pkt_dropped += 1; - continue; - } - /* Appli RSSI offset calibrated for the board */ - pkt_data[nb_pkt_found].rssic += CONTEXT_RF_CHAIN[pkt_data[nb_pkt_found].rf_chain].rssi_offset; - pkt_data[nb_pkt_found].rssis += CONTEXT_RF_CHAIN[pkt_data[nb_pkt_found].rf_chain].rssi_offset; - /* Apply RSSI temperature compensation */ - rssi_temperature_offset = sx1302_rssi_get_temperature_offset(&CONTEXT_RF_CHAIN[pkt_data[nb_pkt_found].rf_chain].rssi_tcomp, current_temperature); - pkt_data[nb_pkt_found].rssic += rssi_temperature_offset; - pkt_data[nb_pkt_found].rssis += rssi_temperature_offset; - DEBUG_PRINTF("INFO: RSSI temperature offset applied: %.3f dB\n", rssi_temperature_offset); - /* Next packet */ - nb_pkt_found += 1; + if (res != LGW_REG_SUCCESS) { + printf("ERROR: failed to parse fetched packet %d, aborting...\n", nb_pkt_found); + return LGW_HAL_ERROR; } + + /* Appli RSSI offset calibrated for the board */ + pkt_data[nb_pkt_found].rssic += CONTEXT_RF_CHAIN[pkt_data[nb_pkt_found].rf_chain].rssi_offset; + pkt_data[nb_pkt_found].rssis += CONTEXT_RF_CHAIN[pkt_data[nb_pkt_found].rf_chain].rssi_offset; + + rssi_temperature_offset = sx1302_rssi_get_temperature_offset(&CONTEXT_RF_CHAIN[pkt_data[nb_pkt_found].rf_chain].rssi_tcomp, current_temperature); + pkt_data[nb_pkt_found].rssic += rssi_temperature_offset; + pkt_data[nb_pkt_found].rssis += rssi_temperature_offset; + DEBUG_PRINTF("INFO: RSSI temperature offset applied: %.3f dB (current temperature %.1f C)\n", rssi_temperature_offset, current_temperature); } - DEBUG_PRINTF("INFO: nb pkt found:%u dropped:%u\n", nb_pkt_found, nb_pkt_dropped); + DEBUG_PRINTF("INFO: nb pkt found:%u left:%u\n", nb_pkt_found, nb_pkt_left); return nb_pkt_found; } diff --git a/libloragw/src/loragw_sx1302.c b/libloragw/src/loragw_sx1302.c index ecb8077..5bc2a20 100644 --- a/libloragw/src/loragw_sx1302.c +++ b/libloragw/src/loragw_sx1302.c @@ -210,6 +210,9 @@ void sx1302_init(struct lgw_conf_timestamp_s *conf_ts) { if (conf_ts != NULL) { timestamp_counter_mode(conf_ts->enable_precision_ts, conf_ts->max_ts_metrics, conf_ts->nb_symbols); } + + /* Initialize RX buffer */ + rx_buffer_new(&rx_buffer); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -1570,25 +1573,30 @@ int sx1302_arb_start(uint8_t version) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -int sx1302_fetch(uint16_t * nb_bytes) { +int sx1302_fetch(uint8_t * nb_pkt) { int err; - /* Initialize RX buffer */ - err = rx_buffer_new(&rx_buffer); - if (err != LGW_REG_SUCCESS) { - printf("ERROR: Failed to initialize RX buffer\n"); - return LGW_REG_ERROR; + /* Fetch packets from sx1302 if no more left in RX buffer */ + if (rx_buffer.buffer_pkt_nb == 0) { + /* Initialize RX buffer */ + err = rx_buffer_new(&rx_buffer); + if (err != LGW_REG_SUCCESS) { + printf("ERROR: Failed to initialize RX buffer\n"); + return LGW_REG_ERROR; + } + + /* Fetch RX buffer if any data available */ + err = rx_buffer_fetch(&rx_buffer); + if (err != LGW_REG_SUCCESS) { + printf("ERROR: Failed to fetch RX buffer\n"); + return LGW_REG_ERROR; + } + } else { + printf("Note: remaining %u packets in RX buffer, do not fetch sx1302 yet...\n", rx_buffer.buffer_pkt_nb); } - /* Fetch RX buffer if any data available */ - err = rx_buffer_fetch(&rx_buffer); - if (err != LGW_REG_SUCCESS) { - printf("ERROR: Failed to fetch RX buffer\n"); - return LGW_REG_ERROR; - } - - /* Return the number of bytes fetched */ - *nb_bytes = rx_buffer.buffer_size; + /* Return the number of packet fetched */ + *nb_pkt = rx_buffer.buffer_pkt_nb; return LGW_REG_SUCCESS; } @@ -1833,7 +1841,7 @@ uint16_t sx1302_lora_payload_crc(const uint8_t * data, uint8_t size) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uint8_t modulation, uint8_t bandwidth) { +int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uint8_t modulation, uint8_t bandwidth, uint16_t * delay) { uint16_t tx_start_delay = TX_START_DELAY_DEFAULT * 32; uint16_t radio_bw_delay = 0; uint16_t filter_delay = 0; @@ -1842,6 +1850,8 @@ int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uin int32_t val; uint8_t chirp_low_pass = 0; + CHECK_NULL(delay); + /* Adjust with radio type and bandwidth */ switch (radio_type) { case LGW_RADIO_TYPE_SX1250: @@ -1896,6 +1906,9 @@ int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uin lgw_reg_w(SX1302_REG_TX_TOP_TX_START_DELAY_MSB_TX_START_DELAY(rf_chain), (uint8_t)(tx_start_delay >> 8)); lgw_reg_w(SX1302_REG_TX_TOP_TX_START_DELAY_LSB_TX_START_DELAY(rf_chain), (uint8_t)(tx_start_delay >> 0)); + /* return tx_start_delay */ + *delay = tx_start_delay; + return LGW_REG_SUCCESS; } @@ -2013,6 +2026,7 @@ int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut, uint8_t pow_index; uint8_t mod_bw; uint8_t pa_en; + uint16_t tx_start_delay; /* CHeck input parameters */ CHECK_NULL(tx_lut); @@ -2244,7 +2258,7 @@ int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut, } /* Set TX start delay */ - sx1302_tx_set_start_delay(pkt_data->rf_chain, radio_type, pkt_data->modulation, pkt_data->bandwidth); + sx1302_tx_set_start_delay(pkt_data->rf_chain, radio_type, pkt_data->modulation, pkt_data->bandwidth, &tx_start_delay); /* Write payload in transmit buffer */ lgw_reg_w(SX1302_REG_TX_TOP_TX_CTRL_WRITE_BUFFER(pkt_data->rf_chain), 0x01); @@ -2265,8 +2279,8 @@ int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut, lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_IMMEDIATE(pkt_data->rf_chain), 0x01); break; case TIMESTAMPED: - count_us = pkt_data->count_us * 32; - DEBUG_PRINTF("--> programming trig delay at %u (%u)\n", pkt_data->count_us, count_us); + count_us = pkt_data->count_us * 32 - tx_start_delay; + DEBUG_PRINTF("--> programming trig delay at %u (%u)\n", pkt_data->count_us - (tx_start_delay / 32), count_us); lgw_reg_w(SX1302_REG_TX_TOP_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG(pkt_data->rf_chain), (uint8_t)((count_us >> 0) & 0x000000FF)); lgw_reg_w(SX1302_REG_TX_TOP_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG(pkt_data->rf_chain), (uint8_t)((count_us >> 8) & 0x000000FF)); diff --git a/libloragw/src/loragw_sx1302_rx.c b/libloragw/src/loragw_sx1302_rx.c index 8689c5a..32b28c3 100644 --- a/libloragw/src/loragw_sx1302_rx.c +++ b/libloragw/src/loragw_sx1302_rx.c @@ -108,6 +108,7 @@ int rx_buffer_new(rx_buffer_t * self) { memset(self->buffer, 0, sizeof self->buffer); self->buffer_size = 0; self->buffer_index = 0; + self->buffer_pkt_nb = 0; return LGW_REG_SUCCESS; } @@ -121,6 +122,7 @@ int rx_buffer_del(rx_buffer_t * self) { /* Reset index & size */ self->buffer_size = 0; self->buffer_index = 0; + self->buffer_pkt_nb = 0; return LGW_REG_SUCCESS; } @@ -160,6 +162,29 @@ int rx_buffer_fetch(rx_buffer_t * self) { } + /* Parse buffer to get number of packet fetched */ + uint8_t payload_len; + uint16_t next_pkt_idx; + int idx = 0; + while (idx < self->buffer_size) { + if ((self->buffer[idx] != SX1302_PKT_SYNCWORD_BYTE_0) || (self->buffer[idx + 1] != SX1302_PKT_SYNCWORD_BYTE_1)) { + printf("ERROR: syncword not found in rx_buffer\n"); + return LGW_REG_ERROR; + } + /* One packet found in the buffer */ + self->buffer_pkt_nb += 1; + + /* Compute the number of bytes for thsi packet */ + payload_len = SX1302_PKT_PAYLOAD_LENGTH(self->buffer, idx); + next_pkt_idx = SX1302_PKT_HEAD_METADATA + + payload_len + + SX1302_PKT_TAIL_METADATA + + (2 * SX1302_PKT_NUM_TS_METRICS(self->buffer, idx + payload_len)); + + /* Move to next packet */ + idx += (int)next_pkt_idx; + } + /* Initialize the current buffer index to iterate on */ self->buffer_index = 0; @@ -295,9 +320,12 @@ int rx_buffer_pop(rx_buffer_t * self, rx_packet_t * pkt) { /* Parse & copy payload in packet struct */ memcpy((void *)pkt->payload, (void *)(&(self->buffer[self->buffer_index + SX1302_PKT_HEAD_METADATA])), pkt->rxbytenb_modem); - /* 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)); + /* Update the umber of packets currently stored in the rx_buffer */ + self->buffer_pkt_nb -= 1; + return LGW_REG_SUCCESS; } diff --git a/libloragw/src/loragw_sx1302_timestamp.c b/libloragw/src/loragw_sx1302_timestamp.c index a51e92a..82bb21f 100644 --- a/libloragw/src/loragw_sx1302_timestamp.c +++ b/libloragw/src/loragw_sx1302_timestamp.c @@ -191,42 +191,31 @@ int timestamp_counter_mode(bool enable_precision_ts, uint8_t max_ts_metrics, uin uint32_t timestamp_counter_correction(int ifmod, uint8_t bandwidth, uint8_t datarate, uint8_t coderate, uint32_t crc_en, uint16_t payload_length) { int32_t val; - uint32_t sf = (uint32_t)datarate, cr = (uint32_t)coderate, bw_pow, ppm; + uint32_t sf = (uint32_t)datarate, cr = (uint32_t)coderate, bw_pow; uint32_t clk_period; uint32_t nb_nibble, nb_nibble_in_hdr, nb_nibble_in_last_block; uint32_t dft_peak_en, nb_iter; uint32_t demap_delay, decode_delay, fft_delay_state3, fft_delay, delay_x; uint32_t timestamp_correction; + uint32_t ppm = SET_PPM_ON(bandwidth, datarate) ? 1 : 0; - /* determine if 'PPM mode' is on */ - if (SET_PPM_ON(bandwidth, datarate)) { - ppm = 1; - } else { - ppm = 0; - } - - /* timestamp correction code, base delay */ switch (bandwidth) { case BW_125KHZ: bw_pow = 1; - delay_x = 16000000 / bw_pow + 2031250; break; case BW_250KHZ: bw_pow = 2; - delay_x = 16000000 / bw_pow + 2031250; break; case BW_500KHZ: bw_pow = 4; - delay_x = 16000000 / bw_pow + 2031250; break; default: DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d IN SWITCH STATEMENT\n", bandwidth); - delay_x = 0; - bw_pow = 0; - break; + return 0; } - clk_period = 250000; + clk_period = 250000 / bw_pow; + delay_x = 16000000 / bw_pow + 2031250; nb_nibble = (payload_length + 2 * crc_en) * 2 + 5; diff --git a/libloragw/tst/test_loragw_hal_rx.c b/libloragw/tst/test_loragw_hal_rx.c index 0e96f36..6cf85b6 100644 --- a/libloragw/tst/test_loragw_hal_rx.c +++ b/libloragw/tst/test_loragw_hal_rx.c @@ -69,11 +69,13 @@ void usage(void) { //printf("Library version information: %s\n", lgw_version_info()); printf( "Available options:\n"); printf( " -h print this help\n"); - printf( " -k Concentrator clock source (Radio A or Radio B) [0..1]\n"); - printf( " -r Radio type (1255, 1257, 1250)\n"); - printf( " -a Radio A RX frequency in MHz\n"); - printf( " -b Radio B RX frequency in MHz\n"); - printf( " -n number of packet received with CRC OK for each HAL start/stop loop\n"); + printf( " -k Concentrator clock source (Radio A or Radio B) [0..1]\n"); + printf( " -r Radio type (1255, 1257, 1250)\n"); + printf( " -a Radio A RX frequency in MHz\n"); + printf( " -b Radio B RX frequency in MHz\n"); + printf( " -n Number of packet received with CRC OK for each HAL start/stop loop\n"); + printf( " -z Size of the RX packet array to be passed to lgw_receive()\n"); + printf( " -m Channel frequency plan mode [0:LoRaWAN-like, 1:Same frequency for all channels (-400000Hz on RF0)]\n"); } /* -------------------------------------------------------------------------- */ @@ -94,31 +96,47 @@ int main(int argc, char **argv) unsigned int arg_u; uint8_t clocksource = 0; lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE; + uint8_t max_rx_pkt = 16; struct lgw_conf_board_s boardconf; struct lgw_conf_rxrf_s rfconf; struct lgw_conf_rxif_s ifconf; - struct lgw_pkt_rx_s rxpkt[16]; - unsigned long nb_pkt_crc_ok = 0, nb_loop = 1, cnt_loop; + unsigned long nb_pkt_crc_ok = 0, nb_loop = 0, cnt_loop; int nb_pkt; - const int32_t channel_if[9] = { + uint8_t channel_mode = 0; /* LoRaWAN-like */ + + const int32_t channel_if_mode0[9] = { -400000, -200000, 0, -400000, -200000, 0, - 200000, - 400000, - -200000 /* lora service */ + -400000, + -200000, + -400000 /* lora service */ }; - const uint8_t channel_rfchain[9] = { 1, 1, 1, 0, 0, 0, 0, 0, 1 }; + const int32_t channel_if_mode1[9] = { + -400000, + -400000, + -400000, + -400000, + -400000, + -400000, + -400000, + -400000, + -400000 /* lora service */ + }; + + const uint8_t channel_rfchain_mode0[9] = { 1, 1, 1, 0, 0, 0, 0, 0, 1 }; + + const uint8_t channel_rfchain_mode1[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* parse command line options */ - while ((i = getopt (argc, argv, "ha:b:k:r:n:")) != -1) { + while ((i = getopt (argc, argv, "ha:b:k:r:n:z:m:")) != -1) { switch (i) { case 'h': usage(); @@ -179,6 +197,24 @@ int main(int argc, char **argv) nb_loop = arg_u; } break; + case 'z': /* Size of the RX packet array to be passed to lgw_receive() */ + i = sscanf(optarg, "%u", &arg_u); + if (i != 1) { + printf("ERROR: argument parsing of -z argument. Use -h to print help\n"); + return EXIT_FAILURE; + } else { + max_rx_pkt = arg_u; + } + break; + case 'm': + i = sscanf(optarg, "%u", &arg_u); + if ((i != 1) || (arg_u > 1)) { + printf("ERROR: argument parsing of -m argument. Use -h to print help\n"); + return EXIT_FAILURE; + } else { + channel_mode = arg_u; + } + break; default: printf("ERROR: argument parsing\n"); usage(); @@ -231,10 +267,18 @@ int main(int argc, char **argv) /* set configuration for LoRa multi-SF channels (bandwidth cannot be set) */ memset(&ifconf, 0, sizeof(ifconf)); - for (i = 0; i < 9; i++) { + for (i = 0; i < 8; i++) { ifconf.enable = true; - ifconf.rf_chain = channel_rfchain[i]; - ifconf.freq_hz = channel_if[i]; + if (channel_mode == 0) { + ifconf.rf_chain = channel_rfchain_mode0[i]; + ifconf.freq_hz = channel_if_mode0[i]; + } else if (channel_mode == 1) { + ifconf.rf_chain = channel_rfchain_mode1[i]; + ifconf.freq_hz = channel_if_mode1[i]; + } else { + printf("ERROR: channel mode not supported\n"); + return EXIT_FAILURE; + } ifconf.datarate = DR_LORA_SF7; if (lgw_rxif_setconf(i, &ifconf) != LGW_HAL_SUCCESS) { printf("ERROR: failed to configure rxif %d\n", i); @@ -242,6 +286,22 @@ int main(int argc, char **argv) } } + /* set configuration for LoRa Service channel */ + memset(&ifconf, 0, sizeof(ifconf)); + ifconf.rf_chain = channel_rfchain_mode0[i]; + ifconf.freq_hz = channel_if_mode0[i]; + ifconf.datarate = DR_LORA_SF7; + ifconf.bandwidth = BW_250KHZ; + if (lgw_rxif_setconf(8, &ifconf) != LGW_HAL_SUCCESS) { + printf("ERROR: failed to configure rxif for LoRa service channel\n"); + return EXIT_FAILURE; + } + + /* set the buffer size to hold received packets */ + struct lgw_pkt_rx_s rxpkt[max_rx_pkt]; + printf("INFO: rxpkt buffer size is set to %u\n", max_rx_pkt); + printf("INFO: Select channel mode %u\n", channel_mode); + /* Loop until user quits */ cnt_loop = 0; while( (quit_sig != 1) && (exit_sig != 1) ) @@ -264,14 +324,13 @@ int main(int argc, char **argv) /* Loop until we have enough packets with CRC OK */ printf("Waiting for packets...\n"); nb_pkt_crc_ok = 0; - while ((nb_pkt_crc_ok < nb_loop) && (quit_sig != 1) && (exit_sig != 1)) { + while (((nb_pkt_crc_ok < nb_loop) || nb_loop == 0) && (quit_sig != 1) && (exit_sig != 1)) { /* fetch N packets */ nb_pkt = lgw_receive(ARRAY_SIZE(rxpkt), rxpkt); if (nb_pkt == 0) { wait_ms(10); } else { - printf("Received %d packets\n", nb_pkt); for (i = 0; i < nb_pkt; i++) { if (rxpkt[i].status == STAT_CRC_OK) { nb_pkt_crc_ok += 1; @@ -294,6 +353,7 @@ int main(int argc, char **argv) } printf("\n"); } + printf("Received %d packets (total:%lu)\n", nb_pkt, nb_pkt_crc_ok); } } diff --git a/readme.md b/readme.md index 06502b1..3744d46 100644 --- a/readme.md +++ b/readme.md @@ -161,6 +161,16 @@ found in the `libtools` directory. ## 6. Changelog +### v1.0.3 ### + +* HAL: Fixed scheduled downlink time precision by taking the tx start delay into +account. +* HAL: Fixed timestamp correction calculation for BW250 & BW500 +* HAL: Fixed possible buffer overflow in lgw_receive() function +* HAL: Keep packet received in RX buffer when the buffer allocated to receive +the packets is too small. Remaining packets will be fetched on the next +lgw_receive calls (aligned on SX1301 behaviour). + ### v1.0.2 ### * Fixed compilation warnings reported by latest versions of GCC