From 7c383be1542368f2601015d9fc2a417197677677 Mon Sep 17 00:00:00 2001 From: Harsh Sharma <92harshsharma@gmail.com> Date: Wed, 13 Jun 2018 13:24:54 -0500 Subject: Initial Commit --- util_tx_test/Makefile | 67 ++++ util_tx_test/readme.md | 75 +++++ util_tx_test/src/util_tx_test.c | 661 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 803 insertions(+) create mode 100644 util_tx_test/Makefile create mode 100644 util_tx_test/readme.md create mode 100644 util_tx_test/src/util_tx_test.c (limited to 'util_tx_test') diff --git a/util_tx_test/Makefile b/util_tx_test/Makefile new file mode 100644 index 0000000..8c35229 --- /dev/null +++ b/util_tx_test/Makefile @@ -0,0 +1,67 @@ +### Application-specific constants + +APP_NAME := util_tx_test + +### Environment constants + +LGW_PATH ?= ../libloragw +ARCH ?= +CROSS_COMPILE ?= + +### External constant definitions +# must get library build option to know if mpsse must be linked or not + +include $(LGW_PATH)/library.cfg + +### Constant symbols + +CC := $(CROSS_COMPILE)gcc +AR := $(CROSS_COMPILE)ar + +CFLAGS=-O2 -Wall -Wextra -std=c99 -Iinc -I. + +OBJDIR = obj + +### Constants for LoRa concentrator HAL library +# List the library sub-modules that are used by the application + +LGW_INC = $(LGW_PATH)/inc/config.h +LGW_INC += $(LGW_PATH)/inc/loragw_hal.h +LGW_INC += $(LGW_PATH)/inc/loragw_aux.h + +### Linking options + +LIBS := -lloragw -lrt -lm + +### General build targets + +all: $(APP_NAME) + +clean: + rm -f $(OBJDIR)/*.o + rm -f $(APP_NAME) + +### HAL library (do no force multiple library rebuild even with 'make -B') + +$(LGW_PATH)/inc/config.h: + @if test ! -f $@; then \ + $(MAKE) all -C $(LGW_PATH); \ + fi + +$(LGW_PATH)/libloragw.a: $(LGW_INC) + @if test ! -f $@; then \ + $(MAKE) all -C $(LGW_PATH); \ + fi + +### Main program compilation and assembly + +$(OBJDIR): + mkdir -p $(OBJDIR) + +$(OBJDIR)/$(APP_NAME).o: src/$(APP_NAME).c $(LGW_INC) | $(OBJDIR) + $(CC) -c $(CFLAGS) -I$(LGW_PATH)/inc $< -o $@ + +$(APP_NAME): $(OBJDIR)/$(APP_NAME).o $(LGW_PATH)/libloragw.a + $(CC) -L$(LGW_PATH) $< -o $@ $(LIBS) + +### EOF diff --git a/util_tx_test/readme.md b/util_tx_test/readme.md new file mode 100644 index 0000000..c46badf --- /dev/null +++ b/util_tx_test/readme.md @@ -0,0 +1,75 @@ + / _____) _ | | + ( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | + (______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech-Cycleo + +LoRa concentrator packet sender +================================ + +1. Introduction +---------------- + +This software is used to send test packets with a LoRa concentrator. The packets +contain little information, on no protocol (ie. MAC address) information but +can be used to assess the functionality of a gateway downlink using other +gateways as receivers. + +2. Dependencies +---------------- + +This program is a typical example of LoRa concentrator HAL usage for sending +packets. + +Only high-level functions are used (the ones contained in loragw_hal) so there +is no hardware dependencies assuming the HAL is matched with the proper version +of the hardware. +Data structures of the sent packets are accessed by name (ie. not at a +binary level) so new functionalities can be added to the API without affecting +that program at all. + +3. Usage +--------- + +The application runs until the specified number of packets have been sent. +Press Ctrl+C to stop the application before that. + +Use the -h to get help and details about available options. + +The payload content is: +[T][E][S][T][packet counter MSB][packet counter LSB] followed by ASCII padding. + +All LoRa data is scrambled and whitened, so the padding has no influence +whatsoever on the packet error rate. + +4. License +----------- + +Copyright (c) 2013, SEMTECH S.A. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of the Semtech corporation nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*EOF* diff --git a/util_tx_test/src/util_tx_test.c b/util_tx_test/src/util_tx_test.c new file mode 100644 index 0000000..74c163f --- /dev/null +++ b/util_tx_test/src/util_tx_test.c @@ -0,0 +1,661 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech-Cycleo + +Description: + Send a bunch of packets on a settable frequency + +License: Revised BSD License, see LICENSE.TXT file include in the project +Maintainer: Sylvain Miermont +*/ + + +/* -------------------------------------------------------------------------- */ +/* --- DEPENDANCIES --------------------------------------------------------- */ + +/* fix an issue between POSIX and C99 */ +#if __STDC_VERSION__ >= 199901L + #define _XOPEN_SOURCE 600 +#else + #define _XOPEN_SOURCE 500 +#endif + +#include /* C99 types */ +#include /* bool type */ +#include /* printf fprintf sprintf fopen fputs */ + +#include /* memset */ +#include /* sigaction */ +#include /* getopt access */ +#include /* exit codes */ +#include /* getopt_long */ + +#include "loragw_hal.h" +#include "loragw_reg.h" +#include "loragw_aux.h" + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE MACROS ------------------------------------------------------- */ + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#define MSG(args...) fprintf(stderr, args) /* message that is destined to the user */ + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE CONSTANTS ---------------------------------------------------- */ + +#define TX_RF_CHAIN 0 /* TX only supported on radio A */ +#define DEFAULT_RSSI_OFFSET 0.0 +#define DEFAULT_MODULATION "LORA" +#define DEFAULT_BR_KBPS 50 +#define DEFAULT_FDEV_KHZ 25 +#define DEFAULT_NOTCH_FREQ 129000U /* 129 kHz */ +#define DEFAULT_SX127X_RSSI_OFFSET -4 /* dB */ + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE VARIABLES (GLOBAL) ------------------------------------------- */ + +/* signal handling variables */ +struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */ +static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */ +static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */ + +/* TX gain LUT table */ +static struct lgw_tx_gain_lut_s txgain_lut = { + .size = 5, + .lut[0] = { + .dig_gain = 0, + .pa_gain = 0, + .dac_gain = 3, + .mix_gain = 12, + .rf_power = 0 + }, + .lut[1] = { + .dig_gain = 0, + .pa_gain = 1, + .dac_gain = 3, + .mix_gain = 12, + .rf_power = 10 + }, + .lut[2] = { + .dig_gain = 0, + .pa_gain = 2, + .dac_gain = 3, + .mix_gain = 10, + .rf_power = 14 + }, + .lut[3] = { + .dig_gain = 0, + .pa_gain = 3, + .dac_gain = 3, + .mix_gain = 9, + .rf_power = 20 + }, + .lut[4] = { + .dig_gain = 0, + .pa_gain = 3, + .dac_gain = 3, + .mix_gain = 14, + .rf_power = 27 + }}; + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */ + +static void sig_handler(int sigio); + +void usage (void); + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */ + +static void sig_handler(int sigio) { + if (sigio == SIGQUIT) { + quit_sig = 1;; + } else if ((sigio == SIGINT) || (sigio == SIGTERM)) { + exit_sig = 1; + } +} + +/* describe command line options */ +void usage(void) { + int i; + + printf("*** Library version information ***\n%s\n\n", lgw_version_info()); + printf("Available options:\n"); + printf(" -h print this help\n"); + printf(" -r radio type (SX1255:1255, SX1257:1257)\n"); + printf(" -n TX notch filter frequency in kHz [126..250]\n"); + printf(" -f target frequency in MHz\n"); + printf(" -k concentrator clock source (0:Radio A, 1:Radio B)\n"); + printf(" -m modulation type ['LORA', 'FSK']\n"); + printf(" -b LoRa bandwidth in kHz [125, 250, 500]\n"); + printf(" -s LoRa Spreading Factor [7-12]\n"); + printf(" -c LoRa Coding Rate [1-4]\n"); + printf(" -d FSK frequency deviation in kHz [1:250]\n"); + printf(" -q FSK bitrate in kbps [0.5:250]\n"); + printf(" -p RF power (dBm) [ "); + for (i = 0; i < txgain_lut.size; i++) { + printf("%ddBm ", txgain_lut.lut[i].rf_power); + } + printf("]\n"); + printf(" -l LoRa preamble length (symbols)\n"); + printf(" -z payload size (bytes, <256)\n"); + printf(" -i send packet using inverted modulation polarity\n"); + printf(" -t pause between packets (ms)\n"); + printf(" -x nb of times the sequence is repeated (-1 loop until stopped)\n"); + printf(" --lbt-freq lbt first channel frequency in MHz\n"); + printf(" --lbt-nbch lbt number of channels [1..8]\n"); + printf(" --lbt-sctm lbt scan time in usec to be applied to all channels [128, 5000]\n"); + printf(" --lbt-rssi lbt rssi target in dBm [-128..0]\n"); + printf(" --lbt-rssi-offset rssi offset in dB to be applied to SX127x RSSI [-128..127]\n"); +} + +/* -------------------------------------------------------------------------- */ +/* --- MAIN FUNCTION -------------------------------------------------------- */ + +int main(int argc, char **argv) +{ + int i; + uint8_t status_var; + + /* user entry parameters */ + int xi = 0; + unsigned int xu = 0; + double xd = 0.0; + float xf = 0.0; + char arg_s[64]; + + /* application parameters */ + char mod[64] = DEFAULT_MODULATION; + uint32_t f_target = 0; /* target frequency - invalid default value, has to be specified by user */ + int sf = 10; /* SF10 by default */ + int cr = 1; /* CR1 aka 4/5 by default */ + int bw = 125; /* 125kHz bandwidth by default */ + int pow = 14; /* 14 dBm by default */ + int preamb = 8; /* 8 symbol preamble by default */ + int pl_size = 16; /* 16 bytes payload by default */ + int delay = 1000; /* 1 second between packets by default */ + int repeat = -1; /* by default, repeat until stopped */ + bool invert = false; + float br_kbps = DEFAULT_BR_KBPS; + uint8_t fdev_khz = DEFAULT_FDEV_KHZ; + bool lbt_enable = false; + uint32_t lbt_f_target = 0; + uint32_t lbt_sc_time = 5000; + int8_t lbt_rssi_target_dBm = -80; + int8_t lbt_rssi_offset_dB = DEFAULT_SX127X_RSSI_OFFSET; + uint8_t lbt_nb_channel = 1; + uint32_t sx1301_count_us; + uint32_t tx_notch_freq = DEFAULT_NOTCH_FREQ; + + /* RF configuration (TX fail if RF chain is not enabled) */ + enum lgw_radio_type_e radio_type = LGW_RADIO_TYPE_NONE; + uint8_t clocksource = 1; /* Radio B is source by default */ + struct lgw_conf_board_s boardconf; + struct lgw_conf_lbt_s lbtconf; + struct lgw_conf_rxrf_s rfconf; + + /* allocate memory for packet sending */ + struct lgw_pkt_tx_s txpkt; /* array containing 1 outbound packet + metadata */ + + /* loop variables (also use as counters in the packet payload) */ + uint16_t cycle_count = 0; + + /* Parameter parsing */ + int option_index = 0; + static struct option long_options[] = { + {"lbt-freq", required_argument, 0, 0}, + {"lbt-sctm", required_argument, 0, 0}, + {"lbt-rssi", required_argument, 0, 0}, + {"lbt-nbch", required_argument, 0, 0}, + {"lbt-rssi-offset", required_argument, 0, 0}, + {0, 0, 0, 0} + }; + + /* parse command line options */ + while ((i = getopt_long (argc, argv, "hif:n:m:b:s:c:p:l:z:t:x:r:k:d:q:", long_options, &option_index)) != -1) { + switch (i) { + case 'h': + usage(); + return EXIT_FAILURE; + break; + + case 'f': /* Target frequency in MHz */ + i = sscanf(optarg, "%lf", &xd); + if ((i != 1) || (xd < 30.0) || (xd > 3000.0)) { + MSG("ERROR: invalid TX frequency\n"); + usage(); + return EXIT_FAILURE; + } else { + f_target = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */ + } + break; + + case 'n': /* TX notch filter frequency in kHz */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || ((xi < 126) || (xi > 250))) { + MSG("ERROR: invalid TX notch filter frequency\n"); + usage(); + return EXIT_FAILURE; + } else { + tx_notch_freq = xi*1000; + } + break; + + case 'm': /* Modulation type */ + i = sscanf(optarg, "%s", arg_s); + if ((i != 1) || ((strcmp(arg_s,"LORA") != 0) && (strcmp(arg_s,"FSK")))) { + MSG("ERROR: invalid modulation type\n"); + usage(); + return EXIT_FAILURE; + } else { + sprintf(mod, "%s", arg_s); + } + break; + + case 'b': /* Modulation bandwidth in kHz */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || ((xi != 125) && (xi != 250) && (xi != 500))) { + MSG("ERROR: invalid LoRa bandwidth\n"); + usage(); + return EXIT_FAILURE; + } else { + bw = xi; + } + break; + + case 's': /* Spreading Factor */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < 7) || (xi > 12)) { + MSG("ERROR: invalid spreading factor\n"); + usage(); + return EXIT_FAILURE; + } else { + sf = xi; + } + break; + + case 'c': /* Coding Rate */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < 1) || (xi > 4)) { + MSG("ERROR: invalid coding rate\n"); + usage(); + return EXIT_FAILURE; + } else { + cr = xi; + } + break; + + case 'p': /* RF power */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < -60) || (xi > 60)) { + MSG("ERROR: invalid RF power\n"); + usage(); + return EXIT_FAILURE; + } else { + pow = xi; + } + break; + + case 'd': /* FSK frequency deviation */ + i = sscanf(optarg, "%u", &xu); + if ((i != 1) || (xu < 1) || (xu > 250)) { + MSG("ERROR: invalid FSK frequency deviation\n"); + usage(); + return EXIT_FAILURE; + } else { + fdev_khz = (uint8_t)xu; + } + break; + + case 'q': /* FSK bitrate */ + i = sscanf(optarg, "%f", &xf); + if ((i != 1) || (xf < 0.5) || (xf > 250)) { + MSG("ERROR: invalid FSK bitrate\n"); + usage(); + return EXIT_FAILURE; + } else { + br_kbps = xf; + } + break; + + case 'l': /* preamble length (symbols) */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < 6)) { + MSG("ERROR: preamble length must be >6 symbols \n"); + usage(); + return EXIT_FAILURE; + } else { + preamb = xi; + } + break; + + case 'z': /* payload length (bytes) */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi <= 0)) { + MSG("ERROR: invalid payload size\n"); + usage(); + return EXIT_FAILURE; + } else { + pl_size = xi; + } + break; + + case 't': /* pause between packets (ms) */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < 0)) { + MSG("ERROR: invalid time between packets\n"); + usage(); + return EXIT_FAILURE; + } else { + delay = xi; + } + break; + + case 'x': /* numbers of times the sequence is repeated */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < -1)) { + MSG("ERROR: invalid number of repeats\n"); + usage(); + return EXIT_FAILURE; + } else { + repeat = xi; + } + break; + + case 'r': /* Radio type (1255, 1257) */ + sscanf(optarg, "%i", &xi); + switch (xi) { + case 1255: + radio_type = LGW_RADIO_TYPE_SX1255; + break; + case 1257: + radio_type = LGW_RADIO_TYPE_SX1257; + break; + default: + printf("ERROR: invalid radio type\n"); + usage(); + return EXIT_FAILURE; + } + break; + + case 'i': /* Send packet using inverted modulation polarity */ + invert = true; + break; + + case 'k': /* Concentrator clock source (Radio A or Radio B) */ + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || ((xi != 0) && (xi != 1))) { + MSG("ERROR: invalid clock source\n"); + usage(); + return EXIT_FAILURE; + } else { + clocksource = (uint8_t)xi; + } + break; + + case 0: + if( strcmp(long_options[option_index].name, "lbt-freq") == 0 ) { /* LBT first channel frequency in MHz */ + i = sscanf(optarg, "%lf", &xd); + if ((i != 1) || (xd < 30.0) || (xd > 3000.0)) { + MSG("ERROR: invalid LBT start frequency\n"); + usage(); + return EXIT_FAILURE; + } else { + lbt_f_target = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */ + lbt_enable = true; + } + } else if( strcmp(long_options[option_index].name, "lbt-sctm") == 0 ) { /* LBT scan time in usec */ + if (lbt_enable == true) { + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < 0)) { + MSG("ERROR: invalid LBT scan time\n"); + usage(); + return EXIT_FAILURE; + } else { + lbt_sc_time = xi; + } + } else { + MSG("ERROR: invalid parameter, LBT start frequency must be set\n"); + usage(); + return EXIT_FAILURE; + } + } else if( strcmp(long_options[option_index].name, "lbt-rssi") == 0 ) { /* LBT RSSI target */ + if (lbt_enable == true) { + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || ((xi < -128) && (xi > 0))) { + MSG("ERROR: invalid LBT RSSI target\n"); + usage(); + return EXIT_FAILURE; + } else { + lbt_rssi_target_dBm = xi; + } + } else { + MSG("ERROR: invalid parameter, LBT start frequency must be set\n"); + usage(); + return EXIT_FAILURE; + } + } else if( strcmp(long_options[option_index].name, "lbt-rssi-offset") == 0 ) { /* LBT RSSI offset */ + if (lbt_enable == true) { + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || ((xi < -128) && (xi > 127))) { + MSG("ERROR: invalid LBT RSSI offset\n"); + usage(); + return EXIT_FAILURE; + } else { + lbt_rssi_offset_dB = xi; + } + } else { + MSG("ERROR: invalid parameter, LBT start frequency must be set\n"); + usage(); + return EXIT_FAILURE; + } + } else if( strcmp(long_options[option_index].name, "lbt-nbch") == 0 ) { /* LBT number of channels */ + if (lbt_enable == true) { + i = sscanf(optarg, "%i", &xi); + if ((i != 1) || (xi < 0)) { + MSG("ERROR: invalid LBT number of channels\n"); + usage(); + return EXIT_FAILURE; + } else { + lbt_nb_channel = xi; + } + } else { + MSG("ERROR: invalid parameter, LBT start frequency must be set\n"); + usage(); + return EXIT_FAILURE; + } + } + break; + default: + MSG("ERROR: argument parsing\n"); + usage(); + return EXIT_FAILURE; + } + } + + /* check parameter sanity */ + if (f_target == 0) { + MSG("ERROR: frequency parameter not set, please use -f option to specify it.\n"); + return EXIT_FAILURE; + } + if (radio_type == LGW_RADIO_TYPE_NONE) { + MSG("ERROR: radio type parameter not properly set, please use -r option to specify it.\n"); + return EXIT_FAILURE; + } + + /* Summary of packet parameters */ + if (strcmp(mod, "FSK") == 0) { + printf("Sending %i FSK packets on %u Hz (FDev %u kHz, Bitrate %.2f, %i bytes payload, %i symbols preamble) at %i dBm, with %i ms between each\n", repeat, f_target, fdev_khz, br_kbps, pl_size, preamb, pow, delay); + } else { + printf("Sending %i LoRa packets on %u Hz (BW %i kHz, SF %i, CR %i, %i bytes payload, %i symbols preamble) at %i dBm, with %i ms between each\n", repeat, f_target, bw, sf, cr, pl_size, preamb, pow, delay); + } + + /* configure signal handling */ + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = 0; + sigact.sa_handler = sig_handler; + sigaction(SIGQUIT, &sigact, NULL); + sigaction(SIGINT, &sigact, NULL); + sigaction(SIGTERM, &sigact, NULL); + + /* starting the concentrator */ + /* board config */ + memset(&boardconf, 0, sizeof(boardconf)); + boardconf.lorawan_public = true; + boardconf.clksrc = clocksource; + lgw_board_setconf(boardconf); + + /* LBT config */ + if (lbt_enable) { + memset(&lbtconf, 0, sizeof(lbtconf)); + lbtconf.enable = true; + lbtconf.nb_channel = lbt_nb_channel; + lbtconf.rssi_target = lbt_rssi_target_dBm; + lbtconf.rssi_offset = lbt_rssi_offset_dB; + lbtconf.channels[0].freq_hz = lbt_f_target; + lbtconf.channels[0].scan_time_us = lbt_sc_time; + for (i=1; i> 8); /* MSB */ + txpkt.payload[5] = (uint8_t)(cycle_count & 0x00FF); /* LSB */ + + /* When LBT is enabled, immediate send is not allowed, so we need + to set a timestamp to the packet */ + if (lbt_enable == true) { + /* Get the current SX1301 time */ + lgw_reg_w(LGW_GPS_EN, 0); + lgw_get_trigcnt(&sx1301_count_us); + lgw_reg_w(LGW_GPS_EN, 1); + + /* Set packet timestamp to current time + few milliseconds */ + txpkt.count_us = sx1301_count_us + 50E3; + } + + /* send packet */ + printf("Sending packet number %u ...", cycle_count); + i = lgw_send(txpkt); /* non-blocking scheduling of TX packet */ + if (i == LGW_HAL_ERROR) { + printf("ERROR\n"); + return EXIT_FAILURE; + } else if (i == LGW_LBT_ISSUE ) { + printf("Failed: Not allowed (LBT)\n"); + } else { + /* wait for packet to finish sending */ + do { + wait_ms(5); + lgw_status(TX_STATUS, &status_var); /* get TX status */ + } while (status_var != TX_FREE); + printf("OK\n"); + } + + /* wait inter-packet delay */ + wait_ms(delay); + + /* exit loop on user signals */ + if ((quit_sig == 1) || (exit_sig == 1)) { + break; + } + } + + /* clean up before leaving */ + lgw_stop(); + + printf("Exiting LoRa concentrator TX test program\n"); + return EXIT_SUCCESS; +} + +/* --- EOF ------------------------------------------------------------------ */ -- cgit v1.2.3