From 81c7bdd2a1c38d35aeb0eacd059100a9c799e17a Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 25 Feb 2019 17:00:11 +0000 Subject: [PATCH] Merged in raiden00/apps/lora (pull request #170) examples: add sx127x demo Approved-by: Gregory Nutt --- examples/README.txt | 5 + examples/sx127x_demo/Kconfig | 32 ++ examples/sx127x_demo/Make.defs | 39 ++ examples/sx127x_demo/Makefile | 55 +++ examples/sx127x_demo/sx127x_demo.c | 650 +++++++++++++++++++++++++++++ 5 files changed, 781 insertions(+) create mode 100644 examples/sx127x_demo/Kconfig create mode 100644 examples/sx127x_demo/Make.defs create mode 100644 examples/sx127x_demo/Makefile create mode 100644 examples/sx127x_demo/sx127x_demo.c diff --git a/examples/README.txt b/examples/README.txt index 79a49d4d2..cfe7fd3b2 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1653,6 +1653,11 @@ examples/stat A simple test of stat(), fstat(), and statfs(). This is useful primarily for bringing up a new file system and verifying the correctness of these operations. +examples/sx127x_demo +^^^^^^^^^^^^^ + + This example demonstrates the use of the SX127X radio/ + examples/system ^^^^^^^^^^^^^^^ diff --git a/examples/sx127x_demo/Kconfig b/examples/sx127x_demo/Kconfig new file mode 100644 index 000000000..760d97266 --- /dev/null +++ b/examples/sx127x_demo/Kconfig @@ -0,0 +1,32 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_SX127X + bool "SX127x example" + default n + depends on LPWAN_SX127X + +config EXAMPLES_SX127X_RFFREQ + int "SX127x RF frequency" + default 930000000 + +config EXAMPLES_SX127X_TXPOWER + int "SX127x TX power" + default 14 + +config EXAMPLES_SX127X_TXDATA + int "SX127x TX data length" + default 5 + +config EXAMPLES_SX127X_TIME + int "SX127x demo time, 0 for infinity" + default 0 + +config EXAMPLES_SX127X_INTERVAL + int "SX127x time interval for modem operations" + default 5 + +if EXAMPLES_SX127X +endif diff --git a/examples/sx127x_demo/Make.defs b/examples/sx127x_demo/Make.defs new file mode 100644 index 000000000..c319606a3 --- /dev/null +++ b/examples/sx127x_demo/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/sx127x_demo/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2019 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS 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. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_SX127X),) +CONFIGURED_APPS += examples/sx127x_demo +endif diff --git a/examples/sx127x_demo/Makefile b/examples/sx127x_demo/Makefile new file mode 100644 index 000000000..79d9e557f --- /dev/null +++ b/examples/sx127x_demo/Makefile @@ -0,0 +1,55 @@ +############################################################################ +# apps/examples/sx127x_demo/Makefile +# +# Copyright (C) 2019 Gregory Nutt. All rights reserved. +# Author: Mateusz Szafoni +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS 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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +# Basic sx127x+ demonstration + +ASRCS = +CSRCS = +MAINSRC = sx127x_demo.c + +CONFIG_XYZ_PROGNAME ?= sx127x_demo$(EXEEXT) +PROGNAME = $(CONFIG_XYZ_PROGNAME) + +# built-in application info + +APPNAME = sx127x +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +MODULE = CONFIG_EXAMPLES_SX127X + +include $(APPDIR)/Application.mk diff --git a/examples/sx127x_demo/sx127x_demo.c b/examples/sx127x_demo/sx127x_demo.c new file mode 100644 index 000000000..f5b193c95 --- /dev/null +++ b/examples/sx127x_demo/sx127x_demo.c @@ -0,0 +1,650 @@ +/**************************************************************************** + * examples/sx127x_demo/sx127x_demo.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Mateusz Szafoni + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEV_NAME "/dev/sx127x" +#define TX_BUFFER_MAX 255 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum app_mode_e +{ + APP_MODE_RX = 0, + APP_MODE_TX = 1, + APP_MODE_RXTX = 2, + APP_MODE_SCAN = 3 +}; + +enum app_modulation_e +{ + APP_MODULATION_LORA = 0, + APP_MODULATION_FSK = 1, + APP_MODULATION_OOK = 2, +}; + +/* Application arguments */ + +struct args_s +{ + uint32_t frequency; + int16_t interval; + int16_t time; + uint8_t app_mode; + uint8_t modulation; + uint8_t datalen; + int8_t power; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct args_s g_args; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_NSH_BUILTIN_APPS + +/**************************************************************************** + * Name: sx127x_help + ****************************************************************************/ + +static void sx127x_help(FAR struct args_s *args) +{ + printf("Usage: sx127x [OPTIONS]\n\n"); + printf(" [-m modulation] modulation scheme (default=0)\n"); + printf(" 0 - LORA\n"); + printf(" 1 - FSK\n"); + printf(" 2 - OOK\n"); + printf(" [-f frequency Hz] RF frequency (default=%d)\n", + CONFIG_EXAMPLES_SX127X_RFFREQ); + printf(" [-i interval sec] radio access time interval (default=%d)\n", + CONFIG_EXAMPLES_SX127X_INTERVAL); + printf(" [-l datalen] data length for TX (default=%d)\n", + CONFIG_EXAMPLES_SX127X_TXDATA); + printf(" [-d time sec] demo time, 0 if infinity (default=%d)\n", + CONFIG_EXAMPLES_SX127X_TIME); + printf(" [-r/-t/-x/-s] select app mode (default=r)\n"); + printf(" r - RX\n"); + printf(" t - TX\n"); + printf(" x - RX/TX (not supported yet)\n"); + printf(" s - SCAN\n"); + printf(" [-p power dBm] TX power (default=%d)\n", + CONFIG_EXAMPLES_SX127X_TXPOWER); + printf(" [-h] print this message\n"); +} + +/**************************************************************************** + * Name: arg_string + ****************************************************************************/ + +static int arg_string(FAR char **arg, FAR char **value) +{ + FAR char *ptr = *arg; + + if (ptr[2] == '\0') + { + *value = arg[1]; + return 2; + } + else + { + *value = &ptr[2]; + return 1; + } +} + +/**************************************************************************** + * Name: arg_decimal + ****************************************************************************/ + +static int arg_decimal(FAR char **arg, FAR int *value) +{ + FAR char *string; + int ret; + + ret = arg_string(arg, &string); + *value = atoi(string); + + return ret; +} + +/**************************************************************************** + * Name: parse_args + ****************************************************************************/ + +static void parse_args(FAR struct args_s *args, int argc, FAR char **argv) +{ + FAR char *ptr; + int index; + int nargs; + int i_value; + + for (index = 1; index < argc;) + { + ptr = argv[index]; + if (ptr[0] != '-') + { + printf("Invalid options format: %s\n", ptr); + exit(0); + } + + switch (ptr[1]) + { + /* Interval between RX/TX operations */ + + case 'i': + { + nargs = arg_decimal(&argv[index], &i_value); + index += nargs; + + args->interval = i_value; + + break; + } + + /* Demo time */ + + case 'd': + { + nargs = arg_decimal(&argv[index], &i_value); + index += nargs; + + args->time = i_value; + + break; + } + + /* Data length for TX */ + + case 'l': + { + nargs = arg_decimal(&argv[index], &i_value); + index += nargs; + + args->datalen = i_value; + + break; + } + + /* Modem RF frequency */ + + case 'f': + { + nargs = arg_decimal(&argv[index], &i_value); + index += nargs; + + args->frequency = i_value; + + break; + } + + /* Modem modulation scheme */ + + case 'm': + { + nargs = arg_decimal(&argv[index], &i_value); + index += nargs; + + args->modulation = i_value; + + break; + } + + /* Modem TX power */ + + case 'p': + { + nargs = arg_decimal(&argv[index], &i_value); + index += nargs; + + args->power = i_value; + + break; + } + + /* RX mode */ + + case 'r': + { + args->app_mode = APP_MODE_RX; + index += 1; + + break; + } + + /* TX mode */ + + case 't': + { + args->app_mode = APP_MODE_TX; + index += 1; + + break; + } + + /* RX-TX mode */ + + case 'x': + { + args->app_mode = APP_MODE_RXTX; + index += 1; + + break; + } + + /* Scan mode */ + + case 's': + { + args->app_mode = APP_MODE_SCAN; + index += 1; + + break; + } + + /* Print help message */ + + case 'h': + { + sx127x_help(args); + exit(0); + } + + /* Unsupported option */ + + default: + { + printf("Unsupported option: %s\n", ptr); + sx127x_help(args); + exit(1); + } + } + } +} + +/**************************************************************************** + * Name: validate_args + ****************************************************************************/ + +static int validate_args(FAR struct args_s *args) +{ + int ret = OK; + + /* TODO */ + + return ret; +} +#endif /* CONFIG_NSH_BUILTIN_APPS */ + +/**************************************************************************** + * Name: print_hex + ****************************************************************************/ + +static void print_hex(uint8_t *data, int len) +{ + int i; + + if(len == 0) + { + printf("empty buffer!\n"); + } + else + { + for(i = 0 ; i < len ; i += 1) + { + printf("0x%02x ", data[i]); + + if((i+1)%10 == 0) + { + printf("\n"); + } + } + } + printf("\n"); +} + +/**************************************************************************** + * Name: modulation_set + ****************************************************************************/ + +static int modulation_set(int fd, uint8_t modulation) +{ + int ret = OK; + + switch (modulation) + { + case APP_MODULATION_LORA: + { + printf("LORA modulation\n"); + + modulation = SX127X_MODULATION_LORA; + ret = ioctl(fd, SX127XIOC_MODULATIONSET, (unsigned long)&modulation); + if (ret < 0) + { + printf("failed change modulation %d!\n", ret); + goto errout; + } + break; + } + + case APP_MODULATION_FSK: + { + printf("FSK modulation\n"); + + modulation = SX127X_MODULATION_FSK; + ret = ioctl(fd, SX127XIOC_MODULATIONSET, (unsigned long)&modulation); + if (ret < 0) + { + printf("failed change modulation %d!\n", ret); + goto errout; + } + break; + } + + case APP_MODULATION_OOK: + { + printf("OOK modulation\n"); + + modulation = SX127X_MODULATION_OOK; + ret = ioctl(fd, SX127XIOC_MODULATIONSET, (unsigned long)&modulation); + if (ret < 0) + { + printf("failed change modulation %d!\n", ret); + goto errout; + } + break; + } + + default: + { + printf("Unsupported app modulation %d!\n", modulation); + goto errout; + } + } + +errout: + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef BUILD_MODULE +int main(int argc, FAR char *argv[]) +#else +int sx127x_main(int argc, char *argv[]) +#endif +{ + struct sx127x_read_hdr_s data; + struct sx127x_chanscan_ioc_s chanscan; + struct args_s *args; + struct timespec tstart; + struct timespec tnow; + uint8_t buffer[TX_BUFFER_MAX]; + uint8_t opmode; + uint8_t i; + int ret; + int fd; + + /* Initialize buffer with data */ + + for (i = 0; i < TX_BUFFER_MAX; i+=1) + { + buffer[i] = i; + } + + /* Initialize variables */ + + args = &g_args; + args->app_mode = APP_MODE_RX; + args->modulation = APP_MODULATION_LORA; + args->frequency = CONFIG_EXAMPLES_SX127X_RFFREQ; + args->power = CONFIG_EXAMPLES_SX127X_TXPOWER; + args->interval = CONFIG_EXAMPLES_SX127X_INTERVAL; + args->time = CONFIG_EXAMPLES_SX127X_TIME; + args->datalen = CONFIG_EXAMPLES_SX127X_TXDATA; + +#ifdef CONFIG_NSH_BUILTIN_APPS + /* Parse the command line */ + + parse_args(args, argc, argv); + + /* Validate arguments */ + + ret = validate_args(args); + if (ret != OK) + { + printf("sx127x_main: validate arguments failed!\n"); + goto errout; + } +#endif + + printf("Start sx127x_demo\n"); + + /* Open device */ + + fd = open(DEV_NAME, O_RDWR); + if (fd < 0) + { + printf("ERROR: Failed to open device!\n"); + goto errout; + } + + /* Set modulation */ + + ret = modulation_set(fd, args->modulation); + if (ret < 0) + { + printf("modulation_set failed\n"); + goto errout; + } + + /* Set RF frequency */ + + printf("Set frequency to %d\n", args->frequency); + + ret = ioctl(fd, WLIOC_SETRADIOFREQ, (unsigned long)&args->frequency); + if (ret < 0) + { + printf("failed to change frequency %d!\n", ret); + goto errout; + } + + /* Set TX power */ + + printf("Set power to %d\n", args->power); + + ret = ioctl(fd, WLIOC_SETTXPOWER, (unsigned long)&args->power); + if (ret < 0) + { + printf("failed to change power %d!\n", ret); + goto errout; + } + + /* Get start time */ + + clock_gettime(CLOCK_REALTIME, &tstart); + + while(1) + { + switch (args->app_mode) + { + /* Transmit some data */ + + case APP_MODE_TX: + { + printf("\nSend %d bytes\n", args->datalen); + + ret = write(fd, buffer, args->datalen); + if (ret < 0) + { + printf("write failed %d!\n", ret); + goto errout; + } + + break; + } + + /* Receive data */ + + case APP_MODE_RX: + { + /* Set radio in RX mode */ + + opmode = SX127X_OPMODE_RX; + + ret = ioctl(fd, SX127XIOC_OPMODESET, (unsigned long)&opmode); + if (ret < 0) + { + printf("failed change opmode to RX %d!\n", ret); + goto errout; + } + + /* TODO: add RX poll if configured */ + + printf("Waiting for data\n"); + + ret = read(fd, &data, sizeof(struct sx127x_read_hdr_s)); + if (ret < 0) + { + printf("Read failed %d!\n", ret); + goto errout; + } + + printf("\nReceived:\n"); + printf("SNR = %d\n", data.snr); + printf("RSSI = %d\n", data.rssi); + printf("len = %d\n", data.datalen); + print_hex(data.data, data.datalen); + printf("\n"); + + break; + } + + /* Send some data and wait for response */ + + case APP_MODE_RXTX: + { + printf("TODO: APP RXTX\n"); + break; + } + + /* Scan channel */ + + case APP_MODE_SCAN: + { + /* TODO: Configure this from command line */ + + chanscan.freq = args->frequency; + chanscan.rssi_thr = -30; + chanscan.stime = 2; + chanscan.free = false; + chanscan.rssi_max = 0; + + ret = ioctl(fd, SX127XIOC_CHANSCAN, (unsigned long)&chanscan); + if (ret < 0) + { + printf("failed chanscan %d!\n", ret); + goto errout; + } + + printf("freq = %d max = %d min = %d free = %d\n", chanscan.freq, + chanscan.rssi_max, chanscan.rssi_min, chanscan.free); + + break; + } + + default: + { + printf("Unsupported app mode!\n"); + goto errout; + } + } + + printf("wait %d sec ...\n", args->interval); + sleep(args->interval); + + if (args->time > 0) + { + /* Get time now */ + + clock_gettime(CLOCK_REALTIME, &tnow); + + if (tnow.tv_sec - tstart.tv_sec >= args->time) + { + printf("Timeout - force exit!\n"); + goto errout; + } + } + } + +errout: + close(fd); + return 0; +}