2019-07-12 15:40:13 +02:00
|
|
|
/*
|
|
|
|
|
/ _____) _ | |
|
|
|
|
|
( (____ _____ ____ _| |_ _____ ____| |__
|
|
|
|
|
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
|
|
|
|
_____) ) ____| | | || |_| ____( (___| | | |
|
|
|
|
|
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
|
|
|
|
(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 LINUXDEV_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( " -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 spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
|
|
|
|
const char * spidev_path = spidev_path_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_NONE;
|
|
|
|
|
|
|
|
|
|
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:p")) != -1) {
|
|
|
|
|
switch (i) {
|
|
|
|
|
case 'h':
|
|
|
|
|
usage();
|
|
|
|
|
return -1;
|
|
|
|
|
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;
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
strncpy(boardconf.spidev_path, spidev_path, sizeof boardconf.spidev_path);
|
2019-08-29 15:05:55 +02:00
|
|
|
boardconf.spidev_path[sizeof boardconf.spidev_path - 1] = '\0'; /* ensure string termination */
|
2019-07-12 15:40:13 +02:00
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Stop the gateway */
|
|
|
|
|
x = lgw_stop();
|
|
|
|
|
if (x != 0) {
|
|
|
|
|
printf("ERROR: failed to stop the gateway\n");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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 ------------------------------------------------------------------ */
|