├── .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 |
46 |
47 |
52 |
53 |
54 |
58 |
61 |
65 |
66 |
67 |
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 |
105 |
106 |
107 |
111 |
114 |
118 |
119 |
120 |
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 |
--------------------------------------------------------------------------------