From e8ce30a56b04192006ccd8d97a0bfe914bcdf11b Mon Sep 17 00:00:00 2001 From: Terry Moore Date: Wed, 14 Aug 2019 00:48:41 -0400 Subject: [PATCH 1/3] Fix #360: add KR-920 regional support --- .travis.yml | 10 + HOWTO-ADD-REGION.md | 80 ++++-- README.md | 90 ++++--- ci/platformio.sh | 5 + .../compliance-otaa-halconfig.ino | 4 +- examples/raw-feather/raw-feather.ino | 24 ++ examples/raw-halconfig/raw-halconfig.ino | 24 ++ project_config/lmic_project_config.h | 1 + src/lmic/lmic.h | 2 +- src/lmic/lmic_bandplan.h | 2 + src/lmic/lmic_bandplan_kr920.h | 95 +++++++ src/lmic/lmic_config_preconditions.h | 14 +- src/lmic/lmic_kr920.c | 255 ++++++++++++++++++ src/lmic/lorabase.h | 47 ++++ src/lmic/lorabase_kr920.h | 84 ++++++ 15 files changed, 670 insertions(+), 67 deletions(-) create mode 100644 src/lmic/lmic_bandplan_kr920.h create mode 100644 src/lmic/lmic_kr920.c create mode 100644 src/lmic/lorabase_kr920.h diff --git a/.travis.yml b/.travis.yml index e63f305e..d1b19863 100644 --- a/.travis.yml +++ b/.travis.yml @@ -145,6 +145,7 @@ script: - _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } #- _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } #- _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } +#- _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } #- _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } - _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_us915 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/raw-feather/raw-feather.ino ; } @@ -152,6 +153,7 @@ script: - _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/raw-feather/raw-feather.ino ; } - _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/raw-feather/raw-feather.ino ; } - _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/raw-feather/raw-feather.ino ; } + - _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/raw-feather/raw-feather.ino ; } - _notavr || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board $(_avropts) $PWD/examples/raw-feather/raw-feather.ino ; } # test the raw sketch @@ -174,6 +176,7 @@ script: - _notsamd || { _projcfg CFG_au921 CFG_sx1276_radio && arduino --verify --board $(_samdopts '' projcfg) $PWD/examples/raw-feather/raw-feather.ino ; } - _notsamd || arduino --verify --board $(_samdopts '' as923) $PWD/examples/raw-feather/raw-feather.ino - _notsamd || arduino --verify --board $(_samdopts '' as923jp) $PWD/examples/raw-feather/raw-feather.ino + - _notsamd || arduino --verify --board $(_samdopts '' kr920) $PWD/examples/raw-feather/raw-feather.ino - _notsamd || arduino --verify --board $(_samdopts '' in866) $PWD/examples/raw-feather/raw-feather.ino # test raw in us915 and eu868 @@ -189,6 +192,7 @@ script: - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } +#- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } # @@ -207,6 +211,7 @@ script: - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa/ttn-otaa.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa/ttn-otaa.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa/ttn-otaa.ino ; } + - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa/ttn-otaa.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa/ttn-otaa.ino ; } # # test ttn-abp with all regions @@ -215,6 +220,7 @@ script: - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp/ttn-abp.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp/ttn-abp.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp/ttn-abp.ino ; } + - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp/ttn-abp.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp/ttn-abp.ino ; } # test ttn-otaa-feather-us915-dht22 in all relevant regions with sx1276 @@ -223,6 +229,7 @@ script: - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915-dht22/ttn-otaa-feather-us915-dht22.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915-dht22/ttn-otaa-feather-us915-dht22.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915-dht22/ttn-otaa-feather-us915-dht22.ino ; } +#- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915-dht22/ttn-otaa-feather-us915-dht22.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-feather-us915-dht22/ttn-otaa-feather-us915-dht22.ino ; } # test ttn-abp-feather-us915-dht22 in all relevant regions with sx1276 @@ -231,6 +238,7 @@ script: - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino ; } +#- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino ; } #- _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino ; } # test ttn-otaa-network-time in all regions @@ -239,6 +247,7 @@ script: - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_au921 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-network-time/ttn-otaa-network-time.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-network-time/ttn-otaa-network-time.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_as923jp CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-network-time/ttn-otaa-network-time.ino ; } + - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_kr920 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-network-time/ttn-otaa-network-time.ino ; } - _notsamd || { _projcfg COMPILE_REGRESSION_TEST CFG_in866 CFG_sx1276_radio && arduino --verify --board mcci:samd:mcci_catena_4450:lorawan_region=projcfg $PWD/examples/ttn-otaa-network-time/ttn-otaa-network-time.ino ; } - _notsamd || arduino --verify --board $(_samdopts 'mcci_catena_4410' us915 ) $PWD/examples/raw-halconfig/raw-halconfig.ino @@ -274,6 +283,7 @@ script: - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' au921 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' as923 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' as923jp) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino + - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' kr920 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' in866 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || { _projcfg COMPILE_REGRESSION_TEST CFG_us915 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } - _notstm32l0 || { _projcfg COMPILE_REGRESSION_TEST CFG_us915 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa/ttn-otaa.ino ; } diff --git a/HOWTO-ADD-REGION.md b/HOWTO-ADD-REGION.md index eeacd89a..ea6b35ef 100644 --- a/HOWTO-ADD-REGION.md +++ b/HOWTO-ADD-REGION.md @@ -1,9 +1,37 @@ # Adding a new region to Arduino LMIC -This variant of the Arduino LMIC code supports adding additional regions beyond the eu868 and us915 bands supoprted by the original IBM LMIC 1.6 code. +This variant of the Arduino LMIC code supports adding additional regions beyond the eu868 and us915 bands supported by the original IBM LMIC 1.6 code. This document outlines how to add a new region. + + + + + + +- [Planning](#planning) + - [Determine the region/region category](#determine-the-regionregion-category) + - [Check whether the region is already listed in `lmic_config_preconditions.h`](#check-whether-the-region-is-already-listed-in-lmic_config_preconditionsh) +- [Make the appropriate changes in `lmic_config_preconditions.h`](#make-the-appropriate-changes-in-lmic_config_preconditionsh) +- [Document your region in `README.md`](#document-your-region-in-readmemd) +- [Add the definitions for your region in `lorabase.h`](#add-the-definitions-for-your-region-in-lorabaseh) +- [Edit `lmic_bandplan.h`](#edit-lmic_bandplanh) +- [Create lmic_newregion.c](#create-codelmic_emnewregionemccode) +- [General Discussion](#general-discussion) +- [Adding the region to the Arduino_LoRaWAN library](#adding-the-region-to-the-arduino_lorawan-library) + + + + + ## Planning ### Determine the region/region category @@ -12,15 +40,15 @@ Compare the target region (in the LoRaWAN regional specification) to the EU868 a 1. The region is like the EU region. There are a limited number of channels (up to 8), and only a small number of channels are used for OTAA join operations. The response masks refer to individual channels, and the JOIN-response can send frequencies of specific channels to be added. -2. The region is like the US region. There are many channels (the US has 64) with fixed frequences, and the channel masks refer to subsets of the fixed channels. +2. The region is like the US region. There are many channels (the US has 64) with fixed frequencies, and the channel masks refer to subsets of the fixed channels. 3. The region is not really like either the EU or US. At the moment, it seems that CN470-510MHz (section 2.6 of LoRaWAN Regional Parameters spec V1.0.2rB) falls into this category. -Bandplans in categories (1) and (2) are easily supported. Bandplans in category (3) are not supoprted by the current code. +Band plans in categories (1) and (2) are easily supported. Band plans in category (3) are not supported by the current code. ### Check whether the region is already listed in `lmic_config_preconditions.h` -Check `src/lmic/lmic_config_preconditions.h` and scan the `LMIC_REGION_...` definitions. The numeric values are assigned based on the subchapter in section 2 of the LoRaWAN 1.0.2 Regional Parmaters document. If your symbol is already there, then the first part of adaptation has already been done. There will already be a corresponding `CFG_...` symbol. But if your region isn't supported, you'll need to add it here. +Check `src/lmic/lmic_config_preconditions.h` and scan the `LMIC_REGION_...` definitions. The numeric values are assigned based on the subchapter in section 2 of the LoRaWAN 1.0.2 Regional Parameters document. If your symbol is already there, then the first part of adaptation has already been done. There will already be a corresponding `CFG_...` symbol. But if your region isn't supported, you'll need to add it here. - `LMIC_REGION_myregion` must be a distinct integer, and must be less than 32 (so as to fit into a bitmask) @@ -31,10 +59,6 @@ Check `src/lmic/lmic_config_preconditions.h` and scan the `LMIC_REGION_...` defi - `CFG_region` evaluates to the `LMIC_REGION_...` value for the selected region (as long as only one region is selected). The header files check for this, so you don't have to. - `CFG_LMIC_EU_like_MASK` is a bitmask of regions that are EU-like, and `CFG_LMIC_US_like_MASK` is a bitmask of regions that are US-like. Add your region to the appropriate one of these two variables. -## Document your region in `config.h` - -You'll see where the regions are listed. Add yours. - ## Document your region in `README.md` You'll see where the regions are listed. Add yours. @@ -43,11 +67,11 @@ You'll see where the regions are listed. Add yours. - If your region is EU like, copy the EU block. Document any duty-cycle limitations. - if your region is US like, copy the US block. -- As appropriate, copy `lorabase_eu868.h` or `lorabase_us915.h` to make your own `lorabase_myregion.h`. Fill in the symbols. +- As appropriate, copy `lorabase_eu868.h` or `lorabase_us915.h` to make your own lorabase_newregion.h. Fill in the symbols. -At time of writing, you need to duplicate some code to copy some settings from `..._CONFIG_SYMBOL` to the corresponding `CONFIG_SYMBOL`; and you need to put some region-specific knowledge into the `lorabase.h` header file. The long-term direction is to put all the regional knowledge into the region-specific header, and then the central code will just copy. The architectural impulse is that we'll want to be able to reuse the regional header files in other contexts. On the other hand, because it's error prone, we don't want to `#include` files that aren't being used; otherwise you could accidentally use EU parameters in US code, etc. +At time of writing, you need to duplicate some code to copy some settings from `lorabase_eu868.h` or `lorabase_us915.h` to the new file; and you need to put some region-specific knowledge into the `lorabase.h` header file. The long-term direction is to put all the regional knowledge into the region-specific header, and then the central code will just copy. The architectural impulse is that we'll want to be able to reuse the regional header files in other contexts. On the other hand, because it's error prone, we don't want to `#include` files that aren't being used; otherwise you could accidentally use EU parameters in US code, etc. -- Now's a good time to test-compile and clean out errors introduced. You'll still have problems compiling, but they should look like this: +- Now's a good time to test-compile and clean out errors introduced. Make sure you set the region to your new target region. You'll have problems compiling, but they should look like this: ```console lmic.c:29: In file included from @@ -59,6 +83,12 @@ At time of writing, you need to duplicate some code to copy some settings from ` # error "pow2dBm() not defined by bandplan" ``` +- If using an MCCI BSP, you might want to edit your local copy of `boards.txt` to add the new region. + +- If using an MCCI BSP, you should definitely edit the template files to add the new region to the list. + +- Modify the `.travis.yml` file to test the new region. + ## Edit `lmic_bandplan.h` The next step is to add the region-specific interfaces for your region. @@ -67,7 +97,17 @@ Do this by editing `lmic_bandplan.h` and adding the appropriate call to a (new) Then, if your region is eu868-like, copy `lmic_bandplan_eu868.h` to create your new region-specific header file; otherwise copy `lmic_bandplan_us915.h`. -## Create `lmic_myregion.c` +Edit the file. + +Try to compile again; you should now get link errors related to your new band-plan, like this: + +```console +c:\tmp\buildfolder\libraries\arduino-lmic\lmic\lmic.c.o: In function `lowerDR': + +C:\Users\tmm\Documents\Arduino\libraries\arduino-lmic\src\lmic/lorabase.h:667: undefined reference to `constant_table__DR2RPS_CRC' +``` + +## Create lmic_newregion.c Once again, you will start by copying either `lmic_eu868.c` or `lmic_us915.c` to create your new file. Then touch it up as necessary. @@ -75,11 +115,21 @@ Once again, you will start by copying either `lmic_eu868.c` or `lmic_us915.c` to - You'll find it easier to do the test compiles using the example scripts in this directory, rather than trying to get all the Catena framework going too. On the other hand, working with the Catena framework will expose more problems. -## Addding the region to the Arduino_LoRaWAN library +- Don't forget to check and update the examples. + +- You will also need to update the `boards.template` file for MCCI BSPs, in order to get the region to show up in the Arduino IDE menu. + +- You will need to update the [`arduino-lorawan`](https://github.com/mcci-catena/arduino-lorawan) library to include support for the new region. (See [below](#adding-the-region-to-the-arduino_lorawan-library) for instructions.) + +- Please increase the version of `arduino-lmic` (symbol `ARDUINO_LMIC_VERSION` in `src/lmic/lmic.h`), and change `arduino-lorawan`'s `Arduino_LoRaWAN_lmic.h` to check for at least that newer version. + +- Please also increase the version of the `arduino-lorawan` library (symbol `ARDUINO_LORAWAN_VERSION`). + +## Adding the region to the Arduino_LoRaWAN library In `Arduino_LoRaWAN_ttn.h`: - Add a new class with name `Arduino_LoRaWAN_ttn_myregion`, copied either from the `Arduino_LoRaWAN_ttn_eu868` class or the `Arduino_LoRaWAN_ttn_us915` class. -- Extend the list of `#if defined(CFG_eu868)` etc to define `Arduino_LoRaWAN_REGION_TAG` to the suffix of your new class if `CFG_myregion` is defined. +- Extend the list of `#if defined(CFG_eu868)` etc. to define `Arduino_LoRaWAN_REGION_TAG` to the suffix of your new class if `CFG_myregion` is defined. -Then copy either `ttn_eu868_netbegin.cpp`/`ttn_eu868_netjoin.cpp` or `ttn_us915_netbegin.cpp`/`ttn_us915_netjoin.cpp` to make your own file(s) for the key functions. +Then copy and edit either `ttn_eu868_netbegin.cpp`/`ttn_eu868_netjoin.cpp` or `ttn_us915_netbegin.cpp`/`ttn_us915_netjoin.cpp` to make your own file(s) for the key functions. diff --git a/README.md b/README.md index f6493f3d..016e2b61 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ requires C99 mode to be enabled by default. - [Known bugs and issues](#known-bugs-and-issues) - [Configuration](#configuration) - [Selecting the LoRaWAN Region Configuration](#selecting-the-lorawan-region-configuration) - - [eu868, as923, in866](#eu868-as923-in866) + - [eu868, as923, in866, kr920](#eu868-as923-in866-kr920) - [us915, au921](#us915-au921) - [Selecting the target radio transceiver](#selecting-the-target-radio-transceiver) - [Controlling use of interrupts](#controlling-use-of-interrupts) @@ -77,7 +77,7 @@ requires C99 mode to be enabled by default. - [Example Sketches](#example-sketches) - [Timing](#timing) - [`LMIC_setClockError()`](#lmic_setclockerror) -- [Downlink datarate](#downlink-datarate) +- [Downlink data rate](#downlink-data-rate) - [Encoding Utilities](#encoding-utilities) - [sflt16](#sflt16) - [JavaScript decoder](#javascript-decoder) @@ -95,6 +95,7 @@ requires C99 mode to be enabled by default. + ## Installing @@ -102,7 +103,7 @@ To install this library: - install it using the Arduino Library manager ("Sketch" -> "Include Library" -> "Manage Libraries..."), or -- download a zipfile from github using the "Download ZIP" button and +- download a zip file from GitHub using the "Download ZIP" button and install it using the IDE ("Sketch" -> "Include Library" -> "Add .ZIP Library..." - clone this git repository into your sketchbook/libraries folder. @@ -122,7 +123,7 @@ What certainly works: - Sending packets uplink, taking into account duty cycling. - Encryption and message integrity checking. - Receiving downlink packets in the RX2 window. -- Custom frequencies and datarate settings. +- Custom frequencies and data rate settings. - Over-the-air activation (OTAA / joining). - Receiving downlink packets in the RX1 and RX2 windows. - Some MAC command processing. @@ -134,7 +135,7 @@ What has not been tested: - FSK has not been extensively tested. If you try one of these untested features and it works, be sure to let -us know (creating a github issue is probably the best way for that). +us know (creating a GitHub issue is probably the best way for that). ## Additional Documentation @@ -169,20 +170,21 @@ The following configuration variables are available. The library supports the following regions: -`-D` variable | CFG region name | CFG region value | LoRa Spec Reference| Frequency +`-D` variable | CFG region name | CFG region value | LoRaWAN Regional Spec 1.0.3 Reference| Frequency ------------|-----------------|:----------------:|:-------------------:|-------- -`-D CFG_eu868` | `LMIC_REGION_eu868` | 1 | 2.1 | EU 863-870 MHz ISM -`-D CFG_us915` | `LMIC_REGION_us915` | 2 | 2.2 | US 902-928 MHz ISM -`-D CFG_au921` | `LMIC_REGION_au921` | 5 | 2.5 | Australia 915-928 MHz ISM -`-D CFG_as923` | `LMIC_REGION_as923` | 7 | 2.7 | Asia 923 MHz ISM -`-D CFG_as923jp` | `LMIC_REGION_as923` and `LMIC_COUNTRY_CODE_JP` | 7 | 2.7 | Asia 923 MHz ISM with Japan listen-before-talk (LBT) rules -`-D CFG_in866` | `LMIC_REGION_in866` | 9 | 2.9 | India 865-867 MHz ISM +`-D CFG_eu868` | `LMIC_REGION_eu868` | 1 | 2.2 | EU 863-870 MHz ISM +`-D CFG_us915` | `LMIC_REGION_us915` | 2 | 2.3 | US 902-928 MHz ISM +`-D CFG_au921` | `LMIC_REGION_au921` | 5 | 2.6 | Australia 915-928 MHz ISM +`-D CFG_as923` | `LMIC_REGION_as923` | 7 | 2.8 | Asia 923 MHz ISM +`-D CFG_as923jp` | `LMIC_REGION_as923` and `LMIC_COUNTRY_CODE_JP` | 7 | 2.8 | Asia 923 MHz ISM with Japan listen-before-talk (LBT) rules +`-D CFG_kr920` | `LMIC_REGION_kr920` | 8 | 2.9 | Korea 920-923 MHz ISM +`-D CFG_in866` | `LMIC_REGION_in866` | 9 | 2.10 | India 865-867 MHz ISM You should define exactly one of `CFG_...` variables. If you don't, the library assumes `CFG_eu868`. The library changes configuration pretty substantially according to the region. Some of the differences are listed below. -#### eu868, as923, in866 +#### eu868, as923, in866, kr920 If the library is configured for EU868, AS923, or IN866 operation, we make the following changes: @@ -265,13 +267,13 @@ is assumed. This variable determines the amount of debug output to be produced by the library. The default is `0`. If `LMIC_DEBUG_LEVEL` is zero, no output is produced. If `1`, limited output is produced. If `2`, more extensive -output is produced. If non-zero, printf() is used, and the Arduino environment must be configured to support it, +output is produced. If non-zero, `printf()` is used, and the Arduino environment must be configured to support it, otherwise the sketch will crash at runtime. #### Selecting the AES library The library comes with two AES implementations. The original implementation is better on -ARM processors becasue it's faster, but it's larger. For smaller AVR8 processors, a +ARM processors because it's faster, but it's larger. For smaller AVR8 processors, a second library ("IDEETRON") is provided that has a smaller code footprint. You may define one of the following variables to choose the AES implementation. If you don't, the library uses the IDEETRON version. @@ -301,7 +303,7 @@ This variable sets the default frequency for the SPI bus connection to the trans The variables `LMIC_FAILURE_TO` and `DISABLE_LMIC_FAILURE_TO` control the handling of runtime assertion failures. By default, assertion messages are displayed using -the `Serial` object. You can define LMIC_FAILURE_TO to be the name of some other `Print`-like obect. You can +the `Serial` object. You can define LMIC_FAILURE_TO to be the name of some other `Print`-like object. You can also define `DISABLE_LMIC_FAILURE_TO` to any value, in which case assert failures will silently halt execution. #### Disabling JOIN @@ -323,11 +325,11 @@ commands. #### Disabling user events -Code to handle registered callbacks for tx, rx, and events can be suppressed by setting `LMIC_ENABLE_user_events` to zero. This C preprocessor macro is always defined as a post-condition of `#include "config.h"`; if non-zero, user events are supported, if zero, user events are not-supported. The default is to support user events. +Code to handle registered callbacks for transmit, receive, and events can be suppressed by setting `LMIC_ENABLE_user_events` to zero. This C preprocessor macro is always defined as a post-condition of `#include "config.h"`; if non-zero, user events are supported, if zero, user events are not-supported. The default is to support user events. #### Disabling external reference to `onEvent()` -In some embedded systems, `onEvent()` may be defined for some other purpose; so the weak reference to the function `onEvent` will be satified, causing the LMIC to try to call that function. All reference to `onEvent()` can be suppressed by setting `LMIC_ENABLE_onEvent` to 0. This C preprocessor macro is always defined as a post-condition of `#include "config.h"`; if non-zero, a weak reference to `onEvent()` will be used; if zero, the user `onEvent()` function is not supported, and the client must register an event handler explicitly. +In some embedded systems, `onEvent()` may be defined for some other purpose; so the weak reference to the function `onEvent` will be satisfied, causing the LMIC to try to call that function. All reference to `onEvent()` can be suppressed by setting `LMIC_ENABLE_onEvent` to 0. This C preprocessor macro is always defined as a post-condition of `#include "config.h"`; if non-zero, a weak reference to `onEvent()` will be used; if zero, the user `onEvent()` function is not supported, and the client must register an event handler explicitly. #### Enabling long messages @@ -367,7 +369,7 @@ some space can be freed up. ## Pre-Integrated Boards -There are two ways of using this library, either with pre-integrated boards or with manualy configured boards. +There are two ways of using this library, either with pre-integrated boards or with manually configured boards. The following boards are pre-integrated. @@ -561,7 +563,7 @@ The names refer to the pins on the transceiver side, the numbers refer to the Arduino pin numbers (to use the analog pins, use constants like `A0`). For the DIO pins, the three numbers refer to DIO0, DIO1 and DIO2 respectively. Any pins that are not needed should be specified as -`LMIC_UNUSED_PIN`. The nss and dio0 pin is required, the others can +`LMIC_UNUSED_PIN`. The NSS and dio0 pins are required. The others can potentially left out (depending on the environments and requirements, see the notes above for when a pin can or cannot be left out). @@ -579,7 +581,7 @@ In some boards require much more advanced management. The LMIC has a very flexib cMyHalConfiguration_t myHalConfigInstance; ``` -4. You add another entry in your `lmic_pinmap`, `pConfig = &myHalConfigInstance`, to link your pinmap to your object. +4. You add another entry in your `lmic_pinmap`, `pConfig = &myHalConfigInstance`, to link your pin-map to your object. The full example looks like this: @@ -609,15 +611,15 @@ public: - `ostime_t setModuleActive(bool state)` is called by the LMIC to make the module active or to deactivate it (the value of `state` is true to activate). The implementation must turn power to the module on and otherwise prepare for it to go to work, and must return the number of OS ticks to wait before starting to use the radio. -- `void begin(void)` is called during intialization, and is your code's chance to do any early setup. +- `void begin(void)` is called during initialization, and is your code's chance to do any early setup. - `void end(void)` is (to be) called during late shutdown. (Late shutdown is not implemented yet; but we wanted to add the API for consistency.) - `bool queryUsingTcxo(void)` shall return `true` if the module uses a TCXO; `false` otherwise. -- `TxPowerPolicy_t getTxPowerPolicy(TxPowerPolicy_t policy, int8_t requestedPower, uint32_t frequency)` allows you to override the LMIC's selection of transmit power. If not provided, the default method forces the LMIC to use PA_BOOST mode. (We chose to do this becuase we found empirically that the Hope RF module doesn't support RFO, and because legacy LMIC code never used anything except PA_BOOST mode.) +- `TxPowerPolicy_t getTxPowerPolicy(TxPowerPolicy_t policy, int8_t requestedPower, uint32_t frequency)` allows you to override the LMIC's selection of transmit power. If not provided, the default method forces the LMIC to use PA_BOOST mode. (We chose to do this because we found empirically that the Hope RF module doesn't support RFO, and because legacy LMIC code never used anything except PA_BOOST mode.) -Caution: the LMIC has no way of knowing whether the mode you return makes sense. Use of 20 dBm mode without limiting duty cycle can over-stress your module. The LMIC currently does not have any code to duty-cycle US transmissions at 20 dBm. If properly limiting transmissions to 400 ms, 1% duty-cycle means at most one message every 40 seconds. This shoudln't be a problem in practice, but buggy upper level software still might do things more rapidly. +Caution: the LMIC has no way of knowing whether the mode you return makes sense. Use of 20 dBm mode without limiting duty cycle can over-stress your module. The LMIC currently does not have any code to duty-cycle US transmissions at 20 dBm. If properly limiting transmissions to 400 milliseconds, a 1% duty-cycle means at most one message every 40 seconds. This shouldn't be a problem in practice, but buggy upper level software still might do things more rapidly. #### LoRa Nexus by Ideetron @@ -648,7 +650,7 @@ This library provides several examples. OTAA is the preferred way to work with production LoRaWAN networks. - [`ttn-otaa-feather-us915.ino`](examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino) is a version of `ttn-otaa.ino` that has - been configured for use with the Feather M0 LoRa, on the US915 bandplan, + been configured for use with the Feather M0 LoRa, on the US915 band plan, with The Things Network. Remember that you may also have to change `config.h` from defaults. This sketch also works with the MCCI Catena family of products as well as with the Feather 32u4 LoRa. @@ -683,7 +685,7 @@ This library provides several examples. [Catena-Arduino-Platform](https://github.com/mcci-catena/Catena-Arduino-Platform). - [`ttn-abp-feather-us915-dht22.ino`](examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino) - refines `ttn-abp.ino` by configuring for use with the Feather M0 LoRa on the US915 bandplan, + refines `ttn-abp.ino` by configuring for use with the Feather M0 LoRa on the US915 band plan, with a single-channel gateway on The Things Network; it measures and transmits temperature and relative humidity using a DHT22 sensor. It's only been tested with Feather M0-family products. @@ -711,8 +713,8 @@ This can be configured in one of two ways (see [Controlling use of interrupts](#controlling-use-of-interrupts)). By default, the routine `hal_io_check()` -polls the enabled pins to determine whether an event has occured. This approach -allows use of any CPU pin to sense the DIOs, and makes no assummptions about +polls the enabled pins to determine whether an event has occurred. This approach +allows use of any CPU pin to sense the DIOs, and makes no assumptions about interrupts. However, it means that the end-of-transmit event is not observed (and time-stamped) until `os_runloop()` is called. @@ -750,16 +752,16 @@ An even more accurate solution could be to use a dedicated timer with an input capture unit, that can store the timestamp of a change on the DIO0 pin (the only one that is timing-critical) entirely in hardware. Experience shows that this is not normally required, so we leave this as -a customization to be performed on a platform-by-platfom basis. We provide +a customization to be performed on a platform-by-platform basis. We provide a special API, `radio_irq_handler_v2(u1_t dio, ostime_t tEvent)`. This API allows you to supply a hardware-captured time for extra accuracy. The practical consequence of inaccurate timing is reduced battery life; -the LMIC must turn on the reciever earlier in order to be sure to capture downlink packets. +the LMIC must turn on the receiver earlier in order to be sure to capture downlink packets. ### `LMIC_setClockError()` -You may call this routine during intialization to infom the LMIC code about the timing accuracy of your system. +You may call this routine during initialization to inform the LMIC code about the timing accuracy of your system. ```c++ enum { MAX_CLOCK_ERROR = 65535 }; @@ -781,9 +783,9 @@ Setting a high clock error causes the RX windows to be opened earlier than it ot This clock error is not reset by `LMIC_reset()`. -## Downlink datarate +## Downlink data rate -Note that the datarate used for downlink packets in the RX2 window varies by region. Consult your network's manual for any divergences from the LoRaWAN Regional Parameters. This library assumes that the network follows the regional default. +Note that the data rate used for downlink packets in the RX2 window varies by region. Consult your network's manual for any divergences from the LoRaWAN Regional Parameters. This library assumes that the network follows the regional default. Some networks use different values than the specification. For example, in Europe, the specification default is DR0 (SF12, 125 kHz bandwidth). However, iot.semtech.com and The Things Network both used SF9 / 125 kHz or DR3). If using over-the-air activation (OTAA), the network will download RX2 parameters as part of the JoinAccept message; the LMIC will honor the downloaded parameters. @@ -1088,30 +1090,34 @@ function uflt12f(rawUflt12) ## Release History +- HEAD adds the following changes. + + - [#360](https://github.com/mcci-catena/arduino-lmic/pull/360) adds support for the KR-920 regional plan. + - v2.3.2 is a patch release. It incorporates two pull requests. - - [#204](https://github.com/mcci-catena/arduino-lmic/pull/204) eliminates a warning if using a custom pinmap. + - [#204](https://github.com/mcci-catena/arduino-lmic/pull/204) eliminates a warning if using a custom pin-map. - [#206](https://github.com/mcci-catena/arduino-lmic/pull/206) updates CI testing to Arduino IDE v1.8.8. -- v2.3.1 is a patch release. It adds ``, which loads the pre-proceesor LMIC configuration variables into scope (issue [#199](https://github.com/mcci-catena/arduino-lmic/issues/199)). +- v2.3.1 is a patch release. It adds ``, which loads the pre-processor LMIC configuration variables into scope (issue [#199](https://github.com/mcci-catena/arduino-lmic/issues/199)). - v2.3.0 introduces two important changes. - 1. The pinmap is extended with an additional field `pConfig`, pointing to a C++ class instance. This instance, if provided, has extra methods for dealing with TCXO control and other fine details of operating the radio. It also gives a natural way for us to extend the behavior of the HAL. + 1. The pin-map is extended with an additional field `pConfig`, pointing to a C++ class instance. This instance, if provided, has extra methods for dealing with TCXO control and other fine details of operating the radio. It also gives a natural way for us to extend the behavior of the HAL. 2. Pinmaps can be pre-configured into the library, so that users don't have to do this in every sketch. - Accompanying this was a fairly large refactoring of inner header files. We now have top-level header file ``, which provides much the same info as the original ``, without bringing most of the LMIC internal definitions into scope. We also changed the SPI API based on a suggestion from @manuelbl, making the HAL more friendly to structured BSPs (and also making the SPI API potentially faster). + Accompanying this was a fairly large refactoring of inner header files. We now have top-level header file ``, which provides much the same info as the original ``, without bringing most of the LMIC internal definitions into scope. We also changed the SPI API based on a suggestion from `@manuelbl`, making the HAL more friendly to structured BSPs (and also making the SPI API potentially faster). - Interim bug fixes: added a new API (`radio_irq_handler_v2()`), which allows the caller to provide the timestamp of the interrupt. This allows for more accurate timing, because the knowledge of interrupt overhead can be moved to a platform-specific layer ([#148](https://github.com/mcci-catena/arduino-lmic/issues/148)). Fixed compile issues on ESP32 ([#140](https://github.com/mcci-catena/arduino-lmic/issues/140) and [#153](https://github.com/mcci-catena/arduino-lmic/issues/150)). We added ESP32 and 32u4 as targets in CI testing. We switched CI testing to Arduino IDE 1.8.7. Fixed issue [#161](https://github.com/mcci-catena/arduino-lmic/issues/161) selecting the Japan version of as923 using `CFG_as923jp` (selecting via `CFG_as923` and `LMIC_COUNTRY_CODE=LMIC_COUNTRY_CODE_JP` worked). Fixed [#38](https://github.com/mcci-catena/arduino-lmic/issues/38) -- now any call to hal_init() will put the NSS line in the idle (high/inactive) state. As a side effect, RXTX is initialized, and RESET code changed to set value before transitioning state. Likely no net effect, but certainly more correct. -- V2.2.2 adds `ttn-abp-feather-us915-dht22.ino` example, and fixes some documentation typos. It also fixes encoding of the `Margin` field of the `DevStatusAns` MAC message ([#130](https://github.com/mcci-catena/arduino-lmic/issues/130)). This makes Arduino LMIC work with newtorks implemented with [LoraServer](https://www.loraserver.io/). +- V2.2.2 adds `ttn-abp-feather-us915-dht22.ino` example, and fixes some documentation typos. It also fixes encoding of the `Margin` field of the `DevStatusAns` MAC message ([#130](https://github.com/mcci-catena/arduino-lmic/issues/130)). This makes Arduino LMIC work with networks implemented with [LoraServer](https://www.loraserver.io/). - V2.2.1 corrects the value of `ARDUINO_LMIC_VERSION` ([#123](https://github.com/mcci-catena/arduino-lmic/issues/123)), allows ttn-otaa-feather-us915 example to compile for the Feather 32u4 LoRa ([#116](https://github.com/mcci-catena/arduino-lmic/issues/116)), and addresses documentation issues ([#122](https://github.com/mcci-catena/arduino-lmic/issues/122), [#120](https://github.com/mcci-catena/arduino-lmic/issues/120)). -- V2.2.0 adds encoding functions and `tn-otaa-feather-us915-dht22.ino` example. Plus a large number of issues: [#59](https://github.com/mcci-catena/arduino-lmic/issues/59), [#60](https://github.com/mcci-catena/arduino-lmic/issues/60), [#63](https://github.com/mcci-catena/arduino-lmic/issues/63), [#64](https://github.com/mcci-catena/arduino-lmic/issues/47) (listen-before-talk for Japan), [#65](https://github.com/mcci-catena/arduino-lmic/issues/65), [#68](https://github.com/mcci-catena/arduino-lmic/issues/68), [#75](https://github.com/mcci-catena/arduino-lmic/issues/75), [#78](https://github.com/mcci-catena/arduino-lmic/issues/78), [#80](https://github.com/mcci-catena/arduino-lmic/issues/80), [#91](https://github.com/mcci-catena/arduino-lmic/issues/91), [#98](https://github.com/mcci-catena/arduino-lmic/issues/98), [#101](https://github.com/mcci-catena/arduino-lmic/issues/101). Added full Travis CI testing, switched to travis-ci.com as the CI service. Prepared to publish library in the offical Arduino library list. +- V2.2.0 adds encoding functions and `tn-otaa-feather-us915-dht22.ino` example. Plus a large number of issues: [#59](https://github.com/mcci-catena/arduino-lmic/issues/59), [#60](https://github.com/mcci-catena/arduino-lmic/issues/60), [#63](https://github.com/mcci-catena/arduino-lmic/issues/63), [#64](https://github.com/mcci-catena/arduino-lmic/issues/47) (listen-before-talk for Japan), [#65](https://github.com/mcci-catena/arduino-lmic/issues/65), [#68](https://github.com/mcci-catena/arduino-lmic/issues/68), [#75](https://github.com/mcci-catena/arduino-lmic/issues/75), [#78](https://github.com/mcci-catena/arduino-lmic/issues/78), [#80](https://github.com/mcci-catena/arduino-lmic/issues/80), [#91](https://github.com/mcci-catena/arduino-lmic/issues/91), [#98](https://github.com/mcci-catena/arduino-lmic/issues/98), [#101](https://github.com/mcci-catena/arduino-lmic/issues/101). Added full Travis CI testing, switched to travis-ci.com as the CI service. Prepared to publish library in the official Arduino library list. - V2.1.5 fixes issue [#56](https://github.com/mcci-catena/arduino-lmic/issues/56) (a documentation bug). Documentation was quickly reviewed and other issues were corrected. The OTAA examples were also updated slightly. @@ -1125,7 +1131,7 @@ function uflt12f(rawUflt12) - V2.1.0 adds support for the Murata LoRaWAN module. -- V2.0.2 adds support for the extended bandplans. +- V2.0.2 adds support for the extended band plans. ## Contributions @@ -1135,9 +1141,9 @@ This library started from the IBM V1.5 open-source code. - Terry Moore, LeRoy Leslie, Frank Rose, and ChaeHee Won did a lot of work on US support. -- Terry Moore added the AU921, AS923 and IN866 bandplans, and created the regionalization framework. +- Terry Moore added the AU921, AS923 and IN866 band plans, and created the regionalization framework. -- [@tanupoo](https://github.com/tanupoo) of the WIDE Project debugged AS923JP and LBT support. +- [`@tanupoo`](https://github.com/tanupoo) of the WIDE Project debugged AS923JP and LBT support. ## Trademark Acknowledgements diff --git a/ci/platformio.sh b/ci/platformio.sh index ce1718aa..88d2ec96 100755 --- a/ci/platformio.sh +++ b/ci/platformio.sh @@ -41,6 +41,7 @@ then PLATFORMIO_BUILD_FLAGS='-D CFG_au921 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa/ttn-otaa.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_as923 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa/ttn-otaa.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_as923jp -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa/ttn-otaa.ino' + PLATFORMIO_BUILD_FLAGS='-D CFG_kr920 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa/ttn-otaa.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_in866 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa/ttn-otaa.ino' # Compile "ttn-abp" example in all regions @@ -49,6 +50,7 @@ then PLATFORMIO_BUILD_FLAGS='-D CFG_au921 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-abp/ttn-abp.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_as923 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-abp/ttn-abp.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_as923jp -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-abp/ttn-abp.ino' + PLATFORMIO_BUILD_FLAGS='-D CFG_kr920 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-abp/ttn-abp.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_in866 -D CFG_sx1276_radio -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --lib . --board heltec_wifi_lora_32 'examples/ttn-abp/ttn-abp.ino' # Compile "ttn-otaa-network-time" example in all regions @@ -57,6 +59,7 @@ then PLATFORMIO_BUILD_FLAGS='-D CFG_au921 -D CFG_sx1276_radio -D LMIC_ENABLE_DeviceTimeReq=1 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --project-option="lib_deps=Time" --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa-network-time/ttn-otaa-network-time.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_as923 -D CFG_sx1276_radio -D LMIC_ENABLE_DeviceTimeReq=1 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --project-option="lib_deps=Time" --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa-network-time/ttn-otaa-network-time.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_as923jp -D CFG_sx1276_radio -D LMIC_ENABLE_DeviceTimeReq=1 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --project-option="lib_deps=Time" --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa-network-time/ttn-otaa-network-time.ino' + PLATFORMIO_BUILD_FLAGS='-D CFG_kr920 -D CFG_sx1276_radio -D LMIC_ENABLE_DeviceTimeReq=1 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --project-option="lib_deps=Time" --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa-network-time/ttn-otaa-network-time.ino' PLATFORMIO_BUILD_FLAGS='-D CFG_in866 -D CFG_sx1276_radio -D LMIC_ENABLE_DeviceTimeReq=1 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS' platformio ci --project-option="lib_deps=Time" --lib . --board heltec_wifi_lora_32 'examples/ttn-otaa-network-time/ttn-otaa-network-time.ino' @@ -72,6 +75,7 @@ then # PLATFORMIO_BUILD_FLAGS='-D ARDUINO_AVR_FEATHER32U4 -D CFG_au921 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_sx1276_radio' platformio ci --lib . --board heltec_wifi_lora_32 'examples/raw-feather/raw-feather.ino' # PLATFORMIO_BUILD_FLAGS='-D ARDUINO_AVR_FEATHER32U4 -D CFG_as923 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_sx1276_radio' platformio ci --lib . --board heltec_wifi_lora_32 'examples/raw-feather/raw-feather.ino' # PLATFORMIO_BUILD_FLAGS='-D ARDUINO_AVR_FEATHER32U4 -D CFG_as923jp -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_sx1276_radio' platformio ci --lib . --board heltec_wifi_lora_32 'examples/raw-feather/raw-feather.ino' + # PLATFORMIO_BUILD_FLAGS='-D ARDUINO_AVR_FEATHER32U4 -D CFG_kr920 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_sx1276_radio' platformio ci --lib . --board heltec_wifi_lora_32 'examples/raw-feather/raw-feather.ino' # PLATFORMIO_BUILD_FLAGS='-D ARDUINO_AVR_FEATHER32U4 -D CFG_in866 -D COMPILE_REGRESSION_TEST -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_sx1276_radio' platformio ci --lib . --board heltec_wifi_lora_32 'examples/raw-feather/raw-feather.ino' # Compile "ttn-otaa-feather-us915" example in US and AU regions @@ -126,6 +130,7 @@ then PLATFORMIO_BUILD_FLAGS='-D COMPILE_REGRESSION_TEST -D LED_BUILTIN=13 -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_au921 -D CFG_sx1276_radio' platformio ci --lib . --board feather32u4 'examples/raw-feather/raw-feather.ino' PLATFORMIO_BUILD_FLAGS='-D COMPILE_REGRESSION_TEST -D LED_BUILTIN=13 -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_as923 -D CFG_sx1276_radio' platformio ci --lib . --board feather32u4 'examples/raw-feather/raw-feather.ino' PLATFORMIO_BUILD_FLAGS='-D COMPILE_REGRESSION_TEST -D LED_BUILTIN=13 -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_as923jp -D CFG_sx1276_radio' platformio ci --lib . --board feather32u4 'examples/raw-feather/raw-feather.ino' + PLATFORMIO_BUILD_FLAGS='-D COMPILE_REGRESSION_TEST -D LED_BUILTIN=13 -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_kr920 -D CFG_sx1276_radio' platformio ci --lib . --board feather32u4 'examples/raw-feather/raw-feather.ino' PLATFORMIO_BUILD_FLAGS='-D COMPILE_REGRESSION_TEST -D LED_BUILTIN=13 -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS -D CFG_in866 -D CFG_sx1276_radio' platformio ci --lib . --board feather32u4 'examples/raw-feather/raw-feather.ino' # Test the raw sketch diff --git a/examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino b/examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino index 946dc891..6428e368 100644 --- a/examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino +++ b/examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino @@ -423,10 +423,10 @@ void myRxMessageCb( } case LMIC_COMPLIANCE_RX_ACTION_IGNORE: { if (port == LORAWAN_PORT_COMPLIANCE) { - Serial.print(F("Received test packet ")); + Serial.print(F("Received test packet 0x")); if (nMessage > 0) Serial.print(pMessage[0], HEX); - Serial.print(F(" length 0x")); + Serial.print(F(" length ")); Serial.println((unsigned) nMessage); } return; diff --git a/examples/raw-feather/raw-feather.ino b/examples/raw-feather/raw-feather.ino index 3ffe7907..7f30f042 100644 --- a/examples/raw-feather/raw-feather.ino +++ b/examples/raw-feather/raw-feather.ino @@ -397,6 +397,30 @@ void setup() { LMIC.lbt_ticks = us2osticks(AS923JP_LBT_US); LMIC.lbt_dbmax = AS923JP_LBT_DB_MAX; } +#elif defined(CFG_kr920) +// make it easier for test, by pull the parameters up to the top of the +// block. Ideally, we'd use the serial port to drive this; or have +// a voting protocol where one side is elected the controller and +// guides the responder through all the channels, powers, ramps +// the transmit power from min to max, and measures the RSSI and SNR. +// Even more amazing would be a scheme where the controller could +// handle multiple nodes; in that case we'd have a way to do +// production test and qualification. However, using an RWC5020A +// is a much better use of development time. + const static uint8_t kChannel = 0; + uint32_t uBandwidth; + + LMIC.freq = KR920_F1 + kChannel * 200000; + uBandwidth = 125; + + LMIC.datarate = KR920_DR_SF7; // DR7 + // default tx power for KR: 14 dBm + LMIC.txpow = KR920_TX_EIRP_MAX_DBM; + if (LMIC.freq < KR920_F14DBM) + LMIC.txpow = KR920_TX_EIRP_MAX_DBM_LOW; + + LMIC.lbt_ticks = us2osticks(KR920_LBT_US); + LMIC.lbt_dbmax = KR920_LBT_DB_MAX; #elif defined(CFG_in866) // make it easier for test, by pull the parameters up to the top of the // block. Ideally, we'd use the serial port to drive this; or have diff --git a/examples/raw-halconfig/raw-halconfig.ino b/examples/raw-halconfig/raw-halconfig.ino index b5784c21..6cc5668a 100644 --- a/examples/raw-halconfig/raw-halconfig.ino +++ b/examples/raw-halconfig/raw-halconfig.ino @@ -363,6 +363,30 @@ void setup() { LMIC.lbt_ticks = us2osticks(AS923JP_LBT_US); LMIC.lbt_dbmax = AS923JP_LBT_DB_MAX; } +#elif defined(CFG_kr920) +// make it easier for test, by pull the parameters up to the top of the +// block. Ideally, we'd use the serial port to drive this; or have +// a voting protocol where one side is elected the controller and +// guides the responder through all the channels, powers, ramps +// the transmit power from min to max, and measures the RSSI and SNR. +// Even more amazing would be a scheme where the controller could +// handle multiple nodes; in that case we'd have a way to do +// production test and qualification. However, using an RWC5020A +// is a much better use of development time. + const static uint8_t kChannel = 0; + uint32_t uBandwidth; + + LMIC.freq = KR920_F1 + kChannel * 200000; + uBandwidth = 125; + + LMIC.datarate = KR920_DR_SF7; // DR7 + // default tx power for KR: 14 dBm + LMIC.txpow = KR920_TX_EIRP_MAX_DBM; + if (LMIC.freq < KR920_F14DBM) + LMIC.txpow = KR920_TX_EIRP_MAX_DBM_LOW; + + LMIC.lbt_ticks = us2osticks(KR920_LBT_US); + LMIC.lbt_dbmax = KR920_LBT_DB_MAX; #elif defined(CFG_in866) // make it easier for test, by pull the parameters up to the top of the // block. Ideally, we'd use the serial port to drive this; or have diff --git a/project_config/lmic_project_config.h b/project_config/lmic_project_config.h index 7c19d39e..5913250b 100644 --- a/project_config/lmic_project_config.h +++ b/project_config/lmic_project_config.h @@ -4,6 +4,7 @@ //#define CFG_au921 1 //#define CFG_as923 1 // #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP /* for as923-JP */ +//#define CFG_kr920 1 //#define CFG_in866 1 #define CFG_sx1276_radio 1 //#define LMIC_USE_INTERRUPTS diff --git a/src/lmic/lmic.h b/src/lmic/lmic.h index 1983d87f..b9764da4 100644 --- a/src/lmic/lmic.h +++ b/src/lmic/lmic.h @@ -105,7 +105,7 @@ extern "C"{ #define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, local) \ (((major) << 24u) | ((minor) << 16u) | ((patch) << 8u) | (local)) -#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 3, 2, 51) /* v2.3.2.51 */ +#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 3, 2, 60) /* v2.3.2.60 */ #define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \ (((v) >> 24u) & 0xFFu) diff --git a/src/lmic/lmic_bandplan.h b/src/lmic/lmic_bandplan.h index 5c837a48..63836c5b 100644 --- a/src/lmic/lmic_bandplan.h +++ b/src/lmic/lmic_bandplan.h @@ -41,6 +41,8 @@ # include "lmic_bandplan_au921.h" #elif defined(CFG_as923) # include "lmic_bandplan_as923.h" +#elif defined(CFG_kr920) +# include "lmic_bandplan_kr920.h" #elif defined(CFG_in866) # include "lmic_bandplan_in866.h" #else diff --git a/src/lmic/lmic_bandplan_kr920.h b/src/lmic/lmic_bandplan_kr920.h new file mode 100644 index 00000000..75b00635 --- /dev/null +++ b/src/lmic/lmic_bandplan_kr920.h @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2014-2016 IBM Corporation. +* Copyright (c) 2017, 2019 MCCI Corporation. +* 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 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 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. +*/ + +#ifndef _lmic_kr920_h_ +# define _lmic_kr920_h_ + +#ifndef _lmic_eu_like_h_ +# include "lmic_eu_like.h" +#endif + +uint8_t LMICkr920_maxFrameLen(uint8_t dr); +#define maxFrameLen(dr) LMICkr920_maxFrameLen(dr) + +int8_t LMICkr920_pow2dBm(uint8_t mcmd_ladr_p1); +#define pow2dBm(mcmd_ladr_p1) LMICkr920_pow2dBm(mcmd_ladr_p1) + +// Times for half symbol per DR +// Per DR table to minimize rounding errors +ostime_t LMICkr920_dr2hsym(uint8_t dr); +#define dr2hsym(dr) LMICkr920_dr2hsym(dr) + + +// TODO(tmm@mcci.com) this looks bogus compared to current 1.02 regional +// spec. https://github.com/mcci-catena/arduino-lmic/issues/18 +static inline int +LMICkr920_isValidBeacon1(const uint8_t *d) { + return d[OFF_BCN_CRC1] != (u1_t)os_crc16(d, OFF_BCN_CRC1); +} + +#undef LMICbandplan_isValidBeacon1 +#define LMICbandplan_isValidBeacon1(pFrame) LMICkr920_isValidBeacon1(pFrame) + +// override default for LMICbandplan_isFSK() +#undef LMICbandplan_isFSK +#define LMICbandplan_isFSK() (/* always false */ 0) + +// txDone handling for FSK. +void +LMICkr920_txDoneFSK(ostime_t delay, osjobcb_t func); + +#define LMICbandplan_txDoneFsk(delay, func) LMICkr920_txDoneFSK(delay, func) + +#define LMICbandplan_getInitialDrJoin() (KR920_DR_SF7) + +void LMICkr920_setBcnRxParams(void); +#define LMICbandplan_setBcnRxParams() LMICkr920_setBcnRxParams() + +u4_t LMICkr920_convFreq(xref2cu1_t ptr); +#define LMICbandplan_convFreq(ptr) LMICkr920_convFreq(ptr) + +void LMICkr920_initJoinLoop(void); +#define LMICbandplan_initJoinLoop() LMICkr920_initJoinLoop() + +ostime_t LMICkr920_nextTx(ostime_t now); +#define LMICbandplan_nextTx(now) LMICkr920_nextTx(now) + +ostime_t LMICkr920_nextJoinState(void); +#define LMICbandplan_nextJoinState() LMICkr920_nextJoinState() + +void LMICkr920_initDefaultChannels(bit_t join); +#define LMICbandplan_initDefaultChannels(join) LMICkr920_initDefaultChannels(join) + +void LMICkr920_setRx1Params(void); +#define LMICbandplan_setRx1Params() LMICkr920_setRx1Params() + +#undef LMICbandplan_updateTx +void LMICkr920_updateTx(ostime_t txbeg); +#define LMICbandplan_updateTx(t) LMICkr920_updateTx(t) + +#endif // _lmic_kr920_h_ diff --git a/src/lmic/lmic_config_preconditions.h b/src/lmic/lmic_config_preconditions.h index 7db50754..6819cab4 100644 --- a/src/lmic/lmic_config_preconditions.h +++ b/src/lmic/lmic_config_preconditions.h @@ -69,7 +69,7 @@ Revision history: #define LMIC_REGION_au921 5 #define LMIC_REGION_cn490 6 #define LMIC_REGION_as923 7 -#define LMIC_REGION_kr921 8 +#define LMIC_REGION_kr920 8 #define LMIC_REGION_in866 9 // Some regions have country-specific overrides. For generality, we specify @@ -103,7 +103,7 @@ Revision history: (1 << LMIC_REGION_au921) | \ /* (1 << LMIC_REGION_cn490) | */ \ (1 << LMIC_REGION_as923) | \ - /* (1 << LMIC_REGION_kr921) | */ \ + (1 << LMIC_REGION_kr920) | \ (1 << LMIC_REGION_in866) | \ 0) @@ -127,7 +127,7 @@ Revision history: (defined(CFG_au921) << LMIC_REGION_au921) | \ (defined(CFG_cn490) << LMIC_REGION_cn490) | \ (defined(CFG_as923) << LMIC_REGION_as923) | \ - (defined(CFG_kr921) << LMIC_REGION_kr921) | \ + (defined(CFG_kr920) << LMIC_REGION_kr920) | \ (defined(CFG_in866) << LMIC_REGION_in866) | \ 0) @@ -152,8 +152,8 @@ Revision history: # define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP #elif defined(CFG_as923) # define CFG_region LMIC_REGION_as923 -#elif defined(CFG_kr921) -# define CFG_region LMIC_REGION_kr921 +#elif defined(CFG_kr920) +# define CFG_region LMIC_REGION_kr920 #elif defined(CFG_in866) # define CFG_region LMIC_REGION_in866 #else @@ -173,7 +173,7 @@ Revision history: /* (1 << LMIC_REGION_au921) | */ \ /* (1 << LMIC_REGION_cn490) | */ \ (1 << LMIC_REGION_as923) | \ - (1 << LMIC_REGION_kr921) | \ + (1 << LMIC_REGION_kr920) | \ (1 << LMIC_REGION_in866) | \ 0) @@ -191,7 +191,7 @@ Revision history: (1 << LMIC_REGION_au921) | \ /* (1 << LMIC_REGION_cn490) | */ \ /* (1 << LMIC_REGION_as923) | */ \ - /* (1 << LMIC_REGION_kr921) | */ \ + /* (1 << LMIC_REGION_kr920) | */ \ /* (1 << LMIC_REGION_in866) | */ \ 0) diff --git a/src/lmic/lmic_kr920.c b/src/lmic/lmic_kr920.c new file mode 100644 index 00000000..468f9773 --- /dev/null +++ b/src/lmic/lmic_kr920.c @@ -0,0 +1,255 @@ +/* +* Copyright (c) 2014-2016 IBM Corporation. +* Copyright (c) 2017, 2019 MCCI Corporation. +* 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 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 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. +*/ + +#define LMIC_DR_LEGACY 0 + +#include "lmic_bandplan.h" + +#if defined(CFG_kr920) +// ================================================================================ +// +// BEG: KR920 related stuff +// + +CONST_TABLE(u1_t, _DR2RPS_CRC)[] = { + ILLEGAL_RPS, + (u1_t)MAKERPS(SF12, BW125, CR_4_5, 0, 0), // [0] + (u1_t)MAKERPS(SF11, BW125, CR_4_5, 0, 0), // [1] + (u1_t)MAKERPS(SF10, BW125, CR_4_5, 0, 0), // [2] + (u1_t)MAKERPS(SF9, BW125, CR_4_5, 0, 0), // [3] + (u1_t)MAKERPS(SF8, BW125, CR_4_5, 0, 0), // [4] + (u1_t)MAKERPS(SF7, BW125, CR_4_5, 0, 0), // [5] + ILLEGAL_RPS, // [6] +}; + +static CONST_TABLE(u1_t, maxFrameLens)[] = { 59+5,59+5,59+5,123+5, 230+5, 230+5 }; + +uint8_t LMICkr920_maxFrameLen(uint8_t dr) { + if (dr < LENOF_TABLE(maxFrameLens)) + return TABLE_GET_U1(maxFrameLens, dr); + else + return 0xFF; +} + +static CONST_TABLE(s1_t, TXPOWLEVELS)[] = { + 14, 12, 10, 8, 6, 4, 2, 0, 0,0,0,0, 0,0,0,0 +}; + +int8_t LMICkr920_pow2dBm(uint8_t mcmd_ladr_p1) { + return TABLE_GET_S1(TXPOWLEVELS, (mcmd_ladr_p1&MCMD_LADR_POW_MASK)>>MCMD_LADR_POW_SHIFT); +} + +// only used in this module, but used by variant macro dr2hsym(). +static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = { + us2osticksRound(128 << 7), // DR_SF12 + us2osticksRound(128 << 6), // DR_SF11 + us2osticksRound(128 << 5), // DR_SF10 + us2osticksRound(128 << 4), // DR_SF9 + us2osticksRound(128 << 3), // DR_SF8 + us2osticksRound(128 << 2), // DR_SF7 +}; + +ostime_t LMICkr920_dr2hsym(uint8_t dr) { + return TABLE_GET_OSTIME(DR2HSYM_osticks, dr); +} + + +// All frequencies are marked as BAND_MILLI, and we don't do duty-cycle. But this lets +// us reuse code. +enum { NUM_DEFAULT_CHANNELS = 3 }; +static CONST_TABLE(u4_t, iniChannelFreq)[NUM_DEFAULT_CHANNELS] = { + // Default operational frequencies + KR920_F1 | BAND_MILLI, + KR920_F2 | BAND_MILLI, + KR920_F3 | BAND_MILLI, +}; + +// korea ignores the join flag, becuase the channel setup is the same either way. +void LMICkr920_initDefaultChannels(bit_t join) { + LMIC_API_PARAMETER(join); + + os_clearMem(&LMIC.channelFreq, sizeof(LMIC.channelFreq)); + os_clearMem(&LMIC.channelDrMap, sizeof(LMIC.channelDrMap)); + os_clearMem(&LMIC.bands, sizeof(LMIC.bands)); + + LMIC.channelMap = (1 << NUM_DEFAULT_CHANNELS) - 1; + for (u1_t fu = 0; fu BAND_MILLI) return 0; + //band_t* b = &LMIC.bands[bandidx]; + xref2band_t b = &LMIC.bands[bandidx]; + b->txpow = txpow; + b->txcap = txcap; + b->avail = os_getTime(); + b->lastchnl = os_getRndU1() % MAX_CHANNELS; + return 1; +} + +bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) { + if (chidx >= MAX_CHANNELS) + return 0; + if (band == -1) { + freq |= BAND_MILLI; + } else { + if (band > BAND_MILLI) return 0; + freq = (freq&~3) | band; + } + LMIC.channelFreq[chidx] = freq; + LMIC.channelDrMap[chidx] = drmap == 0 ? DR_RANGE_MAP(KR920_DR_SF12, KR920_DR_SF7) : drmap; + LMIC.channelMap |= 1 << chidx; // enabled right away + return 1; +} + + + +u4_t LMICkr920_convFreq(xref2cu1_t ptr) { + u4_t freq = (os_rlsbf4(ptr - 1) >> 8) * 100; + if (freq < KR920_FREQ_MIN || freq > KR920_FREQ_MAX) + freq = 0; + return freq; +} + +// return the next time, but also do channel hopping here +// since there's no duty cycle limitation, and no dwell limitation, +// we simply loop through the channels sequentially. +ostime_t LMICkr920_nextTx(ostime_t now) { + const u1_t band = BAND_MILLI; + + for (u1_t ci = 0; ci < MAX_CHANNELS; ci++) { + // Find next channel in given band + u1_t chnl = LMIC.bands[band].lastchnl; + for (u1_t ci = 0; ci= MAX_CHANNELS) + chnl -= MAX_CHANNELS; + if ((LMIC.channelMap & (1 << chnl)) != 0 && // channel enabled + (LMIC.channelDrMap[chnl] & (1 << (LMIC.datarate & 0xF))) != 0 && + band == (LMIC.channelFreq[chnl] & 0x3)) { // in selected band + LMIC.txChnl = LMIC.bands[band].lastchnl = chnl; + return now; + } + } + } + + // no enabled channel found! just use the last channel. + return now; +} + +#if !defined(DISABLE_BEACONS) +void LMICkr920_setBcnRxParams(void) { + LMIC.dataLen = 0; + LMIC.freq = LMIC.channelFreq[LMIC.bcnChnl] & ~(u4_t)3; + LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN), 1), LEN_BCN); +} +#endif // !DISABLE_BEACONS + +#if !defined(DISABLE_JOIN) +ostime_t LMICkr920_nextJoinState(void) { + return LMICeulike_nextJoinState(NUM_DEFAULT_CHANNELS); +} +#endif // !DISABLE_JOIN + +// // txDone handling for FSK. +// void +// LMICkr920_txDoneFSK(ostime_t delay, osjobcb_t func) { +// LMIC.rxtime = LMIC.txend + delay - PRERX_FSK*us2osticksRound(160); +// LMIC.rxsyms = RXLEN_FSK; +// os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func); +// } + +// set the Rx1 dndr, rps. +void LMICkr920_setRx1Params(void) { + u1_t const txdr = LMIC.dndr; + s1_t drOffset; + s1_t candidateDr; + + if ( LMIC.rx1DrOffset <= 5) + drOffset = (s1_t) LMIC.rx1DrOffset; + else + drOffset = 5 - (s1_t) LMIC.rx1DrOffset; + + candidateDr = (s1_t) txdr - drOffset; + if (candidateDr < LORAWAN_DR0) + candidateDr = 0; + else if (candidateDr > LORAWAN_DR5) + candidateDr = LORAWAN_DR5; + + LMIC.dndr = (u1_t) candidateDr; + LMIC.rps = dndr2rps(LMIC.dndr); +} + +void +LMICkr920_initJoinLoop(void) { + LMICeulike_initJoinLoop(NUM_DEFAULT_CHANNELS, /* adr dBm */ KR920_TX_EIRP_MAX_DBM); +} + +void LMICkr920_updateTx(ostime_t txbeg) { + u4_t freq = LMIC.channelFreq[LMIC.txChnl]; + // Update global/band specific duty cycle stats + ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen); + // Update channel/global duty cycle stats + xref2band_t band = &LMIC.bands[freq & 0x3]; + LMIC.freq = freq & ~(u4_t)3; + LMIC.txpow = band->txpow; + if (LMIC.freq <= KR920_FDOWN && LMIC.txpow > KR920_TX_EIRP_MAX_DBM_LOW) { + LMIC.txpow = KR920_TX_EIRP_MAX_DBM_LOW; + } + band->avail = txbeg + airtime * band->txcap; + if (LMIC.globalDutyRate != 0) + LMIC.globalDutyAvail = txbeg + (airtime << LMIC.globalDutyRate); +} + +// +// END: KR920 related stuff +// +// ================================================================================ +#endif diff --git a/src/lmic/lorabase.h b/src/lmic/lorabase.h index ff2f10b0..7b1525a6 100644 --- a/src/lmic/lorabase.h +++ b/src/lmic/lorabase.h @@ -104,6 +104,8 @@ enum _dr_code_t { // post conditions from this block: symbols used by general code that is not // ostensiblly region-specific. // DR_DFLTMIN must be defined as a suitable substititute value if we get a bogus DR +// It is misnamed, it should be the maximum DR (which is the minimum SF) for +// 125 kHz. // DR_PAGE is used only for a non-supported debug system, but should be defined. // CHNL_DNW2 is the channel to be used for RX2 // FREQ_DNW2 is the frequency to be used for RX2 @@ -326,6 +328,51 @@ enum _dr_configured_t { }; # endif // LMIC_DR_LEGACY +#elif defined(CFG_kr920) // ============================================== + +#include "lorabase_kr920.h" + +// per 2.8.3 (1.0.3 2.9.3): is not implemented +#define LMIC_ENABLE_TxParamSetupReq 0 + +enum { DR_DFLTMIN = KR920_DR_SF12 }; // DR2 + // DR_PAGE is a debugging parameter +enum { DR_PAGE = DR_PAGE_KR920 }; + +enum { FREQ_PING = KR920_FBCN }; // default ping freq +enum { DR_PING = KR920_DR_SF9 }; // default ping DR: DR3 +enum { FREQ_DNW2 = KR920_FDOWN }; +enum { DR_DNW2 = KR920_DR_SF12 }; +enum { CHNL_BCN = 11 }; +enum { FREQ_BCN = KR920_FBCN }; +enum { DR_BCN = KR920_DR_SF9 }; +enum { AIRTIME_BCN = 144384 }; // micros +enum { LMIC_REGION_EIRP = KR920_LMIC_REGION_EIRP }; // region uses EIRP + +enum { + // Beacon frame format KR SF9 + OFF_BCN_NETID = 0, + OFF_BCN_TIME = 2, + OFF_BCN_CRC1 = 6, + OFF_BCN_INFO = 8, + OFF_BCN_LAT = 9, + OFF_BCN_LON = 12, + OFF_BCN_CRC2 = 15, + LEN_BCN = 17 +}; + +# if LMIC_DR_LEGACY +enum _dr_configured_t { + DR_SF12 = KR920_DR_SF12, + DR_SF11 = KR920_DR_SF11, + DR_SF10 = KR920_DR_SF10, + DR_SF9 = KR920_DR_SF9, + DR_SF8 = KR920_DR_SF8, + DR_SF7 = KR920_DR_SF7, + DR_NONE = KR920_DR_NONE +}; +# endif // LMIC_DR_LEGACY + #elif defined(CFG_in866) // ============================================== #include "lorabase_in866.h" diff --git a/src/lmic/lorabase_kr920.h b/src/lmic/lorabase_kr920.h new file mode 100644 index 00000000..02fd5a0d --- /dev/null +++ b/src/lmic/lorabase_kr920.h @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2014-2016 IBM Corporation. +* All rights reserved. +* +* Copyright (c) 2017, 2019 MCCI Corporation +* 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 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 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. +*/ + +#ifndef _lorabase_kr920_h_ +#define _lorabase_kr920_h_ + +#ifndef _LMIC_CONFIG_PRECONDITIONS_H_ +# include "lmic_config_preconditions.h" +#endif + +/****************************************************************************\ +| +| Basic definitions for KR920 (always in scope) +| +\****************************************************************************/ + +enum _dr_kr920_t { + KR920_DR_SF12 = 0, // DR0 + KR920_DR_SF11, // DR1 + KR920_DR_SF10, // DR2 + KR920_DR_SF9, // DR3 + KR920_DR_SF8, // DR4 + KR920_DR_SF7, // DR5 + KR920_DR_NONE +}; + +// There is no dwell-time or duty-cycle limitation for IN +// +// max power: 30dBM +// +// freq datarates +enum { + KR920_F1 = 922100000, // SF7-12 (DR0-5) + KR920_F2 = 922300000, // SF7-12 (DR0-5) + KR920_F3 = 922500000, // SF7-12 (DR0-5) + KR920_FBCN = 923100000, // beacon/ping + KR920_F14DBM = 922100000, // Allows 14 dBm (not 10) if >= this. + KR920_FDOWN = 921900000, // RX2 downlink frequency +}; +enum { + KR920_FREQ_MIN = 920900000, + KR920_FREQ_MAX = 923300000 +}; +enum { + KR920_TX_EIRP_MAX_DBM = 14, // 14 dBm for most + KR920_TX_EIRP_MAX_DBM_LOW = 10, // 10 dBm for some +}; +enum { DR_PAGE_KR920 = 0x10 * (LMIC_REGION_kr920 - 1) }; + +enum { KR920_LMIC_REGION_EIRP = 1 }; // region uses EIRP + +enum { KR920_LBT_US = 128 }; // microseconds of LBT time. + +enum { KR920_LBT_DB_MAX = -80 }; // maximum channel strength in dB; if TX + // we measure more than this, we don't tx. + +#endif /* _lorabase_in866_h_ */ \ No newline at end of file From 22c2ca4209aa29144f3ce14ef4366aa92f7bdd65 Mon Sep 17 00:00:00 2001 From: Terry Moore Date: Wed, 14 Aug 2019 10:24:09 -0400 Subject: [PATCH 2/3] Use _projcfg to select region for testing kr920; BSPs aren't released yet --- .travis.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d1b19863..4c377bee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -176,7 +176,9 @@ script: - _notsamd || { _projcfg CFG_au921 CFG_sx1276_radio && arduino --verify --board $(_samdopts '' projcfg) $PWD/examples/raw-feather/raw-feather.ino ; } - _notsamd || arduino --verify --board $(_samdopts '' as923) $PWD/examples/raw-feather/raw-feather.ino - _notsamd || arduino --verify --board $(_samdopts '' as923jp) $PWD/examples/raw-feather/raw-feather.ino - - _notsamd || arduino --verify --board $(_samdopts '' kr920) $PWD/examples/raw-feather/raw-feather.ino +# V2.0.0 of the samd bsp doesn't include kr920 support in menus, use projcfg +# - _notsamd || arduino --verify --board $(_samdopts '' kr920) $PWD/examples/raw-feather/raw-feather.ino + - _notsamd || { _projcfg CFG_kr920 CFG_sx1276_radio && arduino --verify --board $(_samdopts '' projcfg) $PWD/examples/raw-feather/raw-feather.ino ; } - _notsamd || arduino --verify --board $(_samdopts '' in866) $PWD/examples/raw-feather/raw-feather.ino # test raw in us915 and eu868 @@ -283,7 +285,9 @@ script: - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' au921 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' as923 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' as923jp) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' kr920 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino +# V2.4.0 of the stm bsp doesn't include kr920 support in menus, use projcfg +# - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' kr920 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino + - _notstm32l0 || { _projcfg CFG_kr920 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' in866 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || { _projcfg COMPILE_REGRESSION_TEST CFG_us915 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } - _notstm32l0 || { _projcfg COMPILE_REGRESSION_TEST CFG_us915 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa/ttn-otaa.ino ; } From 45cf72f9c203941ebfcb6a03e36af5fb01feb5f8 Mon Sep 17 00:00:00 2001 From: Terry Moore Date: Wed, 14 Aug 2019 10:46:36 -0400 Subject: [PATCH 3/3] Cut/paste error --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4c377bee..6948ade6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -287,7 +287,7 @@ script: - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' as923jp) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino # V2.4.0 of the stm bsp doesn't include kr920 support in menus, use projcfg # - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' kr920 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - - _notstm32l0 || { _projcfg CFG_kr920 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } + - _notstm32l0 || { _projcfg CFG_kr920 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino ; } - _notstm32l0 || arduino --verify --board $(_stm32l0opts '' in866 ) $MCCI_STM32_OPTS $PWD/examples/raw-feather/raw-feather.ino - _notstm32l0 || { _projcfg COMPILE_REGRESSION_TEST CFG_us915 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa-feather-us915/ttn-otaa-feather-us915.ino ; } - _notstm32l0 || { _projcfg COMPILE_REGRESSION_TEST CFG_us915 CFG_sx1276_radio && arduino --verify --board $(_stm32l0opts '' projcfg) $MCCI_STM32_OPTS $PWD/examples/ttn-otaa/ttn-otaa.ino ; }