├── .github ├── ISSUE_TEMPLATE │ ├── 00-support-request.md │ ├── 10-bug_report.md │ ├── 20-feature_request.md │ └── 30-doc_issue.md └── workflows │ └── ci-arduinocli.yml ├── .gitignore ├── .hgignore ├── HOWTO-ADD-REGION.md ├── LICENSE ├── README.md ├── assets ├── Feather-M0-LoRa-Wire.ai └── Feather-M0-LoRa-Wire.png ├── ci ├── lmic-filter-common.sh └── platformio.sh ├── doc ├── HOWTO-Manually-Configure.md ├── IBM-DISCLAIMER.txt ├── IBM-release-notes.txt ├── LMIC-FSM.cdd ├── LMIC-FSM.pdf ├── LMIC-structure-diagram.cdd ├── LMIC-structure-diagram.pdf ├── LMIC-v5.0.0-redline.pdf ├── LMIC-v5.0.0.docx ├── LMIC-v5.0.0.pdf ├── LoRaWAN-at-a-glance.pdf ├── LoRaWAN-at-a-glance.vsdx ├── README.md └── RadioDriver.md ├── examples ├── compliance-otaa-halconfig │ ├── compliance-otaa-halconfig.ino │ └── extra │ │ └── ci │ │ └── lmic-filter.sh ├── header_test │ └── header_test.ino ├── helium-otaa │ └── helium-otaa.ino ├── raw-feather │ ├── extra │ │ └── ci │ │ │ └── lmic-filter.sh │ └── raw-feather.ino ├── raw-halconfig │ └── raw-halconfig.ino ├── raw │ └── raw.ino ├── ttn-abp-feather-us915-dht22 │ ├── extra │ │ └── ci │ │ │ └── lmic-filter.sh │ └── ttn-abp-feather-us915-dht22.ino ├── ttn-abp │ └── ttn-abp.ino ├── ttn-otaa-feather-us915-dht22 │ ├── extra │ │ └── ci │ │ │ └── lmic-filter.sh │ └── ttn-otaa-feather-us915-dht22.ino ├── ttn-otaa-feather-us915 │ ├── extra │ │ └── ci │ │ │ └── lmic-filter.sh │ └── ttn-otaa-feather-us915.ino ├── ttn-otaa-halconfig-us915 │ └── ttn-otaa-halconfig-us915.ino ├── ttn-otaa-network-time │ ├── extra │ │ └── ci │ │ │ └── lmic-filter.sh │ └── ttn-otaa-network-time.ino ├── ttn-otaa-sx1262 │ └── ttn-otaa-sx1262.ino └── ttn-otaa │ └── ttn-otaa.ino ├── library.properties ├── project_config └── lmic_project_config.h └── src ├── aes ├── ideetron │ └── AES-128_V10.cpp ├── lmic.c └── other.c ├── arduino_lmic.h ├── arduino_lmic_hal_boards.h ├── arduino_lmic_hal_configuration.h ├── arduino_lmic_lorawan_compliance.h ├── arduino_lmic_user_configuration.h ├── hal ├── getpinmap_catena4420.cpp ├── getpinmap_catena4551.cpp ├── getpinmap_catena4610.cpp ├── getpinmap_catena4611.cpp ├── getpinmap_catena4612.cpp ├── getpinmap_catena4617.cpp ├── getpinmap_catena4618.cpp ├── getpinmap_catena4630.cpp ├── getpinmap_catena4801.cpp ├── getpinmap_catena4802.cpp ├── getpinmap_disco_l072cs_lrwan1.cpp ├── getpinmap_feather32u4lora.cpp ├── getpinmap_featherm0lora.cpp ├── getpinmap_heltec_lora32.cpp ├── getpinmap_heltec_lora32_v3.cpp ├── getpinmap_thisboard.cpp ├── getpinmap_ttgo_lora32_v1.cpp ├── getpinmap_ttgo_lora32_v2.1.cpp ├── getpinmap_ttgo_tbeam_s3.cpp ├── hal.cpp └── hal.h ├── lmic.h └── lmic ├── config.h ├── hal.h ├── lmic.c ├── lmic.h ├── lmic_as923.c ├── lmic_au915.c ├── lmic_bandplan.h ├── lmic_bandplan_as923.h ├── lmic_bandplan_au915.h ├── lmic_bandplan_eu868.h ├── lmic_bandplan_in866.h ├── lmic_bandplan_kr920.h ├── lmic_bandplan_us915.h ├── lmic_channelshuffle.c ├── lmic_compat.h ├── lmic_compliance.c ├── lmic_compliance.h ├── lmic_config_preconditions.h ├── lmic_env.h ├── lmic_eu868.c ├── lmic_eu_like.c ├── lmic_eu_like.h ├── lmic_in866.c ├── lmic_kr920.c ├── lmic_us915.c ├── lmic_us_like.c ├── lmic_us_like.h ├── lmic_util.c ├── lmic_util.h ├── lorabase.h ├── lorabase_as923.h ├── lorabase_au915.h ├── lorabase_eu868.h ├── lorabase_in866.h ├── lorabase_kr920.h ├── lorabase_us915.h ├── lorawan_spec_compliance.h ├── oslmic.c ├── oslmic.h ├── oslmic_types.h ├── radio_sx126x.c └── radio_sx127x.c /.github/ISSUE_TEMPLATE/00-support-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support request 3 | about: Ask for help on a problem 4 | title: '' 5 | labels: question 6 | assignees: terrillmoore 7 | 8 | --- 9 | 10 | **Consider raising support questions on the forum first** 11 | 12 | There is a discussion site, [forum.mcci.io](https://forum.mcci.io), which includes a [category focused on the Arduino LMIC](https://forum.mcci.io/c/device-software/arduino-lmic/5). Unless you're sure that your problem is a bug in the LMIC, it would be great if you can try for help there first. That will keep issues focused on work that needs to be done by the developers. 13 | 14 | **Describe your question or issue** 15 | 16 | Please give a clear and concise description of the problem you're facing and what you'd like help with. 17 | 18 | **Environment** 19 | 20 | This information is very important; it's hard to help without a complete set of answers. 21 | 22 | - Version of LMIC being used. If using the latest github mainline, let us know, otherwise state the version. 23 | - Version of Arduino IDE being used: 24 | - Network provider (The Things Network, Swisscom, ChirpStack, etc.) 25 | - Region (EU868, US915, etc.) 26 | - Board (MCCI Catena, Adafruit Feather M0, Heltec Wi-Fi LoRa 32 v2, etc.) 27 | - Radio (HopeRF, SX1276, etc.) 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/10-bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a code defect 4 | title: '' 5 | labels: bug 6 | assignees: terrillmoore 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | A clear and concise description of what the bug is. _If you're not sure it's a bug, please consider opening a discussion at [forum.mcci.io](https://forum.mcci.io/c/device-software/arduino-lmic/5), or file a Support Request instead._ A bug is a problem in the code, where you do something that the documentation says should work, but doesn't; _and_ you have reason to believe it's not working due to a defect in the code. 13 | 14 | Wireless is tricky; if in doubt, start with a support request, rather than a bug report. 15 | 16 | **Environment** 17 | 18 | - Version of LMIC being used. If using the latest GitHub mainline, let us know, otherwise state the version. 19 | - Version of Arduino IDE being used. 20 | - Network provider (The Things Network, Swisscom, ChirpStack, etc.) 21 | - Region (EU868, US915, etc.) 22 | - Board (MCCI Catena, Adafruit Feather M0, Heltec, etc.) 23 | - CPU (AVR, STM32L0, etc.) 24 | - Radio (HopeRF, SX1276, etc.) 25 | 26 | **To Reproduce** 27 | 28 | Steps to reproduce the problem. 29 | 30 | **Expected behavior** 31 | 32 | A clear and concise description of what you expected to happen. 33 | 34 | **Screenshots** 35 | 36 | If applicable, add screenshots to help explain your problem. 37 | 38 | **Additional context** 39 | 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/20-feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: terrillmoore 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/30-doc_issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation issue 3 | about: Report a problem in the documentation 4 | title: '' 5 | labels: docs 6 | assignees: terrillmoore 7 | 8 | --- 9 | 10 | Thanks for your contribution! 11 | 12 | **What document is involved?** 13 | 14 | If this is an existing document, please include the full path to the file. 15 | 16 | If there's a need for a new document, please suggest the places in existing docs that should link to it. 17 | 18 | Make sure you mention the version, and please also check the current version at GitHub, to be sure that the problem hasn't already been corrected for a pending release. 19 | 20 | **What changes are needed?** 21 | 22 | Indicate the changes you think are needed. Explicit help is always better. File a PR with your changes if possible! 23 | -------------------------------------------------------------------------------- /.github/workflows/ci-arduinocli.yml: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # 3 | # File: ci-arduinocli.yml 4 | # 5 | # Function: 6 | # YAML file specifying how to do continuous integration for Arduino-LMIC 7 | # (using arduino-cli) 8 | # 9 | ############################################################################## 10 | 11 | # the name that appears in the GitHub UI, the badge, etc 12 | name: Arduino CI 13 | 14 | # global environment 15 | env: 16 | MCCI_CI_LIBRARY: arduino-lmic 17 | 18 | # specify the events that trigger runs. 19 | on: 20 | # pull requests (default settings) 21 | pull_request: 22 | # pushes (default settings) 23 | push: 24 | # repository operations 25 | repository_dispatch: 26 | schedule: 27 | # do a build once a week at 06:07Z Sunday 28 | - cron: '7 6 * * 0' 29 | 30 | # what to do: 31 | jobs: 32 | 33 | # define a job named "arduinocli" 34 | arduinocli: 35 | # select a target OS 36 | runs-on: ubuntu-latest 37 | name: ${{ matrix.arch }} 38 | 39 | strategy: 40 | fail-fast: false 41 | matrix: 42 | arch: [samd, stm32, esp32, avr] 43 | # get info about all the configs. 44 | 45 | # step-by-step 46 | steps: 47 | # check out this repo as {root}/arduino-lmic 48 | - uses: actions/checkout@v2 49 | name: Check out the repo 50 | with: 51 | path: libraries/${{ env.MCCI_CI_LIBRARY }} 52 | 53 | - uses: actions/checkout@v2 54 | name: Set up mcci-catena-ci 55 | with: 56 | repository: mcci-catena/mcci-catena-ci 57 | path: mcci-catena-ci 58 | 59 | - name: "Get library: Adafruit_Sensor" 60 | uses: actions/checkout@v2 61 | with: 62 | repository: adafruit/Adafruit_Sensor 63 | path: libraries/Adafruit_Sensor 64 | 65 | - name: "Get library: DHT-sensor-library" 66 | uses: actions/checkout@v2 67 | with: 68 | repository: adafruit/DHT-sensor-library 69 | path: libraries/DHT-sensor-library 70 | 71 | - name: "Get library: Time" 72 | uses: actions/checkout@v2 73 | with: 74 | repository: PaulStoffregen/Time 75 | path: libraries/Time 76 | 77 | - name: Set up to build 78 | run: bash mcci-catena-ci/setup.sh -l libraries/${{ env.MCCI_CI_LIBRARY }} -a ${{ matrix.arch }} 79 | 80 | - name: Display structure of checkout 81 | run: tree -d $(realpath .) 82 | 83 | - name: Compile examples 84 | run: bash mcci-catena-ci/arduino-lmic-regress-wrap.sh -l libraries/${{env.MCCI_CI_LIBRARY}} -a ${{ matrix.arch }} 85 | 86 | ### end of file ### 87 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | 31 | # Backup files 32 | *.BAK 33 | *.CKP 34 | *.wbk 35 | ~$*.docx 36 | 37 | # files from Visual Micro 38 | Release 39 | *.vcxproj 40 | *.vcxproj.filters 41 | *.vcxitems 42 | vs-readme.txt 43 | __vm 44 | .vs 45 | *.sln 46 | 47 | # files from vscode 48 | .vscode 49 | doxygen 50 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | ^CVS 2 | .*/CVS 3 | .*/CVS/.* 4 | \.\#.*$ 5 | ^\.DS_Store$ 6 | .*\.BAK$ 7 | .*\.bak$ 8 | .*\.CKP$ 9 | ^build 10 | ^build/.* 11 | ^.*\.o$ 12 | ^.*\.d$ 13 | ^.*\.td$ 14 | \.a$ 15 | ^core$ 16 | .*/core$ 17 | .*\.rej$ 18 | -------------------------------------------------------------------------------- /HOWTO-ADD-REGION.md: -------------------------------------------------------------------------------- 1 | # Adding a new region to Arduino LMIC 2 | 3 | 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. 4 | 5 | This document outlines how to add a new region. 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | - [Planning](#planning) 21 | - [Determine the region/region category](#determine-the-regionregion-category) 22 | - [Check whether the region is already listed in `lmic_config_preconditions.h`](#check-whether-the-region-is-already-listed-in-lmic_config_preconditionsh) 23 | - [Make the appropriate changes in `lmic_config_preconditions.h`](#make-the-appropriate-changes-in-lmic_config_preconditionsh) 24 | - [Document your region in `README.md`](#document-your-region-in-readmemd) 25 | - [Add the definitions for your region in `lorabase.h`](#add-the-definitions-for-your-region-in-lorabaseh) 26 | - [Edit `lmic_bandplan.h`](#edit-lmic_bandplanh) 27 | - [Create lmic_newregion.c](#create-codelmic_emnewregionemccode) 28 | - [General Discussion](#general-discussion) 29 | - [Adding the region to the Arduino_LoRaWAN library](#adding-the-region-to-the-arduino_lorawan-library) 30 | 31 | 32 | 33 | 34 | 35 | ## Planning 36 | 37 | ### Determine the region/region category 38 | 39 | Compare the target region (in the LoRaWAN regional specification) to the EU868 and US915 regions. There are three possibilities. 40 | 41 | 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. 42 | 43 | 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. 44 | 45 | 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. 46 | 47 | Band plans in categories (1) and (2) are easily supported. Band plans in category (3) are not supported by the current code. 48 | 49 | ### Check whether the region is already listed in `lmic_config_preconditions.h` 50 | 51 | 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. 52 | 53 | - `LMIC_REGION_myregion` must be a distinct integer, and must be less than 32 (so as to fit into a bitmask) 54 | 55 | ## Make the appropriate changes in `lmic_config_preconditions.h` 56 | 57 | - `LMIC_REGIONS_SUPPORTED` is a bit mask of all regions supported by the code. Your new region must appear in this list. 58 | - `CFG_LMIC_REGION_MASK` is a bit mask that, when expanded, returns a bitmask for each defined `CFG_...` variable. You must add your `CFG_myregion` symbol to this list. 59 | - `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. 60 | - `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. 61 | 62 | ## Document your region in `README.md` 63 | 64 | You'll see where the regions are listed. Add yours. 65 | 66 | ## Add the definitions for your region in `lorabase.h` 67 | 68 | - If your region is EU like, copy the EU block. Document any duty-cycle limitations. 69 | - if your region is US like, copy the US block. 70 | - As appropriate, copy `lorabase_eu868.h` or `lorabase_us915.h` to make your own lorabase_newregion.h. Fill in the symbols. 71 | 72 | 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. 73 | 74 | - 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: 75 | 76 | ```console 77 | lmic.c:29: In file included from 78 | 79 | lmic_bandplan.h: 52:3: error: #error "LMICbandplan_maxFrameLen() not defined by bandplan" 80 | # error "LMICbandplan_maxFrameLen() not defined by bandplan" 81 | 82 | lmic_bandplan.h: 56:3: error: #error "pow2dBm() not defined by bandplan" 83 | # error "pow2dBm() not defined by bandplan" 84 | ``` 85 | 86 | - If using an MCCI BSP, you might want to edit your local copy of `boards.txt` to add the new region. 87 | 88 | - If using an MCCI BSP, you should definitely edit the template files to add the new region to the list. 89 | 90 | - Modify the `.travis.yml` file to test the new region. 91 | 92 | ## Edit `lmic_bandplan.h` 93 | 94 | The next step is to add the region-specific interfaces for your region. 95 | 96 | Do this by editing `lmic_bandplan.h` and adding the appropriate call to a (new) region-specific file `lmic_bandplan_myregion.h`, where "myregion" is the abbreviation for your region. 97 | 98 | 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`. 99 | 100 | Edit the file. 101 | 102 | Try to compile again; you should now get link errors related to your new band-plan, like this: 103 | 104 | ```console 105 | c:\tmp\buildfolder\libraries\arduino-lmic\lmic\lmic.c.o: In function `lowerDR': 106 | 107 | C:\Users\tmm\Documents\Arduino\libraries\arduino-lmic\src\lmic/lorabase.h:667: undefined reference to `constant_table__DR2RPS_CRC' 108 | ``` 109 | 110 | ## Create lmic_newregion.c 111 | 112 | 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. 113 | 114 | ## General Discussion 115 | 116 | - 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. 117 | 118 | - Don't forget to check and update the examples. 119 | 120 | - 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. 121 | 122 | - 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.) 123 | 124 | - 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. 125 | 126 | - Please also increase the version of the `arduino-lorawan` library (symbol `ARDUINO_LORAWAN_VERSION`). 127 | 128 | ## Adding the region to the Arduino_LoRaWAN library 129 | 130 | In `Arduino_LoRaWAN_ttn.h`: 131 | 132 | - 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. 133 | - 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. 134 | 135 | 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. 136 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2014-2016 IBM Corporation 4 | Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 5 | Copyright (c) 2016-2024 MCCI Corporation 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /assets/Feather-M0-LoRa-Wire.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/assets/Feather-M0-LoRa-Wire.ai -------------------------------------------------------------------------------- /assets/Feather-M0-LoRa-Wire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/assets/Feather-M0-LoRa-Wire.png -------------------------------------------------------------------------------- /ci/lmic-filter-common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################## 4 | # 5 | # Module: lmic-filter-common.sh 6 | # 7 | # Function: 8 | # This script must be sourced; it sets variables used by other 9 | # scripts in this directory. 10 | # 11 | # Usage: 12 | # source ci/lmic-filter.sh 13 | # 14 | # Copyright and License: 15 | # See accompanying LICENSE.md file 16 | # 17 | # Author: 18 | # Terry Moore, MCCI February 2021 19 | # 20 | ############################################################################## 21 | 22 | #### Capture the file path #### 23 | MCCI_THISFILE="$0" 24 | 25 | #### mandatory function: do the filtering 26 | function _lmic_filter { 27 | declare -r CMD="$1" 28 | shift 29 | case "$CMD" in 30 | 31 | # return 0 (success) if should process this sketch. 32 | "process") 33 | case "$MCCI_CI_ARCH:$(basename "$1")" in 34 | # we need to skip this sketch until the SAMD 35 | # bsp is updated; the Time library uses prog_read_ptr() 36 | # which is broken in v2.3.0 37 | "samd:ttn-otaa-network-time.ino") 38 | return 1 39 | ;; 40 | # some of the feather sketches fail on non-Feathers 41 | "esp32:raw-feather.ino" | \ 42 | "esp32:ttn-otaa-feather-us915.ino") 43 | return 1 44 | ;; 45 | # some of the feather sketches fail on non-Feathers 46 | "stm32:raw-feather.ino" | \ 47 | "stm32:ttn-otaa-feather-us915.ino") 48 | return 1 49 | ;; 50 | *) 51 | return 0 52 | ;; 53 | esac 54 | ;; 55 | 56 | # print 1 if must use projcfg; 0 if not forced. 57 | "use-projcfg") 58 | if [[ "$MCCI_CI_ARCH" = "avr" ]]; then 59 | echo 1 60 | else 61 | echo 0 62 | fi 63 | ;; 64 | 65 | # call the suitable flavor of _projcfg. 66 | "projcfg") 67 | declare -r LMIC_FILTER_SKETCH="$1" 68 | _debug _lmic_filter: LMIC_FILTER_SKETCH="$LMIC_FILTER_SKETCH" 69 | shift 70 | if [[ "$MCCI_CI_ARCH" = "avr" ]]; then 71 | _projcfg_class_a "$@" "DISABLE_LMIC_FAILURE_TO" 72 | else 73 | _projcfg "$@" 74 | fi 75 | ;; 76 | *) 77 | _error "_lmic_filter: unknown command:" "$@" 78 | ;; 79 | esac 80 | } 81 | -------------------------------------------------------------------------------- /doc/IBM-DISCLAIMER.txt: -------------------------------------------------------------------------------- 1 | The original distribution from IBM includes the following notice as README.txt. 2 | 3 | DISCLAIMER: 4 | Please note that the software is provided AS IS and we cannot 5 | provide support for optimizations, adaptations, integration, 6 | ports to other platforms or device drivers! 7 | -------------------------------------------------------------------------------- /doc/IBM-release-notes.txt: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | LMIC VERSION 1.6 (13-July-2015) 3 | --------------------------------- 4 | 5 | - License changed to BSD 6 | - Modem included, see LMiC-Modem.pdf and examples/modem 7 | - Additional stm32 hardware and Blipper board specific peripheral code 8 | 9 | 10 | ============================================================================== 11 | LMIC VERSION 1.5 (8-May-2015) 12 | ------------------------------ 13 | 14 | - fixed condition in convFreq() 15 | 16 | - fixed freq*100 bug and freq==0 bug for CFList 17 | 18 | - fixed TX scheduling bug 19 | 20 | - better support for GNU compiler toolchain 21 | 22 | 23 | ============================================================================== 24 | LMIC VERSION 1.4 (17-Mar-2015) 25 | ------------------------------- 26 | 27 | - changed API: inverted port indicator flag in LMIC.txrxFlags 28 | (now TXRX_PORT, previously TXRX_NOPORT) 29 | 30 | - fixed offset OFF_CFLIST constant 31 | 32 | - changed CRC-16 algorithm for beacons to CCITT(XMODEM) polynomial 33 | 34 | - fixed radio driver (low data rate optimization for SF11+SF12 only for BW125) 35 | 36 | - fixed timer rollover handling in job queue 37 | 38 | ============================================================================== 39 | -------------------------------------------------------------------------------- /doc/LMIC-FSM.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/doc/LMIC-FSM.pdf -------------------------------------------------------------------------------- /doc/LMIC-structure-diagram.cdd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 18 | 19 | 21 | 22 | 40 | 41 | 44 | LMIC 45 | 46 | 47 | 50 | Radio 51 | 52 | 53 | 54 | 58 | 61 | 65 | 66 | 67 | 70 | Chip 71 | 72 | 73 | 74 | 78 | 80 | 85 | 86 | 87 | 90 | Radio layer just does what it's told.

91 | It's dumb. "Send these bytes" or "start listening" 92 | 93 | 94 | 97 | Hardware: SX1276 98 | 99 | 100 | 103 | Secure Element 104 | 105 | 106 | 107 | 111 | 114 | 118 | 119 | 120 | 123 | AES Decrypt 124 | 125 | 126 | 127 | 131 | 134 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /doc/LMIC-structure-diagram.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/doc/LMIC-structure-diagram.pdf -------------------------------------------------------------------------------- /doc/LMIC-v5.0.0-redline.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/doc/LMIC-v5.0.0-redline.pdf -------------------------------------------------------------------------------- /doc/LMIC-v5.0.0.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/doc/LMIC-v5.0.0.docx -------------------------------------------------------------------------------- /doc/LMIC-v5.0.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/doc/LMIC-v5.0.0.pdf -------------------------------------------------------------------------------- /doc/LoRaWAN-at-a-glance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/doc/LoRaWAN-at-a-glance.pdf -------------------------------------------------------------------------------- /doc/LoRaWAN-at-a-glance.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcci-catena/arduino-lmic/01a880fa84b72961ba7e73607c573185386020b2/doc/LoRaWAN-at-a-glance.vsdx -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | # LMIC Documentation 2 | 3 | This directory contains documentation on the use and implementation of the LMIC. 4 | 5 | ## Usage documentation 6 | 7 | - [`LMIC-v5.0.0.pdf`](./LMIC-v5.0.0.pdf): API documentation on the LMIC as of 5.0.0. 8 | - [`LMIC-v5.0.0-redline.pdf`](./LMIC-v5.0.0-redline.pdf): changes in the document since last update, marked up by Litera Workshare Compare. 9 | 10 | ## Background information 11 | 12 | - [`LoRaWAN-at-a-glance.pdf`](./LoRaWAN-at-a-glance.pdf): a wall chart showing key features of the LoRaWAN 1.0.3 protocol. 13 | 14 | ## Implementation documentation 15 | 16 | - [`RadioDriver.md`](./RadioDriver.md): documentation of the radio driver interface. 17 | - [`LMIC-structure-diagram.pdf`](./LMIC-structure-diagram.pdf): a structural diagram of the LMIC. This is somewhat UML like. 18 | - [`LMIC-FSM.pdf`](./LMIC-FSM.pdf): the operating logic of the LMIC, modeled as a finite state machine. As of version 3.2, this model is idealized; the actual implementation is not an explicit state machine. However, if you search for `os_setCallback()` and `os_setTimedCallback()`, you will see the links between event callbacks, and that will generally correspond to the implementation. The FSM diagram doesn't show class-B or class-C operation as yet. 19 | 20 | ## Historical information 21 | 22 | - `IBM-DISCLAIMER.txt` and `IBM-release-notes.txt` are artifacts of the original IBM distribution, retained for reference. 23 | 24 | ## Meta 25 | 26 | Source files are included for documents that have separate sources. 27 | 28 | - The source for the API documentation is a Microsoft Word file. 29 | - The source for "LoRaWAN at a glance" is a Visio file. 30 | - The sources for LMIC-FSM and LMIC-structure are [Cadifra](https://www.cadifra.com/) files. Cadifra is an inexpensive ($50) commercial tool that the author uses as a UML whiteboard; it's really lightweight and very cleanly implemented on Windows. 31 | -------------------------------------------------------------------------------- /doc/RadioDriver.md: -------------------------------------------------------------------------------- 1 | # Radio Driver parameters 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | - [Radio Driver Operation](#radio-driver-operation) 17 | - [`os_radio(RADIO_RST)`](#os_radioradio_rst) 18 | - [`os_radio(RADIO_TX)`](#os_radioradio_tx) 19 | - [`os_radio(RADIO_RX)`](#os_radioradio_rx) 20 | - [`os_radio(RADIO_RXON)`](#os_radioradio_rxon) 21 | - [Common parameters](#common-parameters) 22 | - [`LMIC.rps` (IN)](#lmicrps-in) 23 | - [`LMIC.freq` (IN)](#lmicfreq-in) 24 | - [`LMIC.saveIrqFlags` (OUT)](#lmicsaveirqflags-out) 25 | - [`LMIC.osjob` (IN/OUT)](#lmicosjob-inout) 26 | - [Transmit parameters](#transmit-parameters) 27 | - [`LMIC.radio_txpow` (IN)](#lmicradio_txpow-in) 28 | - [`LMIC.frame[]` (IN)](#lmicframe-in) 29 | - [`LMIC.datalen` (IN)](#lmicdatalen-in) 30 | - [`LMIC.txend` (OUT)](#lmictxend-out) 31 | - [Receive parameters](#receive-parameters) 32 | - [`LMIC.frame[]` (OUT)](#lmicframe-out) 33 | - [`LMIC.datalen` (OUT)](#lmicdatalen-out) 34 | - [`LMIC.rxtime` (IN/OUT)](#lmicrxtime-inout) 35 | - [`LMIC.lbt_ticks` (IN)](#lmiclbt_ticks-in) 36 | - [`LMIC.lbt_dbmax` (IN)](#lmiclbt_dbmax-in) 37 | - [`LMIC.rxsyms` (IN)](#lmicrxsyms-in) 38 | - [`LMIC.noRXIQinversion` (IN)](#lmicnorxiqinversion-in) 39 | - [`LMIC.snr` (OUT)](#lmicsnr-out) 40 | - [`LMIC.rssi` (OUT)](#lmicrssi-out) 41 | 42 | 43 | 44 | 45 | 46 | ## Radio Driver Operation 47 | 48 | The LMIC radio driver operates asynchronously. Operations are started by calling the `os_radio()` function with a parameter describing the operation to be performed. 49 | 50 | Various parameters in the LMIC structure are as input to control the operation; others are updated to return results. 51 | 52 | ### `os_radio(RADIO_RST)` 53 | 54 | The radio is reset, and put to sleep. This operation is synchronous. 55 | 56 | ### `os_radio(RADIO_TX)` 57 | 58 | A frame is transmitted. The parameters are given in [common parameters](#common-parameters) and [transmit parameters](#transmit-parameters). 59 | 60 | When the operation completes, `LMIC.osjob` is scheduled. 61 | 62 | ### `os_radio(RADIO_RX)` 63 | 64 | A single frame is received ad the specified time, and the radio is put back to sleep if no frame is found. 65 | 66 | When the operation completes, `LMIC.osjob` is scheduled. 67 | 68 | ### `os_radio(RADIO_RXON)` 69 | 70 | The radio is placed in continuous receive mode. If a frame is received, `LMIC.osjob` is scheduled. Continuous receive is canceled by calling [`os_radio(RADIO_RST)`](#os_radioradio_rst). 71 | 72 | This operation is not supported in FSK mode. 73 | 74 | ### `os_radio(RADIO_TX_AT)` 75 | 76 | This is like `os_radio(RADIO_TX)`, but the transmission is scheduled at `LMIC.txend`. 77 | 78 | ## Common parameters 79 | 80 | ### `LMIC.rps` (IN) 81 | 82 | This is the "radio parameter setting", and it encodes several radio settings. 83 | 84 | - Spreading factor: FSK or SF7..12 85 | - Bandwidth: 125, 250 or 500 kHz 86 | - Coding Rate: 4/5, 4/6, 4/7 or 4/8. 87 | - CRC enabled/disabled 88 | - Implicit header mode on/off. (If on, receive length must be known in advance.) 89 | 90 | ### `LMIC.freq` (IN) 91 | 92 | This specifies the frequency, in Hertz. 93 | 94 | ### `LMIC.saveIrqFlags` (OUT) 95 | 96 | Updated for LoRa operations only; the IRQ flags at the time of interrupt. 97 | 98 | ### `LMIC.osjob` (IN/OUT) 99 | 100 | When asynchronous operations complete, `LMIC.osjob.func` is used as the callback function, and `LMIC.osjob` is used to schedule the work. 101 | 102 | ## Transmit parameters 103 | 104 | ### `LMIC.radio_txpow` (IN) 105 | 106 | This specifies the transmit power in dBm. 107 | 108 | ### `LMIC.frame[]` (IN) 109 | 110 | The array of data to be sent. 111 | 112 | ### `LMIC.datalen` (IN) 113 | 114 | The length of the array to be sent. 115 | 116 | ### `LMIC.txend` (IN, OUT) 117 | 118 | For `RADIO_TX_AT`, an input parameter, for the scheduled TX time. 119 | 120 | For all transmissions, updated to the OS time at which the TX end interrupt was recognized. 121 | 122 | ## Receive parameters 123 | 124 | ### `LMIC.frame[]` (OUT) 125 | 126 | Filled with data received. 127 | 128 | ### `LMIC.datalen` (OUT) 129 | 130 | Set to number of bytes received in total. 131 | 132 | ### `LMIC.rxtime` (IN/OUT) 133 | 134 | Input: When to start receiving, in OS tick time. 135 | 136 | Output: time of RXDONE interrupt. (Note: FSK timeout doesn't currently set this cell on RX timeout.) 137 | 138 | ### `LMIC.lbt_ticks` (IN) 139 | 140 | How long to monitor for LBT, in OS ticks. 141 | 142 | ### `LMIC.lbt_dbmax` (IN) 143 | 144 | Maximum RSSI on channel before transmit. 145 | 146 | ### `LMIC.rxsyms` (IN) 147 | 148 | The timeout in symbols. Only used for `os_radio(RADIO_RX)`; not used for continuous receive. 149 | 150 | ### `LMIC.noRXIQinversion` (IN) 151 | 152 | If true, disable IQ inversion during receive. 153 | 154 | ### `LMIC.snr` (OUT) 155 | 156 | Set to SNR * 4 after LoRa receive. (Set to 0 for FSK receive.) 157 | 158 | ### `LMIC.rssi` (OUT) 159 | 160 | Set to RSSI + `RSSI_OFF` after LoRa receive. (Set to 0 for FSK receive; `RSSI_OFF` is 64.) You must subtract RSSI_OFF from `LMIC.rssi` to get the RSSI in dB. 161 | -------------------------------------------------------------------------------- /examples/compliance-otaa-halconfig/extra/ci/lmic-filter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################## 4 | # 5 | # Module: compliance-otaa-halconfig/extra/ci/lmic-filter.sh 6 | # 7 | # Function: 8 | # This script must be sourced; it sets variables used by other 9 | # scripts in this directory. 10 | # 11 | # Usage: 12 | # source ci/lmic-filter.sh 13 | # 14 | # Copyright and License: 15 | # See accompanying LICENSE.md file 16 | # 17 | # Author: 18 | # Terry Moore, MCCI February 2021 19 | # 20 | ############################################################################## 21 | 22 | #### use the common code. 23 | # shellcheck source=../../../../ci/lmic-filter-common.sh 24 | source "$(dirname "$MCCI_CI_FILTER_NAME")"/../../../../ci/lmic-filter-common.sh 25 | 26 | #### end of file #### 27 | -------------------------------------------------------------------------------- /examples/header_test/header_test.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: header_test.ino 4 | 5 | Function: 6 | Simple hello-world (and compile-test) app 7 | 8 | Copyright notice and License: 9 | See LICENSE file accompanying this project. 10 | 11 | Author: 12 | Terry Moore, MCCI Corporation April 2018 13 | 14 | */ 15 | 16 | #include 17 | 18 | # define STATIC_ASSERT(e) \ 19 | void STATIC_ASSERT__(int MCCIADK_C_ASSERT_x[(e) ? 1: -1]) 20 | 21 | STATIC_ASSERT(ARDUINO_LMIC_VERSION >= ARDUINO_LMIC_VERSION_CALC(2,1,5,0)); 22 | 23 | STATIC_ASSERT(ARDUINO_LMIC_VERSION_CALC(1,2,3,4) == 0x01020304); 24 | 25 | STATIC_ASSERT(ARDUINO_LMIC_VERSION_GET_MAJOR(ARDUINO_LMIC_VERSION_CALC(1,2,3,4)) == 1); 26 | STATIC_ASSERT(ARDUINO_LMIC_VERSION_GET_MINOR(ARDUINO_LMIC_VERSION_CALC(1,2,3,4)) == 2); 27 | STATIC_ASSERT(ARDUINO_LMIC_VERSION_GET_PATCH(ARDUINO_LMIC_VERSION_CALC(1,2,3,4)) == 3); 28 | STATIC_ASSERT(ARDUINO_LMIC_VERSION_GET_LOCAL(ARDUINO_LMIC_VERSION_CALC(1,2,3,4)) == 4); 29 | 30 | void setup() 31 | { 32 | } 33 | 34 | void loop() 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /examples/raw-feather/extra/ci/lmic-filter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################## 4 | # 5 | # Module: compliance-otaa-halconfig/extra/ci/lmic-filter.sh 6 | # 7 | # Function: 8 | # This script must be sourced; it sets variables used by other 9 | # scripts in this directory. 10 | # 11 | # Usage: 12 | # source ci/lmic-filter.sh 13 | # 14 | # Copyright and License: 15 | # See accompanying LICENSE.md file 16 | # 17 | # Author: 18 | # Terry Moore, MCCI February 2021 19 | # 20 | ############################################################################## 21 | 22 | #### use the common code. 23 | # shellcheck source=../../../../ci/lmic-filter-common.sh 24 | source "$(dirname "$MCCI_CI_FILTER_NAME")"/../../../../ci/lmic-filter-common.sh 25 | 26 | #### end of file #### 27 | -------------------------------------------------------------------------------- /examples/ttn-abp-feather-us915-dht22/extra/ci/lmic-filter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################## 4 | # 5 | # Module: ttn-abp-feather-us915-dht22/extra/ci/lmic-filter.sh 6 | # 7 | # Function: 8 | # This script must be sourced; it sets variables used by other 9 | # scripts in this directory. 10 | # 11 | # Usage: 12 | # source ci/lmic-filter.sh 13 | # 14 | # Copyright and License: 15 | # See accompanying LICENSE.md file 16 | # 17 | # Author: 18 | # Terry Moore, MCCI February 2021 19 | # 20 | ############################################################################## 21 | 22 | #### use the common code. 23 | # shellcheck source=../../../../ci/lmic-filter-common.sh 24 | source "$(dirname "$MCCI_CI_FILTER_NAME")"/../../../../ci/lmic-filter-common.sh 25 | 26 | #### end of file #### 27 | -------------------------------------------------------------------------------- /examples/ttn-otaa-feather-us915-dht22/extra/ci/lmic-filter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################## 4 | # 5 | # Module: ttn-otaa-feather-us915-dht22/extra/ci/lmic-filter.sh 6 | # 7 | # Function: 8 | # This script must be sourced; it sets variables used by other 9 | # scripts in this directory. 10 | # 11 | # Usage: 12 | # source ci/lmic-filter.sh 13 | # 14 | # Copyright and License: 15 | # See accompanying LICENSE.md file 16 | # 17 | # Author: 18 | # Terry Moore, MCCI February 2021 19 | # 20 | ############################################################################## 21 | 22 | #### use the common code. 23 | # shellcheck source=../../../../ci/lmic-filter-common.sh 24 | source "$(dirname "$MCCI_CI_FILTER_NAME")"/../../../../ci/lmic-filter-common.sh 25 | 26 | #### end of file #### 27 | -------------------------------------------------------------------------------- /examples/ttn-otaa-feather-us915/extra/ci/lmic-filter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################## 4 | # 5 | # Module: ttn-otaa-feather-us915/extra/ci/lmic-filter.sh 6 | # 7 | # Function: 8 | # This script must be sourced; it sets variables used by other 9 | # scripts in this directory. 10 | # 11 | # Usage: 12 | # source ci/lmic-filter.sh 13 | # 14 | # Copyright and License: 15 | # See accompanying LICENSE.md file 16 | # 17 | # Author: 18 | # Terry Moore, MCCI February 2021 19 | # 20 | ############################################################################## 21 | 22 | #### use the common code. 23 | # shellcheck source=../../../../ci/lmic-filter-common.sh 24 | source "$(dirname "$MCCI_CI_FILTER_NAME")"/../../../../ci/lmic-filter-common.sh 25 | 26 | #### end of file #### 27 | -------------------------------------------------------------------------------- /examples/ttn-otaa-network-time/extra/ci/lmic-filter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################## 4 | # 5 | # Module: ttn-otaa-network-time/extra/ci/lmic-filter.sh 6 | # 7 | # Function: 8 | # This script must be sourced; it sets variables used by other 9 | # scripts in this directory. 10 | # 11 | # Usage: 12 | # source ci/lmic-filter.sh 13 | # 14 | # Copyright and License: 15 | # See accompanying LICENSE.md file 16 | # 17 | # Author: 18 | # Terry Moore, MCCI February 2021 19 | # 20 | ############################################################################## 21 | 22 | #### use the common code. 23 | # shellcheck source=../../../../ci/lmic-filter-common.sh 24 | source "$(dirname "$MCCI_CI_FILTER_NAME")"/../../../../ci/lmic-filter-common.sh 25 | 26 | #### end of file #### 27 | -------------------------------------------------------------------------------- /examples/ttn-otaa/ttn-otaa.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 3 | * Copyright (c) 2018 Terry Moore, MCCI 4 | * 5 | * Permission is hereby granted, free of charge, to anyone 6 | * obtaining a copy of this document and accompanying files, 7 | * to do whatever they want with them without any restriction, 8 | * including, but not limited to, copying, modification and redistribution. 9 | * NO WARRANTY OF ANY KIND IS PROVIDED. 10 | * 11 | * This example sends a valid LoRaWAN packet with payload "Hello, 12 | * world!", using frequency and encryption settings matching those of 13 | * the The Things Network. 14 | * 15 | * This uses OTAA (Over-the-air activation), where where a DevEUI and 16 | * application key is configured, which are used in an over-the-air 17 | * activation procedure where a DevAddr and session keys are 18 | * assigned/generated for use with all further communication. 19 | * 20 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 21 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 22 | * violated by this sketch when left running for longer)! 23 | 24 | * To use this sketch, first register your application and device with 25 | * the things network, to set or generate an AppEUI, DevEUI and AppKey. 26 | * Multiple devices can use the same AppEUI, but each device has its own 27 | * DevEUI and AppKey. 28 | * 29 | * Do not forget to define the radio type correctly in 30 | * arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt. 31 | * 32 | *******************************************************************************/ 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | // 39 | // For normal use, we require that you edit the sketch to replace FILLMEIN 40 | // with values assigned by the TTN console. However, for regression tests, 41 | // we want to be able to compile these scripts. The regression tests define 42 | // COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- 43 | // working but innocuous value. 44 | // 45 | #ifdef COMPILE_REGRESSION_TEST 46 | # define FILLMEIN 0 47 | #else 48 | # warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!" 49 | # define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN) 50 | #endif 51 | 52 | // This EUI must be in little-endian format, so least-significant-byte 53 | // first. When copying an EUI from ttnctl output, this means to reverse 54 | // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 55 | // 0x70. 56 | static const u1_t PROGMEM APPEUI[8]={ FILLMEIN }; 57 | void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} 58 | 59 | // This should also be in little endian format, see above. 60 | static const u1_t PROGMEM DEVEUI[8]={ FILLMEIN }; 61 | void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} 62 | 63 | // This key should be in big endian format (or, since it is not really a 64 | // number but a block of memory, endianness does not really apply). In 65 | // practice, a key taken from ttnctl can be copied as-is. 66 | static const u1_t PROGMEM APPKEY[16] = { FILLMEIN }; 67 | void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} 68 | 69 | static uint8_t mydata[] = "Hello, world!"; 70 | static osjob_t sendjob; 71 | 72 | // Schedule TX every this many seconds (might become longer due to duty 73 | // cycle limitations). 74 | const unsigned TX_INTERVAL = 60; 75 | 76 | // Pin mapping 77 | const lmic_pinmap lmic_pins = { 78 | .nss = 6, 79 | .rxtx = LMIC_UNUSED_PIN, 80 | .rst = 5, 81 | .dio = {2, 3, 4}, 82 | }; 83 | 84 | void printHex2(unsigned v) { 85 | v &= 0xff; 86 | if (v < 16) 87 | Serial.print('0'); 88 | Serial.print(v, HEX); 89 | } 90 | 91 | void onEvent (ev_t ev) { 92 | Serial.print(os_getTime()); 93 | Serial.print(": "); 94 | switch(ev) { 95 | case EV_SCAN_TIMEOUT: 96 | Serial.println(F("EV_SCAN_TIMEOUT")); 97 | break; 98 | case EV_BEACON_FOUND: 99 | Serial.println(F("EV_BEACON_FOUND")); 100 | break; 101 | case EV_BEACON_MISSED: 102 | Serial.println(F("EV_BEACON_MISSED")); 103 | break; 104 | case EV_BEACON_TRACKED: 105 | Serial.println(F("EV_BEACON_TRACKED")); 106 | break; 107 | case EV_JOINING: 108 | Serial.println(F("EV_JOINING")); 109 | break; 110 | case EV_JOINED: 111 | Serial.println(F("EV_JOINED")); 112 | { 113 | u4_t netid = 0; 114 | devaddr_t devaddr = 0; 115 | u1_t nwkKey[16]; 116 | u1_t artKey[16]; 117 | LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); 118 | Serial.print("netid: "); 119 | Serial.println(netid, DEC); 120 | Serial.print("devaddr: "); 121 | Serial.println(devaddr, HEX); 122 | Serial.print("AppSKey: "); 123 | for (size_t i=0; i 5 | sentence=Arduino port of the LMIC (LoraWAN-MAC-in-C) framework provided by IBM. 6 | paragraph=Supports LoRaWAN 1.0.2/1.0.3 Class A devices implemented using the Semtech SX1272/SX1276/SX1261/SX1262 (including HopeRF RFM92/RFM95 and Murata modules). Support for EU868, US, AU, AS923, KR and IN regional plans. Untested support for Class B and FSK operation. Various enhancements and bug fixes from MCCI and The Things Network New York. Original IBM URL http://www.research.ibm.com/labs/zurich/ics/lrsc/lmic.html. 7 | category=Communication 8 | url=https://github.com/mcci-catena/arduino-lmic 9 | architectures=* 10 | -------------------------------------------------------------------------------- /project_config/lmic_project_config.h: -------------------------------------------------------------------------------- 1 | // project-specific definitions 2 | //#define CFG_eu868 1 3 | #define CFG_us915 1 4 | //#define CFG_au915 1 5 | //#define CFG_as923 1 6 | // #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP /* for as923-JP; also define CFG_as923 */ 7 | //#define CFG_kr920 1 8 | //#define CFG_in866 1 9 | #define CFG_sx1276_radio 1 10 | //#define CFG_sx1261_radio 1 11 | //#define CFG_sx1262_radio 1 12 | //#define ARDUINO_heltec_wifi_lora_32_V3 13 | //#define LMIC_USE_INTERRUPTS -------------------------------------------------------------------------------- /src/aes/other.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2016 Matthijs Kooijman 3 | * 4 | * LICENSE 5 | * 6 | * Permission is hereby granted, free of charge, to anyone 7 | * obtaining a copy of this document and accompanying files, 8 | * to do whatever they want with them without any restriction, 9 | * including, but not limited to, copying, modification and 10 | * redistribution. 11 | * 12 | * NO WARRANTY OF ANY KIND IS PROVIDED. 13 | *******************************************************************************/ 14 | 15 | /* 16 | * The original LMIC AES implementation integrates raw AES encryption 17 | * with CMAC and AES-CTR in a single piece of code. Most other AES 18 | * implementations (only) offer raw single block AES encryption, so this 19 | * file contains an implementation of CMAC and AES-CTR, and offers the 20 | * same API through the os_aes() function as the original AES 21 | * implementation. This file assumes that there is an encryption 22 | * function available with this signature: 23 | * 24 | * extern "C" void lmic_aes_encrypt(u1_t *data, u1_t *key); 25 | * 26 | * That takes a single 16-byte buffer and encrypts it wit the given 27 | * 16-byte key. 28 | */ 29 | 30 | #include "../lmic/oslmic.h" 31 | 32 | #if !defined(USE_ORIGINAL_AES) 33 | 34 | // This should be defined elsewhere 35 | void lmic_aes_encrypt(u1_t *data, u1_t *key); 36 | 37 | // global area for passing parameters (aux, key) 38 | u4_t AESAUX[16/sizeof(u4_t)]; 39 | u4_t AESKEY[16/sizeof(u4_t)]; 40 | 41 | // Shift the given buffer left one bit 42 | static void shift_left(xref2u1_t buf, u1_t len) { 43 | while (len--) { 44 | u1_t next = len ? buf[1] : 0; 45 | 46 | u1_t val = (*buf << 1); 47 | if (next & 0x80) 48 | val |= 1; 49 | *buf++ = val; 50 | } 51 | } 52 | 53 | // Apply RFC4493 CMAC, using AESKEY as the key. If prepend_aux is true, 54 | // AESAUX is prepended to the message. AESAUX is used as working memory 55 | // in any case. The CMAC result is returned in AESAUX as well. 56 | static void os_aes_cmac(xref2u1_t buf, u2_t len, u1_t prepend_aux) { 57 | if (prepend_aux) 58 | lmic_aes_encrypt(AESaux, AESkey); 59 | else 60 | memset (AESaux, 0, 16); 61 | 62 | while (len > 0) { 63 | u1_t need_padding = 0; 64 | for (u1_t i = 0; i < 16; ++i, ++buf, --len) { 65 | if (len == 0) { 66 | // The message is padded with 0x80 and then zeroes. 67 | // Since zeroes are no-op for xor, we can just skip them 68 | // and leave AESAUX unchanged for them. 69 | AESaux[i] ^= 0x80; 70 | need_padding = 1; 71 | break; 72 | } 73 | AESaux[i] ^= *buf; 74 | } 75 | 76 | if (len == 0) { 77 | // Final block, xor with K1 or K2. K1 and K2 are calculated 78 | // by encrypting the all-zeroes block and then applying some 79 | // shifts and xor on that. 80 | u1_t final_key[16]; 81 | memset(final_key, 0, sizeof(final_key)); 82 | lmic_aes_encrypt(final_key, AESkey); 83 | 84 | // Calculate K1 85 | u1_t msb = final_key[0] & 0x80; 86 | shift_left(final_key, sizeof(final_key)); 87 | if (msb) 88 | final_key[sizeof(final_key)-1] ^= 0x87; 89 | 90 | // If the final block was not complete, calculate K2 from K1 91 | if (need_padding) { 92 | msb = final_key[0] & 0x80; 93 | shift_left(final_key, sizeof(final_key)); 94 | if (msb) 95 | final_key[sizeof(final_key)-1] ^= 0x87; 96 | } 97 | 98 | // Xor with K1 or K2 99 | for (u1_t i = 0; i < sizeof(final_key); ++i) 100 | AESaux[i] ^= final_key[i]; 101 | } 102 | 103 | lmic_aes_encrypt(AESaux, AESkey); 104 | } 105 | } 106 | 107 | // Run AES-CTR using the key in AESKEY and using AESAUX as the 108 | // counter block. The last byte of the counter block will be incremented 109 | // for every block. The given buffer will be encrypted in place. 110 | static void os_aes_ctr (xref2u1_t buf, u2_t len) { 111 | u1_t ctr[16]; 112 | while (len) { 113 | // Encrypt the counter block with the selected key 114 | memcpy(ctr, AESaux, sizeof(ctr)); 115 | lmic_aes_encrypt(ctr, AESkey); 116 | 117 | // Xor the payload with the resulting ciphertext 118 | for (u1_t i = 0; i < 16 && len > 0; i++, len--, buf++) 119 | *buf ^= ctr[i]; 120 | 121 | // Increment the block index byte 122 | AESaux[15]++; 123 | } 124 | } 125 | 126 | u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) { 127 | switch (mode & ~AES_MICNOAUX) { 128 | case AES_MIC: 129 | os_aes_cmac(buf, len, /* prepend_aux */ !(mode & AES_MICNOAUX)); 130 | return os_rmsbf4(AESaux); 131 | 132 | case AES_ENC: 133 | // TODO: Check / handle when len is not a multiple of 16 134 | for (u1_t i = 0; i < len; i += 16) 135 | lmic_aes_encrypt(buf+i, AESkey); 136 | break; 137 | 138 | case AES_CTR: 139 | os_aes_ctr(buf, len); 140 | break; 141 | } 142 | return 0; 143 | } 144 | 145 | #endif // !defined(USE_ORIGINAL_AES) 146 | -------------------------------------------------------------------------------- /src/arduino_lmic.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: arduino_lmic.h 4 | 5 | Function: 6 | Arduino-LMIC C++ top-level include file 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Matthijs Kooijman 2015 13 | Terry Moore, MCCI November 2018 14 | 15 | */ 16 | 17 | #pragma once 18 | 19 | #ifndef _ARDUINO_LMIC_H_ 20 | # define _ARDUINO_LMIC_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | #include "lmic/lmic.h" 27 | #include "lmic/lmic_bandplan.h" 28 | #include "lmic/lmic_util.h" 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /* _ARDUINO_LMIC_H_ */ 35 | -------------------------------------------------------------------------------- /src/arduino_lmic_hal_boards.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: arduino_lmic_hal_boards.h 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #ifndef _arduino_lmic_hal_boards_h_ 19 | # define _arduino_lmic_hal_boards_h_ 20 | 21 | #include "arduino_lmic_hal_configuration.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | const HalPinmap_t *GetPinmap_FeatherM0LoRa(); 26 | const HalPinmap_t *GetPinmap_Feather32U4LoRa(); 27 | 28 | const HalPinmap_t *GetPinmap_Catena4420(); 29 | const HalPinmap_t *GetPinmap_Catena4551(); 30 | const HalPinmap_t *GetPinmap_Catena4610(); 31 | const HalPinmap_t *GetPinmap_Catena4610(); 32 | const HalPinmap_t *GetPinmap_Catena4611(); 33 | const HalPinmap_t *GetPinmap_Catena4612(); 34 | const HalPinmap_t *GetPinmap_Catena4617(); 35 | const HalPinmap_t *GetPinmap_Catena4618(); 36 | const HalPinmap_t *GetPinmap_Catena4630(); 37 | const HalPinmap_t *GetPinmap_Catena4801(); 38 | const HalPinmap_t *GetPinmap_Catena4802(); 39 | const HalPinmap_t* GetPinmap_ttgo_lora32_v1(); 40 | const HalPinmap_t *GetPinmap_ttgo_lora32_v21(); 41 | const HalPinmap_t* GetPinmap_heltec_lora32(); 42 | const HalPinmap_t* GetPinmap_heltec_lora32_v3(); 43 | const HalPinmap_t* GetPinmap_Disco_L072cz_Lrwan1(); 44 | const HalPinmap_t* GetPinmap_ttgo_tbeam_s3(); 45 | 46 | const HalPinmap_t *GetPinmap_ThisBoard(); 47 | 48 | }; /* namespace Arduino_LIMC */ 49 | 50 | #endif /* _arduino_lmic_hal_boards_h_ */ 51 | -------------------------------------------------------------------------------- /src/arduino_lmic_hal_configuration.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: arduino_lmic_hal_configuration.h 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL configuration APIs 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Matthijs Kooijman 2015 13 | Terry Moore, MCCI November 2018 14 | 15 | */ 16 | #pragma once 17 | 18 | #ifndef _arduino_lmic_hal_configuration_h_ 19 | # define _arduino_lmic_hal_configuration_h_ 20 | 21 | #include 22 | #include "lmic/lmic_env.h" 23 | 24 | namespace Arduino_LMIC { 25 | 26 | /* these types should match the types used by the LMIC */ 27 | typedef int32_t ostime_t; 28 | 29 | // this type is used when we need to represent a threee-state signal 30 | enum class ThreeState_t : uint8_t { 31 | Off = 0, 32 | On = 1, 33 | HiZ = 2 34 | }; 35 | 36 | // forward reference 37 | class HalConfiguration_t; 38 | 39 | // 40 | // for legacy reasons, we need a plain-old-data C-like 41 | // structure that defines the "pin mapping" for the 42 | // common pins. Many clients initialize an instance of 43 | // this structure using named-field initialization. 44 | // 45 | // Be careful of alignment below. 46 | struct HalPinmap_t { 47 | // Use this for any unused pins. 48 | static constexpr uint8_t UNUSED_PIN = 0xff; 49 | static constexpr int NUM_DIO = 3; 50 | // for backward compatibility... 51 | static constexpr uint8_t LMIC_UNUSED_PIN = UNUSED_PIN; 52 | 53 | /* the contents */ 54 | uint8_t nss; // byte 0: pin for select 55 | uint8_t rxtx; // byte 1: pin for rx/tx control 56 | uint8_t rst; // byte 2: pin for reset 57 | uint8_t dio[NUM_DIO]; // bytes 3..5: pins for DIO0, DOI1, DIO2 58 | // true if we must set rxtx for rx_active, false for tx_active 59 | uint8_t rxtx_rx_active; // byte 6: polarity of rxtx active 60 | int8_t rssi_cal; // byte 7: cal in dB -- added to RSSI 61 | // measured prior to decision. 62 | // Must include noise guardband! 63 | uint32_t spi_freq; // bytes 8..11: SPI freq in Hz. 64 | 65 | // optional pointer to configuration object (bytes 12..15) 66 | HalConfiguration_t *pConfig; 67 | }; 68 | 69 | class HalConfiguration_t 70 | { 71 | public: 72 | HalConfiguration_t() {}; 73 | 74 | // these must match the constants in radio.c 75 | enum class TxPowerPolicy_t : uint8_t 76 | { 77 | RFO, 78 | PA_BOOST, 79 | PA_BOOST_20dBm 80 | }; 81 | 82 | virtual ostime_t setModuleActive(bool state) { 83 | LMIC_API_PARAMETER(state); 84 | 85 | // by default, if not overridden, do nothing 86 | // and return 0 to indicate that the caller 87 | // need not delay. 88 | return 0; 89 | } 90 | 91 | virtual void begin(void) {} 92 | virtual void end(void) {} 93 | virtual uint8_t queryBusyPin(void) { return HalPinmap_t::LMIC_UNUSED_PIN; } 94 | virtual bool queryUsingTcxo(void) { return false; } 95 | virtual bool queryUsingDcdc(void) { return false; } 96 | virtual bool queryUsingDIO2AsRfSwitch(void) { return false; } 97 | virtual bool queryUsingDIO3AsTCXOSwitch(void) { return false; } 98 | 99 | // compute desired transmit power policy. HopeRF needs 100 | // (and previous versions of this library always chose) 101 | // PA_BOOST mode. So that's our default. Override this 102 | // for the Murata module. 103 | virtual TxPowerPolicy_t getTxPowerPolicy( 104 | TxPowerPolicy_t policy, 105 | int8_t requestedPower, 106 | uint32_t frequency 107 | ) 108 | { 109 | LMIC_API_PARAMETER(policy); 110 | LMIC_API_PARAMETER(requestedPower); 111 | LMIC_API_PARAMETER(frequency); 112 | // default: use PA_BOOST exclusively 113 | return TxPowerPolicy_t::PA_BOOST; 114 | } 115 | }; 116 | 117 | bool lmic_hal_init_with_pinmap(const HalPinmap_t *pPinmap); 118 | 119 | }; // end namespace Arduino_LMIC 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /src/arduino_lmic_lorawan_compliance.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: arduino_lmic_lorawan_compliance.h 4 | 5 | Function: 6 | Arduino-LMIC C++ include file for LoRaWAN compliance 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI March 2019 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #ifndef _ARDUINO_LMIC_LORAWAN_COMPLIANCE_H_ 19 | # define _ARDUINO_LMIC_LORAWAN_COMPLIANCE_H_ 20 | 21 | #ifdef __cplusplus 22 | extern "C"{ 23 | #endif 24 | 25 | #include "lmic/lorawan_spec_compliance.h" 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* _ARDUINO_LMIC_LORAWAN_COMPLIANCE_H_ */ 32 | -------------------------------------------------------------------------------- /src/arduino_lmic_user_configuration.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: arduino_lmic_user_configuration.h 4 | 5 | Function: 6 | Get the Arduino-LMIC configuration into scope 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | #pragma once 16 | 17 | #ifndef _arduino_lmic_user_configuration_h_ 18 | # define _arduino_lmic_user_configuration_h_ 19 | 20 | # ifdef __cplusplus 21 | extern "C" { 22 | # endif 23 | 24 | # include "lmic/lmic_config_preconditions.h" 25 | 26 | # ifdef __cplusplus 27 | } 28 | # endif 29 | 30 | #endif /* _arduino_lmic_user_configuration_h_ */ 31 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4420.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4420.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for MCCI Catena 4420 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4420) || \ 17 | /* legacy names */ \ 18 | defined(ARDUINO_CATENA_4420) 19 | 20 | #include 21 | #include 22 | 23 | #include "../lmic/oslmic.h" 24 | 25 | namespace Arduino_LMIC { 26 | 27 | class HalConfiguration_Catena4420_t : public HalConfiguration_t 28 | { 29 | public: 30 | enum DIGITAL_PINS : uint8_t 31 | { 32 | PIN_SX1276_NSS = 6, 33 | PIN_SX1276_NRESET = 5, 34 | PIN_SX1276_DIO0 = 12, // pin assignment for DIO0 (aka IRQ) 35 | PIN_SX1276_DIO1 = 11, 36 | PIN_SX1276_DIO2 = 10, 37 | PIN_SX1276_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 38 | PIN_SX1276_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 39 | PIN_SX1276_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 40 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 41 | }; 42 | 43 | virtual void begin(void) override 44 | { 45 | digitalWrite(PIN_SX1276_NSS, 1); 46 | pinMode(PIN_SX1276_NSS, OUTPUT); 47 | } 48 | 49 | // virtual void end(void) override 50 | 51 | // virtual ostime_t setModuleActive(bool state) override 52 | 53 | }; 54 | 55 | static HalConfiguration_Catena4420_t myConfig; 56 | 57 | static const HalPinmap_t myPinmap = 58 | { 59 | .nss = HalConfiguration_Catena4420_t::PIN_SX1276_NSS, // chip select is D7 60 | .rxtx = HalConfiguration_Catena4420_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 61 | .rst = HalConfiguration_Catena4420_t::PIN_SX1276_NRESET, // NRESET is D8 62 | 63 | .dio = {HalConfiguration_Catena4420_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 64 | HalConfiguration_Catena4420_t::PIN_SX1276_DIO1, // DIO1 is D26 65 | HalConfiguration_Catena4420_t::PIN_SX1276_DIO2, // DIO2 is D27 66 | }, 67 | .rxtx_rx_active = 0, 68 | .rssi_cal = 10, 69 | .spi_freq = 8000000, /* 8MHz */ 70 | .pConfig = &myConfig 71 | }; 72 | 73 | const HalPinmap_t *GetPinmap_Catena4420(void) 74 | { 75 | return &myPinmap; 76 | } 77 | 78 | } // namespace Arduino_LMIC 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4551.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4551.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4551) || \ 17 | /* legacy names */ \ 18 | defined(ARDUINO_CATENA_4551) 19 | 20 | #include 21 | #include 22 | 23 | #include "../lmic/oslmic.h" 24 | 25 | namespace Arduino_LMIC { 26 | 27 | class HalConfiguration_Catena4551_t : public HalConfiguration_t 28 | { 29 | public: 30 | enum DIGITAL_PINS : uint8_t 31 | { 32 | PIN_SX1276_NSS = D7, 33 | PIN_SX1276_NRESET = D8, 34 | PIN_SX1276_DIO0 = D25, 35 | PIN_SX1276_DIO1 = D26, 36 | PIN_SX1276_DIO2 = D27, 37 | PIN_SX1276_ANT_SWITCH_RX = D29, 38 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 39 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 40 | PIN_VDD_BOOST_ENABLE = A0, 41 | PIN_TCXO_VDD = D33, 42 | }; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_SX1276_NSS, 1); 47 | pinMode(PIN_SX1276_NSS, OUTPUT); 48 | } 49 | 50 | // virtual void end(void) override 51 | 52 | // On the 4551, we can't control the TCXO; it's always on. 53 | // So we use the default. 54 | // virtual ostime_t setModuleActive(bool state) override 55 | virtual bool queryUsingTcxo(void) override { return true; }; 56 | }; 57 | 58 | // save some typing by bringing the pin numbers into scope 59 | static HalConfiguration_Catena4551_t myConfig; 60 | 61 | static const HalPinmap_t myPinmap = 62 | { 63 | .nss = HalConfiguration_Catena4551_t::PIN_SX1276_NSS, // chip select is D7 64 | .rxtx = HalConfiguration_Catena4551_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 65 | .rst = HalConfiguration_Catena4551_t::PIN_SX1276_NRESET, // NRESET is D8 66 | 67 | .dio = {HalConfiguration_Catena4551_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 68 | HalConfiguration_Catena4551_t::PIN_SX1276_DIO1, // DIO1 is D26 69 | HalConfiguration_Catena4551_t::PIN_SX1276_DIO2, // DIO2 is D27 70 | }, 71 | .rxtx_rx_active = 1, 72 | .rssi_cal = 10, 73 | .spi_freq = 8000000, /* 8MHz */ 74 | .pConfig = &myConfig, 75 | }; 76 | 77 | const HalPinmap_t *GetPinmap_Catena4551(void) 78 | { 79 | return &myPinmap; 80 | } 81 | 82 | }; // namespace Arduino_LMIC 83 | 84 | #endif /* defined(ARDUINO_MCCI_CATENA_4551) */ 85 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4610.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4610.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for the Catena 4610 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4610) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | class HalConfiguration_Catena4610_t : public HalConfiguration_t 26 | { 27 | public: 28 | enum DIGITAL_PINS : uint8_t 29 | { 30 | PIN_SX1276_NSS = D7, 31 | PIN_SX1276_NRESET = D8, 32 | PIN_SX1276_DIO0 = D25, 33 | PIN_SX1276_DIO1 = D26, 34 | PIN_SX1276_DIO2 = D27, 35 | PIN_SX1276_ANT_SWITCH_RX = D29, 36 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 37 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 38 | PIN_VDD_BOOST_ENABLE = A0, 39 | PIN_TCXO_VDD = D33, 40 | }; 41 | 42 | static constexpr ostime_t TCXO_DELAY_MS = 5; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_TCXO_VDD, 0); 47 | pinMode(PIN_TCXO_VDD, OUTPUT); 48 | } 49 | 50 | virtual void end(void) override 51 | { 52 | digitalWrite(PIN_TCXO_VDD, 0); 53 | pinMode(PIN_TCXO_VDD, INPUT); 54 | } 55 | 56 | virtual bool queryUsingTcxo(void) override { return true; }; 57 | 58 | virtual ostime_t setModuleActive(bool state) override 59 | { 60 | ostime_t result; 61 | const int oldState = digitalRead(PIN_TCXO_VDD); 62 | 63 | // if turning on, we need to delay. 64 | result = 0; 65 | if (state && ! oldState) 66 | result = ms2osticksCeil(TCXO_DELAY_MS); 67 | 68 | if (state != oldState) 69 | digitalWrite(PIN_TCXO_VDD, state); 70 | 71 | return result; 72 | } 73 | }; 74 | 75 | // save some typing by bringing the pin numbers into scope 76 | static HalConfiguration_Catena4610_t myConfig; 77 | 78 | static const HalPinmap_t myPinmap = 79 | { 80 | .nss = HalConfiguration_Catena4610_t::PIN_SX1276_NSS, // chip select is D7 81 | .rxtx = HalConfiguration_Catena4610_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 82 | .rst = HalConfiguration_Catena4610_t::PIN_SX1276_NRESET, // NRESET is D8 83 | 84 | .dio = {HalConfiguration_Catena4610_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 85 | HalConfiguration_Catena4610_t::PIN_SX1276_DIO1, // DIO1 is D26 86 | HalConfiguration_Catena4610_t::PIN_SX1276_DIO2, // DIO2 is D27 87 | }, 88 | .rxtx_rx_active = 1, 89 | .rssi_cal = 10, 90 | .spi_freq = 8000000, /* 8MHz */ 91 | .pConfig = &myConfig 92 | }; 93 | 94 | const HalPinmap_t *GetPinmap_Catena4610(void) 95 | { 96 | return &myPinmap; 97 | } 98 | 99 | }; // namespace Arduino_LMIC 100 | 101 | #endif /* defined(ARDUINO_MCCI_CATENA_4610 */ 102 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4611.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4611.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4611) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | class HalConfiguration_Catena4611_t : public HalConfiguration_t 26 | { 27 | public: 28 | enum DIGITAL_PINS : uint8_t 29 | { 30 | PIN_SX1276_NSS = D7, 31 | PIN_SX1276_NRESET = D8, 32 | PIN_SX1276_DIO0 = D25, 33 | PIN_SX1276_DIO1 = D26, 34 | PIN_SX1276_DIO2 = D27, 35 | PIN_SX1276_ANT_SWITCH_RX = D29, 36 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 37 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 38 | PIN_VDD_BOOST_ENABLE = A0, 39 | PIN_TCXO_VDD = D33, 40 | }; 41 | 42 | static constexpr ostime_t TCXO_DELAY_MS = 5; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_TCXO_VDD, 0); 47 | pinMode(PIN_TCXO_VDD, OUTPUT); 48 | } 49 | 50 | virtual void end(void) override 51 | { 52 | digitalWrite(PIN_TCXO_VDD, 0); 53 | pinMode(PIN_TCXO_VDD, INPUT); 54 | } 55 | 56 | virtual bool queryUsingTcxo(void) override { return true; }; 57 | 58 | virtual ostime_t setModuleActive(bool state) override 59 | { 60 | ostime_t result; 61 | const int oldState = digitalRead(PIN_TCXO_VDD); 62 | 63 | // if turning on, we need to delay. 64 | result = 0; 65 | if (state && ! oldState) 66 | result = ms2osticksCeil(TCXO_DELAY_MS); 67 | 68 | if (state != oldState) 69 | digitalWrite(PIN_TCXO_VDD, state); 70 | 71 | return result; 72 | } 73 | }; 74 | 75 | // save some typing by bringing the pin numbers into scope 76 | static HalConfiguration_Catena4611_t myConfig; 77 | 78 | static const HalPinmap_t myPinmap = 79 | { 80 | .nss = HalConfiguration_Catena4611_t::PIN_SX1276_NSS, // chip select is D7 81 | .rxtx = HalConfiguration_Catena4611_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 82 | .rst = HalConfiguration_Catena4611_t::PIN_SX1276_NRESET, // NRESET is D8 83 | 84 | .dio = {HalConfiguration_Catena4611_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 85 | HalConfiguration_Catena4611_t::PIN_SX1276_DIO1, // DIO1 is D26 86 | HalConfiguration_Catena4611_t::PIN_SX1276_DIO2, // DIO2 is D27 87 | }, 88 | .rxtx_rx_active = 1, 89 | .rssi_cal = 10, 90 | .spi_freq = 8000000, /* 8MHz */ 91 | .pConfig = &myConfig 92 | }; 93 | 94 | const HalPinmap_t *GetPinmap_Catena4611(void) 95 | { 96 | return &myPinmap; 97 | } 98 | 99 | }; // namespace Arduino_LMIC 100 | 101 | #endif /* defined(ARDUINO_MCCI_CATENA_4611) */ 102 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4612.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4612.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4612) || \ 17 | /* legacy name */ \ 18 | defined(ARDUINO_CATENA_4612) 19 | 20 | #include 21 | #include 22 | 23 | #include "../lmic/oslmic.h" 24 | 25 | namespace Arduino_LMIC { 26 | 27 | class HalConfiguration_Catena4612_t : public HalConfiguration_t 28 | { 29 | public: 30 | enum DIGITAL_PINS : uint8_t 31 | { 32 | PIN_SX1276_NSS = D7, 33 | PIN_SX1276_NRESET = D8, 34 | PIN_SX1276_DIO0 = D25, 35 | PIN_SX1276_DIO1 = D26, 36 | PIN_SX1276_DIO2 = D27, 37 | PIN_SX1276_ANT_SWITCH_RX = D29, 38 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 39 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 40 | PIN_VDD_BOOST_ENABLE = A0, 41 | PIN_TCXO_VDD = D33, 42 | }; 43 | 44 | static constexpr ostime_t TCXO_DELAY_MS = 5; 45 | 46 | virtual void begin(void) override 47 | { 48 | digitalWrite(PIN_TCXO_VDD, 0); 49 | pinMode(PIN_TCXO_VDD, OUTPUT); 50 | } 51 | 52 | virtual void end(void) override 53 | { 54 | digitalWrite(PIN_TCXO_VDD, 0); 55 | pinMode(PIN_TCXO_VDD, INPUT); 56 | } 57 | 58 | virtual bool queryUsingTcxo(void) override { return true; }; 59 | 60 | virtual ostime_t setModuleActive(bool state) override 61 | { 62 | ostime_t result; 63 | const int oldState = digitalRead(PIN_TCXO_VDD); 64 | 65 | // if turning on, we need to delay. 66 | result = 0; 67 | if (state && ! oldState) 68 | result = ms2osticksCeil(TCXO_DELAY_MS); 69 | 70 | if (state != oldState) 71 | digitalWrite(PIN_TCXO_VDD, state); 72 | 73 | return result; 74 | } 75 | }; 76 | 77 | // save some typing by bringing the pin numbers into scope 78 | static HalConfiguration_Catena4612_t myConfig; 79 | 80 | static const HalPinmap_t myPinmap = 81 | { 82 | .nss = HalConfiguration_Catena4612_t::PIN_SX1276_NSS, // chip select is D7 83 | .rxtx = HalConfiguration_Catena4612_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 84 | .rst = HalConfiguration_Catena4612_t::PIN_SX1276_NRESET, // NRESET is D8 85 | 86 | .dio = {HalConfiguration_Catena4612_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 87 | HalConfiguration_Catena4612_t::PIN_SX1276_DIO1, // DIO1 is D26 88 | HalConfiguration_Catena4612_t::PIN_SX1276_DIO2, // DIO2 is D27 89 | }, 90 | .rxtx_rx_active = 1, 91 | .rssi_cal = 10, 92 | .spi_freq = 8000000, /* 8MHz */ 93 | .pConfig = &myConfig 94 | }; 95 | 96 | const HalPinmap_t *GetPinmap_Catena4612(void) 97 | { 98 | return &myPinmap; 99 | } 100 | 101 | }; // namespace Arduino_LMIC 102 | 103 | #endif /* defined(ARDUINO_MCCI_CATENA_4612) || defined(ARDUINO_CATENA_4612) */ 104 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4617.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4617.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Lakshmi Priya Natarajan, MCCI June 2019 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4617) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | class HalConfiguration_Catena4617_t : public HalConfiguration_t 26 | { 27 | public: 28 | enum DIGITAL_PINS : uint8_t 29 | { 30 | PIN_SX1276_NSS = D7, 31 | PIN_SX1276_NRESET = D8, 32 | PIN_SX1276_DIO0 = D25, 33 | PIN_SX1276_DIO1 = D26, 34 | PIN_SX1276_DIO2 = D27, 35 | PIN_SX1276_ANT_SWITCH_RX = D29, 36 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 37 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 38 | PIN_VDD_BOOST_ENABLE = A0, 39 | PIN_TCXO_VDD = D33, 40 | }; 41 | 42 | static constexpr ostime_t TCXO_DELAY_MS = 5; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_TCXO_VDD, 0); 47 | pinMode(PIN_TCXO_VDD, OUTPUT); 48 | } 49 | 50 | virtual void end(void) override 51 | { 52 | digitalWrite(PIN_TCXO_VDD, 0); 53 | pinMode(PIN_TCXO_VDD, INPUT); 54 | } 55 | 56 | virtual bool queryUsingTcxo(void) override { return true; }; 57 | 58 | virtual ostime_t setModuleActive(bool state) override 59 | { 60 | ostime_t result; 61 | const int oldState = digitalRead(PIN_TCXO_VDD); 62 | 63 | // if turning on, we need to delay. 64 | result = 0; 65 | if (state && ! oldState) 66 | result = ms2osticksCeil(TCXO_DELAY_MS); 67 | 68 | if (state != oldState) 69 | digitalWrite(PIN_TCXO_VDD, state); 70 | 71 | return result; 72 | } 73 | }; 74 | 75 | // save some typing by bringing the pin numbers into scope 76 | static HalConfiguration_Catena4617_t myConfig; 77 | 78 | static const HalPinmap_t myPinmap = 79 | { 80 | .nss = HalConfiguration_Catena4617_t::PIN_SX1276_NSS, // chip select is D7 81 | .rxtx = HalConfiguration_Catena4617_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 82 | .rst = HalConfiguration_Catena4617_t::PIN_SX1276_NRESET, // NRESET is D8 83 | 84 | .dio = {HalConfiguration_Catena4617_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 85 | HalConfiguration_Catena4617_t::PIN_SX1276_DIO1, // DIO1 is D26 86 | HalConfiguration_Catena4617_t::PIN_SX1276_DIO2, // DIO2 is D27 87 | }, 88 | .rxtx_rx_active = 1, 89 | .rssi_cal = 10, 90 | .spi_freq = 8000000, /* 8MHz */ 91 | .pConfig = &myConfig 92 | }; 93 | 94 | const HalPinmap_t *GetPinmap_Catena4617(void) 95 | { 96 | return &myPinmap; 97 | } 98 | 99 | }; // namespace Arduino_LMIC 100 | 101 | #endif /* defined(ARDUINO_MCCI_CATENA_4617) || defined(ARDUINO_CATENA_4617) */ 102 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4618.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4618.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Lakshmi Priya Natarajan, MCCI June 2019 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4618) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | class HalConfiguration_Catena4618_t : public HalConfiguration_t 26 | { 27 | public: 28 | enum DIGITAL_PINS : uint8_t 29 | { 30 | PIN_SX1276_NSS = D7, 31 | PIN_SX1276_NRESET = D8, 32 | PIN_SX1276_DIO0 = D25, 33 | PIN_SX1276_DIO1 = D26, 34 | PIN_SX1276_DIO2 = D27, 35 | PIN_SX1276_ANT_SWITCH_RX = D29, 36 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 37 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 38 | PIN_VDD_BOOST_ENABLE = A0, 39 | PIN_TCXO_VDD = D33, 40 | }; 41 | 42 | static constexpr ostime_t TCXO_DELAY_MS = 5; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_TCXO_VDD, 0); 47 | pinMode(PIN_TCXO_VDD, OUTPUT); 48 | } 49 | 50 | virtual void end(void) override 51 | { 52 | digitalWrite(PIN_TCXO_VDD, 0); 53 | pinMode(PIN_TCXO_VDD, INPUT); 54 | } 55 | 56 | virtual bool queryUsingTcxo(void) override { return true; }; 57 | 58 | virtual ostime_t setModuleActive(bool state) override 59 | { 60 | ostime_t result; 61 | const int oldState = digitalRead(PIN_TCXO_VDD); 62 | 63 | // if turning on, we need to delay. 64 | result = 0; 65 | if (state && ! oldState) 66 | result = ms2osticksCeil(TCXO_DELAY_MS); 67 | 68 | if (state != oldState) 69 | digitalWrite(PIN_TCXO_VDD, state); 70 | 71 | return result; 72 | } 73 | }; 74 | 75 | // save some typing by bringing the pin numbers into scope 76 | static HalConfiguration_Catena4618_t myConfig; 77 | 78 | static const HalPinmap_t myPinmap = 79 | { 80 | .nss = HalConfiguration_Catena4618_t::PIN_SX1276_NSS, // chip select is D7 81 | .rxtx = HalConfiguration_Catena4618_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 82 | .rst = HalConfiguration_Catena4618_t::PIN_SX1276_NRESET, // NRESET is D8 83 | 84 | .dio = {HalConfiguration_Catena4618_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 85 | HalConfiguration_Catena4618_t::PIN_SX1276_DIO1, // DIO1 is D26 86 | HalConfiguration_Catena4618_t::PIN_SX1276_DIO2, // DIO2 is D27 87 | }, 88 | .rxtx_rx_active = 1, 89 | .rssi_cal = 10, 90 | .spi_freq = 8000000, /* 8MHz */ 91 | .pConfig = &myConfig 92 | }; 93 | 94 | const HalPinmap_t *GetPinmap_Catena4618(void) 95 | { 96 | return &myPinmap; 97 | } 98 | 99 | }; // namespace Arduino_LMIC 100 | 101 | #endif /* defined(ARDUINO_MCCI_CATENA_4618) || defined(ARDUINO_CATENA_4618) */ 102 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4630.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4630.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Dhinesh Kumar Pitchai, MCCI June 2019 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4630) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | class HalConfiguration_Catena4630_t : public HalConfiguration_t 26 | { 27 | public: 28 | enum DIGITAL_PINS : uint8_t 29 | { 30 | PIN_SX1276_NSS = D7, 31 | PIN_SX1276_NRESET = D8, 32 | PIN_SX1276_DIO0 = D25, 33 | PIN_SX1276_DIO1 = D26, 34 | PIN_SX1276_DIO2 = D27, 35 | PIN_SX1276_ANT_SWITCH_RX = D29, 36 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 37 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 38 | PIN_VDD_BOOST_ENABLE = A0, 39 | PIN_TCXO_VDD = D33, 40 | }; 41 | 42 | static constexpr ostime_t TCXO_DELAY_MS = 5; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_TCXO_VDD, 0); 47 | pinMode(PIN_TCXO_VDD, OUTPUT); 48 | } 49 | 50 | virtual void end(void) override 51 | { 52 | digitalWrite(PIN_TCXO_VDD, 0); 53 | pinMode(PIN_TCXO_VDD, INPUT); 54 | } 55 | 56 | virtual bool queryUsingTcxo(void) override { return true; }; 57 | 58 | virtual ostime_t setModuleActive(bool state) override 59 | { 60 | ostime_t result; 61 | const int oldState = digitalRead(PIN_TCXO_VDD); 62 | 63 | // if turning on, we need to delay. 64 | result = 0; 65 | if (state && ! oldState) 66 | result = ms2osticksCeil(TCXO_DELAY_MS); 67 | 68 | if (state != oldState) 69 | digitalWrite(PIN_TCXO_VDD, state); 70 | 71 | return result; 72 | } 73 | }; 74 | 75 | // save some typing by bringing the pin numbers into scope 76 | static HalConfiguration_Catena4630_t myConfig; 77 | 78 | static const HalPinmap_t myPinmap = 79 | { 80 | .nss = HalConfiguration_Catena4630_t::PIN_SX1276_NSS, // chip select is D7 81 | .rxtx = HalConfiguration_Catena4630_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 82 | .rst = HalConfiguration_Catena4630_t::PIN_SX1276_NRESET, // NRESET is D8 83 | 84 | .dio = {HalConfiguration_Catena4630_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 85 | HalConfiguration_Catena4630_t::PIN_SX1276_DIO1, // DIO1 is D26 86 | HalConfiguration_Catena4630_t::PIN_SX1276_DIO2, // DIO2 is D27 87 | }, 88 | .rxtx_rx_active = 1, 89 | .rssi_cal = 10, 90 | .spi_freq = 8000000, /* 8MHz */ 91 | .pConfig = &myConfig 92 | }; 93 | 94 | const HalPinmap_t *GetPinmap_Catena4630(void) 95 | { 96 | return &myPinmap; 97 | } 98 | 99 | }; // namespace Arduino_LMIC 100 | 101 | #endif /* defined(ARDUINO_MCCI_CATENA_4630) || defined(ARDUINO_CATENA_4630) */ 102 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4801.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4801.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4801) || \ 17 | /* legacy names */ \ 18 | defined(ARDUINO_CATENA_4801) 19 | 20 | #include 21 | #include 22 | 23 | #include "../lmic/oslmic.h" 24 | 25 | namespace Arduino_LMIC { 26 | 27 | class HalConfiguration_Catena4801_t : public HalConfiguration_t 28 | { 29 | public: 30 | enum DIGITAL_PINS : uint8_t 31 | { 32 | PIN_SX1276_NSS = D7, 33 | PIN_SX1276_NRESET = D8, 34 | PIN_SX1276_DIO0 = D25, 35 | PIN_SX1276_DIO1 = D26, 36 | PIN_SX1276_DIO2 = D27, 37 | PIN_SX1276_ANT_SWITCH_RX = D29, 38 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 39 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 40 | PIN_VDD_BOOST_ENABLE = A0, 41 | PIN_TCXO_VDD = D33, 42 | }; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_TCXO_VDD, 0); 47 | pinMode(PIN_TCXO_VDD, OUTPUT); 48 | } 49 | 50 | virtual void end(void) override 51 | { 52 | digitalWrite(PIN_TCXO_VDD, 0); 53 | pinMode(PIN_TCXO_VDD, INPUT); 54 | } 55 | 56 | virtual bool queryUsingTcxo(void) override { return true; }; 57 | 58 | virtual ostime_t setModuleActive(bool state) override 59 | { 60 | ostime_t result; 61 | const int oldState = digitalRead(PIN_TCXO_VDD); 62 | 63 | // if turning on, we need to delay. 64 | result = 0; 65 | if (state && ! oldState) 66 | result = ms2osticksCeil(3); 67 | 68 | if (state != oldState) 69 | digitalWrite(PIN_TCXO_VDD, state); 70 | 71 | return result; 72 | } 73 | }; 74 | 75 | // save some typing by bringing the pin numbers into scope 76 | static HalConfiguration_Catena4801_t myConfig; 77 | 78 | static const HalPinmap_t myPinmap = 79 | { 80 | .nss = HalConfiguration_Catena4801_t::PIN_SX1276_NSS, // chip select is D7 81 | .rxtx = HalConfiguration_Catena4801_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 82 | .rst = HalConfiguration_Catena4801_t::PIN_SX1276_NRESET, // NRESET is D8 83 | 84 | .dio = {HalConfiguration_Catena4801_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 85 | HalConfiguration_Catena4801_t::PIN_SX1276_DIO1, // DIO1 is D26 86 | HalConfiguration_Catena4801_t::PIN_SX1276_DIO2, // DIO2 is D27 87 | }, 88 | .rxtx_rx_active = 1, 89 | .rssi_cal = 10, 90 | .spi_freq = 8000000, /* 8MHz */ 91 | .pConfig = &myConfig 92 | }; 93 | 94 | const HalPinmap_t *GetPinmap_Catena4801(void) 95 | { 96 | return &myPinmap; 97 | } 98 | 99 | }; // namespace Arduino_LMIC 100 | 101 | #endif /* defined(ARDUINO_CATENA_4611) || defined(ARDUINO_CATENA_4801) */ 102 | -------------------------------------------------------------------------------- /src/hal/getpinmap_catena4802.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_catena4802.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for various boards 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Dhinesh Kumar Pitchai, MCCI November 2020 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_MCCI_CATENA_4802) || \ 17 | /* legacy names */ \ 18 | defined(ARDUINO_CATENA_4802) 19 | 20 | #include 21 | #include 22 | 23 | #include "../lmic/oslmic.h" 24 | 25 | namespace Arduino_LMIC { 26 | 27 | class HalConfiguration_Catena4802_t : public HalConfiguration_t 28 | { 29 | public: 30 | enum DIGITAL_PINS : uint8_t 31 | { 32 | PIN_SX1276_NSS = D7, 33 | PIN_SX1276_NRESET = D8, 34 | PIN_SX1276_DIO0 = D25, 35 | PIN_SX1276_DIO1 = D26, 36 | PIN_SX1276_DIO2 = D27, 37 | PIN_SX1276_ANT_SWITCH_RX = D29, 38 | PIN_SX1276_ANT_SWITCH_TX_BOOST = D30, 39 | PIN_SX1276_ANT_SWITCH_TX_RFO = D31, 40 | PIN_VDD_BOOST_ENABLE = A0, 41 | PIN_TCXO_VDD = D33, 42 | }; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_TCXO_VDD, 0); 47 | pinMode(PIN_TCXO_VDD, OUTPUT); 48 | } 49 | 50 | virtual void end(void) override 51 | { 52 | digitalWrite(PIN_TCXO_VDD, 0); 53 | pinMode(PIN_TCXO_VDD, INPUT); 54 | } 55 | 56 | virtual bool queryUsingTcxo(void) override { return true; }; 57 | 58 | virtual ostime_t setModuleActive(bool state) override 59 | { 60 | ostime_t result; 61 | const int oldState = digitalRead(PIN_TCXO_VDD); 62 | 63 | // if turning on, we need to delay. 64 | result = 0; 65 | if (state && ! oldState) 66 | result = ms2osticksCeil(3); 67 | 68 | if (state != oldState) 69 | digitalWrite(PIN_TCXO_VDD, state); 70 | 71 | return result; 72 | } 73 | }; 74 | 75 | // save some typing by bringing the pin numbers into scope 76 | static HalConfiguration_Catena4802_t myConfig; 77 | 78 | static const HalPinmap_t myPinmap = 79 | { 80 | .nss = HalConfiguration_Catena4802_t::PIN_SX1276_NSS, // chip select is D7 81 | .rxtx = HalConfiguration_Catena4802_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 82 | .rst = HalConfiguration_Catena4802_t::PIN_SX1276_NRESET, // NRESET is D8 83 | 84 | .dio = {HalConfiguration_Catena4802_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 85 | HalConfiguration_Catena4802_t::PIN_SX1276_DIO1, // DIO1 is D26 86 | HalConfiguration_Catena4802_t::PIN_SX1276_DIO2, // DIO2 is D27 87 | }, 88 | .rxtx_rx_active = 1, 89 | .rssi_cal = 10, 90 | .spi_freq = 8000000, /* 8MHz */ 91 | .pConfig = &myConfig 92 | }; 93 | 94 | const HalPinmap_t *GetPinmap_Catena4802(void) 95 | { 96 | return &myPinmap; 97 | } 98 | 99 | }; // namespace Arduino_LMIC 100 | 101 | #endif /* defined(ARDUINO_CATENA_4611) || defined(ARDUINO_CATENA_4802) */ 102 | -------------------------------------------------------------------------------- /src/hal/getpinmap_disco_l072cs_lrwan1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getpinmap_disco_l072cz_lrwan1.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmaps for the Discovery L072CZ LRWAN1 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Helium February 2020 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_DISCO_L072CZ_LRWAN1) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | class HalConfiguration_Disco_L072cz_Lrwan1_t : public HalConfiguration_t 26 | { 27 | public: 28 | enum DIGITAL_PINS : uint8_t 29 | { 30 | PIN_SX1276_NSS = 37, 31 | PIN_SX1276_NRESET = 33, 32 | PIN_SX1276_DIO0 = 38, 33 | PIN_SX1276_DIO1 = 39, 34 | PIN_SX1276_DIO2 = 40, 35 | PIN_SX1276_RXTX = 21, 36 | }; 37 | 38 | virtual bool queryUsingTcxo(void) override { return false; }; 39 | }; 40 | // save some typing by bringing the pin numbers into scope 41 | static HalConfiguration_Disco_L072cz_Lrwan1_t myConfig; 42 | 43 | static const HalPinmap_t myPinmap = 44 | { 45 | .nss = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NSS, 46 | .rxtx = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_RXTX, 47 | .rst = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NRESET, 48 | 49 | .dio = {HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO0, 50 | HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO1, 51 | HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO2, 52 | }, 53 | .rxtx_rx_active = 1, 54 | .rssi_cal = 10, 55 | .spi_freq = 8000000, /* 8MHz */ 56 | .pConfig = &myConfig 57 | }; 58 | 59 | const HalPinmap_t *GetPinmap_Disco_L072cz_Lrwan1(void) 60 | { 61 | return &myPinmap; 62 | } 63 | 64 | }; // namespace Arduino_LMIC 65 | 66 | #endif /* defined(ARDUINO_DISCO_L072CZ_LRWAN1) */ 67 | -------------------------------------------------------------------------------- /src/hal/getpinmap_feather32u4lora.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_feather32u4lora.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for Adafruit Feather 32U4 LoRa 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_AVR_FEATHER32U4) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC { 24 | 25 | class HalConfiguration_Feather32U4LoRa_t : public HalConfiguration_t 26 | { 27 | public: 28 | enum DIGITAL_PINS : uint8_t 29 | { 30 | PIN_SX1276_NSS = 8, 31 | PIN_SX1276_NRESET = 4, 32 | PIN_SX1276_DIO0 = 7, 33 | PIN_SX1276_DIO1 = 6, 34 | PIN_SX1276_DIO2 = HalPinmap_t::UNUSED_PIN, 35 | PIN_SX1276_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 36 | PIN_SX1276_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 37 | PIN_SX1276_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 38 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 39 | }; 40 | 41 | virtual void begin(void) override 42 | { 43 | digitalWrite(PIN_SX1276_NSS, 1); 44 | pinMode(PIN_SX1276_NSS, OUTPUT); 45 | } 46 | 47 | // virtual void end(void) override 48 | 49 | // virtual ostime_t setModuleActive(bool state) override 50 | 51 | }; 52 | 53 | static HalConfiguration_Feather32U4LoRa_t myConfig; 54 | 55 | // Pin mapping for Adafruit Feather 32u4 LoRa, etc. 56 | // Just like Feather M0 LoRa, but uses SPI at 1MHz; and that's only 57 | // because MCCI doesn't have a test board; probably higher frequencies 58 | // will work. 59 | 60 | static const HalPinmap_t myPinmap = 61 | { 62 | .nss = HalConfiguration_Feather32U4LoRa_t::PIN_SX1276_NSS, // chip select is D7 63 | .rxtx = HalConfiguration_Feather32U4LoRa_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 64 | .rst = HalConfiguration_Feather32U4LoRa_t::PIN_SX1276_NRESET, // NRESET is D8 65 | 66 | .dio = {HalConfiguration_Feather32U4LoRa_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 67 | HalConfiguration_Feather32U4LoRa_t::PIN_SX1276_DIO1, // DIO1 is D26 68 | HalConfiguration_Feather32U4LoRa_t::PIN_SX1276_DIO2, // DIO2 is D27 69 | }, 70 | .rxtx_rx_active = 0, 71 | .rssi_cal = 8, 72 | .spi_freq = 1000000, /* 1MHz */ 73 | .pConfig = &myConfig, 74 | }; 75 | 76 | const HalPinmap_t *GetPinmap_Feather32U4LoRa(void) 77 | { 78 | return &myPinmap; 79 | } 80 | 81 | }; // namespace Arduino_LMIC 82 | 83 | #endif // ARDUINO_AVR_FEATHER32U4 84 | -------------------------------------------------------------------------------- /src/hal/getpinmap_featherm0lora.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_featherm0lora.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for Adafruit Feather M0 LoRa 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | // The Adafruit FeatherM0 and FeatherM0 Express BSPs are not consistent 17 | // as to how they declare themselves. Both are SAMDs. Detect either one. 18 | #if defined(ARDUINO_ARCH_SAMD) 19 | # if defined(ADAFRUIT_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0) 20 | 21 | #include 22 | #include 23 | 24 | #include "../lmic/oslmic.h" 25 | 26 | namespace Arduino_LMIC { 27 | 28 | class HalConfiguration_FeatherM0LoRa_t : public HalConfiguration_t 29 | { 30 | public: 31 | enum DIGITAL_PINS : uint8_t 32 | { 33 | PIN_SX1276_NSS = 8, 34 | PIN_SX1276_NRESET = 4, 35 | PIN_SX1276_DIO0 = 3, 36 | PIN_SX1276_DIO1 = 6, 37 | PIN_SX1276_DIO2 = HalPinmap_t::UNUSED_PIN, 38 | PIN_SX1276_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 39 | PIN_SX1276_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 40 | PIN_SX1276_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 41 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 42 | }; 43 | 44 | virtual void begin(void) override 45 | { 46 | digitalWrite(PIN_SX1276_NSS, 1); 47 | pinMode(PIN_SX1276_NSS, OUTPUT); 48 | } 49 | 50 | // virtual void end(void) override 51 | 52 | // virtual ostime_t setModuleActive(bool state) override 53 | 54 | }; 55 | 56 | static HalConfiguration_FeatherM0LoRa_t myConfig; 57 | 58 | static const HalPinmap_t myPinmap = 59 | { 60 | .nss = HalConfiguration_FeatherM0LoRa_t::PIN_SX1276_NSS, // chip select is D7 61 | .rxtx = HalConfiguration_FeatherM0LoRa_t::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 62 | .rst = HalConfiguration_FeatherM0LoRa_t::PIN_SX1276_NRESET, // NRESET is D8 63 | 64 | .dio = {HalConfiguration_FeatherM0LoRa_t::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 65 | HalConfiguration_FeatherM0LoRa_t::PIN_SX1276_DIO1, // DIO1 is D26 66 | HalConfiguration_FeatherM0LoRa_t::PIN_SX1276_DIO2, // DIO2 is D27 67 | }, 68 | .rxtx_rx_active = 0, 69 | .rssi_cal = 10, 70 | .spi_freq = 8000000, /* 8MHz */ 71 | .pConfig = &myConfig 72 | }; 73 | 74 | const HalPinmap_t *GetPinmap_FeatherM0LoRa(void) 75 | { 76 | return &myPinmap; 77 | } 78 | 79 | }; // namespace Arduino_LMIC 80 | 81 | # endif // defined(ADAFRUIT_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0) 82 | #endif // defined(ARDUINO_ARCH_SAMD) 83 | -------------------------------------------------------------------------------- /src/hal/getpinmap_heltec_lora32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getpinmap_heltec_lora32.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for Heltec WiFi LoRa 32 (V1 & V2) and Heltec Wireless Stick 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Manuel Bleichenbacher, manuel.bleichenbacher@gmail.com October 2019 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_HELTEC_WIFI_LORA_32) || defined(ARDUINO_HELTEC_WIFI_LORA_32_V2) || defined(ARDUINO_HELTEC_WIRELESS_STICK) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | // Note: The pin constants SS, RST_LoRa and DIOx are defined in pins_arduino.h 24 | // (board-specific variant in Arduino core). Even if it won't be used, this 25 | // file needs to compile for all other variants as well. 26 | #if !defined(ARDUINO_HELTEC_WIFI_LORA_32) && !defined(ARDUINO_HELTEC_WIFI_LORA_32_V2) && !defined(ARDUINO_HELTEC_WIRELESS_STICK) 27 | #undef SS 28 | #undef RST_LoRa 29 | #undef DIO0 30 | #undef DIO1 31 | #undef DIO2 32 | #define SS HalPinmap_t::UNUSED_PIN 33 | #define RST_LoRa HalPinmap_t::UNUSED_PIN 34 | #define DIO0 HalPinmap_t::UNUSED_PIN 35 | #define DIO1 HalPinmap_t::UNUSED_PIN 36 | #define DIO2 HalPinmap_t::UNUSED_PIN 37 | #endif 38 | 39 | 40 | namespace Arduino_LMIC 41 | { 42 | 43 | class HalConfiguration_heltec_lora32 : public HalConfiguration_t 44 | { 45 | public: 46 | enum DIGITAL_PINS : uint8_t 47 | { 48 | PIN_SX1276_NSS = SS, 49 | PIN_SX1276_NRESET = RST_LoRa, 50 | PIN_SX1276_DIO0 = DIO0, 51 | PIN_SX1276_DIO1 = DIO1, 52 | PIN_SX1276_DIO2 = DIO2, 53 | PIN_SX1276_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 54 | PIN_SX1276_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 55 | PIN_SX1276_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 56 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 57 | }; 58 | }; 59 | 60 | static HalConfiguration_heltec_lora32 myConfig; 61 | 62 | static const HalPinmap_t myPinmap = 63 | { 64 | .nss = HalConfiguration_heltec_lora32::PIN_SX1276_NSS, 65 | .rxtx = HalConfiguration_heltec_lora32::PIN_SX1276_ANT_SWITCH_RX, 66 | .rst = HalConfiguration_heltec_lora32::PIN_SX1276_NRESET, 67 | .dio = { 68 | HalConfiguration_heltec_lora32::PIN_SX1276_DIO0, 69 | HalConfiguration_heltec_lora32::PIN_SX1276_DIO1, 70 | HalConfiguration_heltec_lora32::PIN_SX1276_DIO2, 71 | }, 72 | .rxtx_rx_active = 0, 73 | .rssi_cal = 10, 74 | .spi_freq = 8000000, /* 8MHz */ 75 | .pConfig = &myConfig}; 76 | 77 | const HalPinmap_t *GetPinmap_heltec_lora32(void) 78 | { 79 | return &myPinmap; 80 | } 81 | 82 | }; // namespace Arduino_LMIC 83 | 84 | #endif // defined(ARDUINO_HELTEC_WIFI_LORA_32) || defined(ARDUINO_HELTEC_WIFI_LORA_32_V2) || defined(ARDUINO_HELTEC_WIRELESS_STICK) 85 | -------------------------------------------------------------------------------- /src/hal/getpinmap_heltec_lora32_v3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getpinmap_heltec_lora32_v3.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for Heltec Wireless Stick Lite V3 and Wifi Lora32 V3 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Tristan Webber, Shrunk Innovation Labs July 2023 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_heltec_wifi_lora_32_V3) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | namespace Arduino_LMIC 24 | { 25 | 26 | class HalConfiguration_heltec_lora32_v3 : public HalConfiguration_t 27 | { 28 | public: 29 | enum DIGITAL_PINS : uint8_t 30 | { 31 | PIN_SX1262_NSS = SS, 32 | PIN_SX1262_NRESET = RST_LoRa, 33 | PIN_SX1262_BUSY = BUSY_LoRa, 34 | PIN_SX1262_DIO1 = DIO0, 35 | PIN_SX1262_DIO2 = HalPinmap_t::UNUSED_PIN, 36 | PIN_SX1262_DIO3 = HalPinmap_t::UNUSED_PIN, 37 | PIN_SX1262_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 38 | PIN_SX1262_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 39 | PIN_SX1262_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 40 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 41 | }; 42 | 43 | virtual u1_t queryBusyPin(void) override { return HalConfiguration_heltec_lora32_v3::PIN_SX1262_BUSY; }; 44 | 45 | virtual bool queryUsingDcdc(void) override { return true; }; 46 | 47 | virtual bool queryUsingDIO2AsRfSwitch(void) override { return true; }; 48 | 49 | virtual bool queryUsingDIO3AsTCXOSwitch(void) override { return true; }; 50 | }; 51 | 52 | static HalConfiguration_heltec_lora32_v3 myConfig; 53 | 54 | static const HalPinmap_t myPinmap = 55 | { 56 | .nss = HalConfiguration_heltec_lora32_v3::PIN_SX1262_NSS, 57 | .rxtx = HalConfiguration_heltec_lora32_v3::PIN_SX1262_ANT_SWITCH_RX, 58 | .rst = HalConfiguration_heltec_lora32_v3::PIN_SX1262_NRESET, 59 | .dio = { 60 | HalConfiguration_heltec_lora32_v3::PIN_SX1262_DIO1, 61 | HalConfiguration_heltec_lora32_v3::PIN_SX1262_DIO2, 62 | HalConfiguration_heltec_lora32_v3::PIN_SX1262_DIO3, 63 | }, 64 | .rxtx_rx_active = 0, 65 | .rssi_cal = 10, 66 | .spi_freq = 8000000, /* 8MHz */ 67 | .pConfig = &myConfig}; 68 | 69 | const HalPinmap_t *GetPinmap_heltec_lora32_v3(void) 70 | { 71 | return &myPinmap; 72 | } 73 | 74 | }; // namespace Arduino_LMIC 75 | 76 | #endif // defined(ARDUINO_heltec_wifi_lora_32_V3) -------------------------------------------------------------------------------- /src/hal/getpinmap_thisboard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_thisboard.cpp 4 | 5 | Function: 6 | Return a suitable LMIC config for this board. 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | */ 15 | 16 | #include 17 | 18 | namespace Arduino_LMIC { 19 | 20 | const HalPinmap_t *GetPinmap_ThisBoard(void) 21 | { 22 | /* 23 | || Adafruit BSPs are not consistent -- m0 express defs ARDUINO_SAMD_FEATHER_M0, 24 | || m0 defs ADAFRUIT_FEATHER_M0 25 | */ 26 | #if defined(ARDUINO_SAMD_FEATHER_M0) || defined(ADAFRUIT_FEATHER_M0) 27 | # if defined(ARDUINO_MCCI_CATENA_4420) 28 | // this uses a radiowing and an odd configuration 29 | return GetPinmap_Catena4420(); 30 | # else 31 | // others use Feather M0 LoRa 32 | return GetPinmap_FeatherM0LoRa(); 33 | # endif 34 | #elif defined(ARDUINO_AVR_FEATHER32U4) 35 | return GetPinmap_Feather32U4LoRa(); 36 | #elif defined(ARDUINO_MCCI_CATENA_4551) || \ 37 | /* legacy names */ \ 38 | defined(ARDUINO_CATENA_4551) 39 | return GetPinmap_Catena4551(); 40 | #elif defined(ARDUINO_MCCI_CATENA_4610) 41 | return GetPinmap_Catena4610(); 42 | #elif defined(ARDUINO_MCCI_CATENA_4611) || \ 43 | /* legacy names */ \ 44 | defined(ARDUINO_CATENA_4611) 45 | return GetPinmap_Catena4611(); 46 | #elif defined(ARDUINO_MCCI_CATENA_4612) || \ 47 | /* legacy names */ \ 48 | defined(ARDUINO_CATENA_4612) 49 | return GetPinmap_Catena4612(); 50 | #elif defined(ARDUINO_MCCI_CATENA_4617) 51 | return GetPinmap_Catena4617(); 52 | #elif defined(ARDUINO_MCCI_CATENA_4618) 53 | return GetPinmap_Catena4618(); 54 | #elif defined(ARDUINO_MCCI_CATENA_4630) 55 | return GetPinmap_Catena4630(); 56 | #elif defined(ARDUINO_MCCI_CATENA_4801) 57 | return GetPinmap_Catena4801(); 58 | #elif defined(ARDUINO_MCCI_CATENA_4802) 59 | return GetPinmap_Catena4802(); 60 | #elif defined(ARDUINO_DISCO_L072CZ_LRWAN1) 61 | return GetPinmap_Disco_L072cz_Lrwan1(); 62 | #elif defined(PINNOCHIO_SCOUT) 63 | return GetPinmap_PinnochioScount(); 64 | #elif defined(ARDUINO_TTGO_LoRa32_V1) 65 | return GetPinmap_ttgo_lora32_v1(); 66 | #elif defined(ARDUINO_TTGO_LoRa32_v21new) 67 | return GetPinmap_ttgo_lora32_v21(); 68 | #elif defined(ARDUINO_HELTEC_WIFI_LORA_32) || defined(ARDUINO_HELTEC_WIFI_LORA_32_V2) || defined(ARDUINO_HELTEC_WIRELESS_STICK) 69 | return GetPinmap_heltec_lora32(); 70 | #elif defined(ARDUINO_heltec_wifi_lora_32_V3) 71 | return GetPinmap_heltec_lora32_v3(); 72 | #elif defined(ARDUINO_TTGO_T_BEAM_S3) 73 | return GetPinmap_ttgo_tbeam_s3(); 74 | #else 75 | #pragma message("Board not supported -- use an explicit pinmap") 76 | return nullptr; 77 | #endif 78 | } 79 | 80 | }; // namespace Arduino_LMIC 81 | 82 | -------------------------------------------------------------------------------- /src/hal/getpinmap_ttgo_lora32_v1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_ttgo_lora32_v1.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for TTGO ESP32 OLED V1 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | German Martin, gmag11@gmail.com June 2019 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_TTGO_LoRa32_V1) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | #define LORA_DIO0 26 24 | #define LORA_DIO1 33 25 | #define LORA_DIO2 32 26 | 27 | namespace Arduino_LMIC { 28 | 29 | class HalConfiguration_ttgo_lora32_v1 : public HalConfiguration_t 30 | { 31 | public: 32 | enum DIGITAL_PINS : uint8_t 33 | { 34 | PIN_SX1276_NSS = 18, 35 | PIN_SX1276_NRESET = 14, 36 | PIN_SX1276_DIO0 = LORA_DIO0, 37 | PIN_SX1276_DIO1 = LORA_DIO1, 38 | PIN_SX1276_DIO2 = LORA_DIO2, 39 | PIN_SX1276_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 40 | PIN_SX1276_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 41 | PIN_SX1276_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 42 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 43 | }; 44 | 45 | virtual void begin(void) override 46 | { 47 | digitalWrite(PIN_SX1276_NSS, 1); 48 | pinMode(PIN_SX1276_NSS, OUTPUT); 49 | } 50 | 51 | // virtual void end(void) override 52 | 53 | // virtual ostime_t setModuleActive(bool state) override 54 | 55 | }; 56 | 57 | static HalConfiguration_ttgo_lora32_v1 myConfig; 58 | 59 | static const HalPinmap_t myPinmap = 60 | { 61 | .nss = HalConfiguration_ttgo_lora32_v1::PIN_SX1276_NSS, // chip select is D7 62 | .rxtx = HalConfiguration_ttgo_lora32_v1::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 63 | .rst = HalConfiguration_ttgo_lora32_v1::PIN_SX1276_NRESET, // NRESET is D8 64 | 65 | .dio = {HalConfiguration_ttgo_lora32_v1::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 66 | HalConfiguration_ttgo_lora32_v1::PIN_SX1276_DIO1, // DIO1 is D26 67 | HalConfiguration_ttgo_lora32_v1::PIN_SX1276_DIO2, // DIO2 is D27 68 | }, 69 | .rxtx_rx_active = 0, 70 | .rssi_cal = 10, 71 | .spi_freq = 8000000, /* 8MHz */ 72 | .pConfig = &myConfig 73 | }; 74 | 75 | const HalPinmap_t * GetPinmap_ttgo_lora32_v1 (void) 76 | { 77 | return &myPinmap; 78 | } 79 | 80 | }; // namespace Arduino_LMIC 81 | 82 | #endif // ARDUINO_TTGO_LoRa32_V1 83 | -------------------------------------------------------------------------------- /src/hal/getpinmap_ttgo_lora32_v2.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getconfig_ttgo_lora32_v2.1.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for TTGO ESP32 OLED V2.1 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Christoph Schultz, GitHub @ChrSchultz March 2021 13 | 14 | */ 15 | 16 | #if defined(ARDUINO_TTGO_LoRa32_v21new) 17 | 18 | #include 19 | #include 20 | 21 | #include "../lmic/oslmic.h" 22 | 23 | #define LORA_DIO0 26 24 | #define LORA_DIO1 33 25 | #define LORA_DIO2 32 26 | 27 | namespace Arduino_LMIC { 28 | 29 | class HalConfiguration_ttgo_lora32_v21 : public HalConfiguration_t 30 | { 31 | public: 32 | enum DIGITAL_PINS : uint8_t 33 | { 34 | PIN_SX1276_NSS = 18, 35 | PIN_SX1276_NRESET = 23, 36 | PIN_SX1276_DIO0 = LORA_DIO0, 37 | PIN_SX1276_DIO1 = LORA_DIO1, 38 | PIN_SX1276_DIO2 = LORA_DIO2, 39 | PIN_SX1276_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 40 | PIN_SX1276_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 41 | PIN_SX1276_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 42 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 43 | }; 44 | 45 | virtual void begin(void) override 46 | { 47 | digitalWrite(PIN_SX1276_NSS, 1); 48 | pinMode(PIN_SX1276_NSS, OUTPUT); 49 | } 50 | 51 | // virtual void end(void) override 52 | 53 | // virtual ostime_t setModuleActive(bool state) override 54 | 55 | }; 56 | 57 | static HalConfiguration_ttgo_lora32_v21 myConfig; 58 | 59 | static const HalPinmap_t myPinmap = 60 | { 61 | .nss = HalConfiguration_ttgo_lora32_v21::PIN_SX1276_NSS, // chip select is D7 62 | .rxtx = HalConfiguration_ttgo_lora32_v21::PIN_SX1276_ANT_SWITCH_RX, // RXTX is D29 63 | .rst = HalConfiguration_ttgo_lora32_v21::PIN_SX1276_NRESET, // NRESET is D8 64 | 65 | .dio = {HalConfiguration_ttgo_lora32_v21::PIN_SX1276_DIO0, // DIO0 (IRQ) is D25 66 | HalConfiguration_ttgo_lora32_v21::PIN_SX1276_DIO1, // DIO1 is D26 67 | HalConfiguration_ttgo_lora32_v21::PIN_SX1276_DIO2, // DIO2 is D27 68 | }, 69 | .rxtx_rx_active = 0, 70 | .rssi_cal = 10, 71 | .spi_freq = 8000000, /* 8MHz */ 72 | .pConfig = &myConfig 73 | }; 74 | 75 | const HalPinmap_t * GetPinmap_ttgo_lora32_v21 (void) 76 | { 77 | return &myPinmap; 78 | } 79 | 80 | }; // namespace Arduino_LMIC 81 | 82 | #endif // ARDUINO_TTGO_LoRa32_v21new 83 | -------------------------------------------------------------------------------- /src/hal/getpinmap_ttgo_tbeam_s3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: getpinmap_ttgo_tbeam_s3.cpp.cpp 4 | 5 | Function: 6 | Arduino-LMIC C++ HAL pinmap for T-Beam S3 Core and T-Beam Supreme 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | */ 12 | 13 | #if defined(ARDUINO_TTGO_T_BEAM_S3) 14 | 15 | #include 16 | #include 17 | 18 | #include "../lmic/oslmic.h" 19 | 20 | namespace Arduino_LMIC { 21 | 22 | class HalConfiguration_ttgo_tbeam_s3 : public HalConfiguration_t { 23 | public: 24 | enum DIGITAL_PINS : uint8_t { 25 | PIN_SX1262_NSS = 10, 26 | PIN_SX1262_NRESET = 5, 27 | PIN_SX1262_BUSY = 4, 28 | PIN_SX1262_DIO1 = 1, 29 | PIN_SX1262_DIO2 = HalPinmap_t::UNUSED_PIN, 30 | PIN_SX1262_DIO3 = HalPinmap_t::UNUSED_PIN, 31 | PIN_SX1262_ANT_SWITCH_RX = HalPinmap_t::UNUSED_PIN, 32 | PIN_SX1262_ANT_SWITCH_TX_BOOST = HalPinmap_t::UNUSED_PIN, 33 | PIN_SX1262_ANT_SWITCH_TX_RFO = HalPinmap_t::UNUSED_PIN, 34 | PIN_VDD_BOOST_ENABLE = HalPinmap_t::UNUSED_PIN, 35 | }; 36 | 37 | virtual u1_t queryBusyPin(void) override { return HalConfiguration_ttgo_tbeam_s3::PIN_SX1262_BUSY; }; 38 | 39 | virtual bool queryUsingDcdc(void) override { return true; }; 40 | 41 | virtual bool queryUsingDIO2AsRfSwitch(void) override { return true; }; 42 | 43 | virtual bool queryUsingDIO3AsTCXOSwitch(void) override { return true; }; 44 | }; 45 | 46 | static HalConfiguration_ttgo_tbeam_s3 myConfig; 47 | 48 | static const HalPinmap_t myPinmap = 49 | { 50 | .nss = HalConfiguration_ttgo_tbeam_s3::PIN_SX1262_NSS, 51 | .rxtx = HalConfiguration_ttgo_tbeam_s3::PIN_SX1262_ANT_SWITCH_RX, 52 | .rst = HalConfiguration_ttgo_tbeam_s3::PIN_SX1262_NRESET, 53 | .dio = { 54 | HalConfiguration_ttgo_tbeam_s3::PIN_SX1262_DIO1, 55 | HalConfiguration_ttgo_tbeam_s3::PIN_SX1262_DIO2, 56 | HalConfiguration_ttgo_tbeam_s3::PIN_SX1262_DIO3, 57 | }, 58 | .rxtx_rx_active = 0, 59 | .rssi_cal = 8, 60 | .spi_freq = 8000000, /* 8MHz */ 61 | .pConfig = &myConfig 62 | }; 63 | 64 | const HalPinmap_t* GetPinmap_ttgo_tbeam_s3(void) { 65 | return &myPinmap; 66 | } 67 | 68 | }; // namespace Arduino_LMIC 69 | 70 | #endif // defined(ARDUINO_TTGO_T_BEAM_S3) -------------------------------------------------------------------------------- /src/hal/hal.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015-2016 Matthijs Kooijman 3 | * Copyright (c) 2016-2024 MCCI Corporation 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * This the HAL to run LMIC on top of the Arduino environment. 11 | *******************************************************************************/ 12 | #ifndef _hal_hal_h_ 13 | #define _hal_hal_h_ 14 | 15 | #include "arduino_lmic_hal_configuration.h" 16 | #include "lmic/oslmic_types.h" 17 | 18 | // for compatbility reasons, we need to disclose the configuration 19 | // structure as global type lmic_pinmap. 20 | using lmic_pinmap = Arduino_LMIC::HalPinmap_t; 21 | 22 | // similarly, we need to disclose NUM_DIO and LMIC_UNUSED_PIN 23 | static const int NUM_DIO = lmic_pinmap::NUM_DIO; 24 | 25 | // Use this for any unused pins. 26 | const u1_t LMIC_UNUSED_PIN = lmic_pinmap::UNUSED_PIN; 27 | 28 | // Declared here, to be defined and initialized by the application. 29 | // Use os_init_ex() if you want not to use a const table, or if 30 | // you need to define a derived type (so you can override methods). 31 | extern const lmic_pinmap lmic_pins; 32 | 33 | #endif // _hal_hal_h_ 34 | -------------------------------------------------------------------------------- /src/lmic.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: lmic.h 4 | 5 | Function: 6 | Deprecated C++ top-level include file (use instead). 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | 14 | Note: 15 | This header file is deprecated and is included for 16 | transitional purposes. It's deprecated because it's 17 | confusing to have src/lmic.h (this file) and src/lmic/lmic.h 18 | (the API file for the C library). We can't take it out 19 | yet, because it would inconvenience the world, but 20 | we can hope that someday it will wither away (on a major 21 | version bump). 22 | 23 | Please don't add any new functionality in this file; 24 | it is just a wrapper for arduino_lmic.h. 25 | 26 | */ 27 | 28 | #include "arduino_lmic.h" 29 | 30 | /* end of file */ 31 | -------------------------------------------------------------------------------- /src/lmic/hal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2016, 2018-2024 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_hal_h_ 30 | #define _lmic_hal_h_ 31 | 32 | #ifndef _oslmic_types_h_ 33 | # include "oslmic_types.h" 34 | #endif 35 | 36 | #ifndef _lmic_env_h_ 37 | # include "lmic_env.h" 38 | #endif 39 | 40 | #ifdef __cplusplus 41 | extern "C"{ 42 | #endif 43 | 44 | // The type of an optional user-defined failure handler routine 45 | typedef void LMIC_ABI_STD lmic_hal_failure_handler_t(const char* const file, const uint16_t line); 46 | 47 | /* 48 | * initialize hardware (IO, SPI, TIMER, IRQ). 49 | * This API is deprecated as it uses the const global lmic_pins, 50 | * which the platform can't control or change. 51 | */ 52 | void lmic_hal_init (void); 53 | 54 | /* 55 | * Initialize hardware, passing in platform-specific context 56 | * The pointer is to a HalPinmap_t. 57 | */ 58 | void lmic_hal_init_ex (const void *pContext); 59 | 60 | /* 61 | * drive radio RX/TX pins (0=rx, 1=tx). Actual polarity 62 | * is determined by the value of HalPinmap_t::rxtx_rx_active. 63 | */ 64 | void lmic_hal_pin_rxtx (u1_t val); 65 | 66 | /* 67 | * control radio RST pin (0=low, 1=high, 2=floating) 68 | */ 69 | void lmic_hal_pin_rst (u1_t val); 70 | 71 | /* 72 | * Perform SPI write transaction with radio chip 73 | * - write the command byte 'cmd' 74 | * - write 'len' bytes out of 'buf' 75 | */ 76 | void lmic_hal_spi_write(u1_t cmd, const u1_t* buf, size_t len); 77 | 78 | /* 79 | * Perform SPI read transaction with radio chip 80 | * - write the command byte 'cmd' 81 | * - read 'len' bytes into 'buf' 82 | */ 83 | void lmic_hal_spi_read(u1_t cmd, u1_t* buf, size_t len); 84 | 85 | /* 86 | * Perform SPI read transaction with SX126x series radio chip 87 | * - write the command byte 'cmd' 88 | * - write the 'addr_len' register address bytes 'addr' 89 | * - write the 'NOP' byte 0x00 90 | * - read 'buf_len' bytes into 'buf' 91 | */ 92 | #if (defined(CFG_sx1261_radio) || defined(CFG_sx1262_radio)) 93 | void lmic_hal_spi_read_sx126x(u1_t cmd, u1_t* addr, size_t addr_len, u1_t* buf, size_t buf_len); 94 | #endif 95 | 96 | /* 97 | * disable all CPU interrupts. 98 | * - might be invoked nested 99 | * - will be followed by matching call to lmic_hal_enableIRQs() 100 | */ 101 | void lmic_hal_disableIRQs (void); 102 | 103 | /* 104 | * enable CPU interrupts. 105 | */ 106 | void lmic_hal_enableIRQs (void); 107 | 108 | /* 109 | * return CPU interrupt nesting count 110 | */ 111 | uint8_t lmic_hal_getIrqLevel (void); 112 | 113 | /* 114 | * put system and CPU in low-power mode, sleep until interrupt. 115 | */ 116 | void lmic_hal_sleep (void); 117 | 118 | /* 119 | * return 32-bit system time in ticks. 120 | */ 121 | u4_t lmic_hal_ticks (void); 122 | 123 | /* 124 | * busy-wait until specified timestamp (in ticks) is reached. If on-time, return 0, 125 | * otherwise return the number of ticks we were late. 126 | */ 127 | u4_t lmic_hal_waitUntil (u4_t time); 128 | 129 | /* 130 | * check and rewind timer for target time. 131 | * - return 1 if target time is close 132 | * - otherwise rewind timer for target time or full period and return 0 133 | */ 134 | u1_t lmic_hal_checkTimer (u4_t targettime); 135 | 136 | /* 137 | * perform fatal failure action. 138 | * - called by assertions 139 | * - action could be HALT or reboot 140 | */ 141 | void lmic_hal_failed (const char *file, u2_t line); 142 | 143 | /* 144 | * set a custom hal failure handler routine. The default behaviour, defined in 145 | * lmic_hal_failed(), is to halt by looping infintely. 146 | */ 147 | void lmic_hal_set_failure_handler (lmic_hal_failure_handler_t*); 148 | 149 | /* 150 | * get the calibration value for radio_rssi 151 | */ 152 | s1_t lmic_hal_getRssiCal (void); 153 | 154 | /* 155 | * control the radio state 156 | * - if val == 0, turn tcxo off and otherwise prepare for sleep 157 | * - if val == 1, turn tcxo on and otherwise prep for activity 158 | * - return the number of ticks that we need to wait 159 | */ 160 | ostime_t lmic_hal_setModuleActive (bit_t val); 161 | 162 | /* find out if we're using Tcxo controlled by a host pin */ 163 | bit_t lmic_hal_queryUsingTcxo(void); 164 | 165 | /* SX126x function: find out if the board is configured for DC-DC regulator control */ 166 | bit_t lmic_hal_queryUsingDcdc(void); 167 | 168 | /* SX126x function: find out if the board is configured to control the RF switch with modem DIO2 */ 169 | bit_t lmic_hal_queryUsingDIO2AsRfSwitch(void); 170 | 171 | /* SX126x function: find out if the board is configured to control a TCXO with modem DIO3 */ 172 | bit_t lmic_hal_queryUsingDIO3AsTCXOSwitch(void); 173 | 174 | /* represent the various radio TX power policy */ 175 | enum { 176 | LMICHAL_radio_tx_power_policy_rfo = 0, 177 | LMICHAL_radio_tx_power_policy_paboost = 1, 178 | LMICHAL_radio_tx_power_policy_20dBm = 2, 179 | }; 180 | 181 | /* 182 | * query the configuration as to the Tx Power Policy 183 | * to be used on this board, given our desires and 184 | * requested power. 185 | */ 186 | uint8_t lmic_hal_getTxPowerPolicy( 187 | u1_t inputPolicy, 188 | s1_t requestedPower, 189 | u4_t freq 190 | ); 191 | 192 | void lmic_hal_pollPendingIRQs_helper(); 193 | void lmic_hal_processPendingIRQs(void); 194 | bit_t lmic_hal_radio_spi_is_busy(); 195 | 196 | /// \brief check for any pending interrupts: stub if interrupts are enabled. 197 | static inline void lmic_hal_pollPendingIRQs(void) 198 | { 199 | #if !defined(LMIC_USE_INTERRUPTS) 200 | lmic_hal_pollPendingIRQs_helper(); 201 | #endif /* !defined(LMIC_USE_INTERRUPTS) */ 202 | } 203 | 204 | #ifdef __cplusplus 205 | } // extern "C" 206 | #endif 207 | 208 | #endif // _lmic_hal_h_ 209 | -------------------------------------------------------------------------------- /src/lmic/lmic_bandplan_as923.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019-2021 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_bandplan_as923_h_ 30 | # define _lmic_bandplan_as923_h_ 31 | 32 | #ifndef _lmic_eu_like_h_ 33 | # include "lmic_eu_like.h" 34 | #endif 35 | 36 | // return maximum frame length (including PHY header) for this data rate (as923); 0 --> not valid dr. 37 | uint8_t LMICas923_maxFrameLen(uint8_t dr); 38 | // return maximum frame length (including PHY header) for this data rate; 0 --> not valid dr. 39 | #define LMICbandplan_maxFrameLen(dr) LMICas923_maxFrameLen(dr) 40 | 41 | int8_t LMICas923_pow2dBm(uint8_t mcmd_ladr_p1); 42 | #define pow2dBm(mcmd_ladr_p1) LMICas923_pow2dBm(mcmd_ladr_p1) 43 | 44 | // Times for half symbol per DR 45 | // Per DR table to minimize rounding errors 46 | ostime_t LMICas923_dr2hsym(uint8_t dr); 47 | #define dr2hsym(dr) LMICas923_dr2hsym(dr) 48 | 49 | static inline int 50 | LMICas923_isValidBeacon1(const uint8_t *d) { 51 | return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1); 52 | } 53 | 54 | #undef LMICbandplan_isValidBeacon1 55 | #define LMICbandplan_isValidBeacon1(pFrame) LMICas923_isValidBeacon1(pFrame) 56 | 57 | // override default for LMICbandplan_resetDefaultChannels 58 | void 59 | LMICas923_resetDefaultChannels(void); 60 | 61 | #undef LMICbandplan_resetDefaultChannels 62 | #define LMICbandplan_resetDefaultChannels() \ 63 | LMICas923_resetDefaultChannels() 64 | 65 | // override default for LMICbandplan_init 66 | void LMICas923_init(void); 67 | 68 | #undef LMICbandplan_init 69 | #define LMICbandplan_init() \ 70 | LMICas923_init() 71 | 72 | 73 | // override default for LMICbandplan_isFSK() 74 | #undef LMICbandplan_isFSK 75 | #define LMICbandplan_isFSK() (/* RX datarate */LMIC.dndr == AS923_DR_FSK) 76 | 77 | #define LMICbandplan_getInitialDrJoin() (AS923_DR_SF10) 78 | 79 | void LMICas923_setBcnRxParams(void); 80 | #define LMICbandplan_setBcnRxParams() LMICas923_setBcnRxParams() 81 | 82 | u4_t LMICas923_convFreq(xref2cu1_t ptr); 83 | #define LMICbandplan_convFreq(ptr) LMICas923_convFreq(ptr) 84 | 85 | void LMICas923_initJoinLoop(void); 86 | #define LMICbandplan_initJoinLoop() LMICas923_initJoinLoop() 87 | 88 | // for as923, depending on dwell, we may need to do something else 89 | #undef LMICbandplan_setRx1Params 90 | void LMICas923_setRx1Params(void); 91 | #define LMICbandplan_setRx1Params() LMICas923_setRx1Params() 92 | 93 | ostime_t LMICas923_nextTx(ostime_t now); 94 | #define LMICbandplan_nextTx(now) LMICas923_nextTx(now) 95 | 96 | ostime_t LMICas923_nextJoinState(void); 97 | #define LMICbandplan_nextJoinState() LMICas923_nextJoinState() 98 | 99 | void LMICas923_initDefaultChannels(bit_t join); 100 | #define LMICbandplan_initDefaultChannels(join) LMICas923_initDefaultChannels(join) 101 | 102 | // override default for LMICbandplan_updateTX 103 | #undef LMICbandplan_updateTx 104 | void LMICas923_updateTx(ostime_t txbeg); 105 | #define LMICbandplan_updateTx(txbeg) LMICas923_updateTx(txbeg) 106 | 107 | #undef LMICbandplan_nextJoinTime 108 | ostime_t LMICas923_nextJoinTime(ostime_t now); 109 | #define LMICbandplan_nextJoinTime(now) LMICas923_nextJoinTime(now) 110 | 111 | #undef LMICbandplan_validDR 112 | bit_t LMICas923_validDR(dr_t dr); 113 | #define LMICbandplan_validDR(dr) LMICas923_validDR(dr) 114 | 115 | #endif // _lmic_bandplan_as923_h_ 116 | -------------------------------------------------------------------------------- /src/lmic/lmic_bandplan_au915.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019-2021 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_bandplan_au915_h_ 30 | # define _lmic_bandplan_au915_h_ 31 | 32 | // preconditions for lmic_us_like.h 33 | #define LMICuslike_getFirst500kHzDR() (LORAWAN_DR6) 34 | #define LMICuslike_getJoin125kHzDR() (LORAWAN_DR2) 35 | 36 | #ifndef _lmic_us_like_h_ 37 | # include "lmic_us_like.h" 38 | #endif 39 | 40 | // return maximum frame length (including PHY header) for this data rate (au915); 0 --> not valid dr. 41 | uint8_t LMICau915_maxFrameLen(uint8_t dr); 42 | // return maximum frame length (including PHY header) for this data rate; 0 --> not valid dr. 43 | #define LMICbandplan_maxFrameLen(dr) LMICau915_maxFrameLen(dr) 44 | 45 | int8_t LMICau915_pow2dbm(uint8_t mcmd_ladr_p1); 46 | #define pow2dBm(mcmd_ladr_p1) LMICau915_pow2dbm(mcmd_ladr_p1) 47 | 48 | ostime_t LMICau915_dr2hsym(uint8_t dr); 49 | #define dr2hsym(dr) LMICau915_dr2hsym(dr) 50 | 51 | 52 | #define LMICbandplan_getInitialDrJoin() (LORAWAN_DR2) 53 | 54 | void LMICau915_initJoinLoop(void); 55 | #define LMICbandplan_initJoinLoop() LMICau915_initJoinLoop() 56 | 57 | void LMICau915_setBcnRxParams(void); 58 | #define LMICbandplan_setBcnRxParams() LMICau915_setBcnRxParams() 59 | 60 | u4_t LMICau915_convFreq(xref2cu1_t ptr); 61 | #define LMICbandplan_convFreq(ptr) LMICau915_convFreq(ptr) 62 | 63 | void LMICau915_setRx1Params(void); 64 | #define LMICbandplan_setRx1Params() LMICau915_setRx1Params() 65 | 66 | void LMICau915_updateTx(ostime_t txbeg); 67 | #define LMICbandplan_updateTx(txbeg) LMICau915_updateTx(txbeg) 68 | 69 | #undef LMICbandplan_validDR 70 | bit_t LMICau915_validDR(dr_t dr); 71 | #define LMICbandplan_validDR(dr) LMICau915_validDR(dr) 72 | 73 | #endif // _lmic_bandplan_au915_h_ 74 | -------------------------------------------------------------------------------- /src/lmic/lmic_bandplan_eu868.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019-2021 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_eu868_h_ 30 | # define _lmic_eu868_h_ 31 | 32 | #ifndef _lmic_eu_like_h_ 33 | # include "lmic_eu_like.h" 34 | #endif 35 | 36 | // return maximum frame length (including PHY header) for this data rate (eu868); 0 --> not valid dr. 37 | uint8_t LMICeu868_maxFrameLen(uint8_t dr); 38 | // return maximum frame length (including PHY header) for this data rate; 0 --> not valid dr. 39 | #define LMICbandplan_maxFrameLen(dr) LMICeu868_maxFrameLen(dr) 40 | 41 | int8_t LMICeu868_pow2dBm(uint8_t mcmd_ladr_p1); 42 | #define pow2dBm(mcmd_ladr_p1) LMICeu868_pow2dBm(mcmd_ladr_p1) 43 | 44 | // Times for half symbol per DR 45 | // Per DR table to minimize rounding errors 46 | ostime_t LMICeu868_dr2hsym(uint8_t dr); 47 | #define dr2hsym(dr) LMICeu868_dr2hsym(dr) 48 | 49 | 50 | // TODO(tmm@mcci.com) this looks bogus compared to current 1.02 regional 51 | // spec. https://github.com/mcci-catena/arduino-lmic/issues/18 52 | static inline int 53 | LMICeu868_isValidBeacon1(const uint8_t *d) { 54 | return d[OFF_BCN_CRC1] != (u1_t)os_crc16(d, OFF_BCN_CRC1); 55 | } 56 | 57 | #undef LMICbandplan_isValidBeacon1 58 | #define LMICbandplan_isValidBeacon1(pFrame) LMICeu868_isValidBeacon1(pFrame) 59 | 60 | // override default for LMICbandplan_isFSK() 61 | #undef LMICbandplan_isFSK 62 | #define LMICbandplan_isFSK() (/* RX datarate */LMIC.dndr == EU868_DR_FSK) 63 | 64 | #define LMICbandplan_getInitialDrJoin() (EU868_DR_SF7) 65 | 66 | void LMICeu868_setBcnRxParams(void); 67 | #define LMICbandplan_setBcnRxParams() LMICeu868_setBcnRxParams() 68 | 69 | u4_t LMICeu868_convFreq(xref2cu1_t ptr); 70 | #define LMICbandplan_convFreq(ptr) LMICeu868_convFreq(ptr) 71 | 72 | void LMICeu868_initJoinLoop(void); 73 | #define LMICbandplan_initJoinLoop() LMICeu868_initJoinLoop() 74 | 75 | ostime_t LMICeu868_nextTx(ostime_t now); 76 | #define LMICbandplan_nextTx(now) LMICeu868_nextTx(now) 77 | 78 | ostime_t LMICeu868_nextJoinState(void); 79 | #define LMICbandplan_nextJoinState() LMICeu868_nextJoinState() 80 | 81 | void LMICeu868_initDefaultChannels(bit_t join); 82 | #define LMICbandplan_initDefaultChannels(join) LMICeu868_initDefaultChannels(join) 83 | 84 | #undef LMICbandplan_nextJoinTime 85 | ostime_t LMICeu868_nextJoinTime(ostime_t now); 86 | #define LMICbandplan_nextJoinTime(now) LMICeu868_nextJoinTime(now) 87 | 88 | void LMICeu868_setRx1Params(void); 89 | #define LMICbandplan_setRx1Params() LMICeu868_setRx1Params() 90 | 91 | #undef LMICbandplan_validDR 92 | bit_t LMICeu868_validDR(dr_t dr); 93 | #define LMICbandplan_validDR(dr) LMICeu868_validDR(dr) 94 | 95 | #endif // _lmic_eu868_h_ 96 | -------------------------------------------------------------------------------- /src/lmic/lmic_bandplan_in866.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019-2021 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_bandplan_in866_h_ 30 | # define _lmic_bandplan_in866_h_ 31 | 32 | #ifndef _lmic_eu_like_h_ 33 | # include "lmic_eu_like.h" 34 | #endif 35 | 36 | // return maximum frame length (including PHY header) for this data rate (in866); 0 --> not valid dr. 37 | uint8_t LMICin866_maxFrameLen(uint8_t dr); 38 | // return maximum frame length (including PHY header) for this data rate; 0 --> not valid dr. 39 | #define LMICbandplan_maxFrameLen(dr) LMICin866_maxFrameLen(dr) 40 | 41 | int8_t LMICin866_pow2dBm(uint8_t mcmd_ladr_p1); 42 | #define pow2dBm(mcmd_ladr_p1) LMICin866_pow2dBm(mcmd_ladr_p1) 43 | 44 | // Times for half symbol per DR 45 | // Per DR table to minimize rounding errors 46 | ostime_t LMICin866_dr2hsym(uint8_t dr); 47 | #define dr2hsym(dr) LMICin866_dr2hsym(dr) 48 | 49 | static inline int 50 | LMICin866_isValidBeacon1(const uint8_t *d) { 51 | return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1); 52 | } 53 | 54 | #undef LMICbandplan_isValidBeacon1 55 | #define LMICbandplan_isValidBeacon1(pFrame) LMICin866_isValidBeacon1(pFrame) 56 | 57 | // override default for LMICbandplan_isFSK() 58 | #undef LMICbandplan_isFSK 59 | #define LMICbandplan_isFSK() (/* TX datarate */LMIC.dndr == IN866_DR_FSK) 60 | 61 | #define LMICbandplan_getInitialDrJoin() (IN866_DR_SF7) 62 | 63 | void LMICin866_setBcnRxParams(void); 64 | #define LMICbandplan_setBcnRxParams() LMICin866_setBcnRxParams() 65 | 66 | u4_t LMICin866_convFreq(xref2cu1_t ptr); 67 | #define LMICbandplan_convFreq(ptr) LMICin866_convFreq(ptr) 68 | 69 | void LMICin866_initJoinLoop(void); 70 | #define LMICbandplan_initJoinLoop() LMICin866_initJoinLoop() 71 | 72 | ostime_t LMICin866_nextTx(ostime_t now); 73 | #define LMICbandplan_nextTx(now) LMICin866_nextTx(now) 74 | 75 | ostime_t LMICin866_nextJoinState(void); 76 | #define LMICbandplan_nextJoinState() LMICin866_nextJoinState() 77 | 78 | void LMICin866_initDefaultChannels(bit_t join); 79 | #define LMICbandplan_initDefaultChannels(join) LMICin866_initDefaultChannels(join) 80 | 81 | void LMICin866_setRx1Params(void); 82 | #define LMICbandplan_setRx1Params() LMICin866_setRx1Params() 83 | 84 | #undef LMICbandplan_validDR 85 | bit_t LMICin866_validDR(dr_t dr); 86 | #define LMICbandplan_validDR(dr) LMICin866_validDR(dr) 87 | 88 | #endif // _lmic_bandplan_in866_h_ 89 | -------------------------------------------------------------------------------- /src/lmic/lmic_bandplan_kr920.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019-2021 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_kr920_h_ 30 | # define _lmic_kr920_h_ 31 | 32 | #ifndef _lmic_eu_like_h_ 33 | # include "lmic_eu_like.h" 34 | #endif 35 | 36 | // return maximum frame length (including PHY header) for this data rate (kr920); 0 --> not valid dr. 37 | uint8_t LMICkr920_maxFrameLen(uint8_t dr); 38 | // return maximum frame length (including PHY header) for this data rate; 0 --> not valid dr. 39 | #define LMICbandplan_maxFrameLen(dr) LMICkr920_maxFrameLen(dr) 40 | 41 | int8_t LMICkr920_pow2dBm(uint8_t mcmd_ladr_p1); 42 | #define pow2dBm(mcmd_ladr_p1) LMICkr920_pow2dBm(mcmd_ladr_p1) 43 | 44 | // Times for half symbol per DR 45 | // Per DR table to minimize rounding errors 46 | ostime_t LMICkr920_dr2hsym(uint8_t dr); 47 | #define dr2hsym(dr) LMICkr920_dr2hsym(dr) 48 | 49 | 50 | // TODO(tmm@mcci.com) this looks bogus compared to current 1.02 regional 51 | // spec. https://github.com/mcci-catena/arduino-lmic/issues/18 52 | static inline int 53 | LMICkr920_isValidBeacon1(const uint8_t *d) { 54 | return d[OFF_BCN_CRC1] != (u1_t)os_crc16(d, OFF_BCN_CRC1); 55 | } 56 | 57 | #undef LMICbandplan_isValidBeacon1 58 | #define LMICbandplan_isValidBeacon1(pFrame) LMICkr920_isValidBeacon1(pFrame) 59 | 60 | // override default for LMICbandplan_isFSK() 61 | #undef LMICbandplan_isFSK 62 | #define LMICbandplan_isFSK() (/* always false */ 0) 63 | 64 | #define LMICbandplan_getInitialDrJoin() (KR920_DR_SF7) 65 | 66 | void LMICkr920_setBcnRxParams(void); 67 | #define LMICbandplan_setBcnRxParams() LMICkr920_setBcnRxParams() 68 | 69 | u4_t LMICkr920_convFreq(xref2cu1_t ptr); 70 | #define LMICbandplan_convFreq(ptr) LMICkr920_convFreq(ptr) 71 | 72 | void LMICkr920_initJoinLoop(void); 73 | #define LMICbandplan_initJoinLoop() LMICkr920_initJoinLoop() 74 | 75 | ostime_t LMICkr920_nextTx(ostime_t now); 76 | #define LMICbandplan_nextTx(now) LMICkr920_nextTx(now) 77 | 78 | ostime_t LMICkr920_nextJoinState(void); 79 | #define LMICbandplan_nextJoinState() LMICkr920_nextJoinState() 80 | 81 | void LMICkr920_initDefaultChannels(bit_t join); 82 | #define LMICbandplan_initDefaultChannels(join) LMICkr920_initDefaultChannels(join) 83 | 84 | void LMICkr920_setRx1Params(void); 85 | #define LMICbandplan_setRx1Params() LMICkr920_setRx1Params() 86 | 87 | #undef LMICbandplan_updateTx 88 | void LMICkr920_updateTx(ostime_t txbeg); 89 | #define LMICbandplan_updateTx(t) LMICkr920_updateTx(t) 90 | 91 | #undef LMICbandplan_validDR 92 | bit_t LMICkr920_validDR(dr_t dr); 93 | #define LMICbandplan_validDR(dr) LMICkr920_validDR(dr) 94 | 95 | #endif // _lmic_kr920_h_ 96 | -------------------------------------------------------------------------------- /src/lmic/lmic_bandplan_us915.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019-2021 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_bandplan_us915_h_ 30 | # define _lmic_bandplan_us915_h_ 31 | 32 | // preconditions for lmic_us_like.h 33 | #define LMICuslike_getFirst500kHzDR() (LORAWAN_DR4) 34 | #define LMICuslike_getJoin125kHzDR() (LORAWAN_DR0) 35 | 36 | #ifndef _lmic_us_like_h_ 37 | # include "lmic_us_like.h" 38 | #endif 39 | 40 | // return maximum frame length (including PHY header) for this data rate (us915); 0 --> not valid dr. 41 | uint8_t LMICus915_maxFrameLen(uint8_t dr); 42 | // return maximum frame length (including PHY header) for this data rate; 0 --> not valid dr. 43 | #define LMICbandplan_maxFrameLen(dr) LMICus915_maxFrameLen(dr) 44 | 45 | int8_t LMICus915_pow2dbm(uint8_t mcmd_ladr_p1); 46 | #define pow2dBm(mcmd_ladr_p1) LMICus915_pow2dbm(mcmd_ladr_p1) 47 | 48 | ostime_t LMICus915_dr2hsym(uint8_t dr); 49 | #define dr2hsym(dr) LMICus915_dr2hsym(dr) 50 | 51 | 52 | #define LMICbandplan_getInitialDrJoin() (LORAWAN_DR0) 53 | 54 | void LMICus915_setBcnRxParams(void); 55 | #define LMICbandplan_setBcnRxParams() LMICus915_setBcnRxParams() 56 | 57 | u4_t LMICus915_convFreq(xref2cu1_t ptr); 58 | #define LMICbandplan_convFreq(ptr) LMICus915_convFreq(ptr) 59 | 60 | void LMICus915_initJoinLoop(void); 61 | #define LMICbandplan_initJoinLoop() LMICus915_initJoinLoop() 62 | 63 | void LMICus915_setRx1Params(void); 64 | #define LMICbandplan_setRx1Params() LMICus915_setRx1Params() 65 | 66 | void LMICus915_updateTx(ostime_t txbeg); 67 | #define LMICbandplan_updateTx(txbeg) LMICus915_updateTx(txbeg) 68 | 69 | #undef LMICbandplan_validDR 70 | bit_t LMICus915_validDR(dr_t dr); 71 | #define LMICbandplan_validDR(dr) LMICus915_validDR(dr) 72 | 73 | #endif // _lmic_bandplan_us915_h_ 74 | -------------------------------------------------------------------------------- /src/lmic/lmic_channelshuffle.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: lmic_channelshuffle.c 4 | 5 | Function: 6 | Channel scheduling without replacement. 7 | 8 | Copyright and License: 9 | This file copyright (C) 2021 by 10 | 11 | MCCI Corporation 12 | 3520 Krums Corners Road 13 | Ithaca, NY 14850 14 | 15 | See accompanying LICENSE file for copyright and license information. 16 | 17 | Author: 18 | Terry Moore, MCCI Corporation April 2021 19 | 20 | */ 21 | 22 | #include "lmic.h" 23 | #include 24 | 25 | /****************************************************************************\ 26 | | 27 | | Manifest constants and local declarations. 28 | | 29 | \****************************************************************************/ 30 | 31 | static unsigned sidewaysSum16(const uint16_t *pMask, uint16_t nEntries); 32 | static unsigned findNthSetBit(const uint16_t *pMask, uint16_t bitnum); 33 | 34 | /****************************************************************************\ 35 | | 36 | | Read-only data. 37 | | 38 | \****************************************************************************/ 39 | 40 | /****************************************************************************\ 41 | | 42 | | Variables. 43 | | 44 | \****************************************************************************/ 45 | 46 | /* 47 | 48 | Name: LMIC_findNextChannel() 49 | 50 | Function: 51 | Scan a shuffle mask, and select a channel (without replacement). 52 | 53 | Definition: 54 | int LMIC_findNextChannel( 55 | uint16_t *pShuffleMask, 56 | const uint16_t *pEnableMask, 57 | uint16_t nEntries, 58 | int lastChannel 59 | ); 60 | 61 | Description: 62 | pShuffleMask and pEnableMask are bit vectors. Channels correspond to 63 | bits in little-endian order; entry [0] has channels 0 through 15, entry 64 | [1] channels 16 through 31, and so forth. nEntries specifies the number 65 | of entries in the mask vectors. The enable mask is 1 for a given channel 66 | if that channel is eligible for selection, 0 otherwise. 67 | 68 | This routine selects channels from the shuffle mask until all entries 69 | are exhausted; it then refreshes the shuffle mask from the enable mask. 70 | 71 | If it refreshes the channel mask, lastChannel is taken as a channel number 72 | that is to be avoided in the next selection. (This is to avoid back-to-back 73 | use of a channel across a refresh boundary.) Otherwise lastChannel is 74 | ignored. This avoidance can be suppresed by setting lastChannel to -1. 75 | If only one channel is enabled, lastChannel is also ignored. If lastChannel 76 | is actually disabled, lastChannel is also ignored. 77 | 78 | Returns: 79 | A channel number, in 0 .. nEntries-1, or -1 if the enable mask is 80 | identically zero. 81 | 82 | Notes: 83 | This routine is somewhat optimized for AVR processors, which don't have 84 | multi-bit shifts. 85 | 86 | */ 87 | 88 | int LMIC_findNextChannel( 89 | uint16_t *pShuffleMask, 90 | const uint16_t *pEnableMask, 91 | uint16_t nEntries, 92 | int lastChannel 93 | ) { 94 | unsigned nSet16; 95 | uint16_t saveLastChannelVal; 96 | 97 | // in case someone has changed the enable mask, update 98 | // the shuffle mask so there are no disable bits set. 99 | for (unsigned i = 0; i < nEntries; ++i) { 100 | pShuffleMask[i] &= pEnableMask[i]; 101 | } 102 | 103 | // count the set bits in the shuffle mask (with a factor of 16 for speed) 104 | nSet16 = sidewaysSum16(pShuffleMask, nEntries); 105 | 106 | // if zero, copy the enable mask to the shuffle mask, and recount 107 | if (nSet16 == 0) { 108 | memcpy(pShuffleMask, pEnableMask, nEntries * sizeof(*pShuffleMask)); 109 | nSet16 = sidewaysSum16(pShuffleMask, nEntries); 110 | } else { 111 | // don't try to skip the last channel because it can't be chosen. 112 | lastChannel = -1; 113 | } 114 | 115 | // if still zero, return -1. 116 | if (nSet16 == 0) { 117 | return -1; 118 | } 119 | 120 | // if we have to skip a channel, and we have more than one choice, turn off 121 | // the last channel bit. Post condition: if we really clered a bit, 122 | // saveLastChannelVal will be non-zero. 123 | saveLastChannelVal = 0; 124 | if (nSet16 > 16 && lastChannel >= 0 && lastChannel <= (int)(nEntries * 16)) { 125 | uint16_t const saveLastChannelMask = (1 << (lastChannel & 0xF)); 126 | 127 | saveLastChannelVal = pShuffleMask[lastChannel >> 4] & saveLastChannelMask; 128 | pShuffleMask[lastChannel >> 4] &= ~saveLastChannelMask; 129 | 130 | // if we cleared a bit, reduce the count. 131 | if (saveLastChannelVal > 0) 132 | nSet16 -= 16; 133 | } 134 | 135 | if (saveLastChannelVal == 0) { 136 | // We didn't eliminate a channel, so we don't have to worry. 137 | lastChannel = -1; 138 | } 139 | 140 | // get a random number 141 | unsigned choice = os_getRndU2() % ((uint16_t)nSet16 >> 4); 142 | 143 | // choose a bit based on set bit 144 | unsigned channel = findNthSetBit(pShuffleMask, choice); 145 | pShuffleMask[channel / 16] ^= (1 << (channel & 0xF)); 146 | 147 | // handle channel skip 148 | if (lastChannel >= 0) { 149 | pShuffleMask[lastChannel >> 4] |= saveLastChannelVal; 150 | } 151 | return channel; 152 | } 153 | 154 | static unsigned sidewaysSum16(const uint16_t *pMask, uint16_t nEntries) { 155 | unsigned result; 156 | 157 | result = 0; 158 | for (; nEntries > 0; --nEntries, ++pMask) 159 | { 160 | uint16_t v = *pMask; 161 | 162 | // the following is an adaptation of Knuth 7.1.3 (62). To avoid 163 | // lots of shifts (slow on AVR, and code intensive) and table lookups, 164 | // we sum popc * 16, then divide by 16. 165 | 166 | // sum adjacent bits, making a series of 2-bit sums 167 | v = v - ((v >> 1) & 0x5555u); 168 | v = (v & 0x3333u) + ((v >> 2) & 0x3333u); 169 | // this assumes multiplies are essentialy free; 170 | v = (v & 0xF0F0u) + ((v & 0x0F0Fu) * 16u); 171 | // Accumulate result, but note it's times 16. 172 | // AVR compiler should optimize the x8 shift. 173 | result += (v & 0xFF) + (v >> 8); 174 | } 175 | 176 | // 177 | return result; 178 | } 179 | 180 | static unsigned findNthSetBit(const uint16_t *pMask, uint16_t bitnum) { 181 | unsigned result; 182 | result = 0; 183 | bitnum = bitnum * 16; 184 | for (;; result += 16) { 185 | uint16_t m = *pMask++; 186 | if (m == 0) 187 | continue; 188 | uint16_t v = m - ((m >> 1) & 0x5555u); 189 | v = (v & 0x3333u) + ((v >> 2) & 0x3333u); 190 | // this assumes multiplies are essentialy free; 191 | v = (v & 0xF0F0u) + ((v & 0x0F0Fu) * 16u); 192 | // Accumulate result, but note it's times 16. 193 | // AVR compiler should optimize the x8 shift. 194 | v = (v & 0xFF) + (v >> 8); 195 | if (v <= bitnum) 196 | bitnum -= v; 197 | else { 198 | // the selected bit is in this word. We need to count. 199 | while (bitnum > 0) { 200 | m &= m - 1; 201 | bitnum -= 16; 202 | } 203 | // now the lsb of m is our choice. 204 | // get a mask, then use Knuth 7.1.3 (59) to find the 205 | // bit number. 206 | m &= -m; 207 | result += ((m & 0x5555u) ? 0 : 1) 208 | + ((m & 0x3333u) ? 0 : 2) 209 | + ((m & 0x0F0Fu) ? 0 : 4) 210 | + ((m & 0x00FFu) ? 0 : 8) 211 | ; 212 | break; 213 | } 214 | } 215 | 216 | return result; 217 | } -------------------------------------------------------------------------------- /src/lmic/lmic_compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: lmic_compat.h 4 | 5 | Function: 6 | Symbols that are defined for backward compatibility 7 | 8 | Copyright notice and license info: 9 | See LICENSE file accompanying this project. 10 | 11 | Author: 12 | Terry Moore, MCCI Corporation January 2020 13 | 14 | Description: 15 | This include file centralizes backwards compatibility 16 | definitions. The idea is to centralize the decision, 17 | so it's clear as to what's deprecated. 18 | 19 | */ 20 | 21 | #ifndef _lmic_compat_h_ /* prevent multiple includes */ 22 | #define _lmic_compat_h_ 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif 27 | 28 | #ifndef ARDUINO_LMIC_VERSION 29 | # error "This file is normally included from lmic.h, not stand alone" 30 | #endif 31 | 32 | #define LMIC_DEPRECATE(m) _Pragma(#m) 33 | 34 | #if ! defined(LMIC_REGION_au921) && ARDUINO_LMIC_VERSION < ARDUINO_LMIC_VERSION_CALC(5,0,0,0) 35 | # define LMIC_REGION_au921 LMIC_DEPRECATE(GCC warning "LMIC_REGION_au921 is deprecated, EOL at V5, use LMIC_REGION_au915") \ 36 | LMIC_REGION_au915 37 | 38 | // Frequency plan symbols 39 | # define AU921_DR_SF12 LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF12 40 | # define AU921_DR_SF11 LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF11 41 | # define AU921_DR_SF10 LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF10 42 | # define AU921_DR_SF9 LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF9 43 | # define AU921_DR_SF8 LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF8 44 | # define AU921_DR_SF7 LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF7 45 | # define AU921_DR_SF8C LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF8C 46 | # define AU921_DR_NONE LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_NONE 47 | # define AU921_DR_SF12CR LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF12CR 48 | # define AU921_DR_SF11CR LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF11CR 49 | # define AU921_DR_SF10CR LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF10CR 50 | # define AU921_DR_SF9CR LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF9CR 51 | # define AU921_DR_SF8CR LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF8CR 52 | # define AU921_DR_SF7CR LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_DR_SF7CR 53 | # define AU921_125kHz_UPFBASE LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_125kHz_UPFBASE 54 | # define AU921_125kHz_UPFSTEP LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_125kHz_UPFSTEP 55 | # define AU921_500kHz_UPFBASE LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_500kHz_UPFBASE 56 | # define AU921_500kHz_UPFSTEP LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_500kHz_UPFSTEP 57 | # define AU921_500kHz_DNFBASE LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_500kHz_DNFBASE 58 | # define AU921_500kHz_DNFSTEP LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_500kHz_DNFSTEP 59 | # define AU921_FREQ_MIN LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_FREQ_MIN 60 | # define AU921_FREQ_MAX LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_FREQ_MAX 61 | # define AU921_TX_EIRP_MAX_DBM LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_TX_EIRP_MAX_DBM 62 | # define AU921_INITIAL_TxParam_UplinkDwellTime LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_INITIAL_TxParam_UplinkDwellTime 63 | # define AU921_UPLINK_DWELL_TIME_osticks LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_UPLINK_DWELL_TIME_osticks 64 | # define DR_PAGE_AU921 LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") DR_PAGE_AU915 65 | # define AU921_LMIC_REGION_EIRP LMIC_DEPRECATE(GCC warning "A921 symbols are deprecated EOL V5, use AU915") AU915_LMIC_REGION_EIRP 66 | #endif 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | 72 | #endif /* _lmic_compat_h_ */ 73 | -------------------------------------------------------------------------------- /src/lmic/lmic_compliance.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: lmic_compliance.h 4 | 5 | Function: 6 | Internal header file for compliance-related work. 7 | 8 | Copyright notice and license info: 9 | See LICENSE file accompanying this project. 10 | 11 | Author: 12 | Terry Moore, MCCI Corporation March 2019 13 | 14 | Description: 15 | This header file allows us to break up the compliance 16 | functions into multiple .c files if we wish. 17 | 18 | */ 19 | 20 | #ifndef _lmic_compliance_h_ /* prevent multiple includes */ 21 | #define _lmic_compliance_h_ 22 | 23 | #ifdef __cplusplus 24 | extern "C"{ 25 | #endif 26 | 27 | #ifndef _lmic_h_ 28 | # include "lmic.h" 29 | #endif 30 | 31 | #include 32 | #include 33 | 34 | typedef struct lmic_compliance_s lmic_compliance_t; 35 | 36 | // concrete type for the state enumeration for the compliance engine. 37 | typedef uint8_t lmic_compliance_state_t; 38 | 39 | enum lmic_compliance_state_e { 40 | LMIC_COMPLIANCE_STATE_IDLE = 0, // app state 41 | LMIC_COMPLIANCE_STATE_STOPPING = 1, // transitioning back to app 42 | LMIC_COMPLIANCE_STATE_ACTIVATING = 2, // transitioning to compliance state 43 | LMIC_COMPLIANCE_STATE_ACTIVE = 3, // in compliance state 44 | }; 45 | 46 | // return true if a state value indicates that the FSM is active. 47 | static inline bool 48 | lmic_compliance_state_IsActive(lmic_compliance_state_t s) { 49 | return s >= LMIC_COMPLIANCE_STATE_ACTIVATING; 50 | } 51 | 52 | // events from the outside world to the FSM 53 | typedef uint8_t lmic_compliance_eventflags_t; 54 | 55 | enum lmic_compliance_eventflags_e { 56 | LMIC_COMPLIANCE_EVENT_ACTIVATE = 1u << 0, 57 | LMIC_COMPLIANCE_EVENT_DEACTIVATE = 1u << 1, 58 | LMIC_COMPLIANCE_EVENT_TIMER_EXPIRED = 1u << 2, 59 | LMIC_COMPLIANCE_EVENT_UPLINK_COMPLETE = 1u << 3, 60 | LMIC_COMPLIANCE_EVENT_ECHO_REQUEST = 1u << 4, 61 | }; 62 | 63 | typedef uint8_t lmic_compliance_fsmflags_t; 64 | enum lmic_compliance_fsmflags_e { 65 | LMIC_COMPLIANCE_FSM_ACTIVE = 1u << 0, 66 | LMIC_COMPLIANCE_FSM_REENTERED = 1u << 1, 67 | LMIC_COMPLIANCE_FSM_CONFIRM = 1u << 2, 68 | }; 69 | 70 | typedef uint8_t lmic_compliance_fsmstate_t; 71 | enum lmic_compliance_fsmstate_e { 72 | LMIC_COMPLIANCE_FSMSTATE_INITIAL = 0, 73 | LMIC_COMPLIANCE_FSMSTATE_NOCHANGE = 1, 74 | LMIC_COMPLIANCE_FSMSTATE_ACTIVE = 2, 75 | LMIC_COMPLIANCE_FSMSTATE_INACTIVE = 3, 76 | LMIC_COMPLIANCE_FSMSTATE_TESTMODE = 4, // sending test uplinks 77 | LMIC_COMPLIANCE_FSMSTATE_ECHOING = 5, 78 | LMIC_COMPLIANCE_FSMSTATE_REPORTING = 6, 79 | LMIC_COMPLIANCE_FSMSTATE_RECOVERY = 7, 80 | LMIC_COMPLIANCE_FSMSTATE_TXBUSY = 8, 81 | }; 82 | 83 | #define LMIC_COMPLIANCE_FSMSTATE__NAMES \ 84 | "INITIAL", "NOCHANGE", "ACTIVE", "INACTIVE", "TESTMODE", \ 85 | "ECHOING", "REPORTING", "RECOVERY", "TXBUSY" 86 | 87 | typedef struct lmic_compliance_eventcb_s lmic_compliance_eventcb_t; 88 | struct lmic_compliance_eventcb_s { 89 | // save the user's event CB while active. 90 | lmic_event_cb_t *pEventCb; 91 | // save the user's event data while active. 92 | void *pUserData; 93 | }; 94 | 95 | // structure for saving band settings during test 96 | typedef struct lmic_compliance_band_s lmic_compliance_band_t; 97 | struct lmic_compliance_band_s { 98 | u2_t txcap; // saved 1/duty cycle 99 | }; 100 | 101 | // the state of the compliance engine. 102 | struct lmic_compliance_s { 103 | // uint64 104 | // uintptr 105 | osjob_t timerJob; // the job for driving uplinks 106 | osjob_t fsmJob; // job for reevaluating the FSM. 107 | lmic_compliance_eventcb_t saveEvent; // the user's event handler. 108 | 109 | // uint32 110 | 111 | // uint16 112 | #if CFG_LMIC_EU_like 113 | lmic_compliance_band_t saveBands[MAX_BANDS]; 114 | #endif // CFG_LMIC_EU_like 115 | 116 | // we are required to maintain a downlink count 117 | // that is reset on join/test entry and incremented for 118 | // each valid test message. 119 | uint16_t downlinkCount; 120 | 121 | // uint8 122 | 123 | lmic_compliance_state_t state; // current state of compliance engine. 124 | lmic_compliance_eventflags_t eventflags; // incoming events. 125 | lmic_compliance_fsmflags_t fsmFlags; // FSM operational flags 126 | lmic_compliance_fsmstate_t fsmState; // FSM current state 127 | 128 | uint8_t uplinkSize; 129 | uint8_t uplinkMessage[MAX_LEN_PAYLOAD]; 130 | }; 131 | 132 | extern lmic_compliance_t LMIC_Compliance; 133 | 134 | #ifdef __cplusplus 135 | } // extern "C" 136 | #endif 137 | 138 | #endif /* _lmic_compliance_h_ */ -------------------------------------------------------------------------------- /src/lmic/lmic_env.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: lmic_env.h 4 | 5 | Function: 6 | Sets up macros etc. to make things a little easier for portabilty 7 | 8 | Copyright notice and license info: 9 | See LICENSE file accompanying this project. 10 | 11 | Author: 12 | Terry Moore, MCCI Corporation November 2018 13 | 14 | Description: 15 | This file is an adaptation of MCCI's standard IOCTL framework. 16 | We duplicate a bit of functionality that we might get from other 17 | libraries, so that the LMIC library can continue to stand alone. 18 | 19 | */ 20 | 21 | #ifndef _lmic_env_h_ /* prevent multiple includes */ 22 | #define _lmic_env_h_ 23 | 24 | /* 25 | 26 | Macro: LMIC_C_ASSERT() 27 | 28 | Function: 29 | Declaration-like macro that will cause a compile error if arg is FALSE. 30 | 31 | Definition: 32 | LMIC_C_ASSERT( 33 | BOOL fErrorIfFalse 34 | ); 35 | 36 | Description: 37 | This macro, if used where an external reference declarataion is 38 | permitted, will either compile cleanly, or will cause a compilation 39 | error. The results of using this macro where a declaration is not 40 | permitted are unspecified. 41 | 42 | This is different from #if !(fErrorIfFalse) / #error in that the 43 | expression is evaluated by the compiler rather than by the pre- 44 | processor. Therefore things like sizeof() can be used. 45 | 46 | Returns: 47 | No explicit result -- either compiles cleanly or causes a compile 48 | error. 49 | 50 | */ 51 | 52 | #ifndef LMIC_C_ASSERT 53 | # define LMIC_C_ASSERT(e) \ 54 | void LMIC_C_ASSERT__(int LMIC_C_ASSERT_x[(e) ? 1: -1]) 55 | #endif 56 | 57 | /****************************************************************************\ 58 | | 59 | | Define the begin/end declaration tags for C++ co-existance 60 | | 61 | \****************************************************************************/ 62 | 63 | #ifdef __cplusplus 64 | # define LMIC_BEGIN_DECLS extern "C" { 65 | # define LMIC_END_DECLS } 66 | #else 67 | # define LMIC_BEGIN_DECLS /* nothing */ 68 | # define LMIC_END_DECLS /* nothing */ 69 | #endif 70 | 71 | //---------------------------------------------------------------------------- 72 | // Annotations to avoid various "unused" warnings. These must appear as a 73 | // statement in the function body; the macro annotates the variable to quiet 74 | // compiler warnings. The way this is done is compiler-specific, and so these 75 | // definitions are fall-backs, which might be overridden. 76 | // 77 | // Although these are all similar, we don't want extra macro expansions, 78 | // so we define each one explicitly rather than relying on a common macro. 79 | //---------------------------------------------------------------------------- 80 | 81 | // signal that a parameter is intentionally unused. 82 | #ifndef LMIC_UNREFERENCED_PARAMETER 83 | # define LMIC_UNREFERENCED_PARAMETER(v) do { (void) (v); } while (0) 84 | #endif 85 | 86 | // an API parameter is a parameter that is required by an API definition, but 87 | // happens to be unreferenced in this implementation. This is a stronger 88 | // assertion than LMIC_UNREFERENCED_PARAMETER(): this parameter is here 89 | // becuase of an API contract, but we have no use for it in this function. 90 | #ifndef LMIC_API_PARAMETER 91 | # define LMIC_API_PARAMETER(v) do { (void) (v); } while (0) 92 | #endif 93 | 94 | // an intentionally-unreferenced variable. 95 | #ifndef LMIC_UNREFERENCED_VARIABLE 96 | # define LMIC_UNREFERENCED_VARIABLE(v) do { (void) (v); } while (0) 97 | #endif 98 | 99 | // we have three (!) debug levels (LMIC_DEBUG_LEVEL > 0, LMIC_DEBUG_LEVEL > 1, 100 | // and LMIC_X_DEBUG_LEVEL > 0. In each case we might have parameters or 101 | // or varables that are only refereneced at the target debug level. 102 | 103 | // Parameter referenced only if debugging at level > 0. 104 | #ifndef LMIC_DEBUG1_PARAMETER 105 | # if LMIC_DEBUG_LEVEL > 0 106 | # define LMIC_DEBUG1_PARAMETER(v) do { ; } while (0) 107 | # else 108 | # define LMIC_DEBUG1_PARAMETER(v) do { (void) (v); } while (0) 109 | # endif 110 | #endif 111 | 112 | // variable referenced only if debugging at level > 0 113 | #ifndef LMIC_DEBUG1_VARIABLE 114 | # if LMIC_DEBUG_LEVEL > 0 115 | # define LMIC_DEBUG1_VARIABLE(v) do { ; } while (0) 116 | # else 117 | # define LMIC_DEBUG1_VARIABLE(v) do { (void) (v); } while (0) 118 | # endif 119 | #endif 120 | 121 | // parameter referenced only if debugging at level > 1 122 | #ifndef LMIC_DEBUG2_PARAMETER 123 | # if LMIC_DEBUG_LEVEL > 1 124 | # define LMIC_DEBUG2_PARAMETER(v) do { ; } while (0) 125 | # else 126 | # define LMIC_DEBUG2_PARAMETER(v) do { (void) (v); } while (0) 127 | # endif 128 | #endif 129 | 130 | // variable referenced only if debugging at level > 1 131 | #ifndef LMIC_DEBUG2_VARIABLE 132 | # if LMIC_DEBUG_LEVEL > 1 133 | # define LMIC_DEBUG2_VARIABLE(v) do { ; } while (0) 134 | # else 135 | # define LMIC_DEBUG2_VARIABLE(v) do { (void) (v); } while (0) 136 | # endif 137 | #endif 138 | 139 | // parameter referenced only if LMIC_X_DEBUG_LEVEL > 0 140 | #ifndef LMIC_X_DEBUG_PARAMETER 141 | # if LMIC_X_DEBUG_LEVEL > 0 142 | # define LMIC_X_DEBUG_PARAMETER(v) do { ; } while (0) 143 | # else 144 | # define LMIC_X_DEBUG_PARAMETER(v) do { (void) (v); } while (0) 145 | # endif 146 | #endif 147 | 148 | // variable referenced only if LMIC_X_DEBUG_LEVEL > 0 149 | #ifndef LMIC_X_DEBUG_VARIABLE 150 | # if LMIC_X_DEBUG_LEVEL > 0 151 | # define LMIC_X_DEBUG_VARIABLE(v) do { ; } while (0) 152 | # else 153 | # define LMIC_X_DEBUG_VARIABLE(v) do { (void) (v); } while (0) 154 | # endif 155 | #endif 156 | 157 | // parameter referenced only if EV() macro is enabled (which it never is) 158 | // TODO(tmm@mcci.com) take out the EV() framework as it reuqires C++, and 159 | // this code is really C-99 to its bones. 160 | #ifndef LMIC_EV_PARAMETER 161 | # define LMIC_EV_PARAMETER(v) do { (void) (v); } while (0) 162 | #endif 163 | 164 | // variable referenced only if EV() macro is defined. 165 | #ifndef LMIC_EV_VARIABLE 166 | # define LMIC_EV_VARIABLE(v) do { (void) (v); } while (0) 167 | #endif 168 | 169 | /* 170 | 171 | Macro: LMIC_ABI_STD 172 | 173 | Index: Macro: LMIC_ABI_VARARGS 174 | 175 | Function: 176 | Annotation macros to force a particular binary calling sequence. 177 | 178 | Definition: 179 | #define LMIC_ABI_STD compiler-specific 180 | #define LMIC_ABI_VARARGS compiler-specific 181 | 182 | Description: 183 | These macros are used when declaring a function type, and indicate 184 | that a particular calling sequence is to be used. They are normally 185 | used between the type portion of the function declaration and the 186 | name of the function. For example: 187 | 188 | typedef void LMIC_ABI_STD myCallBack_t(void); 189 | 190 | It's important to use this in libraries on platforms with multiple 191 | calling sequences, because different components can be compiled with 192 | different defaults. 193 | 194 | Returns: 195 | Not applicable. 196 | 197 | */ 198 | 199 | /* ABI marker for normal (fixed parameter count) functions -- used for function types */ 200 | #ifndef LMIC_ABI_STD 201 | # ifdef _MSC_VER 202 | # define LMIC_ABI_STD __stdcall 203 | # else 204 | # define LMIC_ABI_STD /* nothing */ 205 | # endif 206 | #endif 207 | 208 | /* ABI marker for VARARG functions -- used for function types */ 209 | #ifndef LMIC_ABI_VARARGS 210 | # ifdef _MSC_VER 211 | # define LMIC_ABI_VARARGS __cdecl 212 | # else 213 | # define LMIC_ABI_VARARGS /* nothing */ 214 | # endif 215 | #endif 216 | 217 | /* 218 | 219 | Macro: LMIC_DECLARE_FUNCTION_WEAK() 220 | 221 | Function: 222 | Declare an external function as a weak reference. 223 | 224 | Definition: 225 | #define LMIC_DECLARE_FUNCTION_WEAK(ReturnType, FunctionName, Params) ... 226 | 227 | Description: 228 | This macro generates a weak reference to the specified function. 229 | 230 | Example: 231 | LMIC_DECLARE_FUNCTION_WEAK(void, onEvent, (ev_t e)); 232 | 233 | This saya that onEvent is a weak external reference. When calling 234 | onEvent, you must always first check whether it's supplied: 235 | 236 | if (onEvent != NULL) 237 | onEvent(e); 238 | 239 | Returns: 240 | This macro expands to a declaration, without a trailing semicolon. 241 | 242 | Notes: 243 | This form allows for compilers that use _Pragma(weak, name) instead 244 | of inline attributes. 245 | 246 | */ 247 | 248 | #define LMIC_DECLARE_FUNCTION_WEAK(a_ReturnType, a_FunctionName, a_Params) \ 249 | a_ReturnType __attribute__((__weak__)) a_FunctionName a_Params 250 | 251 | #endif /* _lmic_env_h_ */ -------------------------------------------------------------------------------- /src/lmic/lmic_eu_like.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_eu_like_h_ 30 | # define _lmic_eu_like_h_ 31 | 32 | #ifndef _lmic_h_ 33 | # include "lmic.h" 34 | #endif 35 | 36 | // make sure we want US-like code 37 | #if !CFG_LMIC_EU_like 38 | # error "lmic not configured for EU-like bandplan" 39 | #endif 40 | 41 | // TODO(tmm@mcci.com): this should come from the lmic.h or lorabase.h file; and 42 | // it's probably affected by the fix to this issue: 43 | // https://github.com/mcci-catena/arduino-lmic/issues/2 44 | #define DNW2_SAFETY_ZONE ms2osticks(3000) 45 | 46 | // provide a default for LMICbandplan_isValidBeacon1() 47 | static inline int 48 | LMICeulike_isValidBeacon1(const uint8_t *d) { 49 | return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1); 50 | } 51 | 52 | #define LMICbandplan_isValidBeacon1(pFrame) LMICeulike_isValidBeacon1(pFrame) 53 | 54 | 55 | // provide a default for LMICbandplan_isFSK() 56 | #define LMICbandplan_isFSK() (0) 57 | 58 | // provide a default LMICbandplan_txDoneDoFSK() 59 | void LMICeulike_txDoneFSK(ostime_t delay, osjobcb_t func); 60 | #define LMICbandplan_txDoneFSK(delay, func) LMICeulike_txDoneFSK(delay, func) 61 | 62 | #define LMICbandplan_joinAcceptChannelClear() LMICbandplan_initDefaultChannels(/* normal, not join */ 0) 63 | 64 | enum { BAND_MILLI = 0, BAND_CENTI = 1, BAND_DECI = 2, BAND_AUX = 3 }; 65 | 66 | // there's a CFList on joins for EU-like plans 67 | #define LMICbandplan_hasJoinCFlist() (1) 68 | 69 | /// \brief process CFLists from JoinAccept for EU-like regions 70 | void LMICeulike_processJoinAcceptCFList(void); 71 | /// \brief by default, EU-like plans use LMICeulike_processJoinAcceptCFList 72 | #define LMICbandplan_processJoinAcceptCFList LMICeulike_processJoinAcceptCFList 73 | 74 | #define LMICbandplan_advanceBeaconChannel() \ 75 | do { /* nothing */ } while (0) 76 | 77 | #define LMICbandplan_resetDefaultChannels() \ 78 | do { /* nothing */ } while (0) 79 | 80 | #define LMICbandplan_setSessionInitDefaultChannels() \ 81 | do { LMICbandplan_initDefaultChannels(/* normal, not join */ 0); } while (0) 82 | 83 | bit_t LMICeulike_canMapChannels(u1_t chpage, u2_t chmap); 84 | #define LMICbandplan_canMapChannels(c, m) LMICeulike_canMapChannels(c, m) 85 | 86 | bit_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap); 87 | #define LMICbandplan_mapChannels(c, m) LMICeulike_mapChannels(c, m) 88 | 89 | void LMICeulike_initJoinLoop(u1_t nDefaultChannels, s1_t adrTxPow); 90 | 91 | void LMICeulike_updateTx(ostime_t txbeg); 92 | #define LMICbandplan_updateTx(t) LMICeulike_updateTx(t) 93 | 94 | ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels); 95 | 96 | static inline ostime_t LMICeulike_nextJoinTime(ostime_t now) { 97 | return now; 98 | } 99 | #define LMICbandplan_nextJoinTime(now) LMICeulike_nextJoinTime(now) 100 | 101 | #define LMICbandplan_init() \ 102 | do { /* nothing */ } while (0) 103 | 104 | void LMICeulike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer); 105 | #define LMICbandplan_saveAdrState(pState) LMICeulike_saveAdrState(pState) 106 | 107 | bit_t LMICeulike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer); 108 | #define LMICbandplan_compareAdrState(pState) LMICeulike_compareAdrState(pState) 109 | 110 | void LMICeulike_restoreAdrState(const lmic_saved_adr_state_t *pStateBuffer); 111 | #define LMICbandplan_restoreAdrState(pState) LMICeulike_restoreAdrState(pState) 112 | 113 | // set Rx1 frequency (might be different than uplink). 114 | void LMICeulike_setRx1Freq(void); 115 | 116 | bit_t LMICeulike_isDataRateFeasible(dr_t dr); 117 | #define LMICbandplan_isDataRateFeasible(dr) LMICeulike_isDataRateFeasible(dr) 118 | 119 | 120 | #endif // _lmic_eu_like_h_ 121 | -------------------------------------------------------------------------------- /src/lmic/lmic_us_like.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2017, 2019 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _lmic_us_like_h_ 30 | # define _lmic_us_like_h_ 31 | 32 | // make sure we want US-like code 33 | #if !CFG_LMIC_US_like 34 | # error "lmic not configured for us-like bandplan" 35 | #endif 36 | 37 | // TODO(tmm@mcci.com): this should come from the lmic.h or lorabase.h file; and 38 | // it's probably affected by the fix to this issue: 39 | // https://github.com/mcci-catena/arduino-lmic/issues/2 40 | #define DNW2_SAFETY_ZONE ms2osticks(750) 41 | 42 | #define IS_CHANNEL_125khz(c) (c<64) 43 | #define IS_CHANNEL_500khz(c) (c>=64 && c<72) 44 | #define ENABLED_CHANNEL(chnl) ((LMIC.channelMap[(chnl >> 4)] & (1<<(chnl & 0x0F))) != 0) 45 | 46 | // library functions: called from bandplan 47 | void LMICuslike_initJoinLoop(void); 48 | 49 | // provide the isValidBeacon1 function -- int for bool. 50 | static inline int 51 | LMICuslike_isValidBeacon1(const uint8_t *d) { 52 | return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1); 53 | } 54 | 55 | #define LMICbandplan_isValidBeacon1(pFrame) LMICuslike_isValidBeacon1(pFrame) 56 | 57 | // provide a default for LMICbandplan_isFSK() 58 | #define LMICbandplan_isFSK() (0) 59 | 60 | // provide a default LMICbandplan_txDoneFSK() 61 | #define LMICbandplan_txDoneFSK(delay, func) do { } while (0) 62 | 63 | // provide a default LMICbandplan_joinAcceptChannelClear() 64 | #define LMICbandplan_joinAcceptChannelClear() do { } while (0) 65 | 66 | /// \brief there's a CFList on joins for US-like plans 67 | #define LMICbandplan_hasJoinCFlist() (1) 68 | 69 | /// \brief process CFLists from JoinAccept for EU-like regions 70 | void LMICuslike_processJoinAcceptCFList(void); 71 | /// \brief by default, EU-like plans use LMICuslike_processJoinAcceptCFList 72 | #define LMICbandplan_processJoinAcceptCFList LMICuslike_processJoinAcceptCFList 73 | 74 | 75 | #define LMICbandplan_advanceBeaconChannel() \ 76 | do { LMIC.bcnChnl = (LMIC.bcnChnl+1) & 7; } while (0) 77 | 78 | // TODO(tmm@mcci.com): decide whether we want to do this on every 79 | // reset or just restore the last sub-band selected by the user. 80 | #define LMICbandplan_resetDefaultChannels() \ 81 | LMICbandplan_initDefaultChannels(/* normal */ 0) 82 | 83 | void LMICuslike_initDefaultChannels(bit_t fJoin); 84 | #define LMICbandplan_initDefaultChannels(fJoin) LMICuslike_initDefaultChannels(fJoin) 85 | 86 | #define LMICbandplan_setSessionInitDefaultChannels() \ 87 | do { /* nothing */} while (0) 88 | 89 | bit_t LMICuslike_canMapChannels(u1_t chpage, u2_t chmap); 90 | #define LMICbandplan_canMapChannels(chpage, chmap) LMICuslike_canMapChannels(chpage, chmap) 91 | 92 | bit_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap); 93 | #define LMICbandplan_mapChannels(chpage, chmap) LMICuslike_mapChannels(chpage, chmap) 94 | 95 | ostime_t LMICuslike_nextTx(ostime_t now); 96 | #define LMICbandplan_nextTx(now) LMICuslike_nextTx(now) 97 | 98 | ostime_t LMICuslike_nextJoinState(void); 99 | #define LMICbandplan_nextJoinState() LMICuslike_nextJoinState(); 100 | 101 | static inline ostime_t LMICuslike_nextJoinTime(ostime_t now) { 102 | return now; 103 | } 104 | #define LMICbandplan_nextJoinTime(now) LMICuslike_nextJoinTime(now) 105 | 106 | #define LMICbandplan_init() \ 107 | do { /* nothing */ } while (0) 108 | 109 | void LMICuslike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer); 110 | #define LMICbandplan_saveAdrState(pState) LMICuslike_saveAdrState(pState) 111 | 112 | bit_t LMICuslike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer); 113 | #define LMICbandplan_compareAdrState(pState) LMICuslike_compareAdrState(pState) 114 | 115 | void LMICuslike_restoreAdrState(const lmic_saved_adr_state_t *pStateBuffer); 116 | #define LMICbandplan_restoreAdrState(pState) LMICuslike_restoreAdrState(pState) 117 | 118 | bit_t LMICuslike_isDataRateFeasible(dr_t dr); 119 | #define LMICbandplan_isDataRateFeasible(dr) LMICuslike_isDataRateFeasible(dr) 120 | 121 | #endif // _lmic_us_like_h_ 122 | -------------------------------------------------------------------------------- /src/lmic/lmic_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: lmic_util.h 4 | 5 | Function: 6 | Declare encoding and decoding utilities for LMIC clients. 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI September 2018 13 | 14 | */ 15 | 16 | #ifndef _LMIC_UTIL_H_ 17 | # define _LMIC_UTIL_H_ 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #include 24 | 25 | uint16_t LMIC_f2sflt16(float); 26 | uint16_t LMIC_f2sflt12(float); 27 | uint16_t LMIC_f2uflt16(float); 28 | uint16_t LMIC_f2uflt12(float); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /* _LMIC_UTIL_H_ */ 35 | -------------------------------------------------------------------------------- /src/lmic/lorabase_as923.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * All rights reserved. 4 | * 5 | * Copyright (c) 2017 MCCI Corporation 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of the nor the 16 | * names of its contributors may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _lorabase_as923_h_ 32 | #define _lorabase_as923_h_ 33 | 34 | #ifndef _LMIC_CONFIG_PRECONDITIONS_H_ 35 | # include "lmic_config_preconditions.h" 36 | #endif 37 | 38 | /****************************************************************************\ 39 | | 40 | | Basic definitions for AS923 (always in scope) 41 | | 42 | \****************************************************************************/ 43 | 44 | enum _dr_as923_t { 45 | AS923_DR_SF12 = 0, 46 | AS923_DR_SF11, 47 | AS923_DR_SF10, 48 | AS923_DR_SF9, 49 | AS923_DR_SF8, 50 | AS923_DR_SF7, 51 | AS923_DR_SF7B, 52 | AS923_DR_FSK, 53 | AS923_DR_NONE 54 | }; 55 | 56 | // Bands: 57 | // g1 : 1% 16dBm 58 | // freq band datarates 59 | enum { 60 | AS923_F1 = 923200000, // g1 SF7-12 61 | AS923_F2 = 923400000, // g1 SF7-12 62 | AS923_FDOWN = 923200000, // (RX2 freq, DR2) 63 | AS923_FBCN = 923400000, // default BCN, DR3 64 | AS923_FPING = 923400000, // default ping, DR3 65 | }; 66 | enum { 67 | AS923_FREQ_MIN = 915000000, 68 | AS923_FREQ_MAX = 928000000 69 | }; 70 | enum { 71 | AS923_JP_TX_EIRP_MAX_DBM = 13, // 13 dBm = 19.95mW < 20mW 72 | AS923_TX_EIRP_MAX_DBM = 16 // 16 dBm 73 | }; 74 | enum { DR_PAGE_AS923 = 0x10 * (LMIC_REGION_as923 - 1) }; 75 | 76 | enum { AS923_LMIC_REGION_EIRP = 1 }; // region uses EIRP 77 | 78 | enum { AS923JP_LBT_US = 5000 }; // microseconds of LBT time -- 5000 ==> 79 | // 5 ms. We use us rather than ms for 80 | // future 128us support, and just for 81 | // backward compatibility -- there 82 | // is code that uses the _US constant, 83 | // and it's awkward to break it. 84 | 85 | enum { AS923JP_LBT_DB_MAX = -80 }; // maximum channel strength in dB; if TX 86 | // we measure more than this, we don't tx. 87 | 88 | // AS923 v1.1, all channels face a 1% duty cycle. So this will have to change 89 | // in the future via a config. But this code base needs major changes for 90 | // v1.1 in any case. 91 | enum { AS923_V102_TX_CAP = 100 }; // v1.0.2 allows 100% 92 | 93 | #ifndef AS923_TX_CAP 94 | # define AS923_TX_CAP AS923_V102_TX_CAP 95 | #endif 96 | 97 | // TxParam defaults 98 | enum { 99 | // initial value of UplinkDwellTime before TxParamSetupReq received. 100 | AS923_INITIAL_TxParam_UplinkDwellTime = 1, 101 | // initial value of DownlinkDwellTime before TxParamSetupReq received. 102 | AS923_INITIAL_TxParam_DownlinkDwellTime = 1, 103 | AS923_UPLINK_DWELL_TIME_osticks = sec2osticks(20), 104 | }; 105 | 106 | #endif /* _lorabase_as923_h_ */ 107 | -------------------------------------------------------------------------------- /src/lmic/lorabase_au915.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * All rights reserved. 4 | * 5 | * Copyright (c) 2017 MCCI Corporation 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of the nor the 16 | * names of its contributors may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _lorabase_au915_h_ 32 | #define _lorabase_au915_h_ 33 | 34 | #ifndef _LMIC_CONFIG_PRECONDITIONS_H_ 35 | # include "lmic_config_preconditions.h" 36 | #endif 37 | 38 | /****************************************************************************\ 39 | | 40 | | Basic definitions for AU 915 (always in scope) 41 | | 42 | \****************************************************************************/ 43 | 44 | // Frequency plan for AU 915 MHz 45 | enum _dr_au915_t { 46 | AU915_DR_SF12 = 0, 47 | AU915_DR_SF11, 48 | AU915_DR_SF10, 49 | AU915_DR_SF9, 50 | AU915_DR_SF8, 51 | AU915_DR_SF7, 52 | AU915_DR_SF8C, 53 | AU915_DR_NONE, 54 | // Devices behind a router: 55 | AU915_DR_SF12CR = 8, 56 | AU915_DR_SF11CR, 57 | AU915_DR_SF10CR, 58 | AU915_DR_SF9CR, 59 | AU915_DR_SF8CR, 60 | AU915_DR_SF7CR 61 | }; 62 | 63 | // Default frequency plan for AU 915MHz 64 | enum { 65 | AU915_125kHz_UPFBASE = 915200000, 66 | AU915_125kHz_UPFSTEP = 200000, 67 | AU915_500kHz_UPFBASE = 915900000, 68 | AU915_500kHz_UPFSTEP = 1600000, 69 | AU915_500kHz_DNFBASE = 923300000, 70 | AU915_500kHz_DNFSTEP = 600000 71 | }; 72 | enum { 73 | AU915_FREQ_MIN = 915000000, 74 | AU915_FREQ_MAX = 928000000 75 | }; 76 | enum { 77 | AU915_TX_EIRP_MAX_DBM = 30 // 30 dBm 78 | }; 79 | enum { 80 | // initial value of UplinkDwellTime before TxParamSetupReq received. 81 | AU915_INITIAL_TxParam_UplinkDwellTime = 1, 82 | AU915_UPLINK_DWELL_TIME_osticks = sec2osticks(20), 83 | }; 84 | 85 | enum { DR_PAGE_AU915 = 0x10 * (LMIC_REGION_au915 - 1) }; 86 | 87 | enum { AU915_LMIC_REGION_EIRP = 1 }; // region uses EIRP 88 | 89 | #endif /* _lorabase_au915_h_ */ -------------------------------------------------------------------------------- /src/lmic/lorabase_eu868.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * All rights reserved. 4 | * 5 | * Copyright (c) 2017 MCCI Corporation 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of the nor the 16 | * names of its contributors may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _lorabase_eu868_h_ 32 | #define _lorabase_eu868_h_ 33 | 34 | #ifndef _LMIC_CONFIG_PRECONDITIONS_H_ 35 | # include "lmic_config_preconditions.h" 36 | #endif 37 | 38 | /****************************************************************************\ 39 | | 40 | | Basic definitions for EU868 (always in scope) 41 | | 42 | \****************************************************************************/ 43 | 44 | // 45 | // Default frequency plan for EU 868MHz ISM band 46 | // data rates 47 | // this is a little confusing: the integer values of these constants are the 48 | // DataRates from the LoRaWAN Regional Parmaeter spec. The names are just 49 | // convenient indications, so we can use them in the rare case that we need to 50 | // choose a DataRate by SF and configuration, not by DR code. 51 | 52 | enum _dr_eu868_t { 53 | EU868_DR_SF12 = 0, 54 | EU868_DR_SF11, 55 | EU868_DR_SF10, 56 | EU868_DR_SF9, 57 | EU868_DR_SF8, 58 | EU868_DR_SF7, 59 | EU868_DR_SF7B, 60 | EU868_DR_FSK, 61 | EU868_DR_NONE 62 | }; 63 | 64 | // Bands: 65 | // g1 : 1% 14dBm 66 | // g2 : 0.1% 14dBm 67 | // g3 : 10% 27dBm 68 | // freq band datarates 69 | enum { 70 | EU868_F1 = 868100000, // g1 SF7-12 71 | EU868_F2 = 868300000, // g1 SF7-12 FSK SF7/250 72 | EU868_F3 = 868500000, // g1 SF7-12 73 | EU868_F4 = 868850000, // g2 SF7-12 74 | EU868_F5 = 869050000, // g2 SF7-12 75 | EU868_F6 = 869525000, // g3 SF7-12 76 | EU868_J4 = 864100000, // g2 SF7-12 used during join 77 | EU868_J5 = 864300000, // g2 SF7-12 ditto 78 | EU868_J6 = 864500000, // g2 SF7-12 ditto 79 | }; 80 | enum { 81 | EU868_FREQ_MIN = 863000000, 82 | EU868_FREQ_MAX = 870000000 83 | }; 84 | enum { 85 | EU868_TX_EIRP_MAX_DBM = 16 // 16 dBm EIRP. So subtract 3 dBm for a 3 dBi antenna. 86 | }; 87 | 88 | enum { EU868_LMIC_REGION_EIRP = 1 }; // region uses EIRP 89 | 90 | enum { DR_PAGE_EU868 = 0x10 * (LMIC_REGION_eu868 - 1) }; 91 | 92 | #endif /* _lorabase_eu868_h_ */ -------------------------------------------------------------------------------- /src/lmic/lorabase_in866.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * All rights reserved. 4 | * 5 | * Copyright (c) 2017 MCCI Corporation 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of the nor the 16 | * names of its contributors may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _lorabase_in866_h_ 32 | #define _lorabase_in866_h_ 33 | 34 | #ifndef _LMIC_CONFIG_PRECONDITIONS_H_ 35 | # include "lmic_config_preconditions.h" 36 | #endif 37 | 38 | /****************************************************************************\ 39 | | 40 | | Basic definitions for IN866 (always in scope) 41 | | 42 | \****************************************************************************/ 43 | 44 | enum _dr_in866_t { 45 | IN866_DR_SF12 = 0, // DR0 46 | IN866_DR_SF11, // DR1 47 | IN866_DR_SF10, // DR2 48 | IN866_DR_SF9, // DR3 49 | IN866_DR_SF8, // DR4 50 | IN866_DR_SF7, // DR5 51 | IN866_DR_RFU, // - 52 | IN866_DR_FSK, // DR7 53 | IN866_DR_NONE 54 | }; 55 | 56 | // There is no dwell-time or duty-cycle limitation for IN 57 | // 58 | // max power: 30dBM 59 | // 60 | // freq datarates 61 | enum { 62 | IN866_F1 = 865062500, // SF7-12 (DR0-5) 63 | IN866_F2 = 865402500, // SF7-12 (DR0-5) 64 | IN866_F3 = 865985000, // SF7-12 (DR0-5) 65 | IN866_FB = 866550000, // beacon/ping 66 | }; 67 | enum { 68 | IN866_FREQ_MIN = 865000000, 69 | IN866_FREQ_MAX = 867000000 70 | }; 71 | enum { 72 | IN866_TX_EIRP_MAX_DBM = 30 // 30 dBm 73 | }; 74 | enum { DR_PAGE_IN866 = 0x10 * (LMIC_REGION_in866 - 1) }; 75 | 76 | enum { IN866_LMIC_REGION_EIRP = 1 }; // region uses EIRP 77 | 78 | #endif /* _lorabase_in866_h_ */ -------------------------------------------------------------------------------- /src/lmic/lorabase_kr920.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * All rights reserved. 4 | * 5 | * Copyright (c) 2017, 2019 MCCI Corporation 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of the nor the 16 | * names of its contributors may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _lorabase_kr920_h_ 32 | #define _lorabase_kr920_h_ 33 | 34 | #ifndef _LMIC_CONFIG_PRECONDITIONS_H_ 35 | # include "lmic_config_preconditions.h" 36 | #endif 37 | 38 | /****************************************************************************\ 39 | | 40 | | Basic definitions for KR920 (always in scope) 41 | | 42 | \****************************************************************************/ 43 | 44 | enum _dr_kr920_t { 45 | KR920_DR_SF12 = 0, // DR0 46 | KR920_DR_SF11, // DR1 47 | KR920_DR_SF10, // DR2 48 | KR920_DR_SF9, // DR3 49 | KR920_DR_SF8, // DR4 50 | KR920_DR_SF7, // DR5 51 | KR920_DR_NONE 52 | }; 53 | 54 | // There is no dwell-time or duty-cycle limitation for IN 55 | // 56 | // max power: 30dBM 57 | // 58 | // freq datarates 59 | enum { 60 | KR920_F1 = 922100000, // SF7-12 (DR0-5) 61 | KR920_F2 = 922300000, // SF7-12 (DR0-5) 62 | KR920_F3 = 922500000, // SF7-12 (DR0-5) 63 | KR920_FBCN = 923100000, // beacon/ping 64 | KR920_F14DBM = 922100000, // Allows 14 dBm (not 10) if >= this. 65 | KR920_FDOWN = 921900000, // RX2 downlink frequency 66 | }; 67 | enum { 68 | KR920_FREQ_MIN = 920900000, 69 | KR920_FREQ_MAX = 923300000 70 | }; 71 | enum { 72 | KR920_TX_EIRP_MAX_DBM = 14, // 14 dBm for most 73 | KR920_TX_EIRP_MAX_DBM_LOW = 10, // 10 dBm for some 74 | }; 75 | enum { DR_PAGE_KR920 = 0x10 * (LMIC_REGION_kr920 - 1) }; 76 | 77 | enum { KR920_LMIC_REGION_EIRP = 1 }; // region uses EIRP 78 | 79 | enum { KR920_LBT_US = 128 }; // microseconds of LBT time. 80 | 81 | enum { KR920_LBT_DB_MAX = -80 }; // maximum channel strength in dB; if TX 82 | // we measure more than this, we don't tx. 83 | 84 | #endif /* _lorabase_in866_h_ */ -------------------------------------------------------------------------------- /src/lmic/lorabase_us915.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * All rights reserved. 4 | * 5 | * Copyright (c) 2017 MCCI Corporation 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of the nor the 16 | * names of its contributors may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _lorabase_us915_h_ 32 | #define _lorabase_us915_h_ 33 | 34 | #ifndef _LMIC_CONFIG_PRECONDITIONS_H_ 35 | # include "lmic_config_preconditions.h" 36 | #endif 37 | 38 | /****************************************************************************\ 39 | | 40 | | Basic definitions for US915 (always in scope) 41 | | 42 | \****************************************************************************/ 43 | 44 | // Frequency plan for US 915MHz ISM band 45 | // data rates 46 | enum _dr_us915_t { 47 | US915_DR_SF10 = 0, 48 | US915_DR_SF9, 49 | US915_DR_SF8, 50 | US915_DR_SF7, 51 | US915_DR_SF8C, 52 | US915_DR_NONE, 53 | // Devices "behind a router" (and upper half of DR list): 54 | US915_DR_SF12CR = 8, 55 | US915_DR_SF11CR, 56 | US915_DR_SF10CR, 57 | US915_DR_SF9CR, 58 | US915_DR_SF8CR, 59 | US915_DR_SF7CR 60 | }; 61 | 62 | // Default frequency plan for US 915MHz 63 | enum { 64 | US915_125kHz_UPFBASE = 902300000, 65 | US915_125kHz_UPFSTEP = 200000, 66 | US915_500kHz_UPFBASE = 903000000, 67 | US915_500kHz_UPFSTEP = 1600000, 68 | US915_500kHz_DNFBASE = 923300000, 69 | US915_500kHz_DNFSTEP = 600000 70 | }; 71 | enum { 72 | US915_FREQ_MIN = 902000000, 73 | US915_FREQ_MAX = 928000000 74 | }; 75 | enum { 76 | US915_TX_MAX_DBM = 30 // 30 dBm (but not EIRP): assumes we're 77 | // on an 64-channel bandplan. See code 78 | // that computes tx power. 79 | }; 80 | 81 | enum { 82 | US915_LinkAdrReq_POW_MAX_1_0_2 = 0xA, 83 | US915_LinkAdrReq_POW_MAX_1_0_3 = 0xE, 84 | }; 85 | 86 | enum { DR_PAGE_US915 = 0x10 * (LMIC_REGION_us915 - 1) }; 87 | 88 | enum { US915_LMIC_REGION_EIRP = 0 }; // region doesn't use EIRP, uses tx power 89 | 90 | #endif /* _lorabase_us915_h_ */ -------------------------------------------------------------------------------- /src/lmic/lorawan_spec_compliance.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: lorawan_spec_compliance.h 4 | 5 | Function: 6 | Details from the LoRaWAN specification for compliance. 7 | 8 | Copyright notice and license info: 9 | See LICENSE file accompanying this project. 10 | 11 | Author: 12 | Terry Moore, MCCI Corporation March 2019 13 | 14 | */ 15 | 16 | #ifndef _lorawan_spec_COMPLIANCE_H_ /* prevent multiple includes */ 17 | #define _lorawan_spec_COMPLIANCE_H_ 18 | 19 | #ifdef __cplusplus 20 | extern "C"{ 21 | #endif 22 | 23 | enum { 24 | // the port for MAC commands 25 | LORAWAN_PORT_MAC = 0u, 26 | // the first port available for applications 27 | LORAWAN_PORT_USER_MIN = 1u, 28 | // the last port available for applications 29 | LORAWAN_PORT_USER_MAX = 223u, 30 | // the base of the reserved port numbers 31 | LORAWAN_PORT_RESERVED = 224u, 32 | // the port for the compliance protocol 33 | LORAWAN_PORT_COMPLIANCE = LORAWAN_PORT_RESERVED + 0u, 34 | }; 35 | 36 | enum lowawan_compliance_cmd_e { 37 | LORAWAN_COMPLIANCE_CMD_DEACTIVATE = 0u, 38 | LORAWAN_COMPLIANCE_CMD_ACTIVATE = 1u, 39 | LORAWAN_COMPLIANCE_CMD_SET_CONFIRM = 2u, 40 | LORAWAN_COMPLIANCE_CMD_SET_UNCONFIRM = 3u, 41 | LORAWAN_COMPLIANCE_CMD_ECHO = 4u, 42 | LORAWAN_COMPLIANCE_CMD_LINK = 5u, 43 | LORAWAN_COMPLIANCE_CMD_JOIN = 6u, 44 | LORAWAN_COMPLIANCE_CMD_CW = 7u, 45 | LORAWAN_COMPLIANCE_CMD_MFG_BASE = 0x80u, 46 | }; 47 | 48 | typedef unsigned char lorawan_compliance_cmd_t; 49 | 50 | // info on specific commands 51 | enum { 52 | LORAWAN_COMPLIANCE_CMD_ACTIVATE_LEN = 4u, 53 | LORAWAN_COMPLIANCE_CMD_ACTIVATE_MAGIC = 1u, 54 | 55 | // Maximum crypto frame size; although the spec says 18, it 56 | // is also used for testing max packet size. 57 | LORAWAN_COMPLIANCE_CMD_ECHO_LEN_MAX = 242u, 58 | }; 59 | 60 | #ifdef __cplusplus 61 | } // extern "C" 62 | #endif 63 | 64 | #endif /* _lorawan_spec_COMPLIANCE_H_ */ -------------------------------------------------------------------------------- /src/lmic/oslmic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 IBM Corporation. 3 | * Copyright (c) 2016-2024, 2019 MCCI Corporation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of the nor the 14 | * names of its contributors may be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #define LMIC_DR_LEGACY 0 30 | 31 | #include "lmic.h" 32 | 33 | extern const struct lmic_pinmap lmic_pins; 34 | 35 | // RUNTIME STATE 36 | static struct { 37 | osjob_t* scheduledjobs; 38 | osjob_t* runnablejobs; 39 | } OS; 40 | 41 | int os_init_ex (const void *pintable) { 42 | memset(&OS, 0x00, sizeof(OS)); 43 | lmic_hal_init_ex(pintable); 44 | if (! radio_init()) 45 | return 0; 46 | LMIC_init(); 47 | return 1; 48 | } 49 | 50 | void os_init() { 51 | if (os_init_ex((const void *)&lmic_pins)) 52 | return; 53 | ASSERT(0); 54 | } 55 | 56 | ostime_t os_getTime () { 57 | return lmic_hal_ticks(); 58 | } 59 | 60 | // unlink job from queue, return if removed 61 | static int unlinkjob (osjob_t** pnext, osjob_t* job) { 62 | for( ; *pnext; pnext = &((*pnext)->next)) { 63 | if(*pnext == job) { // unlink 64 | *pnext = job->next; 65 | return 1; 66 | } 67 | } 68 | return 0; 69 | } 70 | 71 | static osjob_t** getJobQueue(osjob_t* job) { 72 | return os_jobIsTimed(job) ? &OS.scheduledjobs : &OS.runnablejobs; 73 | } 74 | 75 | // clear scheduled job 76 | void os_clearCallback (osjob_t* job) { 77 | lmic_hal_disableIRQs(); 78 | 79 | unlinkjob(getJobQueue(job), job); 80 | 81 | lmic_hal_enableIRQs(); 82 | } 83 | 84 | // schedule immediately runnable job 85 | void os_setCallback (osjob_t* job, osjobcb_t cb) { 86 | osjob_t** pnext; 87 | lmic_hal_disableIRQs(); 88 | 89 | // remove if job was already queued 90 | unlinkjob(getJobQueue(job), job); 91 | 92 | // fill-in job. Ascending memory order is write-queue friendly 93 | job->next = NULL; 94 | job->deadline = 0; 95 | job->func = cb; 96 | 97 | // add to end of run queue 98 | for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next)); 99 | *pnext = job; 100 | lmic_hal_enableIRQs(); 101 | } 102 | 103 | // schedule timed job 104 | void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) { 105 | osjob_t** pnext; 106 | 107 | // special case time 0 -- it will be one tick late. 108 | if (time == 0) 109 | time = 1; 110 | 111 | lmic_hal_disableIRQs(); 112 | 113 | // remove if job was already queued 114 | unlinkjob(getJobQueue(job), job); 115 | 116 | // fill-in job 117 | job->next = NULL; 118 | job->deadline = time; 119 | job->func = cb; 120 | 121 | // insert into schedule 122 | for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) { 123 | if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!) 124 | // enqueue before next element and stop 125 | job->next = *pnext; 126 | break; 127 | } 128 | } 129 | *pnext = job; 130 | lmic_hal_enableIRQs(); 131 | } 132 | 133 | // execute jobs from timer and from run queue 134 | void os_runloop () { 135 | while(1) { 136 | os_runloop_once(); 137 | } 138 | } 139 | 140 | void os_runloop_once() { 141 | osjob_t* j = NULL; 142 | lmic_hal_processPendingIRQs(); 143 | 144 | lmic_hal_disableIRQs(); 145 | // check for runnable jobs 146 | if(OS.runnablejobs) { 147 | j = OS.runnablejobs; 148 | OS.runnablejobs = j->next; 149 | } else if(OS.scheduledjobs && lmic_hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs 150 | j = OS.scheduledjobs; 151 | OS.scheduledjobs = j->next; 152 | } else { // nothing pending 153 | lmic_hal_sleep(); // wake by irq (timer already restarted) 154 | } 155 | lmic_hal_enableIRQs(); 156 | if(j) { // run job callback 157 | j->func(j); 158 | } 159 | } 160 | 161 | // return true if there are any jobs scheduled within time ticks from now. 162 | // return false if any jobs scheduled are at least time ticks in the future. 163 | bit_t os_queryTimeCriticalJobs(ostime_t time) { 164 | if (OS.scheduledjobs && 165 | OS.scheduledjobs->deadline - os_getTime() < time) 166 | return 1; 167 | else 168 | return 0; 169 | } 170 | -------------------------------------------------------------------------------- /src/lmic/oslmic_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Module: oslmic_types.h 4 | 5 | Function: 6 | Basic types from oslmic.h, shared by all layers. 7 | 8 | Copyright & License: 9 | See accompanying LICENSE file. 10 | 11 | Author: 12 | Terry Moore, MCCI November 2018 13 | (based on oslmic.h from IBM). 14 | 15 | */ 16 | 17 | #ifndef _oslmic_types_h_ 18 | # define _oslmic_types_h_ 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | //================================================================================ 27 | //================================================================================ 28 | // Target platform as C library 29 | typedef uint8_t bit_t; 30 | typedef uint8_t u1_t; 31 | typedef int8_t s1_t; 32 | typedef uint16_t u2_t; 33 | typedef int16_t s2_t; 34 | typedef uint32_t u4_t; 35 | typedef int32_t s4_t; 36 | typedef unsigned int uint; 37 | typedef const char* str_t; 38 | 39 | // the HAL needs to give us ticks, so it ought to know the right type. 40 | typedef s4_t ostime_t; 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | /* end of oslmic_types.h */ 47 | #endif /* _oslmic_types_h_ */ 48 | --------------------------------------------------------------------------------