From e4724aacff32a8b15081f597ab810d7b1c36da33 Mon Sep 17 00:00:00 2001 From: Leonel Lopes Parente Date: Sat, 17 Apr 2021 18:28:44 +0200 Subject: [PATCH] Add initial contents --- .gitignore | 20 + LICENSE | 2 + keyfiles/lorawan-keys_example.h | 67 ++ .../lmic-node-uplink-formatters.js | 27 + platformio.ini | 715 ++++++++++++++++ src/LMIC-node.cpp | 786 ++++++++++++++++++ src/LMIC-node.h | 314 +++++++ src/boards/adafruit_feather_m0_lora.h | 131 +++ src/boards/blackpill_f103c8.h | 163 ++++ src/boards/bluepill_f103c8.h | 162 ++++ src/boards/disco_l072cz_lrwan1.h | 175 ++++ src/boards/heltec_wifi_lora_32.h | 149 ++++ src/boards/heltec_wifi_lora_32_v2.h | 143 ++++ src/boards/heltec_wireless_stick.h | 148 ++++ src/boards/heltec_wireless_stick_lite.h | 145 ++++ src/boards/lolin32.h | 127 +++ src/boards/lolin_d32.h | 127 +++ src/boards/lolin_d32_pro.h | 127 +++ src/boards/lopy4.h | 174 ++++ src/boards/lora32u4II.h | 128 +++ src/boards/nodemcu_32s.h | 126 +++ src/boards/nodemcuv2.h | 138 +++ src/boards/pro8mhzatmega328.h | 138 +++ src/boards/ttgo_lora32_v1.h | 151 ++++ src/boards/ttgo_lora32_v2.h | 135 +++ src/boards/ttgo_lora32_v21.h | 125 +++ src/boards/ttgo_tbeam_v07.h | 132 +++ src/boards/ttgo_tbeam_v10.h | 169 ++++ src/boards/zerousb.h | 133 +++ 29 files changed, 5077 insertions(+) create mode 100644 .gitignore create mode 100644 keyfiles/lorawan-keys_example.h create mode 100644 payload-formatters/lmic-node-uplink-formatters.js create mode 100644 platformio.ini create mode 100644 src/LMIC-node.cpp create mode 100644 src/LMIC-node.h create mode 100644 src/boards/adafruit_feather_m0_lora.h create mode 100644 src/boards/blackpill_f103c8.h create mode 100644 src/boards/bluepill_f103c8.h create mode 100644 src/boards/disco_l072cz_lrwan1.h create mode 100644 src/boards/heltec_wifi_lora_32.h create mode 100644 src/boards/heltec_wifi_lora_32_v2.h create mode 100644 src/boards/heltec_wireless_stick.h create mode 100644 src/boards/heltec_wireless_stick_lite.h create mode 100644 src/boards/lolin32.h create mode 100644 src/boards/lolin_d32.h create mode 100644 src/boards/lolin_d32_pro.h create mode 100644 src/boards/lopy4.h create mode 100644 src/boards/lora32u4II.h create mode 100644 src/boards/nodemcu_32s.h create mode 100644 src/boards/nodemcuv2.h create mode 100644 src/boards/pro8mhzatmega328.h create mode 100644 src/boards/ttgo_lora32_v1.h create mode 100644 src/boards/ttgo_lora32_v2.h create mode 100644 src/boards/ttgo_lora32_v21.h create mode 100644 src/boards/ttgo_tbeam_v07.h create mode 100644 src/boards/ttgo_tbeam_v10.h create mode 100644 src/boards/zerousb.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b107ca --- /dev/null +++ b/.gitignore @@ -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/ diff --git a/LICENSE b/LICENSE index 431b0aa..6a66232 100644 --- a/LICENSE +++ b/LICENSE @@ -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 diff --git a/keyfiles/lorawan-keys_example.h b/keyfiles/lorawan-keys_example.h new file mode 100644 index 0000000..9ec14c9 --- /dev/null +++ b/keyfiles/lorawan-keys_example.h @@ -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 "" + +// 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 "" + +// 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_ diff --git a/payload-formatters/lmic-node-uplink-formatters.js b/payload-formatters/lmic-node-uplink-formatters.js new file mode 100644 index 0000000..bc21214 --- /dev/null +++ b/payload-formatters/lmic-node-uplink-formatters.js @@ -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 + }; +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..86ac4ad --- /dev/null +++ b/platformio.ini @@ -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 = + 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//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 \ No newline at end of file diff --git a/src/LMIC-node.cpp b/src/LMIC-node.cpp new file mode 100644 index 0000000..91d8088 --- /dev/null +++ b/src/LMIC-node.cpp @@ -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 +#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(); +} diff --git a/src/LMIC-node.h b/src/LMIC-node.h new file mode 100644 index 0000000..8cd93be --- /dev/null +++ b/src/LMIC-node.h @@ -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 +#include "lmic.h" +#include "hal/hal.h" + +#ifdef USE_DISPLAY + #include + #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 \ + "<>", \ + "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 \ + "<>\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_ diff --git a/src/boards/adafruit_feather_m0_lora.h b/src/boards/adafruit_feather_m0_lora.h new file mode 100644 index 0000000..2e0b8be --- /dev/null +++ b/src/boards/adafruit_feather_m0_lora.h @@ -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_ \ No newline at end of file diff --git a/src/boards/blackpill_f103c8.h b/src/boards/blackpill_f103c8.h new file mode 100644 index 0000000..6e2a620 --- /dev/null +++ b/src/boards/blackpill_f103c8.h @@ -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_ \ No newline at end of file diff --git a/src/boards/bluepill_f103c8.h b/src/boards/bluepill_f103c8.h new file mode 100644 index 0000000..7ecf2a9 --- /dev/null +++ b/src/boards/bluepill_f103c8.h @@ -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_ \ No newline at end of file diff --git a/src/boards/disco_l072cz_lrwan1.h b/src/boards/disco_l072cz_lrwan1.h new file mode 100644 index 0000000..d6f08aa --- /dev/null +++ b/src/boards/disco_l072cz_lrwan1.h @@ -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 +#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_ \ No newline at end of file diff --git a/src/boards/heltec_wifi_lora_32.h b/src/boards/heltec_wifi_lora_32.h new file mode 100644 index 0000000..d72a119 --- /dev/null +++ b/src/boards/heltec_wifi_lora_32.h @@ -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_ \ No newline at end of file diff --git a/src/boards/heltec_wifi_lora_32_v2.h b/src/boards/heltec_wifi_lora_32_v2.h new file mode 100644 index 0000000..b5e6e18 --- /dev/null +++ b/src/boards/heltec_wifi_lora_32_v2.h @@ -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_ \ No newline at end of file diff --git a/src/boards/heltec_wireless_stick.h b/src/boards/heltec_wireless_stick.h new file mode 100644 index 0000000..6b620be --- /dev/null +++ b/src/boards/heltec_wireless_stick.h @@ -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_ \ No newline at end of file diff --git a/src/boards/heltec_wireless_stick_lite.h b/src/boards/heltec_wireless_stick_lite.h new file mode 100644 index 0000000..bcc03db --- /dev/null +++ b/src/boards/heltec_wireless_stick_lite.h @@ -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_ \ No newline at end of file diff --git a/src/boards/lolin32.h b/src/boards/lolin32.h new file mode 100644 index 0000000..a0279d5 --- /dev/null +++ b/src/boards/lolin32.h @@ -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_ \ No newline at end of file diff --git a/src/boards/lolin_d32.h b/src/boards/lolin_d32.h new file mode 100644 index 0000000..e3ec5aa --- /dev/null +++ b/src/boards/lolin_d32.h @@ -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_ \ No newline at end of file diff --git a/src/boards/lolin_d32_pro.h b/src/boards/lolin_d32_pro.h new file mode 100644 index 0000000..9b07bf6 --- /dev/null +++ b/src/boards/lolin_d32_pro.h @@ -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_ \ No newline at end of file diff --git a/src/boards/lopy4.h b/src/boards/lopy4.h new file mode 100644 index 0000000..2a6ae5d --- /dev/null +++ b/src/boards/lopy4.h @@ -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 +#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_ \ No newline at end of file diff --git a/src/boards/lora32u4II.h b/src/boards/lora32u4II.h new file mode 100644 index 0000000..ecd2c2f --- /dev/null +++ b/src/boards/lora32u4II.h @@ -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_ \ No newline at end of file diff --git a/src/boards/nodemcu_32s.h b/src/boards/nodemcu_32s.h new file mode 100644 index 0000000..746b8b8 --- /dev/null +++ b/src/boards/nodemcu_32s.h @@ -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_ \ No newline at end of file diff --git a/src/boards/nodemcuv2.h b/src/boards/nodemcuv2.h new file mode 100644 index 0000000..f33eac1 --- /dev/null +++ b/src/boards/nodemcuv2.h @@ -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 +#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_ \ No newline at end of file diff --git a/src/boards/pro8mhzatmega328.h b/src/boards/pro8mhzatmega328.h new file mode 100644 index 0000000..5c68b3f --- /dev/null +++ b/src/boards/pro8mhzatmega328.h @@ -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_ \ No newline at end of file diff --git a/src/boards/ttgo_lora32_v1.h b/src/boards/ttgo_lora32_v1.h new file mode 100644 index 0000000..6c32ab2 --- /dev/null +++ b/src/boards/ttgo_lora32_v1.h @@ -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_ \ No newline at end of file diff --git a/src/boards/ttgo_lora32_v2.h b/src/boards/ttgo_lora32_v2.h new file mode 100644 index 0000000..e0ed369 --- /dev/null +++ b/src/boards/ttgo_lora32_v2.h @@ -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_ \ No newline at end of file diff --git a/src/boards/ttgo_lora32_v21.h b/src/boards/ttgo_lora32_v21.h new file mode 100644 index 0000000..b536261 --- /dev/null +++ b/src/boards/ttgo_lora32_v21.h @@ -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_ \ No newline at end of file diff --git a/src/boards/ttgo_tbeam_v07.h b/src/boards/ttgo_tbeam_v07.h new file mode 100644 index 0000000..dd107b6 --- /dev/null +++ b/src/boards/ttgo_tbeam_v07.h @@ -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_ \ No newline at end of file diff --git a/src/boards/ttgo_tbeam_v10.h b/src/boards/ttgo_tbeam_v10.h new file mode 100644 index 0000000..02bb508 --- /dev/null +++ b/src/boards/ttgo_tbeam_v10.h @@ -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_ \ No newline at end of file diff --git a/src/boards/zerousb.h b/src/boards/zerousb.h new file mode 100644 index 0000000..9b6d687 --- /dev/null +++ b/src/boards/zerousb.h @@ -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_ \ No newline at end of file