diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..54dd494f --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*/*.a +*/obj/ +*.swp +bin/ +libloragw/inc/config.h +libloragw/test_loragw_* +packet_forwarder/lora_pkt_fwd +util_chip_id/chip_id +util_net_downlink/net_downlink \ No newline at end of file diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100644 index 00000000..a59e9676 --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,80 @@ +Copyright (c) 2019, 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. + + +--- For the parson library used by the packet forwarder --- + +Parson ( http://kgabis.github.com/parson/ ) +Copyright (c) 2012 Krzysztof Gabis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +--- For the tinyMT32 library used by the HAL --- + +Copyright (c) 2011 Mutsuo Saito, Makoto Matsumoto, Hiroshima +University and The University of Tokyo. 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 Hiroshima University 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. diff --git a/VERSION b/VERSION index 21e8796a..ee90284c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.3 +1.0.4 diff --git a/libloragw/inc/loragw_hal.h b/libloragw/inc/loragw_hal.h index a41bc737..a3d2e663 100644 --- a/libloragw/inc/loragw_hal.h +++ b/libloragw/inc/loragw_hal.h @@ -170,12 +170,13 @@ struct lgw_rssi_tcomp_s { @brief Configuration structure for a RF chain */ struct lgw_conf_rxrf_s { - bool enable; /*!> enable or disable that RF chain */ - uint32_t freq_hz; /*!> center frequency of the radio in Hz */ - float rssi_offset; /*!> Board-specific RSSI correction factor */ - struct lgw_rssi_tcomp_s rssi_tcomp; /*!> Board-specific RSSI temperature compensation coefficients */ - lgw_radio_type_t type; /*!> Radio type for that RF chain (SX1255, SX1257....) */ - bool tx_enable; /*!> enable or disable TX on that RF chain */ + bool enable; /*!> enable or disable that RF chain */ + uint32_t freq_hz; /*!> center frequency of the radio in Hz */ + float rssi_offset; /*!> Board-specific RSSI correction factor */ + struct lgw_rssi_tcomp_s rssi_tcomp; /*!> Board-specific RSSI temperature compensation coefficients */ + lgw_radio_type_t type; /*!> Radio type for that RF chain (SX1255, SX1257....) */ + bool tx_enable; /*!> enable or disable TX on that RF chain */ + bool single_input_mode; /*!> Configure the radio in single or differential input mode (SX1250 only) */ }; /** diff --git a/libloragw/inc/loragw_sx1250.h b/libloragw/inc/loragw_sx1250.h index af5b6bb4..eb3db90d 100644 --- a/libloragw/inc/loragw_sx1250.h +++ b/libloragw/inc/loragw_sx1250.h @@ -95,7 +95,7 @@ int sx1250_write_command(uint8_t rf_chain, sx1250_op_code_t op_code, uint8_t *da int sx1250_read_command(uint8_t rf_chain, sx1250_op_code_t op_code, uint8_t *data, uint16_t size); int sx1250_calibrate(uint8_t rf_chain, uint32_t freq_hz); -int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz); +int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz, bool single_input_mode); #endif diff --git a/libloragw/readme.md b/libloragw/readme.md index 7b546e80..5bdc4b15 100644 --- a/libloragw/readme.md +++ b/libloragw/readme.md @@ -362,7 +362,18 @@ To debug your application, it might help to compile the loragw_hal function with the debug messages activated (set DEBUG_HAL=1 in library.cfg). It then send a lot of details, including detailed error messages to *stderr*. -## 6. License +## 6. Notes + +### 6.1. Spreading factor SF5 & SF6 + +The sx1302 supports SF5 and SF6 spreading factors, and the HAL also. But it is +important to note that the only syncword supported for SF5 and SF6 is 0x12 +(also known as "private"). + +This is true whatever how of the "lorawan_public" field of lgw_conf_board_s is +set. + +## 7. License Copyright (c) 2019, SEMTECH S.A. All rights reserved. diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c index a09016a0..3b00c09c 100644 --- a/libloragw/src/loragw_hal.c +++ b/libloragw/src/loragw_hal.c @@ -291,13 +291,15 @@ int lgw_rxrf_setconf(uint8_t rf_chain, struct lgw_conf_rxrf_s * conf) { CONTEXT_RF_CHAIN[rf_chain].rssi_tcomp.coeff_e = conf->rssi_tcomp.coeff_e; CONTEXT_RF_CHAIN[rf_chain].type = conf->type; CONTEXT_RF_CHAIN[rf_chain].tx_enable = conf->tx_enable; + CONTEXT_RF_CHAIN[rf_chain].single_input_mode = conf->single_input_mode; - DEBUG_PRINTF("Note: rf_chain %d configuration; en:%d freq:%d rssi_offset:%f radio_type:%d tx_enable:%d\n", rf_chain, + DEBUG_PRINTF("Note: rf_chain %d configuration; en:%d freq:%d rssi_offset:%f radio_type:%d tx_enable:%d single_input_mode:%d\n", rf_chain, CONTEXT_RF_CHAIN[rf_chain].enable, CONTEXT_RF_CHAIN[rf_chain].freq_hz, CONTEXT_RF_CHAIN[rf_chain].rssi_offset, CONTEXT_RF_CHAIN[rf_chain].type, - CONTEXT_RF_CHAIN[rf_chain].tx_enable); + CONTEXT_RF_CHAIN[rf_chain].tx_enable, + CONTEXT_RF_CHAIN[rf_chain].single_input_mode); return LGW_HAL_SUCCESS; } @@ -594,7 +596,7 @@ int lgw_start(void) { sx1302_radio_reset(i, CONTEXT_RF_CHAIN[i].type); switch (CONTEXT_RF_CHAIN[i].type) { case LGW_RADIO_TYPE_SX1250: - sx1250_setup(i, CONTEXT_RF_CHAIN[i].freq_hz); + sx1250_setup(i, CONTEXT_RF_CHAIN[i].freq_hz, CONTEXT_RF_CHAIN[i].single_input_mode); break; case LGW_RADIO_TYPE_SX1255: case LGW_RADIO_TYPE_SX1257: diff --git a/libloragw/src/loragw_sx1250.c b/libloragw/src/loragw_sx1250.c index 99ad2d5b..24246f4c 100644 --- a/libloragw/src/loragw_sx1250.c +++ b/libloragw/src/loragw_sx1250.c @@ -198,7 +198,7 @@ int sx1250_calibrate(uint8_t rf_chain, uint32_t freq_hz) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz) { +int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz, bool single_input_mode) { int32_t freq_reg; uint8_t buff[16]; @@ -297,6 +297,15 @@ int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz) { buff[2] = 0xFF; sx1250_write_command(rf_chain, SET_RX, buff, 3); /* Rx Continuous */ + /* Select single input or differential input mode */ + if (single_input_mode == true) { + printf("INFO: Configuring SX1250_%u in single input mode\n", rf_chain); + buff[0] = 0x08; + buff[1] = 0xE2; + buff[2] = 0x0D; + sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3); + } + buff[0] = 0x05; buff[1] = 0x87; buff[2] = 0x0B; diff --git a/libloragw/tst/test_loragw_cal.c b/libloragw/tst/test_loragw_cal.c index 854a0426..d1e643d4 100644 --- a/libloragw/tst/test_loragw_cal.c +++ b/libloragw/tst/test_loragw_cal.c @@ -103,6 +103,7 @@ void usage(void) { printf(" -k Concentrator clock source (Radio A or Radio B) [0..1]\n"); printf(" -c RF chain to be used for TX (Radio A or Radio B) [0..1]\n"); printf(" -r Radio type (1255, 1257, 1250)\n"); + printf(" -j Set radio in single input mode (SX1250 only)\n"); printf(" -f Radio TX frequency in MHz\n"); printf( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); printf(" --pa PA gain [0..3]\n"); @@ -465,6 +466,7 @@ int main(int argc, char **argv) uint8_t clocksource = 0; uint8_t rf_chain = 0; lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE; + bool single_input_mode = false; struct lgw_conf_board_s boardconf; struct lgw_conf_rxrf_s rfconf; @@ -490,7 +492,7 @@ int main(int argc, char **argv) }; /* parse command line options */ - while ((i = getopt_long (argc, argv, "hf:k:r:c:d:", long_options, &option_index)) != -1) { + while ((i = getopt_long (argc, argv, "hjf:k:r:c:d:", long_options, &option_index)) != -1) { switch (i) { case 'h': usage(); @@ -543,6 +545,10 @@ int main(int argc, char **argv) } break; + case 'j': + single_input_mode = true; + break; + case 'f': /* Radio TX frequency in MHz */ i = sscanf(optarg, "%lf", &arg_d); if (i != 1) { @@ -616,6 +622,7 @@ int main(int argc, char **argv) rfconf.freq_hz = ft; rfconf.type = radio_type; rfconf.tx_enable = true; + rfconf.single_input_mode = single_input_mode; if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) { printf("ERROR: failed to configure rxrf 0\n"); return EXIT_FAILURE; @@ -626,6 +633,7 @@ int main(int argc, char **argv) rfconf.freq_hz = ft; rfconf.type = radio_type; rfconf.tx_enable = true; + rfconf.single_input_mode = single_input_mode; if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) { printf("ERROR: failed to configure rxrf 1\n"); return EXIT_FAILURE; diff --git a/libloragw/tst/test_loragw_capture_ram.c b/libloragw/tst/test_loragw_capture_ram.c index a8acba75..db120449 100644 --- a/libloragw/tst/test_loragw_capture_ram.c +++ b/libloragw/tst/test_loragw_capture_ram.c @@ -196,7 +196,7 @@ int main(int argc, char **argv) sx1302_radio_reset(i, rf_radio_type[i]); switch (radio_type) { case LGW_RADIO_TYPE_SX1250: - sx1250_setup(i, rf_rx_freq[i]); + sx1250_setup(i, rf_rx_freq[i], false); break; case LGW_RADIO_TYPE_SX1255: case LGW_RADIO_TYPE_SX1257: diff --git a/libloragw/tst/test_loragw_counter.c b/libloragw/tst/test_loragw_counter.c index 3d70ed5e..c5f6ba18 100644 --- a/libloragw/tst/test_loragw_counter.c +++ b/libloragw/tst/test_loragw_counter.c @@ -192,6 +192,7 @@ int main(int argc, char **argv) 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; @@ -202,6 +203,7 @@ int main(int argc, char **argv) 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; @@ -235,6 +237,7 @@ int main(int argc, char **argv) lgw_get_trigcnt(&counter); } wait_ms(10); + printf("%u\n", counter); } /* Stop the gateway */ diff --git a/libloragw/tst/test_loragw_gps.c b/libloragw/tst/test_loragw_gps.c index 3d332e43..5c8900dd 100644 --- a/libloragw/tst/test_loragw_gps.c +++ b/libloragw/tst/test_loragw_gps.c @@ -286,6 +286,7 @@ int main(int argc, char **argv) rfconf.rssi_offset = 0.0; 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; @@ -297,6 +298,7 @@ int main(int argc, char **argv) rfconf.rssi_offset = 0.0; 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; diff --git a/libloragw/tst/test_loragw_hal_rx.c b/libloragw/tst/test_loragw_hal_rx.c index 6cf85b66..ec55a3ba 100644 --- a/libloragw/tst/test_loragw_hal_rx.c +++ b/libloragw/tst/test_loragw_hal_rx.c @@ -67,15 +67,16 @@ static void sig_handler(int sigio) { void usage(void) { //printf("Library version information: %s\n", lgw_version_info()); - printf( "Available options:\n"); - printf( " -h print this help\n"); - printf( " -k Concentrator clock source (Radio A or Radio B) [0..1]\n"); - printf( " -r Radio type (1255, 1257, 1250)\n"); - printf( " -a Radio A RX frequency in MHz\n"); - printf( " -b Radio B RX frequency in MHz\n"); - printf( " -n Number of packet received with CRC OK for each HAL start/stop loop\n"); - printf( " -z Size of the RX packet array to be passed to lgw_receive()\n"); - printf( " -m Channel frequency plan mode [0:LoRaWAN-like, 1:Same frequency for all channels (-400000Hz on RF0)]\n"); + printf("Available options:\n"); + printf(" -h print this help\n"); + printf(" -k Concentrator clock source (Radio A or Radio B) [0..1]\n"); + printf(" -r Radio type (1255, 1257, 1250)\n"); + printf(" -a Radio A RX frequency in MHz\n"); + printf(" -b Radio B RX frequency in MHz\n"); + printf(" -n Number of packet received with CRC OK for each HAL start/stop loop\n"); + printf(" -z Size of the RX packet array to be passed to lgw_receive()\n"); + printf(" -m Channel frequency plan mode [0:LoRaWAN-like, 1:Same frequency for all channels (-400000Hz on RF0)]\n"); + printf(" -j Set radio in single input mode (SX1250 only)\n"); } /* -------------------------------------------------------------------------- */ @@ -97,6 +98,7 @@ int main(int argc, char **argv) uint8_t clocksource = 0; lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE; uint8_t max_rx_pkt = 16; + bool single_input_mode = false; struct lgw_conf_board_s boardconf; struct lgw_conf_rxrf_s rfconf; @@ -136,7 +138,7 @@ int main(int argc, char **argv) const uint8_t channel_rfchain_mode1[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* parse command line options */ - while ((i = getopt (argc, argv, "ha:b:k:r:n:z:m:")) != -1) { + while ((i = getopt (argc, argv, "hja:b:k:r:n:z:m:")) != -1) { switch (i) { case 'h': usage(); @@ -170,6 +172,9 @@ int main(int argc, char **argv) clocksource = (uint8_t)arg_u; } break; + case 'j': /* Set radio in single input mode */ + single_input_mode = true; + break; case 'a': /* Radio A RX frequency in MHz */ i = sscanf(optarg, "%lf", &arg_d); if (i != 1) { @@ -250,6 +255,7 @@ int main(int argc, char **argv) rfconf.freq_hz = fa; rfconf.type = radio_type; rfconf.tx_enable = false; + rfconf.single_input_mode = single_input_mode; if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) { printf("ERROR: failed to configure rxrf 0\n"); return EXIT_FAILURE; @@ -260,6 +266,7 @@ int main(int argc, char **argv) rfconf.freq_hz = fb; rfconf.type = radio_type; rfconf.tx_enable = false; + rfconf.single_input_mode = single_input_mode; if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) { printf("ERROR: failed to configure rxrf 1\n"); return EXIT_FAILURE; diff --git a/libloragw/tst/test_loragw_hal_tx.c b/libloragw/tst/test_loragw_hal_tx.c index d2c70769..8489c664 100644 --- a/libloragw/tst/test_loragw_hal_tx.c +++ b/libloragw/tst/test_loragw_hal_tx.c @@ -80,6 +80,7 @@ void usage(void) { printf(" -t TX mode timestamped with delay in ms. If delay is 0, TX mode GPS trigger\n"); printf(" -p RF power in dBm\n"); printf(" -i Send LoRa packet using inverted modulation polarity\n"); + printf(" -j Set radio in single input mode (SX1250 only)\n"); printf( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); printf(" --pa PA gain SX125x:[0..3], SX1250:[0,1]\n"); printf(" --dig sx1302 digital gain for sx125x [0..3]\n"); @@ -131,6 +132,7 @@ int main(int argc, char **argv) uint16_t preamble = 8; bool invert_pol = false; bool no_header = false; + bool single_input_mode = false; struct lgw_conf_board_s boardconf; struct lgw_conf_rxrf_s rfconf; @@ -165,7 +167,7 @@ int main(int argc, char **argv) }; /* parse command line options */ - while ((i = getopt_long (argc, argv, "hif:s:b:n:z:p:k:r:c:l:t:m:o:q:d:", long_options, &option_index)) != -1) { + while ((i = getopt_long (argc, argv, "hjif:s:b:n:z:p:k:r:c:l:t:m:o:q:d:", long_options, &option_index)) != -1) { switch (i) { case 'h': usage(); @@ -174,6 +176,9 @@ int main(int argc, char **argv) case 'i': /* Send packet using inverted modulation polarity */ invert_pol = true; break; + case 'j': /* Set radio in single input mode */ + single_input_mode = true; + break; case 'r': /* Radio type */ i = sscanf(optarg, "%u", &arg_u); if ((i != 1) || ((arg_u != 1255) && (arg_u != 1257) && (arg_u != 1250))) { @@ -424,9 +429,10 @@ int main(int argc, char **argv) memset( &rfconf, 0, sizeof rfconf); rfconf.enable = true; /* rf chain 0 needs to be enabled for calibration to work on sx1257 */ - rfconf.freq_hz = 868500000; /* dummy */ + rfconf.freq_hz = ft; rfconf.type = radio_type; rfconf.tx_enable = true; + rfconf.single_input_mode = single_input_mode; if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) { printf("ERROR: failed to configure rxrf 0\n"); return EXIT_FAILURE; @@ -434,9 +440,10 @@ int main(int argc, char **argv) memset( &rfconf, 0, sizeof rfconf); rfconf.enable = (((rf_chain == 1) || (clocksource == 1)) ? true : false); - rfconf.freq_hz = 868500000; /* dummy */ + rfconf.freq_hz = ft; rfconf.type = radio_type; rfconf.tx_enable = false; + rfconf.single_input_mode = single_input_mode; if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) { printf("ERROR: failed to configure rxrf 1\n"); return EXIT_FAILURE; diff --git a/packet_forwarder/Makefile b/packet_forwarder/Makefile index 7075b427..83097507 100644 --- a/packet_forwarder/Makefile +++ b/packet_forwarder/Makefile @@ -62,8 +62,8 @@ install: install_conf: @echo "---- Copying packet_forwarder conf files to $(TARGET_IP):$(TARGET_DIR)" @ssh $(TARGET_USR)@$(TARGET_IP) "mkdir -p $(TARGET_DIR)" - @scp global_conf.json.sx1250 $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR) - @scp global_conf.json.sx1257 $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR) + @scp global_conf.json.sx1250.* $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR) + @scp global_conf.json.sx1257.* $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR) else @echo "ERROR: TARGET_USR is not configured in target.cfg" endif diff --git a/packet_forwarder/PROTOCOL.md b/packet_forwarder/PROTOCOL.md index 59f6c307..ac2bb295 100644 --- a/packet_forwarder/PROTOCOL.md +++ b/packet_forwarder/PROTOCOL.md @@ -41,7 +41,7 @@ losses (no retries). +- - - - - - - - - - - - - - - -+ __Concentrator__: radio RX/TX board, based on Semtech multichannel modems -(SX130x), transceivers (SX135x) and/or low-power stand-alone modems (SX127x). +(SX130x), transceivers (SX125x) and/or low-power stand-alone modems (SX127x). __Host__: embedded computer on which the packet forwarder is run. Drives the concentrator through a SPI link. @@ -224,21 +224,23 @@ That object contains the status of the gateway, with the following fields: ackr | number | Percentage of upstream datagrams that were acknowledged dwnb | number | Number of downlink datagrams received (unsigned integer) txnb | number | Number of packets emitted (unsigned integer) + temp | number | Current temperature in degree celcius (float) Example (white-spaces, indentation and newlines added for readability): ``` json {"stat":{ - "time":"2014-01-12 08:59:28 GMT", - "lati":46.24000, - "long":3.25230, - "alti":145, - "rxnb":2, - "rxok":2, - "rxfw":2, - "ackr":100.0, - "dwnb":2, - "txnb":2 + "time":"2014-01-12 08:59:28 GMT", + "lati":46.24000, + "long":3.25230, + "alti":145, + "rxnb":2, + "rxok":2, + "rxfw":2, + "ackr":100.0, + "dwnb":2, + "txnb":2, + "temp": 23.2 }} ``` diff --git a/packet_forwarder/global_conf.json.sx1250.CN490 b/packet_forwarder/global_conf.json.sx1250.CN490 new file mode 100644 index 00000000..eeca5be9 --- /dev/null +++ b/packet_forwarder/global_conf.json.sx1250.CN490 @@ -0,0 +1,100 @@ +{ + "SX130x_conf": { + "spidev_path": "/dev/spidev0.0", + "lorawan_public": true, + "clksrc": 0, + "antenna_gain": 0, /* antenna gain, in dBi */ + "full_duplex": false, + "precision_timestamp": { + "enable": false, + "max_ts_metrics": 255, + "nb_symbols": 1 + }, + "radio_0": { + "enable": true, + "type": "SX1250", + "single_input_mode": true, + "freq": 471400000, + "rssi_offset": -207.0, + "rssi_tcomp": {"coeff_a": 0, "coeff_b": 0, "coeff_c": 20.41, "coeff_d": 2162.56, "coeff_e": 0}, + "tx_enable": true, + "tx_freq_min": 500000000, + "tx_freq_max": 510000000, + "tx_gain_lut":[ + {"rf_power": -6, "pa_gain": 0, "pwr_idx": 0}, + {"rf_power": -3, "pa_gain": 0, "pwr_idx": 1}, + {"rf_power": 0, "pa_gain": 0, "pwr_idx": 2}, + {"rf_power": 3, "pa_gain": 1, "pwr_idx": 3}, + {"rf_power": 6, "pa_gain": 1, "pwr_idx": 4}, + {"rf_power": 10, "pa_gain": 1, "pwr_idx": 5}, + {"rf_power": 11, "pa_gain": 1, "pwr_idx": 6}, + {"rf_power": 12, "pa_gain": 2, "pwr_idx": 7}, + {"rf_power": 13, "pa_gain": 1, "pwr_idx": 8}, + {"rf_power": 14, "pa_gain": 2, "pwr_idx": 9}, + {"rf_power": 16, "pa_gain": 2, "pwr_idx": 10}, + {"rf_power": 20, "pa_gain": 3, "pwr_idx": 11}, + {"rf_power": 23, "pa_gain": 3, "pwr_idx": 12}, + {"rf_power": 25, "pa_gain": 3, "pwr_idx": 13}, + {"rf_power": 26, "pa_gain": 3, "pwr_idx": 14}, + {"rf_power": 27, "pa_gain": 3, "pwr_idx": 15} + ] + }, + "radio_1": { + "enable": true, + "type": "SX1250", + "single_input_mode": true, + "freq": 475000000, + "rssi_offset": -207.0, + "rssi_tcomp": {"coeff_a": 0, "coeff_b": 0, "coeff_c": 20.41, "coeff_d": 2162.56, "coeff_e": 0}, + "tx_enable": false + }, + "chan_multiSF_0": {"enable": true, "radio": 0, "if": -300000}, + "chan_multiSF_1": {"enable": true, "radio": 0, "if": -100000}, + "chan_multiSF_2": {"enable": true, "radio": 0, "if": 100000}, + "chan_multiSF_3": {"enable": true, "radio": 0, "if": 300000}, + "chan_multiSF_4": {"enable": true, "radio": 1, "if": -300000}, + "chan_multiSF_5": {"enable": true, "radio": 1, "if": -100000}, + "chan_multiSF_6": {"enable": true, "radio": 1, "if": 100000}, + "chan_multiSF_7": {"enable": true, "radio": 1, "if": 300000}, + "chan_Lora_std": {"enable": true, "radio": 1, "if": -200000, "bandwidth": 250000, "spread_factor": 7, + "implicit_hdr": false, "implicit_payload_length": 17, "implicit_crc_en": false, "implicit_coderate": 1}, + "chan_FSK": {"enable": true, "radio": 1, "if": 300000, "bandwidth": 125000, "datarate": 50000} + }, + + "gateway_conf": { + "gateway_ID": "AA555A0000000000", + /* change with default server address/ports */ + "server_address": "localhost", + "serv_port_up": 1730, + "serv_port_down": 1730, + /* adjust the following parameters for your network */ + "keepalive_interval": 10, + "stat_interval": 30, + "push_timeout_ms": 100, + /* forward only valid packets */ + "forward_crc_valid": true, + "forward_crc_error": false, + "forward_crc_disabled": false, + /* GPS configuration */ + "gps_tty_path": "/dev/ttyS0", + /* GPS reference coordinates */ + "ref_latitude": 0.0, + "ref_longitude": 0.0, + "ref_altitude": 0, + /* Beaconing parameters */ + "beacon_period": 0, + "beacon_freq_hz": 869525000, + "beacon_datarate": 9, + "beacon_bw_hz": 125000, + "beacon_power": 14, + "beacon_infodesc": 0 + }, + + "debug_conf": { + "ref_payload":[ + {"id": "0xCAFE1234"}, + {"id": "0xCAFE2345"} + ], + "log_file": "loragw_hal.log" + } +} diff --git a/packet_forwarder/global_conf.json.sx1250 b/packet_forwarder/global_conf.json.sx1250.EU868 similarity index 99% rename from packet_forwarder/global_conf.json.sx1250 rename to packet_forwarder/global_conf.json.sx1250.EU868 index 01b8ae3c..d09bc21d 100644 --- a/packet_forwarder/global_conf.json.sx1250 +++ b/packet_forwarder/global_conf.json.sx1250.EU868 @@ -80,7 +80,7 @@ "ref_longitude": 0.0, "ref_altitude": 0, /* Beaconing parameters */ - "beacon_period": 128, + "beacon_period": 0, "beacon_freq_hz": 869525000, "beacon_datarate": 9, "beacon_bw_hz": 125000, diff --git a/packet_forwarder/global_conf.json.sx1257 b/packet_forwarder/global_conf.json.sx1257.EU868 similarity index 99% rename from packet_forwarder/global_conf.json.sx1257 rename to packet_forwarder/global_conf.json.sx1257.EU868 index 985d1efd..249547b5 100644 --- a/packet_forwarder/global_conf.json.sx1257 +++ b/packet_forwarder/global_conf.json.sx1257.EU868 @@ -80,7 +80,7 @@ "ref_longitude": 0.0, "ref_altitude": 0, /* Beaconing parameters */ - "beacon_period": 128, + "beacon_period": 0, "beacon_freq_hz": 869525000, "beacon_datarate": 9, "beacon_bw_hz": 125000, diff --git a/packet_forwarder/src/lora_pkt_fwd.c b/packet_forwarder/src/lora_pkt_fwd.c index d60f3599..08508938 100644 --- a/packet_forwarder/src/lora_pkt_fwd.c +++ b/packet_forwarder/src/lora_pkt_fwd.c @@ -464,6 +464,14 @@ static int parse_SX130x_configuration(const char * conf_file) { } else { MSG("WARNING: invalid radio type: %s (should be SX1255 or SX1257 or SX1250)\n", str); } + snprintf(param_name, sizeof param_name, "radio_%i.single_input_mode", i); + val = json_object_dotget_value(conf_obj, param_name); + if (json_value_get_type(val) == JSONBoolean) { + rfconf.single_input_mode = (bool)json_value_get_boolean(val); + } else { + rfconf.single_input_mode = false; + } + snprintf(param_name, sizeof param_name, "radio_%i.tx_enable", i); val = json_object_dotget_value(conf_obj, param_name); if (json_value_get_type(val) == JSONBoolean) { @@ -574,7 +582,7 @@ static int parse_SX130x_configuration(const char * conf_file) { } else { rfconf.tx_enable = false; } - MSG("INFO: radio %i enabled (type %s), center frequency %u, RSSI offset %f, tx enabled %d\n", i, str, rfconf.freq_hz, rfconf.rssi_offset, rfconf.tx_enable); + MSG("INFO: radio %i enabled (type %s), center frequency %u, RSSI offset %f, tx enabled %d, single input mode %d\n", i, str, rfconf.freq_hz, rfconf.rssi_offset, rfconf.tx_enable, rfconf.single_input_mode); } /* all parameters parsed, submitting configuration to the HAL */ if (lgw_rxrf_setconf(i, &rfconf) != LGW_HAL_SUCCESS) { @@ -1600,9 +1608,9 @@ int main(int argc, char ** argv) /* generate a JSON report (will be sent to server by upstream thread) */ pthread_mutex_lock(&mx_stat_rep); if (((gps_enabled == true) && (coord_ok == true)) || (gps_fake_enable == true)) { - snprintf(status_report, STATUS_SIZE, "\"stat\":{\"time\":\"%s\",\"lati\":%.5f,\"long\":%.5f,\"alti\":%i,\"rxnb\":%u,\"rxok\":%u,\"rxfw\":%u,\"ackr\":%.1f,\"dwnb\":%u,\"txnb\":%u}", stat_timestamp, cp_gps_coord.lat, cp_gps_coord.lon, cp_gps_coord.alt, cp_nb_rx_rcv, cp_nb_rx_ok, cp_up_pkt_fwd, 100.0 * up_ack_ratio, cp_dw_dgram_rcv, cp_nb_tx_ok); + snprintf(status_report, STATUS_SIZE, "\"stat\":{\"time\":\"%s\",\"lati\":%.5f,\"long\":%.5f,\"alti\":%i,\"rxnb\":%u,\"rxok\":%u,\"rxfw\":%u,\"ackr\":%.1f,\"dwnb\":%u,\"txnb\":%u,\"temp\":%.1f}", stat_timestamp, cp_gps_coord.lat, cp_gps_coord.lon, cp_gps_coord.alt, cp_nb_rx_rcv, cp_nb_rx_ok, cp_up_pkt_fwd, 100.0 * up_ack_ratio, cp_dw_dgram_rcv, cp_nb_tx_ok, temperature); } else { - snprintf(status_report, STATUS_SIZE, "\"stat\":{\"time\":\"%s\",\"rxnb\":%u,\"rxok\":%u,\"rxfw\":%u,\"ackr\":%.1f,\"dwnb\":%u,\"txnb\":%u}", stat_timestamp, cp_nb_rx_rcv, cp_nb_rx_ok, cp_up_pkt_fwd, 100.0 * up_ack_ratio, cp_dw_dgram_rcv, cp_nb_tx_ok); + snprintf(status_report, STATUS_SIZE, "\"stat\":{\"time\":\"%s\",\"rxnb\":%u,\"rxok\":%u,\"rxfw\":%u,\"ackr\":%.1f,\"dwnb\":%u,\"txnb\":%u,\"temp\":%.1f}", stat_timestamp, cp_nb_rx_rcv, cp_nb_rx_ok, cp_up_pkt_fwd, 100.0 * up_ack_ratio, cp_dw_dgram_rcv, cp_nb_tx_ok, temperature); } report_ready = true; pthread_mutex_unlock(&mx_stat_rep); diff --git a/readme.md b/readme.md index 3744d465..41162e36 100644 --- a/readme.md +++ b/readme.md @@ -161,6 +161,13 @@ found in the `libtools` directory. ## 6. Changelog +### v1.0.4 ### + +* Added missing LICENSE.TXT file +* HAL & Packet Forwarder: added support for sx1250-based reference design for +CN490 region +* Packet Forwarder: disabled beaconing by default + ### v1.0.3 ### * HAL: Fixed scheduled downlink time precision by taking the tx start delay into diff --git a/tools/systemd/lora_pkt_fwd.service b/tools/systemd/lora_pkt_fwd.service index 1d99ab4a..a95280cf 100644 --- a/tools/systemd/lora_pkt_fwd.service +++ b/tools/systemd/lora_pkt_fwd.service @@ -6,7 +6,7 @@ Wants=network-online.target [Service] Type=simple WorkingDirectory=/home/pi/sx1302_hal/bin -ExecStart=/home/pi/sx1302_hal/bin/lora_pkt_fwd -c /home/pi/sx1302_hal/bin/global_conf.json.sx1250 +ExecStart=/home/pi/sx1302_hal/bin/lora_pkt_fwd -c /home/pi/sx1302_hal/bin/global_conf.json.sx1250.EU868 Restart=always RestartSec=30 StandardOutput=syslog diff --git a/util_chip_id/src/chip_id.c b/util_chip_id/src/chip_id.c index 05fc53da..76afe330 100644 --- a/util_chip_id/src/chip_id.c +++ b/util_chip_id/src/chip_id.c @@ -92,7 +92,7 @@ int main(int argc, char **argv) }; /* parse command line options */ - while ((i = getopt_long (argc, argv, "hd:", long_options, &option_index)) != -1) { + while ((i = getopt_long (argc, argv, "hd:k:r:", long_options, &option_index)) != -1) { switch (i) { case 'h': usage(); @@ -163,6 +163,7 @@ int main(int argc, char **argv) rfconf.freq_hz = 868500000; /* dummy */ 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; @@ -173,6 +174,7 @@ int main(int argc, char **argv) rfconf.freq_hz = 868500000; /* dummy */ 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;