sx1302_hal/libloragw/tst/test_loragw_counter.c
Michael Coracin 2c14708bdb v2.0.0
> #### New features

* Added support for USB interface between the HOST and the concentrator,
for sx1250 based concentrator only.
* Added support for Listen-Before-Talk for AS923 region, using the additional
sx1261 radio from the Semtech Corecell reference design v3.
* Added support for Spectral Scan with additional sx1261 radio from the Semtech
Corecell reference design v3.
* Added support for SX1303 chip, for further Fine Timestamping support.
* Merged the master-fdd-cn490 branch to bring support for CN490 Full-Duplex
reference design. It is an integration of the releases v1.1.0, v1.1.1, v1.1.2
described below.

> #### Changes

* HAL: Reworked the complete communication layer. A new loragw_com module has
been introduced to handle switching from a USB or a SPI communication interface,
aligned function prototypes for sx125x, sx1250 and sx1261 radios. For USB, a
mode has been added to group SPI write commands request to the STM32 MCU, in
order to optimize latency during time critical configuration phases.
* HAL: Added preliminary support for Fine Timestamping for TDOA localization.
* HAL: Updated AGC firmware to v6: add configurable delay for PA to start, add
Listen-Before-Talk support.
* HAL: Added new API function lgw_demod_setconf() to set global demodulator
settings.
* HAL: Added new API functions for Spectral Scan.
* Packet Forwarder: The type of interface is configurable in the
global_conf.json file: com_type can be "USB" or "SPI".
* Packet Forwarder: Changed the parameters to configure fine timestamping in the
global_conf.json.
* Packet Forwarder: Added sections to configure the spectral scan and
Listen-Before-Talk features.
* Packet Forwarder: Added a new thread for background spectral scan example,
to show how to use the spectral scan API provided by the HAL, without
interfering with the main tasks of the gateway (aka Receive uplinks and transmit
downlinks).
* Packet Forwarder: Added "nhdr" field parsing from "txpk" JSON downlink request
in order to be able to send beacon request from Network Server.
* Packet Forwarder: Added chan_multiSF_All in global_conf.json to choose which
spreading factors to enable for multi-sf demodulators.
* Packet Forwarder: Updated PROTOCOL.md to v1.6.
* Tools: added util_spectral_scan, a standalone spectral scanner utility.

> #### Notes

* This release has been validated on the Semtech Corecell reference design v3
with USB interface.

v1.1.2

> Integrated in ***v2.0.0*** from ***master-fdd-cn490*** branch.

* packet forwarder: updated global_conf.json.sx1255.CN490.full-duplex with RSSI
temperature compensation coefficients, and updated RSSI offset for radio 1.

v1.1.1

> Integrated in ***v2.0.0*** from ***master-fdd-cn490*** branch.

* HAL: Updated SX1302 LNA/PA LUT configuration for Full Duplex CN490 reference
design.
* test_loragw_hal_rx/tx: added --fdd option to enable Full Duplex
* packet forwarder: updated global_conf.json.sx1255.CN490.full-duplex for CN490
reference design.

v1.1.0

> Integrated in ***v2.0.0*** from ***master-fdd-cn490*** branch.

* HAL: Added support for CN490 full duplex reference design.
2020-12-09 09:21:09 +01:00

279 lines
8.8 KiB
C

/*
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(C)2019 Semtech
Description:
Minimum test program for HAL timestamp counter handling
License: Revised BSD License, see LICENSE.TXT file include in the project
*/
/* -------------------------------------------------------------------------- */
/* --- DEPENDANCIES --------------------------------------------------------- */
/* fix an issue between POSIX and C99 */
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <math.h>
#include "loragw_hal.h"
#include "loragw_reg.h"
#include "loragw_aux.h"
/* -------------------------------------------------------------------------- */
/* --- PRIVATE MACROS ------------------------------------------------------- */
#define COM_TYPE_DEFAULT LGW_COM_SPI
#define COM_PATH_DEFAULT "/dev/spidev0.0"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define RAND_RANGE(min, max) (rand() % (max + 1 - min) + min)
/* -------------------------------------------------------------------------- */
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
#define DEFAULT_FREQ_HZ 868500000U
/* -------------------------------------------------------------------------- */
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
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 */
/* -------------------------------------------------------------------------- */
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
static void sig_handler(int sigio) {
if (sigio == SIGQUIT) {
quit_sig = 1;;
} else if ((sigio == SIGINT) || (sigio == SIGTERM)) {
exit_sig = 1;
}
}
void usage(void) {
//printf("Library version information: %s\n", lgw_version_info());
printf("Available options:\n");
printf(" -h print this help\n");
printf(" -u set COM type as USB (default is SPI)\n");
printf(" -d <path> COM path to be used to connect the concentrator\n");
printf(" => default path (SPI): " COM_PATH_DEFAULT "\n");
printf(" -k <uint> Concentrator clock source (Radio A or Radio B) [0..1]\n");
printf(" -r <uint> Radio type (1255, 1257, 1250)\n");
printf(" -p Test PPS trig counter when set\n" );
}
/* -------------------------------------------------------------------------- */
/* --- MAIN FUNCTION -------------------------------------------------------- */
int main(int argc, char **argv)
{
/* SPI interfaces */
const char com_path_default[] = COM_PATH_DEFAULT;
const char * com_path = com_path_default;
lgw_com_type_t com_type = COM_TYPE_DEFAULT;
struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
int i, x;
uint32_t fa = DEFAULT_FREQ_HZ;
uint32_t fb = DEFAULT_FREQ_HZ;
unsigned int arg_u;
uint8_t clocksource = 0;
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_SX1250;
struct lgw_conf_board_s boardconf;
struct lgw_conf_rxrf_s rfconf;
struct lgw_conf_rxif_s ifconf;
uint32_t counter;
bool trig_cnt = false;
const int32_t channel_if[9] = {
-400000,
-200000,
0,
-400000,
-200000,
0,
200000,
400000,
-200000 /* lora service */
};
const uint8_t channel_rfchain[9] = { 1, 1, 1, 0, 0, 0, 0, 0, 1 };
/* parse command line options */
while ((i = getopt (argc, argv, "hk:r:pd:u")) != -1) {
switch (i) {
case 'h':
usage();
return -1;
break;
case 'd':
if (optarg != NULL) {
com_path = optarg;
}
break;
case 'r': /* <uint> Radio type */
i = sscanf(optarg, "%u", &arg_u);
if ((i != 1) || ((arg_u != 1255) && (arg_u != 1257) && (arg_u != 1250))) {
printf("ERROR: argument parsing of -r argument. Use -h to print help\n");
return EXIT_FAILURE;
} else {
switch (arg_u) {
case 1255:
radio_type = LGW_RADIO_TYPE_SX1255;
break;
case 1257:
radio_type = LGW_RADIO_TYPE_SX1257;
break;
default: /* 1250 */
radio_type = LGW_RADIO_TYPE_SX1250;
break;
}
}
break;
case 'k': /* <uint> Clock Source */
i = sscanf(optarg, "%u", &arg_u);
if ((i != 1) || (arg_u > 1)) {
printf("ERROR: argument parsing of -k argument. Use -h to print help\n");
return EXIT_FAILURE;
} else {
clocksource = (uint8_t)arg_u;
}
break;
case 'p':
trig_cnt = true;
break;
case 'u':
com_type = LGW_COM_USB;
break;
default:
printf("ERROR: argument parsing\n");
usage();
return -1;
}
}
/* 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);
printf("===== sx1302 counter test =====\n");
if (com_type == LGW_COM_SPI) {
/* Board reset */
if (system("./reset_lgw.sh start") != 0) {
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
exit(EXIT_FAILURE);
}
}
/* Configure the gateway */
memset(&boardconf, 0, sizeof boardconf);
boardconf.lorawan_public = true;
boardconf.clksrc = clocksource;
boardconf.full_duplex = false;
boardconf.com_type = com_type;
strncpy(boardconf.com_path, com_path, sizeof boardconf.com_path);
boardconf.com_path[sizeof boardconf.com_path - 1] = '\0'; /* ensure string termination */
if (lgw_board_setconf(&boardconf) != LGW_HAL_SUCCESS) {
printf("ERROR: failed to configure board\n");
return EXIT_FAILURE;
}
/* set configuration for RF chains */
memset(&rfconf, 0, sizeof rfconf);
rfconf.enable = true;
rfconf.freq_hz = fa;
rfconf.type = radio_type;
rfconf.tx_enable = false;
rfconf.single_input_mode = false;
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
printf("ERROR: failed to configure rxrf 0\n");
return EXIT_FAILURE;
}
memset(&rfconf, 0, sizeof rfconf);
rfconf.enable = true;
rfconf.freq_hz = fb;
rfconf.type = radio_type;
rfconf.tx_enable = false;
rfconf.single_input_mode = false;
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
printf("ERROR: failed to configure rxrf 1\n");
return EXIT_FAILURE;
}
/* set configuration for LoRa multi-SF channels (bandwidth cannot be set) */
memset(&ifconf, 0, sizeof(ifconf));
for (i = 0; i < 9; i++) {
ifconf.enable = true;
ifconf.rf_chain = channel_rfchain[i];
ifconf.freq_hz = channel_if[i];
ifconf.datarate = DR_LORA_SF7;
if (lgw_rxif_setconf(i, &ifconf) != LGW_HAL_SUCCESS) {
printf("ERROR: failed to configure rxif %d\n", i);
return EXIT_FAILURE;
}
}
/* connect, configure and start the LoRa concentrator */
x = lgw_start();
if (x != 0) {
printf("ERROR: failed to start the gateway\n");
return EXIT_FAILURE;
}
/* Loop until user quits */
while( (quit_sig != 1) && (exit_sig != 1) ) {
if (trig_cnt == false) {
lgw_get_instcnt(&counter);
} else {
lgw_get_trigcnt(&counter);
}
wait_ms(10);
printf("%u\n", counter);
}
/* Stop the gateway */
x = lgw_stop();
if (x != 0) {
printf("ERROR: failed to stop the gateway\n");
return EXIT_FAILURE;
}
if (com_type == LGW_COM_SPI) {
/* Board reset */
if (system("./reset_lgw.sh stop") != 0) {
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
exit(EXIT_FAILURE);
}
}
printf("=========== Test End ===========\n");
return 0;
}
/* --- EOF ------------------------------------------------------------------ */