diff options
| author | Sylvain Miermont <smiermont@semtech.com> | 2013-10-22 18:23:52 +0200 | 
|---|---|---|
| committer | Sylvain Miermont <smiermont@semtech.com> | 2013-10-24 09:29:51 +0200 | 
| commit | 4977430ef31fb52994fed42b9cb180930ed943d0 (patch) | |
| tree | 27f4fadea5fa35f25933d59bcd7b99cca8c965c8 /loragw_tx_test | |
| parent | b922932d1c9869d82042b600db2382d8c15f63dc (diff) | |
| download | lora_gateway-4977430ef31fb52994fed42b9cb180930ed943d0.tar.gz lora_gateway-4977430ef31fb52994fed42b9cb180930ed943d0.tar.bz2 lora_gateway-4977430ef31fb52994fed42b9cb180930ed943d0.zip | |
Beta 8v1.b8
- API: lgw_receive now return info on RX frequency and RF path for each packet (no need to keep track of RF/IF settings)
- Unified some portion of the code with the 470 MHz variant of the HAL (use SX1255 radios instead of SX1257)
- Improved AGC and ARB firmwares
- Adding -Wall -Wextra for compilation, fixing all the new warnings for cleaner code
- Fixed bugs in handling of FSK datarate
- test_loragw_hal now dumps the content of all Lora registers after configuration in reg_dump.log
Diffstat (limited to 'loragw_tx_test')
| -rw-r--r-- | loragw_tx_test/LICENSE.TXT | 8 | ||||
| -rw-r--r-- | loragw_tx_test/Makefile | 34 | ||||
| -rw-r--r-- | loragw_tx_test/README.TXT | 65 | ||||
| -rw-r--r-- | loragw_tx_test/obj/.gitkeep | 0 | ||||
| -rw-r--r-- | loragw_tx_test/src/loragw_tx_test.c | 290 | 
5 files changed, 397 insertions, 0 deletions
| diff --git a/loragw_tx_test/LICENSE.TXT b/loragw_tx_test/LICENSE.TXT new file mode 100644 index 0000000..e406dcb --- /dev/null +++ b/loragw_tx_test/LICENSE.TXT @@ -0,0 +1,8 @@ +Copyright (C) 2013 SEMTECH S.A. + + THE FOLLOWING SOFTWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND  +(2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. +CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR +CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT +OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION +CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. diff --git a/loragw_tx_test/Makefile b/loragw_tx_test/Makefile new file mode 100644 index 0000000..5d07c6d --- /dev/null +++ b/loragw_tx_test/Makefile @@ -0,0 +1,34 @@ +### Application-specific constants + +APP_NAME=loragw_tx_test + +### constant symbols + +CC=gcc +CFLAGS=-O2 -Wall -Wextra -Iinc +C99FLAGS=-O2 -Wall -Wextra -std=c99 -Iinc +FLAG_AUX= + +### constants for Lora Gateway HAL library + +LGW_PATH=../loragw_hal +LGW_INC=-I$(LGW_PATH)/inc +#LGW_LNK=-lloragw -lrt +LGW_LNK=-lloragw -lrt -lmpsse +# add libmpsse or not, depending on what option you compiled the libloragw with + +### general build targets + +all: $(APP_NAME) + +clean: +	rm -f obj/*.o +	rm -f $(APP_NAME) + +### main program compilation and assembly + +obj/$(APP_NAME).o: src/$(APP_NAME).c  +	$(CC) -c $(C99FLAGS) -o obj/$(APP_NAME).o $(LGW_INC) src/$(APP_NAME).c $(FLAG_AUX) + +$(APP_NAME): $(LGW_PATH)/libloragw.a obj/$(APP_NAME).o +	$(CC) -o $(APP_NAME) obj/$(APP_NAME).o -L$(LGW_PATH) $(LGW_LNK) diff --git a/loragw_tx_test/README.TXT b/loragw_tx_test/README.TXT new file mode 100644 index 0000000..2f95735 --- /dev/null +++ b/loragw_tx_test/README.TXT @@ -0,0 +1,65 @@ +	 / _____)             _              | |     +	( (____  _____ ____ _| |_ _____  ____| |__   +	 \____ \| ___ |    (_   _) ___ |/ ___)  _ \  +	 _____) ) ____| | | || |_| ____( (___| | | | +	(______/|_____)_|_|_| \__)_____)\____)_| |_| +		©2013 Semtech-Cycleo + +Lora Gateway 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 Gateway 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. + +It was tested with beta8 of the libloragw library, and should be compatible +with any later version of the library assuming the API is downward-compatible. + +3. Usage +--------- + +The application runs until the specified number of packets have been send. +Press Ctrl+C to stop the application before that. + +Use the -f option followed by a real number (decimal point and scientific +'E notation' are OK) to specify the modulation central frequency. +Use the -s option to specify the Spreading Factor of Lora modulation (values 7 +to 12 are valid). +Use the -b option to set Lora modulation bandwidth in kHz (accepted values: 125, +250 or 500). +Use the -p option to set the concentrator TX power in dBm. Not all values are +supported by hardware (typically 14 et 20 dBm are supported, other values might +not give expected power). Check with a RF power meter before connecting any +sensitive equipment. +Use the -t option to specify the number of milliseconds of pause between +packets. Using zero will result in a quasi-continuous emission. +Use the -x to specify how many packets should be sent. + +The packets are 20 bytes long, and protected by the smallest supported ECC. + +The payload content is: +[T][E][S][T][packet counter MSB][packet counter MSB] followed by ASCII padding. +All Lora data is whitened, so the padding has no influence whatsoever on the +packet error rate. + +4. Changelog +------------- + +2013-10-18, beta 1 +Initial version. diff --git a/loragw_tx_test/obj/.gitkeep b/loragw_tx_test/obj/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/loragw_tx_test/obj/.gitkeep diff --git a/loragw_tx_test/src/loragw_tx_test.c b/loragw_tx_test/src/loragw_tx_test.c new file mode 100644 index 0000000..bb8fe2c --- /dev/null +++ b/loragw_tx_test/src/loragw_tx_test.c @@ -0,0 +1,290 @@ +/* + / _____)             _              | | +( (____  _____ ____ _| |_ _____  ____| |__ + \____ \| ___ |    (_   _) ___ |/ ___)  _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| +    ©2013 Semtech-Cycleo + +Description: +	Send a bunch of packets on a settable frequency +*/ + + +/* -------------------------------------------------------------------------- */ +/* --- 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>		/* C99 types */ +#include <stdbool.h>	/* bool type */ +#include <stdio.h>		/* printf fprintf sprintf fopen fputs */ + +#include <string.h>		/* memset */ +#include <signal.h>		/* sigaction */ +#include <unistd.h>		/* getopt access */ +#include <stdlib.h>		/* exit codes */ + +#include "loragw_hal.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		RF_CHAIN				0	/* we'll use radio A only */ + +const uint32_t lowfreq[LGW_RF_CHAIN_NB] = LGW_RF_TX_LOWFREQ; +const uint32_t upfreq[LGW_RF_CHAIN_NB] = LGW_RF_TX_UPFREQ; + +/* -------------------------------------------------------------------------- */ +/* --- 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 */ + +/* -------------------------------------------------------------------------- */ +/* --- 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) { +	MSG( "Available options:\n"); +	MSG( " -h print this help\n"); +	MSG( " -f <float> target frequency in MHz\n"); +	MSG( " -s <int> Spreading Factor\n"); +	MSG( " -b <int> Modulation bandwidth in kHz\n"); +	MSG( " -p <int> RF power (dBm)\n"); +	MSG( " -t <int> pause between packets (ms)\n"); +	MSG( " -x <int> numbers of times the sequence is repeated\n"); +	MSG( " -i send packet using inverted modulation polarity \n"); +} + +/* -------------------------------------------------------------------------- */ +/* --- MAIN FUNCTION -------------------------------------------------------- */ + +int main(int argc, char **argv) +{ +	int i; +	uint8_t status_var; +	 +	/* user entry parameters */ +	int xi = 0; +	double xd = 0.0; +	uint32_t f_min; +	uint32_t f_max; +	 +	/* application parameters */ +	uint32_t f_target = lowfreq[RF_CHAIN]/2 + upfreq[RF_CHAIN]/2; /* target frequency */ +	int sf = 10; /* SF10 by default */ +	int bw = 125; /* 125kHz bandwidth by default */ +	int pow = 14; /* 14 dBm by default */ +	int delay = 1000; /* 1 second between packets by default */ +	int repeat = 1; /* sweep only once by default */ +	bool invert = false; +	 +	/* RF configuration (TX fail if RF chain is not enabled) */ +	const struct lgw_conf_rxrf_s rfconf = {true, lowfreq[RF_CHAIN]}; +	 +	/* 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; +	 +	/* parse command line options */ +	while ((i = getopt (argc, argv, "hf:s:b:p:t:x:i")) != -1) { +		switch (i) { +			case 'h': +				usage(); +				return EXIT_FAILURE; +				break; +			 +			case 'f': /* -f <float> target frequency in MHz */ +				i = sscanf(optarg, "%lf", &xd); +				if ((i != 1) || (xd < 30.0) || (xd > 3000.0)) { +					MSG("ERROR: invalid TX frequency\n"); +					return EXIT_FAILURE; +				} else { +					f_target = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */ +				} +				break; +			 +			case 's': /* -s <int> Spreading Factor */ +				i = sscanf(optarg, "%i", &xi); +				if ((i != 1) || (xi < 7) || (xi > 12)) { +					MSG("ERROR: invalid spreading factor\n"); +					return EXIT_FAILURE; +				} else { +					sf = xi; +				} +				break; +			 +			case 'b': /* -b <int> Modulation bandwidth in kHz */ +				i = sscanf(optarg, "%i", &xi); +				if ((i != 1) || ((xi != 125)&&(xi != 250)&&(xi != 500))) { +					MSG("ERROR: invalid Lora bandwidth\n"); +					return EXIT_FAILURE; +				} else { +					bw = xi; +				} +				break; +			 +			case 'p': /* -p <int> RF power */ +				i = sscanf(optarg, "%i", &xi); +				if ((i != 1) || (xi < 0) || (xi > 20)) { +					MSG("ERROR: invalid RF power\n"); +					return EXIT_FAILURE; +				} else { +					pow = xi; +				} +				break; +			 +			case 't': /* -t <int> pause between packets (ms) */ +				i = sscanf(optarg, "%i", &xi); +				if ((i != 1) || (xi < 0)) { +					MSG("ERROR: invalid time between packets\n"); +					return EXIT_FAILURE; +				} else { +					delay = xi; +				} +				break; +			 +			case 'x': /* -x <int> numbers of times the sequence is repeated */ +				i = sscanf(optarg, "%i", &xi); +				if ((i != 1) || (xi < 1)) { +					MSG("ERROR: invalid number of repeats\n"); +					return EXIT_FAILURE; +				} else { +					repeat = xi; +				} +				break; +			 +			case 'i': /* -i send packet using inverted modulation polarity */ +				invert = true; +				break; +			 +			default: +				MSG("ERROR: argument parsing use -h option for help\n"); +				usage(); +				return EXIT_FAILURE; +		} +	} +	 +	/* check parameter sanity */ +	f_min = lowfreq[RF_CHAIN] + (500 * bw); +	f_max = upfreq[RF_CHAIN] - (500 * bw); +	if ((f_target < f_min) || (f_target > f_max)) { +		MSG("ERROR: frequency out of authorized band (accounting for modulation bandwidth)\n"); +		return EXIT_FAILURE; +	} +	printf("Sending %u packets on %u Hz (BW %u kHz, SF %u, 20 bytes payload) at %i dBm, with %u ms between each\n", repeat, f_target, bw, sf, 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 */ +	lgw_rxrf_setconf(RF_CHAIN, rfconf); +	i = lgw_start(); +	if (i == LGW_HAL_SUCCESS) { +		MSG("INFO: concentrator started, packet can be sent\n"); +	} else { +		MSG("ERROR: failed to start the concentrator\n"); +		return EXIT_FAILURE; +	} +	 +	/* fill-up payload and parameters */ +	memset(&txpkt, 0, sizeof(txpkt)); +	txpkt.freq_hz = f_target; +	txpkt.tx_mode = IMMEDIATE; +	txpkt.rf_chain = RF_CHAIN; +	txpkt.rf_power = pow; +	txpkt.modulation = MOD_LORA; +	switch (bw) { +		case 125: txpkt.bandwidth = BW_125KHZ; break; +		case 250: txpkt.bandwidth = BW_250KHZ; break; +		case 500: txpkt.bandwidth = BW_500KHZ; break; +		default: +			MSG("ERROR: invalid 'bw' variable\n"); +			return EXIT_FAILURE; +	} +	switch (sf) { +		case  7: txpkt.datarate = DR_LORA_SF7;  break; +		case  8: txpkt.datarate = DR_LORA_SF8;  break; +		case  9: txpkt.datarate = DR_LORA_SF9;  break; +		case 10: txpkt.datarate = DR_LORA_SF10; break; +		case 11: txpkt.datarate = DR_LORA_SF11; break; +		case 12: txpkt.datarate = DR_LORA_SF12; break; +		default: +			MSG("ERROR: invalid 'sf' variable\n"); +			return EXIT_FAILURE; +	} +	txpkt.coderate = CR_LORA_4_5; +	txpkt.invert_pol = invert; +	txpkt.preamble = 8; +	txpkt.size = 20; /* should be close to typical payload length */ +	strcpy((char *)txpkt.payload, "TEST**abcdefghijklmn" ); /* abc.. is for padding */ +	 +	/* main loop */ +	for (cycle_count = 0; cycle_count < repeat; ++cycle_count) { +		/* refresh counters in payload (big endian, for readability) */ +		txpkt.payload[4] = (uint8_t)(cycle_count >> 8); /* MSB */ +		txpkt.payload[5] = (uint8_t)(cycle_count & 0x00FF); /* LSB */ +		 +		/* send packet */ +		printf("Sending packet number %u ...", cycle_count); +		i = lgw_send(txpkt); /* non-blocking scheduling of TX packet */ +		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 ------------------------------------------------------------------ */ | 
