Add initial contents

This commit is contained in:
Leonel Lopes Parente 2021-04-17 18:28:44 +02:00
parent c48ccbc1ca
commit e4724aacff
29 changed files with 5077 additions and 0 deletions

20
.gitignore vendored Normal file
View file

@ -0,0 +1,20 @@
# .gitignore file for LMIC-node
# Exclude any Visual Studio Code and PlatformIO folders/files
.pio
.vscode
.vs
.pioenvs
.piolibdeps
# Exclude all contens from any keyfiles folder
keyfiles/**
# Except following example file
!keyfiles/lorawan-keys_example.h
# Exclude any LoRaWAN key files with following pattern
*lorawan-keys.h
# Exlude lib and include project folders (PlatformIO)
/lib/
/include/

View file

@ -1,6 +1,8 @@
MIT License
Copyright (c) 2021 Leonel Lopes Parente
Copyright (c) 2018 Terry Moore, MCCI
Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -0,0 +1,67 @@
/*******************************************************************************
*
* File: lorawan-keys_example.h
*
* Function: Example for lorawan-keys.h required by LMIC-node.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* Important DO NOT EDIT THIS EXAMPLE FILE (see instructions below)
*
* Decription: lorawan-keys.h defines LoRaWAN keys needed by the LMIC library.
* It can contain keys for both OTAA and for ABP activation.
* Only the keys for the used activation type need to be specified.
*
* It is essential that each key is specified in the correct format.
* lsb: least-significant-byte first, msb: most-significant-byte first.
*
* For security reasons all files in the keyfiles folder (except file
* lorawan-keys_example.h) are excluded from the Git(Hub) repository.
* Also excluded are all files matching the pattern *lorawan-keys.h.
* This way they cannot be accidentally committed to a public repository.
*
* Instructions: 1. Copy this file lorawan-keys_example.h to file lorawan-keys.h
* in the same folder (keyfiles).
* 2. Place/edit required LoRaWAN keys in the new lorawan-keys.h file.
*
******************************************************************************/
#pragma once
#ifndef LORAWAN_KEYS_H_
#define LORAWAN_KEYS_H_
// Optional: If DEVICEID is defined it will be used instead of the default defined in the BSF.
// #define DEVICEID "<deviceid>"
// Keys required for OTAA activation:
// End-device Identifier (u1_t[8]) in lsb format
#define OTAA_DEVEUI 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// Application Identifier (u1_t[8]) in lsb format
#define OTAA_APPEUI 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// Application Key (u1_t[16]) in msb format
#define OTAA_APPKEY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// -----------------------------------------------------------------------------
// Optional: If DEVICEID_ABP is defined it will be used instead of the default defined in the BSF.
// #define ABP_DEVICEID "<deviceid>"
// Keys required for ABP activation:
// End-device Address (u4_t) in uint32_t format.
// Note: The value must start with 0x (current version of TTN Console does not provide this).
#define ABP_DEVADDR 0x00000000
// Network Session Key (u1_t[16]) in msb format
#define ABP_NWKSKEY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// Application Session K (u1_t[16]) in msb format
#define ABP_APPSKEY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
#endif // LORAWAN_KEYS_H_

View file

@ -0,0 +1,27 @@
/*******************************************************************************
*
* File: lmic-node-uplink-formatters.js
*
* Function: LMIC-node uplink payload formatter JavaScript function(s).
*
* Author: Leonel Lopes Parente
*
* Description: These function(s) are for use with The Things Network V3.
*
******************************************************************************/
function decodeUplink(input) {
var data = {};
var warnings = [];
if (input.fPort == 10) {
data.counter = (input.bytes[0] << 8) + input.bytes[1];
}
else {
warnings.push("Unsupported fPort");
}
return {
data: data,
warnings: warnings
};
}

715
platformio.ini Normal file
View file

@ -0,0 +1,715 @@
;-------------------------------------------------------------------------------
;
; File: platformio.ini
;
; Function: Project configuration file for LMIC-node.
;
; Copyright: Copyright (c) 2021 Leonel Lopes Parente
;
; License: MIT License. See accompanying LICENSE file.
;
; Author: Leonel Lopes Parente
;
; Description: This is the main configuration file. It contains:
; - Board selector to select your board type
; - Common settings used for all boards
; - Board specific settings that can be altered per board.
;
; For a description of all settings see README.md
;
;-------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; | Board Selector |
; | |
; | Select your board by uncommenting EXACTLY ONE board-id below. |
; ------------------------------------------------------------------------------
[platformio]
default_envs =
<platformio.ini board selector guard> Comment this line and uncomment one board-id below:
;
; --- LoRa development boards with integrated LoRa support ---
;
; adafruit_feather_m0_lora
; disco_l072cz_lrwan1
; heltec_wifi_lora_32_v2
; heltec_wifi_lora_32
; heltec_wireless_stick_lite
; heltec_wireless_stick
; lopy4
; lora32u4II
; ttgo_lora32_v1
; ttgo_lora32_v2
; ttgo_lora32_v21
; ttgo_tbeam_v07
; ttgo_tbeam_v10
;
; --- Development boards that require an external LoRa module ---
;
; blackpill_f103c8_128k
; blackpill_f103c8
; bluepill_f103c8_128k
; bluepill_f103c8
; lolin_d32_pro
; lolin_d32
; lolin32
; nodemcu_32s
; nodemcuv2
; pro8mhzatmega328
; zerousb
; ------------------------------------------------------------------------------
; | Common Settings |
; | |
; | These settings are shared by all board configurations except for |
; | nodemcuv2 which uses its own monitor_speed setting. |
; ------------------------------------------------------------------------------
[common]
monitor_speed = 115200
build_flags =
-D DO_WORK_INTERVAL_SECONDS=60
; -D ABP_ACTIVATION ; Use ABP instead of OTAA activation
;
; -D WAITFOR_SERIAL_SECONDS=10 ; Can be used to override the default value (10)
; Only used for boards with default set to != 0 in BSF
lib_deps =
olikraus/U8g2 ; OLED display library
lnlp/EasyLed ; LED library
; --------------------------------------------------
; | MCCI LoRaWAN LMIC library specific settings |
; --------------------------------------------------
[mcci_lmic]
; LMIC-node was tested with MCCI LoRaWAN LMIC library v3.3.0.
; Some changes have been announced for future versions of the MCCI library
; which may be incompatible with LMIC-node. In case of problems just
; use mcci-catena/MCCI LoRaWAN LMIC library@3.3.0 below which will
; explicitly use v3.3.0 of the library.
; Perform PlatformIO: Clean after changing library version and
; in case of issues remove the old version from .pio/libdeps/*.
lib_deps =
; Only ONE of below LMIC libraries should be enabled.
mcci-catena/MCCI LoRaWAN LMIC library ; MCCI LMIC library (latest release)
; mcci-catena/MCCI LoRaWAN LMIC library@3.3.0 ; MCCI LMIC library v3.3.0
build_flags =
; Use platformio.ini for settings instead lmic_project_config.h.
-D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS
;
; Ping and beacons not supported for class A, disable to save memory.
-D DISABLE_PING
-D DISABLE_BEACONS
;
; If LMIC_DEBUG_LEVEL is set to value > 0 then LMIC_PRINTF_TO will
; be automatically set to serial (do not set it explicitly).
; -D LMIC_DEBUG_LEVEL=1 ; 0, 1 or 2
;
; -D CFG_sx1272_radio=1 ; Use for SX1272 radio
-D CFG_sx1276_radio=1 ; Use for SX1276 radio
-D USE_ORIGINAL_AES ; Faster but larger, see docs
; -D LMIC_USE_INTERRUPTS ; Not tested or supported on many platforms
; -D LMIC_ENABLE_DeviceTimeReq=1 ; Network time support
;
; --- Regional settings -----
; Enable only one of the following regions:
; -D CFG_as923=1
; -D CFG_as923jp=1
; -D CFG_au915=1
; -D CFG_cn490=1 ; Not yet supported
; -D CFG_cn783=1 ; Not yet supported
; -D CFG_eu433=1 ; Not yet supported
-D CFG_eu868=1
; -D CFG_in866=1
; -D CFG_kr920=1
; -D CFG_us915=1
; --------------------------------------------------
; | IBM LMIC framework library specific settings |
; --------------------------------------------------
[classic_lmic]
; IMPORTANT:
; Region, radio and debug settings CANNOT be changed in platformio.ini.
; They must be configured in file: config.h in the following location:
; .pio/libdeps/<board-id>/IBM LMIC framework/src/lmic
;
; When making changes to config.h:
; CONFIG.H MUST BE CHANGED FOR EACH BOARD SEPARATELY!
; (By default libraries are installed per project per build config/board.)
;
; If LMIC_DEBUG_LEVEL is set to value > 0 then LMIC_PRINTF_TO will
; be automatically set to serial (do not set it explicitly).
lib_deps =
matthijskooijman/IBM LMIC framework ; [Deprecated] Classic LMIC library
build_flags =
; Default values defined in config.h:
; CFG_sx1276_radio 1
; CFG_eu868 1
; LMIC_DEBUG_LEVEL 0
;
; Ping and beacons not supported for class A, disable to save memory.
-D DISABLE_PING
-D DISABLE_BEACONS
; ------------------------------------------------------------------------------
; | LoRa development boards with integrated LoRa support |
; | |
; | Some but not all of these boards have an onboard display. |
; | Some boards require additional wiring that needs to be manually added. |
; | Check the Board Support Files in the boards folder for information. |
; ------------------------------------------------------------------------------
[env:adafruit_feather_m0_lora]
; Adafruit Feather M0 with RF9x LoRa (SAMD21)
; Be aware that this board needs pin (D)IO0 to be manually wired to GPIO pin 5.
; No onboard display.
platform = atmelsam
board = adafruit_feather_m0
framework = arduino
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/adafruit_feather_m0_lora.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:disco_l072cz_lrwan1]
; ST B-L072Z-LRWAN1 Discovery kit (STM32L072CZ)
; Note: When using upload_protocol mbed then upload_port must be set manually (HW and OS dependent).
; No onboard display
platform = ststm32
board = disco_l072cz_lrwan1
framework = arduino
upload_protocol = stlink ; If this fails then try mbed
; upload_protocol = jlink ; Requires onboard programmer firmware upgrade with Segger STLinkReflash utility
; upload_protocol = mbed ; On Windows PlatformIO fails to recognize DIS_L072Z as drive volume
; upload_port = E: ; drive much be explicitly specified for upload port (HA and OS dependent)
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/disco_l072cz_lrwan1.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:heltec_wifi_lora_32_v2]
; Heltec WiFi LoRa 32 V2 (ESP32)
; Onboard OLED display SSD1306 0.96" 128x64
platform = espressif32
board = heltec_wifi_lora_32_V2
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/heltec_wifi_lora_32_v2.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
-D USE_DISPLAY
[env:heltec_wifi_lora_32]
; Heltec WiFi LoRa 32 versions 1.x (ESP32)
; Onboard OLED display SSD1306 0.96" 128x64
platform = espressif32
board = heltec_wifi_lora_32
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/heltec_wifi_lora_32.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
-D USE_DISPLAY
[env:heltec_wireless_stick_lite]
; Heltec Wireless Stick Lite (ESP32)
; No display
platform = espressif32
board = heltec_wireless_stick_lite
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/heltec_wireless_stick_lite.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:heltec_wireless_stick]
; Heltec Wireless Stick (ESP32)
; Onboard OLED display SSD1306 0.49" 64x32
; Display is not supported by LMIC-node because resolution is too low.
platform = espressif32
board = heltec_wireless_stick
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/heltec_wireless_stick.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; NOT SUPPORTED because resolution too low
[env:lopy4]
; Pycom LoPy4 (ESP32)
; Onboard LED is not supported by lmic-node because WS2812 RGB LED.
; No onboard display.
; Requires a Pycom Expansion Board (preferred) or USB to Serial adapter
; for firmware upload and serial port monitoring. See BSP for pin details.
; To put board in upload mode: Manually connect GPIO0 to GND
; with a wire, then press reset and then remove wire from GPIO0 to GND again.
; After upload press the reset button again to start.
platform = espressif32
board = lopy4
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/lopy4.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
; -D USE_LED ; Onboard LED type is not supported
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:lora32u4II]
; BSFrance LoRa32u4 II (ATmega32u4)
; Depending on the version this board may require additional wiring for DIO1.
; lmic-node will not work with MCCI LMIC for this board because not enough memory.
; Therefore Classic LMIC is hardcoded here (independent of setting in [common]).
; No onboard display.
; This is an 8-bit MCU with limited memory, therefore IBM LMIC framework library is used.
platform = atmelavr
board = lora32u4II
framework = arduino
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${classic_lmic.lib_deps}
; ${mcci_lmic.lib_deps} ; MCCI LMIC better LoRaWAN compliance but uses more memory
build_flags =
${common.build_flags}
${classic_lmic.build_flags}
; ${mcci_lmic.lib_deps} ; MCCI LMIC better LoRaWAN compliance but uses more memory
-D BSFILE=\"boards/lora32u4II.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:ttgo_lora32_v1]
; TTGO LoRa32 v1.3 (ESP32)
; Onboard OLED display SSD1306 0.96" 128x64
; Currently unknown if board has programmable onboard LED
platform = espressif32
board = ttgo-lora32-v1
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/ttgo_lora32_v1.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
; -D USE_LED ; Not supported, boards appears to have no user LED
-D USE_DISPLAY
[env:ttgo_lora32_v2]
; TTGO LoRa32 v2.0 (ESP32)
; This board requires manual wiring of DIO1.
; Onboard OLED display SSD1306 0.96" 128x64
; Onboard LED is not usable because LED GPIO is shared with I2C SCL used for display
platform = espressif32
board = ttgo-lora32-v2
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/ttgo_lora32_v2.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
; -D USE_LED ; Not usable because of conflict with I2C
-D USE_DISPLAY
[env:ttgo_lora32_v21]
; TTGO LoRa32 v2.1.6 (ESP32)
; Onboard OLED display SSD1306 0.96" 128x64 SSD1306 0.96" 128x64
; Onboard LED is not usable because LED GPIO is shared with I2C SCL used for display
platform = espressif32
board = ttgo-lora32-v21
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/ttgo_lora32_v21.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
; -D USE_LED ; Not usable because of conflict with I2C
-D USE_DISPLAY
[env:ttgo_tbeam_v07]
; TTGO T-Beam versions 0.x (ESP32)
; No onboard display
platform = espressif32
board = ttgo-t-beam
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/ttgo_tbeam_v07.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:ttgo_tbeam_v10]
; TTGO T-Beam version 1.0 (aka T22_08) (ESP32)
; Requires additional library for its AXP192 power management chip
; No onboard display
platform = espressif32
board = ttgo-t-beam
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
lewisxhe/AXP202X_Library ; Power management chip library
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/ttgo_tbeam_v10.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
; ------------------------------------------------------------------------------
; | Development boards that require an external SPI LoRa module |
; | |
; | None of these boards have an onboard display. |
; | Check the Board Support Files in the boards folder for required wiring!! |
; ------------------------------------------------------------------------------
[env:blackpill_f103c8_128k]
; Blackill F103C8 128k (STMF103C8T6)
; Select the upload protocol to use below.
platform = ststm32
board = blackpill_f103c8_128
framework = arduino
; upload_protocol = serial
upload_protocol = stlink
; upload_protocol = jlink
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/blackpill_f103c8.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:blackpill_f103c8]
; Blackpill F103C8 (64k) (STMF103C8T6)
; Select the upload protocol to use below.
platform = ststm32
board = blackpill_f103c8
framework = arduino
; upload_protocol = serial
upload_protocol = stlink
; upload_protocol = jlink
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/blackpill_f103c8.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:bluepill_f103c8_128k]
; Bluepill F103C8 128k (STMF103C8T6)
; Select the upload protocol to use below.
platform = ststm32
board = bluepill_f103c8_128k
framework = arduino
; upload_protocol = serial
upload_protocol = stlink
; upload_protocol = jlink
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/bluepill_f103c8.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:bluepill_f103c8]
; Bluepill F103C8 (64k) (STMF103C8T6)
; Select the upload protocol to use below.
platform = ststm32
board = bluepill_f103c8
framework = arduino
; upload_protocol = serial
upload_protocol = stlink
; upload_protocol = jlink
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/bluepill_f103c8.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:lolin_d32_pro]
; Wemos Lolin D32 Pro (ESP32)
platform = espressif32
board = lolin_d32_pro
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/lolin_d32_pro.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:lolin_d32]
; Wemos Lolin D32 (ESP32)
platform = espressif32
board = lolin_d32
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/lolin_d32.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:lolin32]
; Wemos Lolin32 (ESP32)
platform = espressif32
board = lolin32
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/lolin32.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:nodemcu_32s]
; NodeMCU-32S (ESP32)
platform = espressif32
board = nodemcu-32s
framework = arduino
upload_speed = 921600
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/nodemcu_32s.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:nodemcuv2]
; NodeMCU V2 (aka NodeMCU 1.0) (ESP8266)
; I2C and external OLED display cannot be used due to shortage of GPIO pins.
; monitor_speed is set to 74880 (independent of setting in [common])
; to be able to read ESP8266 boot messages.
platform = espressif8266
board = nodemcuv2
framework = arduino
upload_speed = 921600
monitor_speed = 74880 ; 74880 so we can read ESP8266 boot messages
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/nodemcuv2.h\"
-D MONITOR_SPEED=${env:nodemcuv2.monitor_speed}
-D USE_SERIAL
-D USE_LED
[env:pro8mhzatmega328]
; Arduino Pro Mini 8 MHz (ATmega328)
; Onboard LED is not usable because GPIO is shared with SPI SCK needed for LoRa module.
; This is an 8-bit MCU with limited memory, therefore IBM LMIC framework library is used.
platform = atmelavr
board = pro8MHzatmega328
framework = arduino
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${classic_lmic.lib_deps}
; ${mcci_lmic.lib_deps} ; MCCI LMIC better LoRaWAN compliance but uses more memory
build_flags =
${common.build_flags}
${classic_lmic.build_flags}
; ${mcci_lmic.lib_deps} ; MCCI LMIC better LoRaWAN compliance but uses more memory
-D BSFILE=\"boards/pro8mhzatmega328.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
; -D USE_LED ; Not usable because of conflict with SPI
; -D USE_DISPLAY ; Requires external I2C OLED display
[env:zerousb]
; Arduino Zero USB (SAMD21)
; For SPI use the ICSP connector on top of the board. It provides
; the SCK, MOSI and MISO pins needed for connecting the LoRa module.
platform = atmelsam
board = zeroUSB
framework = arduino
monitor_speed = ${common.monitor_speed}
lib_deps =
${common.lib_deps}
${mcci_lmic.lib_deps}
build_flags =
${common.build_flags}
${mcci_lmic.build_flags}
-D BSFILE=\"boards/zerousb.h\"
-D MONITOR_SPEED=${common.monitor_speed}
-D USE_SERIAL
-D USE_LED
; -D USE_DISPLAY ; Requires external I2C OLED display
; end of file

786
src/LMIC-node.cpp Normal file
View file

@ -0,0 +1,786 @@
/*******************************************************************************
*
* File: LMIC-node.cpp
*
* Function: LMIC-node main application file.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
* Copyright (c) 2018 Terry Moore, MCCI
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
*
* Permission is hereby granted, free of charge, to anyone
* obtaining a copy of this document and accompanying files to do,
* whatever they want with them without any restriction, including,
* but not limited to, copying, modification and redistribution.
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY.
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: To get LMIC-node up and running no changes need to be made
* to any source code. Only configuration is required
* in platform-io.ini and lorawan-keys.h.
*
* If you want to modify the code e.g. to add your own sensors,
* that can be done in the two area's that start with
* USER CODE BEGIN and end with USER CODE END. There's no need
* to change code in other locations (unless you have a reason).
* See README.md for documentation and how to use LMIC-node.
*
* LMIC-node uses the concepts from the original ttn-otaa.ino
* and ttn-abp.ino examples provided with the LMIC libraries.
* LMIC-node combines both OTAA and ABP support in a single example,
* supports multiple LMIC libraries, contains several improvements
* and enhancements like display support, support for downlinks,
* separates LoRaWAN keys from source code into a separate keyfile,
* provides formatted output to serial port and display
* and supports many popular development boards out of the box.
* To get a working node up and running only requires some configuration.
* No programming or customization of source code required.
*
* Dependencies: External libraries:
* MCCI LoRaWAN LMIC library https://github.com/mcci-catena/arduino-lmic
* IBM LMIC framework https://github.com/matthijskooijman/arduino-lmic
* U8g2 https://github.com/olikraus/u8g2
* EasyLed https://github.com/lnlp/EasyLed
*
******************************************************************************/
#include <Arduino.h>
#include "lmic-node.h"
// █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▄ █▀▀ █▀▀ ▀█▀ █▀█
// █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▄ █▀▀ █ █ █ █ █
// ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀
const uint16_t payloadBufferLength = 4; // Adjust to fit max payload length
// █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▀ █▀█ █▀▄
// █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▀ █ █ █ █
// ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀
uint8_t payloadBuffer[payloadBufferLength];
static osjob_t doWorkJob;
uint32_t doWorkIntervalSeconds = DO_WORK_INTERVAL_SECONDS; // Change value in platformio.ini
// Note: LoRa module pin mappings are defined in the Board Support Files.
// Set LoRaWAN keys defined in lorawan-keys.h.
#ifdef OTAA_ACTIVATION
static const u1_t PROGMEM DEVEUI[8] = { OTAA_DEVEUI } ;
static const u1_t PROGMEM APPEUI[8] = { OTAA_APPEUI };
static const u1_t PROGMEM APPKEY[16] = { OTAA_APPKEY };
// Below callbacks are used by LMIC for reading above values.
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8); }
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8); }
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16); }
#else
// ABP activation
static const u4_t DEVADDR = ABP_DEVADDR ;
static const PROGMEM u1_t NWKSKEY[16] = { ABP_NWKSKEY };
static const u1_t PROGMEM APPSKEY[16] = { ABP_APPSKEY };
// Below callbacks are not used be they must be defined.
void os_getDevEui (u1_t* buf) { }
void os_getArtEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }
#endif
int16_t getSnrTenfold()
{
// Returns ten times the SNR (dB) value of the last received packet.
// Ten times to prevent the use of float but keep 1 decimal digit accuracy.
// Calculation per SX1276 datasheet (Rev.6) 6.4.
// LMIC.snr contains value of PacketSnr, which is 4 times the actual SNR value.
return (LMIC.snr * 10) / 4;
}
int16_t getRssi(int16_t snr)
{
// Returns correct RSSI (dBm) value of the last received packet.
// Calculation per SX1276 datasheet (Rev.6) 5.5.5.
// Correct calculation of RSSI depends on whether the HF or LF port is used.
// Note: Below code assumes that only HF port is used and only SX1276 is used (not SX1272)
// if not then the values will be less reliable.
const int16_t rssiOffset = -157; // For HF port use -157, for LF port use -164.
// LMIC.rssi contains modified value of PacketRssi.
// Revert modification (applied in lmic/radio.c) to get PacketRssi.
// (Purpose of modification is unclear and the magic numbers seem undocumented.)
int16_t packetRssi = LMIC.rssi + 125 - 64;
int16_t rssi;
if (snr < 0)
{
rssi = rssiOffset + packetRssi + snr;
}
else
{
rssi = rssiOffset + (16 / 15.0 * packetRssi);
}
return rssi;
}
void printEvent(ostime_t timestamp,
const char * const message,
PrintTarget target = PrintTarget::All,
bool clearDisplayStatusRow = true,
bool eventLabel = false)
{
#ifdef USE_DISPLAY
if (target == PrintTarget::All || target == PrintTarget::Display)
{
display.clearLine(TIME_ROW);
display.setCursor(0, TIME_ROW);
display.print(F("Time:"));
display.print(timestamp);
display.clearLine(EVENT_ROW);
if (clearDisplayStatusRow)
{
display.clearLine(STATUS_ROW);
}
display.setCursor(0, EVENT_ROW);
display.print(message);
}
#endif
#ifdef USE_SERIAL
// Create padded/indented output without using printf().
// printf() is not default supported/enabled in each Arduino core.
// Not using printf() will save memory for memory constrainted devices.
String timeString(timestamp);
uint8_t len = timeString.length();
uint8_t zerosCount = TIMESTAMP_WIDTH > len ? TIMESTAMP_WIDTH - len : 0;
if (target == PrintTarget::All || target == PrintTarget::Serial)
{
printChars(serial, '0', zerosCount);
serial.print(timeString);
serial.print(": ");
if (eventLabel)
{
serial.print(F("Event: "));
}
serial.println(message);
}
#endif
}
void printEvent(ostime_t timestamp, ev_t ev, PrintTarget target = PrintTarget::All, bool clearDisplayStatusRow = true)
{
printEvent(timestamp, lmicEventNames[ev], target, clearDisplayStatusRow, true);
}
void printFrameCounters(PrintTarget target = PrintTarget::All)
{
#ifdef USE_DISPLAY
if (target == PrintTarget::Display || target == PrintTarget::All)
{
display.clearLine(FRMCNTRS_ROW);
display.setCursor(0, FRMCNTRS_ROW);
display.print(F("Up:"));
display.print(LMIC.seqnoUp);
display.print(F(" Dn:"));
display.print(LMIC.seqnoDn);
}
#endif
#ifdef USE_SERIAL
if (target == PrintTarget::Serial || target == PrintTarget::All)
{
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Up#: "));
serial.print(LMIC.seqnoUp);
serial.print(F(", Dn#: "));
serial.println(LMIC.seqnoDn);
}
#endif
}
void printSessionKeys()
{
#if defined(USE_SERIAL) && defined(MCCI_LMIC)
u4_t networkId = 0;
devaddr_t deviceAddress = 0;
u1_t networkSessionKey[16];
u1_t applicationSessionKey[16];
LMIC_getSessionKeys(&networkId, &deviceAddress,
networkSessionKey, applicationSessionKey);
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Network Id: "));
serial.println(networkId, DEC);
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Device Address: "));
serial.println(deviceAddress, HEX);
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Application Session Key: "));
printHex(serial, applicationSessionKey, 16, true, '-');
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Network Session Key: "));
printHex(serial, networkSessionKey, 16, true, '-');
#endif
}
void printDownlinkInfo()
{
#if defined(USE_SERIAL) || defined(USE_DISPLAY)
uint8_t dataLength = LMIC.dataLen;
// bool ackReceived = LMIC.txrxFlags & TXRX_ACK;
int16_t snrTenfold = getSnrTenfold();
int16_t snr = snrTenfold / 10;
int16_t snrDecimalFraction = snrTenfold % 10;
int16_t rssi = getRssi(snr);
uint8_t fPort = 0;
if (LMIC.txrxFlags & TXRX_PORT)
{
fPort = LMIC.frame[LMIC.dataBeg -1];
}
#ifdef USE_DISPLAY
display.clearLine(EVENT_ROW);
display.setCursor(0, EVENT_ROW);
display.print(F("RX P:"));
display.print(fPort);
if (dataLength != 0)
{
display.print(" Len:");
display.print(LMIC.dataLen);
}
display.clearLine(STATUS_ROW);
display.setCursor(0, STATUS_ROW);
display.print(F("RSSI"));
display.print(rssi);
display.print(F(" SNR"));
display.print(snr);
display.print(".");
display.print(snrDecimalFraction);
#endif
#ifdef USE_SERIAL
printSpaces(serial, MESSAGE_INDENT);
serial.println(F("Downlink received"));
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("RSSI: "));
serial.print(rssi);
serial.print(F(" dBm, SNR: "));
serial.print(snr);
serial.print(".");
serial.print(snrDecimalFraction);
serial.println(F(" dB"));
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Port: "));
serial.println(fPort);
if (dataLength != 0)
{
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Length: "));
serial.println(LMIC.dataLen);
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("Data: "));
printHex(serial, LMIC.frame+LMIC.dataBeg, LMIC.dataLen, true, ' ');
}
#endif
#endif
}
void printHeader(void)
{
#ifdef USE_DISPLAY
display.clear();
display.setCursor(0, HEADER_ROW);
display.print(F("LMIC-node"));
// OTAA is default so is not shown here
#ifdef ABP_ACTIVATION
display.print(F(" ABP"));
#endif
display.drawString(0, DEVICEID_ROW, deviceId);
display.setCursor(0, INTERVAL_ROW);
display.print(F("Interval:"));
display.print(doWorkIntervalSeconds);
display.print("s");
#endif
#ifdef USE_SERIAL
serial.println(F("\n\nLMIC-node\n"));
serial.print(F("Device-id: "));
serial.println(deviceId);
serial.print(F("Activation: "));
#ifdef OTAA_ACTIVATION
serial.println(F("OTAA"));
#else
serial.println(F("ABP"));
#endif
serial.print(F("Interval: "));
serial.print(doWorkIntervalSeconds);
serial.println(F(" seconds"));
#endif
}
#ifdef ABP_ACTIVATION
void setAbpParameters(void)
{
// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
#ifdef PROGMEM
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
#else
// If not running an AVR with PROGMEM, just use the arrays directly
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
#endif
#if defined(CFG_eu868)
// Set up the channels used by the Things Network, which corresponds
// to the defaults of most gateways. Without this, only three base
// channels from the LoRaWAN specification are used, which certainly
// works, so it is good for debugging, but can overload those
// frequencies, so be sure to configure the full frequency range of
// your network here (unless your network autoconfigures them).
// Setting up channels should happen after LMIC_setSession, as that
// configures the minimal channel set. The LMIC doesn't let you change
// the three basic settings, but we show them here.
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
// TTN defines an additional channel at 869.525Mhz using SF9 for class B
// devices' ping slots. LMIC does not have an easy way to define set this
// frequency and support for class B is spotty and untested, so this
// frequency is not configured here.
#elif defined(CFG_us915) || defined(CFG_au915)
// NA-US and AU channels 0-71 are configured automatically
// but only one group of 8 should (a subband) should be active
// TTN recommends the second sub band, 1 in a zero based count.
// https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json
LMIC_selectSubBand(1);
#elif defined(CFG_as923)
// Set up the channels used in your country. Only two are defined by default,
// and they cannot be changed. Use BAND_CENTI to indicate 1% duty cycle.
// LMIC_setupChannel(0, 923200000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI);
// LMIC_setupChannel(1, 923400000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI);
// ... extra definitions for channels 2..n here
#elif defined(CFG_kr920)
// Set up the channels used in your country. Three are defined by default,
// and they cannot be changed. Duty cycle doesn't matter, but is conventionally
// BAND_MILLI.
// LMIC_setupChannel(0, 922100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI);
// LMIC_setupChannel(1, 922300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI);
// LMIC_setupChannel(2, 922500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI);
// ... extra definitions for channels 3..n here.
#elif defined(CFG_in866)
// Set up the channels used in your country. Three are defined by default,
// and they cannot be changed. Duty cycle doesn't matter, but is conventionally
// BAND_MILLI.
// LMIC_setupChannel(0, 865062500, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI);
// LMIC_setupChannel(1, 865402500, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI);
// LMIC_setupChannel(2, 865985000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI);
// ... extra definitions for channels 3..n here.
#endif
// Disable link check validation
LMIC_setLinkCheckMode(0);
// TTN uses SF9 for its RX2 window.
LMIC.dn2Dr = DR_SF9;
// Set data rate and transmit power (note: txpow seems to be ignored by the library)
LMIC_setDrTxpow(DR_SF7, 14);
}
#endif //ABP_ACTIVATION
void initLmic() {
// Initialize LMIC runtime environment
os_init();
// Reset MAC state
LMIC_reset();
#ifdef ABP_ACTIVATION
setAbpParameters();
#endif
// Enable or disable ADR (data rate adaptation).
// Should be turned off if the device is not stationary (mobile).
// 1 is on, 0 is off.
const bit_t adrEnabled = 1;
LMIC_setAdrMode(adrEnabled);
// Set/override data rate and transmit power.
// Should only be used if ADR is disabled.
// Note: When using ABP activation below values will override those set in setAbpParameters();
#if adrEnabled == 0
// LMIC_setDrTxpow(DR_SF7, 14);
#endif
// Relax LMIC timing if defined
#if defined(LMIC_CLOCK_ERROR_PPM) && LMIC_CLOCK_ERROR_PPM > 0
#if defined(MCCI_LMIC) && LMIC_CLOCK_ERROR_PPM > 4000
// Allow clock error percentage to be > 0.4%
#define LMIC_ENABLE_arbitrary_clock_error 1
#endif
uint32_t clockError = (LMIC_CLOCK_ERROR_PPM / 100) * (MAX_CLOCK_ERROR / 100) / 100;
LMIC_setClockError(clockError);
#ifdef USE_SERIAL
serial.print(F("\nClock Error: "));
serial.print(LMIC_CLOCK_ERROR_PPM);
serial.print(" ppm (");
serial.print(clockError);
serial.println(")");
#endif
#endif
}
void onEvent(ev_t ev)
{
// LMIC event handler
ostime_t timestamp = os_getTime();
switch (ev)
{
#ifdef MCCI_LMIC
// Only supported in MCCI LMIC library:
case EV_RXSTART:
// Do not print anything for this event or it will mess up timing.
break;
case EV_TXSTART:
#ifdef USE_LED
led.on();
#endif
#ifdef USE_DISPLAY
displayTxSymbol();
#endif
printEvent(timestamp, ev);
break;
#endif
case EV_JOINED:
printEvent(timestamp, ev);
printSessionKeys();
// Disable link check validation.
// Link check validation is automatically enabled
// during join, but because slow data rates change
// max TX size, it is not used in this example.
LMIC_setLinkCheckMode(0);
break;
case EV_TXCOMPLETE:
// Transmit completed, includes waiting for RX windows.
#ifdef USE_LED
led.off();
#endif
#ifdef USE_DISPLAY
displayTxSymbol(false);
#endif
printEvent(timestamp, ev);
printFrameCounters();
// Check if downlink was received
if (LMIC.dataLen != 0 || LMIC.dataBeg != 0)
{
uint8_t fPort = 0;
if (LMIC.txrxFlags & TXRX_PORT)
{
fPort = LMIC.frame[LMIC.dataBeg -1];
}
printDownlinkInfo();
processDownlink(timestamp, fPort, LMIC.frame + LMIC.dataBeg, LMIC.dataLen);
}
break;
// Below events are printed only.
case EV_SCAN_TIMEOUT:
case EV_BEACON_FOUND:
case EV_BEACON_MISSED:
case EV_BEACON_TRACKED:
case EV_RFU1: // This event is defined but not used in code
case EV_JOINING:
case EV_JOIN_FAILED:
case EV_REJOIN_FAILED:
case EV_LOST_TSYNC:
case EV_RESET:
case EV_RXCOMPLETE:
case EV_LINK_DEAD:
case EV_LINK_ALIVE:
#ifdef MCCI_LMIC
// Only supported in MCCI LMIC library:
case EV_SCAN_FOUND: // This event is defined but not used in code
case EV_TXCANCELED:
case EV_JOIN_TXCOMPLETE:
#endif
printEvent(timestamp, ev);
break;
default:
printEvent(timestamp, "Unknown Event");
break;
}
}
static void doWorkCallback(osjob_t* job)
{
// Event hander for doWorkJob. Gets called by the LMIC scheduler.
// The actual work is performed in function processWork() which is called below.
ostime_t timestamp = os_getTime();
#ifdef USE_SERIAL
serial.println();
printEvent(timestamp, "doWork job started", PrintTarget::Serial);
#endif
// Do the work that needs to be performed.
processWork(timestamp);
// This job must explicitly reschedule itself for the next run.
ostime_t startAt = timestamp + sec2osticks((int64_t)doWorkIntervalSeconds);
os_setTimedCallback(&doWorkJob, startAt, doWorkCallback);
}
lmic_tx_error_t scheduleUplink(uint8_t fPort, uint8_t* data, uint8_t dataLength, bool confirmed = false)
{
// This function is called from the processWork() function to schedule
// transmission of an uplink message that was prepared by processWork().
// Transmission will be performed at the next possible time
#ifdef CLASSIC_LMIC
// For MCCI_LMIC this will be handled in EV_TXSTART
#ifdef USE_LED
led.on();
#endif
#ifdef USE_DISPLAY
displayTxSymbol();
#endif
#endif
ostime_t timestamp = os_getTime();
printEvent(timestamp, "Packet queued");
lmic_tx_error_t retval = LMIC_setTxData2(fPort, data, dataLength, confirmed ? 1 : 0);
timestamp = os_getTime();
if (retval != LMIC_ERROR_SUCCESS)
{
String errmsg;
#ifdef USE_SERIAL
errmsg = "LMIC Error: ";
#ifdef MCCI_LMIC
errmsg.concat(lmicErrorNames[abs(retval)]);
#else
errmsg.concat(retval);
#endif
printEvent(timestamp, errmsg.c_str(), PrintTarget::Serial);
#endif
#ifdef USE_DISPLAY
errmsg = "LMIC Err: ";
errmsg.concat(retval);
printEvent(timestamp, errmsg.c_str(), PrintTarget::Display);
#endif
}
return retval;
}
// █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▄ █▀▀ █▀▀ ▀█▀ █▀█
// █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▄ █▀▀ █ █ █ █ █
// ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀
static volatile uint16_t counter_ = 0;
uint16_t getCounterValue()
{
// Increments counter and returns the new value.
delay(50); // Fake this takes some time
return ++counter_;
}
void resetCounter()
{
// Reset counter to 0
counter_ = 0;
}
void processWork(ostime_t doWorkJobTimeStamp)
{
// This function is called from the doWorkCallback()
// callback function when the doWork job is executed.
// Uses globals: payloadBuffer and LMIC data structure.
// This is where the main work is performed like
// reading sensor, GPS data and schedule
// uplink messages is anything needs to be transmitted.
// Gather data.
// For simplicity LMIC-node uses a counter to simulate a sensor.
// The counter is increased automatically by getCounterValue()
// and can be reset with a 'reset counter' command downlink message.
uint16_t counterValue = getCounterValue();
ostime_t timestamp = os_getTime();
#ifdef USE_DISPLAY
// Interval and Counter values are combined on a single row.
// This allows to keep the 3rd row empty which makes the
// information better readable on the small display.
display.clearLine(INTERVAL_ROW);
display.setCursor(0, INTERVAL_ROW);
display.print("I:");
display.print(doWorkIntervalSeconds);
display.print("s");
display.print(" Ctr:");
display.print(counterValue);
#endif
#ifdef USE_SERIAL
printEvent(timestamp, "Data read", PrintTarget::Serial);
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("COUNTER value: "));
serial.println(counterValue);
#endif
// For simplicity LMIC-node will try to send an uplink
// message every time processWork() is executed.
// Schedule uplink message if possible
if (LMIC.opmode & OP_TXRXPEND)
{
// TxRx is currently pending, do not send.
#ifdef USE_SERIAL
printEvent(timestamp, "Uplink not scheduled because TxRx pending", PrintTarget::Serial);
#endif
#ifdef USE_DISPLAY
printEvent(timestamp, "UL not scheduled", PrintTarget::Display);
#endif
}
else
{
// Prepare uplink payload.
uint8_t fPort = 10;
payloadBuffer[0] = counterValue >> 8;
payloadBuffer[1] = counterValue & 0xFF;
uint8_t payloadLength = 2;
scheduleUplink(fPort, payloadBuffer, payloadLength);
}
}
void processDownlink(ostime_t txCompleteTimestamp, uint8_t fPort, uint8_t* data, uint8_t dataLength)
{
// This function is called from the onEvent() event handler
// on EV_TXCOMPLETE when a downlink message was received.
// Implements a 'reset counter' command that can be sent via a downlink message.
// To send the reset counter command to the node, send a downlink message
// (e.g. from the TTN Console) with single byte value resetCmd on port cmdPort.
const uint8_t cmdPort = 100;
const uint8_t resetCmd= 0xC0;
if (fPort == cmdPort && dataLength == 1 && data[0] == resetCmd)
{
#ifdef USE_SERIAL
printSpaces(serial, MESSAGE_INDENT);
serial.println(F("Reset cmd received"));
#endif
ostime_t timestamp = os_getTime();
resetCounter();
printEvent(timestamp, "Counter reset", PrintTarget::All, false);
}
}
// █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▀ █▀█ █▀▄
// █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▀ █ █ █ █
// ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀
void setup()
{
// boardInit(InitType::Hardware) must be called at start of setup() before anything else.
bool hardwareInitSucceeded = boardInit(InitType::Hardware);
#ifdef USE_DISPLAY
initDisplay();
#endif
#ifdef USE_SERIAL
initSerial(MONITOR_SPEED, WAITFOR_SERIAL_S);
#endif
boardInit(InitType::PostInitSerial);
#if defined(USE_SERIAL) || defined(USE_DISPLAY)
printHeader();
#endif
if (!hardwareInitSucceeded)
{
#ifdef USE_SERIAL
serial.println(F("Error: hardware init failed."));
serial.flush();
#endif
#ifdef USE_DISPLAY
// Following mesage shown only if failure was unrelated to I2C.
display.setCursor(0, FRMCNTRS_ROW);
display.print(F("HW init failed"));
#endif
abort();
}
initLmic();
// Schedule initial doWork job for immediate execution.
os_setCallback(&doWorkJob, doWorkCallback);
}
void loop()
{
os_runloop_once();
}

314
src/LMIC-node.h Normal file
View file

@ -0,0 +1,314 @@
/*******************************************************************************
*
* File: LMIC-node.h
*
* Function: LMIC-node main header file.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
* Copyright (c) 2018 Terry Moore, MCCI
*
* Permission is hereby granted, free of charge, to anyone
* obtaining a copy of this document and accompanying files to do,
* whatever they want with them without any restriction, including,
* but not limited to, copying, modification and redistribution.
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY.
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
******************************************************************************/
#pragma once
#ifndef LMIC_NODE_H_
#define LMIC_NODE_H_
#include <Arduino.h>
#include "lmic.h"
#include "hal/hal.h"
#ifdef USE_DISPLAY
#include <Wire.h>
#include "U8x8lib.h"
#endif
#ifdef USE_LED
#include "EasyLed.h"
#endif
enum class InitType { Hardware, PostInitSerial };
enum class PrintTarget { All, Serial, Display };
// Forward declarations
void processWork(ostime_t timestamp);
void processDownlink(ostime_t eventTimestamp, uint8_t fPort, uint8_t* data, uint8_t dataLength);
#ifndef DO_WORK_INTERVAL_SECONDS // Should be set in platformio.ini
#define DO_WORK_INTERVAL_SECONDS 300 // Default 5 minutes if not set
#endif
#define TIMESTAMP_WIDTH 12 // Number of columns to display eventtime (zero-padded)
#define MESSAGE_INDENT TIMESTAMP_WIDTH + 3
// Determine which LMIC library is used
#ifdef _LMIC_CONFIG_PRECONDITIONS_H_
#define MCCI_LMIC
#else
#define CLASSIC_LMIC
#endif
// Determine if a valid region is defined.
// This actually has little effect because
// CLASSIC LMIC: defines CFG_eu868 by default,
// MCCI LMIC: if no region is defined it
// sets CFG_eu868 as default.
#if ( \
( defined(CLASSIC_LMIC) \
&& !( defined(CFG_eu868) \
|| defined(CFG_us915) ) ) \
|| \
( defined(MCCI_LMIC) \
&& !( defined(CFG_as923) \
|| defined(CFG_as923jp) \
|| defined(CFG_au915) \
|| defined(CFG_eu868) \
|| defined(CFG_in866) \
|| defined(CFG_kr920) \
|| defined(CFG_us915) ) ) \
)
#Error No valid region defined
#endif
#include BSFILE // Include Board Support File
#include "../keyfiles/lorawan-keys.h"
#ifdef OTAA_ACTIVATION
#if !defined(OTAA_DEVEUI) || !defined(OTAA_APPEUI) || !defined(OTAA_APPKEY)
#error One or more LoRaWAN keys (OTAA_DEVEUI, OTAA_APPEUI, OTAA_APPKEY) are not defined.
#endif
#else
// ABP activation
#if !defined(ABP_DEVADDR) || !defined(ABP_NWKSKEY) || !defined(ABP_APPSKEY)
#error One or more LoRaWAN keys (ABP_DEVADDR, ABP_NWKSKEY, ABP_APPSKEY) are not defined.
#endif
#endif
#if defined(LMIC_DEBUG_LEVEL) && LMIC_DEBUG_LEVEL > 0
#ifdef LMIC_PRINTF_TO
#undef LMIC_PRINTF_TO
#endif
#define LMIC_PRINTF_TO serial
#endif
#if defined(ABP_ACTIVATION) && defined(OTAA_ACTIVATION)
#error Only one of ABP_ACTIVATION and OTAA_ACTIVATION can be defined.
#endif
#if !defined(ABP_ACTIVATION) && !defined(OTAA_ACTIVATION)
#define OTAA_ACTIVATION
#endif
#if defined(ABP_ACTIVATION) && defined(DEVICEID_ABP)
const char deviceId[] = DEVICEID_ABP;
#elif defined(DEVICEID)
const char deviceId[] = DEVICEID;
#else
const char deviceId[] = DEVICEID_DEFAULT;
#endif
// Allow WAITFOR_SERIAL_SECONDS to be defined in platformio.ini.
// If used it shall be defined in the [common] section.
// The common setting will only be used for boards that have
// WAITFOR_SERIAL_SECONDS_DEFAULT defined (in BSP) with a value != 0
#if defined(WAITFOR_SERIAL_SECONDS_DEFAULT) && WAITFOR_SERIAL_SECONDS_DEFAULT != 0
#ifdef WAITFOR_SERIAL_SECONDS
#define WAITFOR_SERIAL_S WAITFOR_SERIAL_SECONDS
#else
#define WAITFOR_SERIAL_S WAITFOR_SERIAL_SECONDS_DEFAULT
#endif
#else
#define WAITFOR_SERIAL_S 0
#endif
#ifndef LMIC_MCCI
#define LMIC_ERROR_SUCCESS 0
typedef int lmic_tx_error_t;
// In MCCI LMIC these are already defined.
// This macro can be used to initalize an array of event strings
#define LEGACY_LMIC_EVENT_NAME_TABLE__INIT \
"<<zero>>", \
"EV_SCAN_TIMEOUT", "EV_BEACON_FOUND", \
"EV_BEACON_MISSED", "EV_BEACON_TRACKED", "EV_JOINING", \
"EV_JOINED", "EV_RFU1", "EV_JOIN_FAILED", "EV_REJOIN_FAILED", \
"EV_TXCOMPLETE", "EV_LOST_TSYNC", "EV_RESET", \
"EV_RXCOMPLETE", "EV_LINK_DEAD", "EV_LINK_ALIVE"
// If working on an AVR (or worried about memory size), you can use this multi-zero
// string and put this in a single const F() string to store it in program memory.
// Index through this counting up from 0, until you get to the entry you want or
// to an entry that begins with a \0.
#define LEGACY_LMIC_EVENT_NAME_MULTISZ__INIT \
"<<zero>>\0" \ \
"EV_SCAN_TIMEOUT\0" "EV_BEACON_FOUND\0" \
"EV_BEACON_MISSED\0" "EV_BEACON_TRACKED\0" "EV_JOINING\0" \
"EV_JOINED\0" "EV_RFU1\0" "EV_JOIN_FAILED\0" "EV_REJOIN_FAILED\0" \
"EV_TXCOMPLETE\0" "EV_LOST_TSYNC\0" "EV_RESET\0" \
"EV_RXCOMPLETE\0" "EV_LINK_DEAD\0" "EV_LINK_ALIVE\0"
#endif // LMIC_MCCI
#if defined(USE_SERIAL) || defined(USE_DISPLAY)
#ifdef MCCI_LMIC
static const char * const lmicEventNames[] = { LMIC_EVENT_NAME_TABLE__INIT };
static const char * const lmicErrorNames[] = { LMIC_ERROR_NAME__INIT };
#else
static const char * const lmicEventNames[] = { LEGACY_LMIC_EVENT_NAME_TABLE__INIT };
#endif
void printChars(Print& printer, char ch, uint8_t count, bool linefeed = false)
{
for (uint8_t i = 0; i < count; ++i)
{
printer.print(ch);
}
if (linefeed)
{
printer.println();
}
}
void printSpaces(Print& printer, uint8_t count, bool linefeed = false)
{
printChars(printer, ' ', count, linefeed);
}
void printHex(Print& printer, uint8_t* bytes, size_t length = 1, bool linefeed = false, char separator = 0)
{
for (size_t i = 0; i < length; ++i)
{
if (i > 0 && separator != 0)
{
printer.print(separator);
}
if (bytes[i] <= 0x0F)
{
printer.print('0');
}
printer.print(bytes[i], HEX);
}
if (linefeed)
{
printer.println();
}
}
#endif // USE_SERIAL || USE_DISPLAY
#ifdef USE_DISPLAY
uint8_t transmitSymbol[8] = {0x18, 0x18, 0x00, 0x24, 0x99, 0x42, 0x3c, 0x00};
#define LAST_COL 15
#define HEADER_ROW 0
#define DEVICEID_ROW 1
#define INTERVAL_ROW 2
#define TIME_ROW 4
#define EVENT_ROW 5
#define STATUS_ROW 6
#define FRMCNTRS_ROW 7
#define ROW_0 0
#define ROW_1 1
#define ROW_2 2
#define ROW_3 3
#define ROW_4 4
void initDisplay()
{
display.begin();
display.setFont(u8x8_font_victoriamedium8_r);
}
void displayTxSymbol(bool visible = true)
{
if (visible)
{
display.drawTile(LAST_COL, ROW_0, 1, transmitSymbol);
}
else
{
display.drawGlyph(LAST_COL, ROW_0, char(0x20));
}
}
#endif // USE_DISPLAY
#ifdef USE_SERIAL
bool initSerial(unsigned long speed = 115200, int16_t timeoutSeconds = 0)
{
// Initializes the serial port.
// Optionally waits for serial port to be ready.
// Will display status and progress on display (if enabled)
// which can be useful for tracing (e.g. ATmega328u4) serial port issues.
// A negative timeoutSeconds value will wait indefinitely.
// A value of 0 (default) will not wait.
// Returns: true when serial port ready,
// false when not ready.
serial.begin(speed);
#if WAITFOR_SERIAL_S != 0
if (timeoutSeconds != 0)
{
bool indefinite = (timeoutSeconds < 0);
uint16_t secondsLeft = timeoutSeconds;
#ifdef USE_DISPLAY
display.setCursor(0, ROW_1);
display.print(F("Waiting for"));
display.setCursor(0, ROW_2);
display.print(F("serial port"));
#endif
while (!serial && (indefinite || secondsLeft > 0))
{
if (!indefinite)
{
#ifdef USE_DISPLAY
display.clearLine(ROW_4);
display.setCursor(0, ROW_4);
display.print(F("timeout in "));
display.print(secondsLeft);
display.print('s');
#endif
--secondsLeft;
}
delay(1000);
}
#ifdef USE_DISPLAY
display.setCursor(0, ROW_4);
if (serial)
{
display.print(F("Connected"));
}
else
{
display.print(F("NOT connected"));
}
#endif
}
#endif
return serial;
}
#endif
#endif // LMIC_NODE_H_

View file

@ -0,0 +1,131 @@
/*******************************************************************************
*
* File: adafruit_feather_m0_lora.h
*
* Function: Board Support File for Adafruit Feather M0 RFMx LoRa.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by the MCU).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display con be connected.
*
* DIO1 MUST BE MANUALLY WIRED TO GPIO5 (see below)
*
* Connect DIO1 and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 13 (LED_BUILTIN, PIN_LED, PIN_LED_13) active-high
* LED2 <> 25 (RX, PIN_LED2, PIN_LED_RXL)
* LED3 <> 26 (TX, PIN_LED3, PIN_LED_TXL)
*
* I2C [display] GPIO
* --- ----
* SDA <> 20 (SDA)
* SCL <> 21 (SCL)
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 23 (MOSI)
* MISO <> 22 (MISO)
* SCK <> 24 (SCK)
* NSS <> 8
* RST <> 4
* DIO0 <> 3
* DIO1 <----------> 5 NOT WIRED on PCB
* DIO2 - Not needed for LoRa
*
* Identifiers: LMIC-node
* board-id: adafruit_feather_m0_lora
* PlatformIO
* board: adafruit_feather_m0
* platform: atmelsam
* Arduino
* board: ARDUINO_SAMD_FEATHER_M0
* architecture: ARDUINO_ARCH_SAMD
*
******************************************************************************/
#pragma once
#ifndef ADAFRUIT_FEATHER_M0_LORA_H_
#define ADAFRUIT_FEATHER_M0_LORA_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "feather-m0" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
#define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
// Pin mappings for LoRa tranceiver
const lmic_pinmap lmic_pins = {
.nss = 8,
.rxtx = LMIC_UNUSED_PIN,
.rst = 4,
.dio = { /*dio0*/ 3, /*dio1*/ 5, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
Serial_& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // ADAFRUIT_FEATHER_M0_LORA_H_

View file

@ -0,0 +1,163 @@
/*******************************************************************************
*
* File: blackpill_f103c8.h
*
* Function: Board Support File for STM32 F103C8T6 'blackpill' 64k and 128k
* with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This Board has onboard USB (provided by the MCU).
* However, the default bootloader does not support automatic
* firmware upload and serial over USB.
* No onboard display. Optionally an external display can be connected.
*
* For firmware upload use a USB to serial adapter, STLink programmer,
* or special bootloader (not standard supported).
* The upload_protocol setting for this board (in platformio.ini)
* must be set to the preferred upload method (default is stlink).
* For serial monitor use a USB to serial adapter.
* (It may also be possible to configure the onboard USB
* for this but I haven't yet figured out how.)
*
* This board requires a workaround to prevent losing output
* printed to the serial port (see boardInit() below).
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> PB12 / 16 (LED_BUILTIN) Active-low
*
* I2C [display] GPIO
* --- ----
* SDA <> PB7 / 2 (SCA)
* SCL <> PB6 / 3 (SCL)
*
* SPI/LoRa module GPIO
* --- ----
* MOSI <> PA7 / 27 (MOSI)
* MISO <> PA6 / 26 (MISO)
* SCK <> PA5 / 25 (SCK)
* NSS <> PA4 / 24 (SS)
* RST <> PB0 / 28
* DIO0 <> PA3 / 23
* DIO1 <> PA2 / 22
* DIO2 - Not needed for LoRa.
*
* Serial GPIO
* ------ ----
* RX <> PA10 / 10 (PIN_SERIAL_RX)
* TX <> PA9 / 11 (PIN_SERIAL_TX)
*
* SWD GPIO
* --- ----
* SWCLK <> PA14 / 34
* SWDIO <> PA13 / 33
*
* USB GPIO
* --- ----
* D- <> PA11 / 9
* D+ <> PA12 / 8
*
* Identifiers: LMIC-node
* board-id: blackpill_f103c8 (64k version)
* blackpill_f103c8_128k (128k version)
* PlatformIO
* board: blackpill_f103c8 (64k version)
* blackpill_f103c8_128k (128k version)
* platform: ststm32
* Arduino
* board: ARDUINO_BLACKPILL_F103C8
* architecture: ARDUINO_ARCH_STM32
*
******************************************************************************/
#pragma once
#ifndef BLACKPILL_F103C8_H_
#define BLACKPILL_F103C8_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "blackpill"
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// This board by default does not support serial over USB but
// wait for serial is enabled anyway for if boards have a different bootloader.
#define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
// Pin mappings for LoRa tranceiver
const lmic_pinmap lmic_pins = {
.nss = PA4,
.rxtx = LMIC_UNUSED_PIN,
.rst = PB0,
.dio = { /*dio0*/ PA3, /*dio1*/ PA2, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// Required workaround:
// Data printed to the serial port during the first second gets lost.
// Inserting a 1500 millisecond delay will usually fix this.
delay(1500);
break;
}
return success;
}
#endif // BLACKPILL_F103C8_H_

View file

@ -0,0 +1,162 @@
/*******************************************************************************
*
* File: bluepill_f103c8.h
*
* Function: Board Support File for STM32 F103C8T6 'bluepill' 64k and 128k
* with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: Board has onboard USB but the default bootloader does not
* support automatic upload via USB and serial over USB.
* No onboard display. Optionally an external display
* can be connected to the I2C pins.
*
* For firmware upload use a USB to serial adapter, STLink programmer,
* or special bootloader (not standard supported).
* The upload_protocol setting for this board (in platformio.ini)
* must be set to the preferred upload method (default is stlink).
* For serial monitor use a USB to serial adapter.
* (It may also be possible to configure the onboard USB
* for this but I haven't yet figured out how.)
*
* This board requires a workaround to prevent losing output
* printed to the serial port (see boardInit() below).
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> PC13 / 17 (LED_BUILTIN) Active-low
*
* I2C [display] GPIO
* --- ----
* SDA <> PB7 / 2 (SCA)
* SCL <> PB6 / 3 (SCL)
*
* SPI/LoRa module GPIO
* --- ----
* MOSI <> PA7 / 27 (MOSI)
* MISO <> PA6 / 26 (MISO)
* SCK <> PA5 / 25 (SCK)
* NSS <> PA4 / 24 (SS)
* RST <> PB0 / 28
* DIO0 <> PA3 / 23
* DIO1 <> PA2 / 22
* DIO2 - Not needed for LoRa.
*
* Serial GPIO
* ------ ----
* RX <> PA10 / 10 (PIN_SERIAL_RX)
* TX <> PA9 / 11 (PIN_SERIAL_TX)
*
* SWD GPIO
* --- ----
* SWCLK <> PA14 / 34
* SWDIO <> PA13 / 33
*
* USB GPIO
* --- ----
* D- <> PA11 / 9
* D+ <> PA12 / 8
*
* Identifiers: LMIC-node
* board-id: bluepill_f103c8 (64k version)
* bluepill_f103c8_128k (128k version)
* PlatformIO
* board: bluepill_f103c8 (64k version)
* bluepill_f103c8_128k (128k version)
* platform: ststm32
* Arduino
* board: ARDUINO_BLUEPILL_F103C8
* architecture: ARDUINO_ARCH_STM32
*
******************************************************************************/
#pragma once
#ifndef BLUEPILL_F103C8_H_
#define BLUEPILL_F103C8_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "bluepill"
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// This board by default does not support serial over USB but
// wait for serial is enabled anyway for if boards have a different bootloader.
#define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = PA4,
.rxtx = LMIC_UNUSED_PIN,
.rst = PB0,
.dio = { /*dio0*/ PA3, /*dio1*/ PA2, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(PC13, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// Required workaround:
// Data printed to the serial port during the first second gets lost.
// Inserting a 1500 millisecond delay will usually fix this.
delay(1500);
break;
}
return success;
}
#endif // BLUEPILL_F103C8_H_

View file

@ -0,0 +1,175 @@
/*******************************************************************************
*
* File: disco_l072cz_lrwan1.h
*
* Function: Board Support File for ST B-L072Z-LRWAN1 Discovery kit.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard STLink programmer).
* It supports automatic upload (via stlink) and serial over USB.
* No onboard display. Optionally an external display can be connected.
*
* The standard SPI pins defined in the BSP do not match the
* GPIO pins that the SX1276 LoRa chip is connected to.
* LMIC uses the default SPI parameters for initializing the SPI bus
* which will not work here. Therefore the SPI object is explicitly
* initialized with the correct pins (see boardInit() below).
*
* This board requires a workaround to prevent losing the first
* output printed to the serial port (see boardInit() below).
*
* Connect an optional display according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> PA5 / 32 (LED_BUILTIN) Useless because PA5 is used for DIO4
* RED <> PB7 / 5 (LED_RED, LED_LD4)
* GREEN <> PB5 / 4 (LED_GREEN, LED_LD1) Also used for SS1
* BLUE <> PB6 / 10 (LED_BLUE, LED3) Also used for SS
*
* I2C [display] GPIO
* --- ----
* SDA <> PB9 / 14 (SDA)
* SCL <> PB8 / 15 (SCL)
*
* SPI GPIO
* --- ----
* MOSI <> PB15 / 11 (MOSI)
* MISO <> PB14 / 12 (MISO)
* SCK <> PB13 / 13 (SCK)
* SS <> PB6 / 10 (SS)
* SS1 <> PB5 / 4 (SS1)
* SS2 <> PA8 / 7 (SS2)
* SS3 <> PA9 / 8 (SS3)
*
* LoRa GPIO
* ---- ----
* MOSI <> PA7 / 34 (RADIO_MOSI_PORT)
* MISO <> PA6 / 35 (RADIO_MISO_PORT)
* SCK <> PB3 / 36 (RADIO_SCLK_PORT)
* NSS <> PA15 / 37 (RADIO_NSS_PORT)
* RST <> PC0 / 33 (RADIO_RESET_PORT)
* RXTX <> PA1 / 21
* DIO0 <> PB4 / 38 (RADIO_DIO_0_PORT)
* DIO1 <> PB1 / 39 (RADIO_DIO_1_PORT)
* DIO2 <> PB0 / 40 (RADIO_DIO_2_PORT)
* DIO3 <> PC13 / 41 (RADIO_DIO_3_PORT)
* DIO4 <> PA5 / 32 (RADIO_DIO_4_PORT)
* DIO5 <> PA4 / 28 (RADIO_DIO_5_PORT)
*
* Serial GPIO
* ------ ----
* RX <> PA3 / 0 (PIN_SERIAL_RX) ST-Link RX
* TX <> PA2 / 1 (PIN_SERIAL_TX) ST-Link TX
*
* Button switch GPIO
* ------ ----
* USER <> PB2 / 6 (USER_BTN)
*
* Definitions: LMIC-node
* board-id: disco_l072cz_lrwan1
* PlatformIO
* board: disco_l072cz_lrwan1
* platform: ststm32
* Arduino
* board: ARDUINO_DISCO_L072CZ_LRWAN1
* architecture: ARDUINO_ARCH_STM32
*
******************************************************************************/
#pragma once
#ifndef DISCO_L072CZ_LRWAN1_H_
#define DISCO_L072CZ_LRWAN1_H_
#include <SPI.h>
#include "lmic-node.h"
#define DEVICEID_DEFAULT "l072cz-lrwan1" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// Board appears to work better with clock error enabled (value 4000 empirically determined).
#define LMIC_CLOCK_ERROR_PPM 4000
const lmic_pinmap lmic_pins = {
.nss = PA15,
.rxtx = PA1,
.rst = PC0,
.dio = { /*dio0*/ PB4, /*dio1*/ PB1, /*dio2*/ PB0 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 1,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BLUE, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ PB8, /*sda*/ PB9);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// Redefine GPIO pins of default SPI object.
// These pins will be remembered and will not change if any library
// later calls SPI.begin() without parameters.
SPI.setMOSI(PA7);
SPI.setMISO(PA6);
SPI.setSCLK(PB3);
SPI.setSSEL(PA15);
SPI.begin();
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// Required workaround:
// Data printed to the serial port during the first second gets lost.
// Inserting a 1500 millisecond delay will usually fix this.
delay(1500);
break;
}
return success;
}
#endif // DISCO_L072CZ_LRWAN1_H_

View file

@ -0,0 +1,149 @@
/*******************************************************************************
*
* File: heltec_wifi_lora_32.h
*
* Function: Board Support File for Heltec Wifi LoRa 32 (1.x versions).
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* Has onboard display.
*
* The standard I2C pins defined in the BSP do not match the
* GPIO pins that the display is connected to. Therefore the
* the I2C Wire object is explicitly initialized with the
* correct pins (see boardInit() below).
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 25 (LED_BUILTIN) Active-high
*
* I2C/Display GPIO
* --- ----
* SDA <> 4 (SDA_OLED) - NOT SDA!
* SCL <> 15 (SCL_OLED) - NOT SCL!
* RST <> 16 (RST_OLED)
* - 21 (SDA)
* - 22 (SCL)
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 27 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 5 (SCK)
* NSS <> 18 (SS)
* RST <> 14 (RST_LoRa)
* DIO0 <> 26 (DIO0)
* DIO1 <> 33 (DIO1)
* DIO2 <> 32 (DIO2)
*
* Definitions: LMIC-node:
* board-id: heltec_wifi_lora_32
* PlatformIO
* board: heltec_wifi_lora_32
* platform: espressif32
* Arduino
* board: ARDUINO_HELTEC_WIFI_LORA_32
* architecture: ARDUINO_ARCH_ESP32
*
* Warning: In the Arduino BSP the values of SDA and SCL are incorrectly
* defined for this board. This requires special precautions.
* SDA is defined as GPIO21 and SCL as GPIO22 but these are not
* the pins where the display is connected to.
*
* When initializing the Wire (I2C) interface with Wire.begin()
* without parameters this will by default use pin definitions SDA and SCL.
* Most libraries (including U8x8) will call Wire.begin() without parameters.
* It is not possible to change the pins of the Wire interface
* after it has been initialized. Therefore the Wire interface must be
* initialized with the correct pins before initializing any other library.
*
******************************************************************************/
#pragma once
#ifndef HELTEC_WIFILORA32_V1_H_
#define HELTEC_WIFILORA32_V1_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "wifi-lora-32" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst =14,
.dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(25, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ 16, /*scl*/ 15, /*sda*/ 4);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
#ifdef USE_DISPLAY
// Initialize I2C Wire object with GPIO pins the display is connected to.
// These pins will be remembered and will not change if any library
// later calls Wire.begin() without parameters.
Wire.begin(/*sda*/ 4, /*scl*/ 15);
#endif
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // HELTEC_WIFILORA32_V1_H_

View file

@ -0,0 +1,143 @@
/*******************************************************************************
*
* File: heltec_wifi_lora_32_v2.h
*
* Function: Board Support File for Heltec Wifi LoRa 32 V2.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* Has onboard display.
*
* The standard I2C pins defined in the BSP do not match the
* GPIO pins that the display is connected to. Therefore the
* the I2C Wire object is explicitly initialized with the
* correct pins (see boardInit() below).
*
* WARNING: Vext and the standard I2C SDA pin are both defined as GPIO21.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 25 (LED_BUILTIN) Active-high
*
* I2C/Display GPIO
* --- ----
* SDA <> 4 (SDA_OLED) - NOT SDA!
* SCL <> 15 (SCL_OLED) - NOT SCL!
* RST <> 16 (RST_OLED)
* - 21 (SDA) used for VExt!!!
* - 22 (SCL)
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 27 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 5 (SCK)
* NSS <> 18 (SS)
* RST <> 14 (RST_LoRa)
* DIO0 <> 26 (DIO0)
* DIO1 <> 35 (DIO1)
* DIO2 <> 34 (DIO2)
*
* Other GPIO
* ----- ----
* VExt <> 21 (Vext, SDA) Active-low
*
* Identifiers: LMIC-node:
* board-id: heltec_wifi_lora_32_v2
* PlatformIO
* board: heltec_wifi_lora_32_V2
* platform: espressif32
* Arduino
* board: ARDUINO_HELTEC_WIFI_LORA_32_V2
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef HELTEC_WIFILORA32_V2_H_
#define HELTEC_WIFILORA32_V2_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "wifi-lora-32-v2" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst =14,
.dio = { /*dio0*/ 26, /*dio1*/ 35, /*dio2*/ 34 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ 16, /*scl*/ 15, /*sda*/ 4);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
#ifdef USE_DISPLAY
// Initialize I2C Wire object with GPIO pins the display is connected to.
// These pins will be remembered and will not change if any library
// later calls Wire.begin() without parameters.
Wire.begin(/*sda*/ 4, /*scl*/ 15);
#endif
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // HELTEC_WIFILORA32_V2_H_

View file

@ -0,0 +1,148 @@
/*******************************************************************************
*
* File: heltec_wireless_stick.h
*
* Function: Board Support File for Heltec Wireless Stick.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* Has onboard display (SSD1306 I2C OLED display 0.49" 64x32).
* Display is not supported by LMIC-node because resolution is too low.
*
* The standard I2C pins defined in the BSP do not match the
* GPIO pins that the display is connected to. Therefore the
* the I2C Wire object is explicitly initialized with the
* correct pins (see boardInit() below).
*
* WARNING: Vext and the standard I2C SDA pin are both defined as GPIO21.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 25 (LED_BUILTIN) Active-high
*
* I2C/Display GPIO
* ---- ----
* SDA <> 4 (SDA_OLED) - NOT SDA!
* SCL <> 15 (SCL_OLED) - NOT SCL!
* RST <> 16 (RST_OLED)
* - 21 (SDA, Vext) used for VExt!!!
* - 22 (SCL)
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 27 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 5 (SCK)
* NSS <> 18 (SS)
* RST <> 14 (RST_LoRa)
* DIO0 <> 26 (DIO0)
* DIO1 <> 35 (DIO1)
* DIO2 <> 34 (DIO2)
*
* Other GPIO
* ----- ----
* VExt <> 21 (Vext, SDA) Active-low - see remarks
*
* Identifiers: LMIC-node:
* board-id: heltec_wireless_stick
* PlatformIO
* board: heltec_wireless_stick
* platform: espressif32
* Arduino
* board: ARDUINO_HELTEC_WIRELESS_STICK
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef HELTEC_WIRELESS_STICK_H_
#define HELTEC_WIRELESS_STICK_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "wireless-stick" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst =14,
.dio = { /*dio0*/ 26, /*dio1*/ 35, /*dio2*/ 34 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_DISPLAY
#error Onboard display is not supported because resolution is too low.
#endif
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_64X32_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ 15, /*sda*/ 4);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
#ifdef USE_DISPLAY
// Initialize I2C Wire object with GPIO pins the display is connected to.
// These pins will be remembered and will not change if any library
// later calls Wire.begin() without parameters.
Wire.begin(/*sda*/ 4, /*scl*/ 15);
#endif
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // HELTEC_WIRELESS_STICK_H_

View file

@ -0,0 +1,145 @@
/*******************************************************************************
*
* File: heltec_wireless_stick_lite.h
*
* Function: Board Support File for Heltec Wireless Stick Lite.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display con be connected.
*
* The standard I2C pins defined in the BSP do not match the
* GPIO pins that the display is connected to. Therefore the
* the I2C Wire object is explicitly initialized with the
* correct pins (see boardInit() below).
*
* WARNING: Vext and the standard I2C SDA pin are both defined as GPIO21.
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 25 (LED_BUILTIN) Active-high
*
* I2C [display] GPIO
* ---- ----
* SDA <> 4 NOT SDA!
* SCL <> 15 NOT SCL!
* - 21 (SDA, Vext) used for VExt!!!
* - 22 (SCL)
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 27 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 5 (SCK)
* NSS <> 18 (SS)
* RST <> 14 (RST_LoRa)
* DIO0 <> 26 (DIO0)
* DIO1 <> 35 (DIO1)
* DIO2 <> 34 (DIO2)
*
* Other GPIO
* ----- ----
* VExt <> 21 (Vext, SDA) Active-low
*
* Definitions: LMIC-node:
* board-id: heltec_wireless_stick_lite
* PlatformIO
* board: heltec_wireless_stick_lite
* platform: espressif32
* Arduino
* board: ARDUINO_HELTEC_WIRELESS_STICK_LITE
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef HELTEC_WIRELESS_STICK_LITE_H_
#define HELTEC_WIRELESS_STICK_LITE_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "wireless-sticklt" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst =14,
.dio = { /*dio0*/ 26, /*dio1*/ 35, /*dio2*/ 34 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(25, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ 15, /*sda*/ 4);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
#ifdef USE_DISPLAY
// Initialize I2C Wire object with GPIO pins the display is connected to.
// These pins will be remembered and will not change if any library
// later calls Wire.begin() without parameters.
Wire.begin(/*sda*/ 4, /*scl*/ 15);
#endif
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // HELTEC_WIRELESS_STICK_LITE_H_

127
src/boards/lolin32.h Normal file
View file

@ -0,0 +1,127 @@
/*******************************************************************************
*
* File: lolin32.h
*
* Function: Board Support File for Lolin32 with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display can be connected.
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 5 (LED_BUILTIN) (SS) Active-low
* Conflicts with SS.
*
* I2C [display] GPIO
* --- ----
* SDA <> 21 (SDA)
* SCL <> 22 (SCL)
*
* SPI/LoRa module GPIO
* --- ----
* MOSI <> 23 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 18 (SCK)
* NSS <> 32 Do not use SS because conflicts with LED_BUILTIN.
* RST <> 33
* DIO0 <> 34
* DIO1 <> 35
* DIO2 - Not needed for LoRa.
*
* Definitions: LMIC-node
* board: lolin32
* PlatformIO
* board: lolin32
* platform: espressif32
* Arduino
* board: ARDUINO_LOLIN32
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef LOLIN32_H_
#define LOLIN32_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "lolin32" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 32,
.rxtx = LMIC_UNUSED_PIN,
.rst =33,
.dio = { /*dio0*/ 34, /*dio1*/ 35, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(5, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // LOLIN32_H_

127
src/boards/lolin_d32.h Normal file
View file

@ -0,0 +1,127 @@
/*******************************************************************************
*
* File: lolin_d32.h
*
* Function: Board Support File for Lolin D32 with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display can be connected.
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 5 (LED_BUILTIN) (SS) Active-low
* Conflicts with SS.
*
* I2C [display] GPIO
* --- ----
* SDA <> 21 (SDA)
* SCL <> 22 (SCL)
*
* SPI/LoRa module GPIO
* --- ----
* MOSI <> 23 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 18 (SCK)
* NSS <> 27 Do not use SS because conflicts with LED_BUILTIN.
* RST <> 32
* DIO0 <> 33
* DIO1 <> 34
* DIO2 - Not needed for LoRa.
*
* Definitions: LMIC-node
* board-id: lolin_d32
* PlatformIO
* board: lolin_d32
* platform: espressif32
* Arduino
* board: ARDUINO_LOLIN_D32
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef LOLIN_D32_H_
#define LOLIN_D32_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "lolin-d32" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 27,
.rxtx = LMIC_UNUSED_PIN,
.rst =32,
.dio = { /*dio0*/ 33, /*dio1*/ 34, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // LOLIN_D32_H_

127
src/boards/lolin_d32_pro.h Normal file
View file

@ -0,0 +1,127 @@
/*******************************************************************************
*
* File: lolin_d32_pro.h
*
* Function: Board Support File for Lolin D32 Pro with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display can be connected.
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 5 (LED_BUILTIN) (SS) Active-low
* Conflicts with SS.
*
* I2C [display] GPIO
* --- ----
* SDA <> 21 (SDA)
* SCL <> 22 (SCL)
*
* SPI/LoRa module GPIO
* --- ----
* MOSI <> 23 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 18 (SCK)
* NSS <> 27 Do not use SS because conflicts with LED_BUILTIN.
* RST <> 32
* DIO0 <> 33
* DIO1 <> 34
* DIO2 - Not needed for LoRa.
*
* Definitions: LMIC-node
* board-id: lolin_d32_pro
* PlatformIO
* board: lolin_d32_pro
* platform: espressif32
* Arduino
* board: ARDUINO_LOLIN_D32_PRO
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef LOLIN_D32_PRO_H_
#define LOLIN_D32_PRO_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "lolin-d32-pro" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 27,
.rxtx = LMIC_UNUSED_PIN,
.rst = 32,
.dio = { /*dio0*/ 33, /*dio1*/ 34, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // LOLIN_D32_PRO_H_

174
src/boards/lopy4.h Normal file
View file

@ -0,0 +1,174 @@
/*******************************************************************************
*
* File: lopy4.h
*
* Description: Board Support File for Pycom LoPy4.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This Board has no onboard USB and no onboard display.
* Optionally an external display can be connected.
* Has onboard LED but this is a special WS2812 RGB LED which requires
* a separate library and is currently not supported in LMIC-node.
*
* The standard SPI pins defined in the BSP do not match the
* GPIO pins that the SX1276 LoRa chip is connected to.
* LMIC uses the default SPI parameters for initializing the SPI bus
* which will not work here. Therefore the SPI object is explicitly
* initialized with the correct pins (see boardInit() below).
*
* For firmware upload and serial monitor use a USB to serial adapter.
* Lopy4 is made for use with MicroPython and does not provide
* automatic upload for C/C++ firmware (and no GPIO0 button).
* To put an ESP32 in firmware upload mode: First press the GPIO0
* button, then while keeping it pressed press the reset button,
* then release the reset button and then release the GPIO0 button.
* Because the Lopy4 does not have a GPIO0 button, instead of pressing
* the GPIO0 button connect a wire from GPIO0 (labeled '2' on the PCB)
* to GND and instead of releasing the GPIO0 button remove the wire again.
* Pycom also sells an Expansion board with onboard USB that
* supports firmware upload and serial over USB. The upload is not
* automatic however and the ESP32 must still be put in upload mode
* manually which still requires a wire because it also has no GPIO0 button.
* After firmware upload the Lopy4 must be manually reset (with button).
*
* LoRa DIO0, DIO1 and DIO2 are all wired (via diodes) to the same single GPIO port.
*
* WARNING: The 3.3V pin is OUTPUT ONLY don't use it to power the board!!
* The board must be powered on pin Vin with +3.5V to +5V.
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* WS2812 <---------> 0 (LED_BUILTIN) WS2812 RGB LED, not regular LED!
* pin labeled '2' on the PCB.
*
* I2C [display] GPIO
* --- ----
* SDA <> 12 (SDA)
* SCL <> 13 (SCL)
*
* SPI GPIO
* --- ----
* MOSI <> 22 (MOSI)
* MISO <> 37 (MISO)
* SCK <> 13 (SCK)
* SS <> 18 (SS)
*
* LoRa GPIO
* ---- ----
* MOSI <> 27 (LORA_MOSI)
* MISO <> 19 (LORA_MISO)
* SCK <> 5 (LORA_SCK)
* NSS <> 18 (LORA_CS)
* RST -
* RXTX -
* DIO0 <> 23 (LORA_IRQ, LORA_IO0)
* DIO1 <> 23 (LORA_IRQ, LORA_IO1)
* DIO2 <> 23 (LORA_IRQ, LORA_IO2)
*
* Serial GPIO
* ------ ----
* RX <> 3 (RX) pin labeled '0' on the PCB.
* TX <> 1 (TX) pin labeled '1' on the PCB.
*
* Identifiers: LMIC-node
* board-id: lopy4
* PlatformIO
* board: lopy4
* platform: espressif32
* Arduino
* board: ARDUINO_LoPy4
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef LOPY4_H_
#define LOPY4_H_
#include <SPI.h>
#include "lmic-node.h"
#define DEVICEID_DEFAULT "lopy4" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst =LMIC_UNUSED_PIN,
.dio = { /*dio0*/ 23, /*dio1*/ 23, /*dio2*/ 23 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
// Using onboard LED is currently not supported for this board
// because it is not a standard LED but a WS2812 RGB LED.
#error "USE_LED is not supported for this board."
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// Initialize standard SPI object with non-standard SPI pins for LoRa module.
// These pins will be remembered and will not change if any library
// later calls SPI.begin() without parameters.
SPI.begin(5, 19, 27, 18);
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // LOPY4_H_

128
src/boards/lora32u4II.h Normal file
View file

@ -0,0 +1,128 @@
/*******************************************************************************
*
* File: lora32u4II.h
*
* Function: Board Support File for BSFrance LoRa32u4 II versions 1.0 to 1.3.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by the MCU).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display con be connected.
*
* DIO1 MUST BE MANUALLY WIRED TO GPIO5 for versions < 1.3 (see below)
* For version 1.3 (see label om PCB) DIO1 is already wired on PCB.
*
* Connect DIO1 and optional display according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 13 (LED_BUILTIN) Active-high
*
* I2C [display] GPIO
* SDA <> 2 (SDA)
* SCL <> 3 (SCL)
*
* SPI/LoRa module GPIO
* MOSI <> 16 (MOSI)
* MISO <> 14 (MISO)
* SCK <> 15 (SCK)
* NSS <> 8
* RST <> 4
* DIO0 <> 7
* DIO1 <----------> 5 NOT WIRED on PCB for versions < 1.3
* DIO2 - Not needed for LoRa
*
* Definitions: LMIC-node
* board-id: lora32u4II
* PlatformIO
* board: lora32u4II
* platform: atmelavr
* Arduino
* board: ARDUINO_AVR_FEATHER32U4
* architecture: ARDUINO_ARCH_AVR
*
******************************************************************************/
#pragma once
#ifndef BSFRANCE_LORA32U4II_H_
#define BSFRANCE_LORA32U4II_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "lora32u4II" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
#define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// Value (30000) was determined empirically.
#define LMIC_CLOCK_ERROR_PPM 30000
const lmic_pinmap lmic_pins = {
.nss = 8,
.rxtx = LMIC_UNUSED_PIN,
.rst = 4,
.dio = { /*dio0*/ 7, /*dio1*/ 5, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 1000000 /* 1 MHz */
#endif
};
#ifdef USE_SERIAL
Serial_& serial = Serial;
// HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // BSFRANCE_LORA32U4II_H_

126
src/boards/nodemcu_32s.h Normal file
View file

@ -0,0 +1,126 @@
/*******************************************************************************
*
* File: nodemcu_32s.h
*
* Function: Board Support File for NodeMCU-32S with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display can be connected.
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 2 (LED_BUILTIN) Active-high
*
* I2C [display] GPIO
* --- ----
* SDA <> 21 (SDA)
* SCL <> 22 (SCL)
*
* SPI/LoRa module GPIO
* --- ----
* MOSI <> 23 (MOSI)
* MISO <> 19 (MISO)
* SCK <> 18 (SCK)
* NSS <> 5 (SS)
* RST <> 27
* DIO0 <> 34
* DIO1 <> 35
* DIO2 - Not needed for LoRa.
*
* Identifiers: LMIC-node
* board: nodemcu_32s
* PlatformIO
* board: nodemcu-32s
* platform: espressif32
* rduino
* board: ARDUINO_NodeMCU_32S
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef NODEMCU_32S_H_
#define NODEMCU_32S_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "nodemcu-32s" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 5,
.rxtx = LMIC_UNUSED_PIN,
.rst =27,
.dio = { /*dio0*/ 34, /*dio1*/ 35, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // NODEMCU_32S_H_

138
src/boards/nodemcuv2.h Normal file
View file

@ -0,0 +1,138 @@
/*******************************************************************************
*
* File: nodemcuv2.h
*
* Function: Board Support File for NodeMCU V2 (aka v1.0) with
* external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display.
*
* Due to the limited amount of available GPIO pins on the ESP8266
* and limitations for some of those pins it is not possible
* to use I2C and an external display.
*
* Connect the LoRa module according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* On NodeMCU <> D0 / 16 (LED_BUILTIN)
* On ESP12E <> D4 / 2 On ESP12E module, Active-low.
*
* I2C GPIO I2C cannot be used
* --- ----
* SCL <> D1 / 5 (SCL) is used for DIO0
* SDA <> D2 / 4 (SDA) is used for DIO1
*
* SPI/LoRa module GPIO
* --- ----
* NSS <> D8 / 15 (SS)
* MOSI <> D7 / 13 (MOSI)
* MISO <> D6 / 12 (MISO)
* SCK <> D5 / 14 (SCK)
* RST <> - Not connected (or connect to NodeMCU RST)
* DIO0 <> D1 / 5 (SCL)
* DIO1 <> D2 / 6 (SDA)
* DIO2 - Not needed for LoRa.
*
* Definitions: LMIC-node
* board: nodemcuv2
* PlatformIO
* board: nodemcuv2
* platform: espressif8266
* Arduino
* board: ARDUINO_ESP8266_NODEMCU
* architecture: ARDUINO_ARCH_ESP8266
*
******************************************************************************/
#pragma once
#ifndef NODEMCU_V2_H_
#define NODEMCU_V2_H_
#include <ESP8266WiFi.h>
#include "lmic-node.h"
#define DEVICEID_DEFAULT "nodemcuv2" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 15,
.rxtx = LMIC_UNUSED_PIN,
.rst = LMIC_UNUSED_PIN,
.dio = { /*dio0*/ 5, /*dio1*/ 4, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 1000000 /* 1 MHz */
#endif
};
#define LORA_NSS 15 //D8
#define LORA_RST LMIC_UNUSED_PIN
#define LORA_DIO0 5 //D1
#define LORA_DIO1 4 //D2
#define LORA_DIO2 LMIC_UNUSED_PIN
#define LORA_RXTX LMIC_UNUSED_PIN
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
#error "Display and I2C interface cannot be used with this board due to shortage of GPIO pins."
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // NODEMCU_V2_H_

View file

@ -0,0 +1,138 @@
/*******************************************************************************
*
* File: pro8mhzatmega328.h
*
* Description: Board Support File for Arduino Pro Mini ATmega328 8MHz
* with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See included LICENSE file.
*
* Description: This Board has no onboard USB and no onboard display.
* Optionally an external display can be connected.
*
* For firmware upload and serial monitor use a USB to serial
* adapter that supports DTR (for automatic firmware upload).
*
* Connect the LoRa module and optional display
* according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 13 (LED_BUILTIN) (SCK) Active-high,
* Useless, shared with SCK.
* LED_EXTERNAL <---> 6 Optional external LED.
*
* I2C [display] GPIO
* --- ----
* SDA <> 2 (SDA)
* SCL <> 3 (SCL)
*
* SPI/LoRa module GPIO
* ---- ----
* MOSI <> 11 (MOSI)
* MISO <> 12 (MISO)
* SCK <> 13 (SCK)
* NSS <> 10 (SS)
* RST <> 7
* DIO0 <> 8
* DIO1 <> 9
* DIO2 - Not needed for LoRa.
*
* Definitions: LMIC-node
* board: pro8mhzatmega328
* PlatformIO
* board: pro8MHzatmega328
* platform: atmelavr
* Arduino
* board: ARDUINO_AVR_PRO
* architecture: ARDUINO_ARCH_AVR
*
******************************************************************************/
#pragma once
#ifndef ARDUINO_PROMINI_328_8MHZ_H_
#define ARDUINO_PROMINI_328_8MHZ_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "pro-mini" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// Value 30000 was determined empirically.
#define LMIC_CLOCK_ERROR_PPM 30000
const lmic_pinmap lmic_pins = {
.nss = 10,
.rxtx = LMIC_UNUSED_PIN,
.rst = 7,
.dio = { /*dio0*/ 8, /*dio1*/ 9, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 1000000 /* 1 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#define LED_EXTERNAL 6
// #define LED LED_EXTERNAL
#define LED LED_BUILTIN
#ifdef USE_LED
#if LED == LED_BUILTIN
#error Cannot use LED_BUILTIN because it conflicts with SPI (alternative: use external LED).
#else
EasyLed led(LED, EasyLed::ActiveLevel::High);
#endif
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // ARDUINO_PROMINI_328_8MHZ_H_

151
src/boards/ttgo_lora32_v1.h Normal file
View file

@ -0,0 +1,151 @@
/*******************************************************************************
*
* File: ttgo_lora32_v1.h
*
* Function: Board Support File for TTGO LoRa32 (aka T3) v1.3.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* Has onboard display.
*
* The standard I2C pins defined in the BSP do not match the
* GPIO pins that the display is connected to. Therefore the
* the I2C Wire object is explicitly initialized with the
* correct pins (see boardInit() below).
*
* LED_BUILTIN is defined in BSP but schematic diagram and
* and pinout diagram show no onboard user LED.
* Based on documentation USE_LED is not supported for this board.
*
* OLED_RST and LORA_RST are defined in BSP but neither is connected to GPIO.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 2 Defined in BSP as LED_BUILTIN, however:
* According to documentation this board has no LED.
*
* I2C/Display GPIO
* --- ----
* SDA <> 4 Not SDA! (OLED_SDA)
* SCL <> 15 Not SCL! (OLED_SCL)
* RST OLED_RST is defined in BSP but not connected to GPIO.
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 27 (MOSI) (LORA_MOSI)
* MISO <> 19 (MISO) (LORA_MISO)
* SCK <> 5 (SCK) (LORA_SCK)
* NSS <> 18 (SS) (LORA_CS)
* RST <> 14 (LORA_RST)
* DIO0 <> 26 (LORA_IRQ)
* DIO1 <> 33
* DIO2 <> 32
*
* Button switches GPIO
* ------ ----
* Button <> 36 (V_SP) Active-low
*
* Battery measure GPIO
* ------- ----
* VBAT <> 35 Battery voltage via 50% voltage divider
*
* Definitions: LMIC-node
* board: ttgo_lora32_v1
* PlatformIO
* board: ttgo-lora32-v1
* platform: espressif32
* Arduino
* board: ARDUINO_TTGO_LoRa32_V1
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef TTGO_LORA32_V1_H_
#define TTGO_LORA32_V1_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "ttgo-lora32-v1" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = 14, // See remark about LORA_RST above.
.dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
#error Unknown if this board has a user LED therefore USE_LED is not supported.
// EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low); // Or active-high?
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ 15, /*sda*/ 4);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
#ifdef USE_DISPLAY
// Initialize I2C Wire object with GPIO pins the display is connected to.
// These pins will be remembered and will not change if any library
// later calls Wire.begin() without parameters.
Wire.begin(4, 15);
#endif
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // TTGO_LORA32_V1_H_

135
src/boards/ttgo_lora32_v2.h Normal file
View file

@ -0,0 +1,135 @@
/*******************************************************************************
*
* File: ttgo_lora32_v2.h
*
* Description: Board Support File for TTGO LoRa32 (aka T3) v2.0.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* Has onboard display.
*
* DIO1 MUST BE MANUALLY WIRED TO GPIO33 (see below)
*
* LED_BUILTIN and I2C SCL share the same pin.
* Therefore cannot use USE_DISPLAY and USE_LED together.
*
* OLED_RST and LORA_RST are defined in BSP but neither is connected to GPIO.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 22 (LED_BUILTIN) (SCL) Active-low
* Shared with I2C SCL
*
* I2C/Display GPIO
* --- ----
* SDA <> 21 (SDA) (OLED_SDA)
* SCL <> 22 (SCL) (OLED_SCL) (LED_BUILTIN)
* RST - OLED_RST is defined in BSP but not wired to GPIO
*
* SPI/LoRa GPIO
* MOSI <> 27 (MOSI) (LORA_MOSI)
* MISO <> 19 (MISO) (LORA_MISO)
* SCK <> 5 (SCK) (LORA_SCK)
* NSS <> 18 (SS) (LORA_CS)
* RST <> - Not LORA_RST
* DIO0 <> 26 (LORA_IRQ)
* DIO1 <----------> 33 NOT WIRED on PCB
* DIO2 - Not needed for LoRa
*
* Identifiers: LMIC-node
* board: ttgo_lora32_v2
* PlatformIO
* board: ttgo-lora32-v2
* platform: espressif32
* Arduino
* board: ARDUINO_TTGO_LoRa32_V2
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef TTGO_LORA32_V2_H_
#define TTGO_LORA32_V2_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "ttgo-lora32-v2" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = LMIC_UNUSED_PIN,
.dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#if defined(USE_DISPLAY) && defined(USE_LED) && LED_PIN == LED_ONBOARD
#error USE_DISPLAY and USE_LED cannot be used together for onboard LED
#endif
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // TTGO_LORA32_V2_H_

View file

@ -0,0 +1,125 @@
/*******************************************************************************
*
* File: ttgo_lora32_v216.h
*
* Description: Board Support File for TTGO LoRa32 v2.1.6
* (aka T3 V1.6 and LoRa32 V2.1 release 1.6).
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* Has onboard display.
*
* LORA_RST is defined in BSP but has incorrect value (12).
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 25 (LED_BUILTIN) Active-low (?)
*
* I2C/Display GPIO
* SDA <> 21 (SDA) (OLED_SDA)
* SCL <> 22 (SCL) (OLED_SCL)
* RST <> 16 (OLED_RST)
*
* SPI/LoRa GPIO
* MOSI <> 27 (MOSI) (LORA_MOSI)
* MISO <> 19 (MISO) (LORA_MISO)
* SCK <> 5 (SCK) (LORA_SCK)
* NSS <> 18 (SS) (LORA_CS)
* RST <> 23 Not LORA_RST
* DIO0 <> 26 (LORA_IRQ)
* DIO1 <> 33 (LORA_D1)
* DIO2 <> 32 (LORA_D2)
*
* Definitions: LMIC-node
* board: ttgo_lora32_v21
* PlatformIO
* board: ttgo-lora32-v21
* platform: espressif32
* Arduino
* board: ARDUINO_TTGO_LoRa32_v21new
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef TTGO_LORA32_V21_H_
#define TTGO_LORA32_V21_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "ttgo-lora32-v21" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = 23,
.dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ OLED_RST, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // TTGO_LORA32_V21_H_

132
src/boards/ttgo_tbeam_v07.h Normal file
View file

@ -0,0 +1,132 @@
/*******************************************************************************
*
* File: ttgo_tbeam_v07.h
*
* Description: Board Support File for TTGO T-Beam (aka T22) v0.7.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display con be connected.
* Also has onboard GPS which is not used by LMIC-node.
*
* Connect an optional display according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 14 (LED_BUILTIN) Active-high
*
* I2C [display] GPIO
* ---- ----
* SDA <> 21 (SDA)
* SCL <> 22 (SCL)
* RST -
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 27 (MOSI) (LORA_MOSI)
* MISO <> 19 (MISO) (LORA_MISO)
* SCK <> 5 (SCK) (LORA_SCK)
* NSS <> 18 (SS) (LORA_CS)
* RST <> 23 (LORA_RST)
* DIO0 <> 26 (LORA_IO0)
* DIO1 <> 33 (LORA_IO1)
* DIO2 <> 32 (LORA_IO2)
*
* GPS GPIO
* --- ----
* RX <> 15
* TX <> 12
*
* Definitions: LMIC-node
* board: ttgo_tbeam_v07
* PlatformIO
* board: ttgo-t-beam
* platform: espressif32
* Arduino
* board: ARDUINO_T_Beam
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef TTGO_TBEAM_V07_H_
#define TTGO_TBEAM_V07_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "ttgo-tbeam-v07" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = 23,
.dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // TTGO_TBEAM_V07_H_

169
src/boards/ttgo_tbeam_v10.h Normal file
View file

@ -0,0 +1,169 @@
/*******************************************************************************
*
* File: ttgo_tbeam_v10.h
*
* Description: Board Support File for TTGO T-Beam V1.0 (aka T22_08).
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by onboard USB to serial).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display con be connected.
* Also has onboard GPS which is not used by LMIC-node.
*
* This board uses an AXP192 power management chip to power
* onboard components and the +3.3V output pin.
* The AXP192 must be correctly configured for things to work
* (see boardInit() below).
*
* Connect an optional display according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> 14 (LED_BUILTIN) Active-high
*
* I2C [display] GPIO
* ---- ----
* SDA <> 21 (SDA)
* SCL <> 22 (SCL)
* RST -
*
* SPI/LoRa GPIO
* --- ----
* MOSI <> 27 (MOSI) (LORA_MOSI)
* MISO <> 19 (MISO) (LORA_MISO)
* SCK <> 5 (SCK) (LORA_SCK)
* NSS <> 18 (SS) (LORA_CS)
* RST <> 23 (LORA_RST)
* DIO0 <> 26 (LORA_IO0)
* DIO1 <> 33 (LORA_IO1)
* DIO2 <> 32 (LORA_IO2)
*
* GPS GPIO
* --- ----
* RX <> 34 (or 12?)
* TX <> 12 (or 34?)
* PPS <> 37
*
* Power Management GPIO
* ----- ----
* PMU <> 35
*
* Button switches GPIO
* ------ ----
* USR_SW <> 39 (KEY_BUILTIN)
*
* Definitions: LMIC-node
* board: ttgo_tbeam_v10
* PlatformIO
* board: ttgo-t-beam
* platform: espressif32
* Arduino
* board: ARDUINO_T_Beam
* architecture: ARDUINO_ARCH_ESP32
*
******************************************************************************/
#pragma once
#ifndef TTGO_TBEAM_V10_H_
#define TTGO_TBEAM_V10_H_
#include "axp20x.h"
#include "lmic-node.h"
#define DEVICEID_DEFAULT "ttgo-tbeam-v10" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
// #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = 23,
.dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
AXP20X_Class axp;
#ifdef USE_SERIAL
HardwareSerial& serial = Serial;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// This board contains an AXP192 power management chip.
// Power output must be enabled for several components before they can be initialized.
Wire.begin(SDA, SCL);
if (axp.begin(Wire, AXP192_SLAVE_ADDRESS) != 0)
{
success = false;
}
else
{
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
// Explicitly set voltages because AXP192 power-on values may be lower.
axp.setDCDC1Voltage(3300); // 3.3V pin
axp.setLDO2Voltage (3300); // LoRa
axp.setLDO3Voltage (3000); // GPS (unknown if this must be 3.0 or 3.3V)
}
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // TTGO_TBEAM_V10_H_

133
src/boards/zerousb.h Normal file
View file

@ -0,0 +1,133 @@
/*******************************************************************************
*
* File: zerousb.h
*
* Function: Board Support File for Arduino Zero (USB Native port)
* and SAMD21 M0-Mini, with external SPI LoRa module.
*
* Copyright: Copyright (c) 2021 Leonel Lopes Parente
*
* License: MIT License. See accompanying LICENSE file.
*
* Author: Leonel Lopes Parente
*
* Description: This board has onboard USB (provided by the MCU).
* It supports automatic firmware upload and serial over USB.
* No onboard display. Optionally an external display con be connected.
*
* The SPI pins are located on the top side of the PCB as part of
* the ICSP connector. It is strange that this board has an ICSP
* connector because the board has an ARM MCU (not AVR)
* So the SPI pins are not breadboard friendly.
*
* Connect an optional display according to below connection details.
*
* CONNECTIONS AND PIN DEFINITIONS:
*
* Indentifiers between parentheses are defined in the board's
* Board Support Package (BSP) which is part of the Arduino core.
*
* Leds GPIO
* ---- ----
* LED <> PA17 / 13 (LED_BUILTIN, PIN_LED, PIN_LED_13)
* LED2 <> PB03 / 25 (RX, PIN_LED2, PIN_LED_RXL)
* LED3 <> PA27 / 26 (TX, PIN_LED3, PIN_LED_TXL)
*
* I2C [display] GPIO
* --- ----
* SDA <> PA22 / 20 (SDA)
* SCL <> PA23 / 21 (SCL)
*
* SPI/LoRa module GPIO
* --- ----
* MOSI <> PB10 / 23 (MOSI) ICSP connector pin 4
* MISO <> PA12 / 22 (MISO) ICSP connector pin 1
* SCK <> PB11 / 24 (SCK) ICSP connector pin 3
* NSS <> PA20 / 6
* RST <> PA21 / 7
* DIO0 <> PA06 / 8
* DIO1 <> PA07 / 9
* DIO2 - Not needed for LoRa.
*
* Definitions: LMIC-node
* board: zerousb
* PlatformIO
* board: zeroUSB
* platform: atmelsam
* Arduino
* board: ARDUINO_SAMD_ZERO
* architecture: ARDUINO_ARCH_SAMD
*
******************************************************************************/
#pragma once
#ifndef ARDUINO_ZERO_USB_H_
#define ARDUINO_ZERO_USB_H_
#include "lmic-node.h"
#define DEVICEID_DEFAULT "zero-usb" // Default deviceid value
// Wait for Serial
// Can be useful for boards with MCU with integrated USB support.
#define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely
// LMIC Clock Error
// This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4).
// Value is defined in parts per million (of MAX_CLOCK_ERROR).
// #define LMIC_CLOCK_ERROR_PPM 0
const lmic_pinmap lmic_pins = {
.nss = 6,
.rxtx = LMIC_UNUSED_PIN,
.rst = 7,
.dio = { /*dio0*/ 8, /*dio1*/ 9, /*dio2*/ LMIC_UNUSED_PIN }
#ifdef MCCI_LMIC
,
.rxtx_rx_active = 0,
.rssi_cal = 10,
.spi_freq = 8000000 /* 8 MHz */
#endif
};
#ifdef USE_SERIAL
Serial_& serial = SerialUSB;
#endif
#ifdef USE_LED
EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High);
#endif
#ifdef USE_DISPLAY
// Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C.
U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA);
#endif
bool boardInit(InitType initType)
{
// This function is used to perform board specific initializations.
// Required as part of standard template.
// InitType::Hardware Must be called at start of setup() before anything else.
// InitType::PostInitSerial Must be called after initSerial() before other initializations.
bool success = true;
switch (initType)
{
case InitType::Hardware:
// Note: Serial port and display are not yet initialized and cannot be used use here.
// No actions required for this board.
break;
case InitType::PostInitSerial:
// Note: If enabled Serial port and display are already initialized here.
// No actions required for this board.
break;
}
return success;
}
#endif // ARDUINO_ZERO_USB_H_