Merge branch 'master' into master

This commit is contained in:
Jm Casler 2021-03-19 23:38:42 -07:00 committed by GitHub
commit 0befad82a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 676 additions and 244 deletions

View File

@ -7,7 +7,7 @@
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc... is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes - Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on - Please do not reformat lines that you didn't have to change the code on
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor, - We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor and the 'clang-format' extension,
because automatically follows our indentation rules and it's auto reformatting will not cause spurious changes to lines. because automatically follows our indentation rules and it's auto reformatting will not cause spurious changes to lines.
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description. - If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed. - If your other co-developers have comments on your PR please tweak as needed.

View File

@ -15,10 +15,10 @@ jobs:
uses: actions/setup-python@v2 uses: actions/setup-python@v2
with: with:
python-version: 3.x python-version: 3.x
- name: Install Platform IO - name: Install Platform IO and meshtastic-python
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio meshtastic
- name: Install extra python tools - name: Install extra python tools
run: | run: |
pip install -U adafruit-nrfutil pip install -U adafruit-nrfutil
@ -31,6 +31,11 @@ jobs:
run: platformio run -e heltec run: platformio run -e heltec
- name: Build for lora-relay-v1 - name: Build for lora-relay-v1
run: platformio run -e lora-relay-v1 run: platformio run -e lora-relay-v1
# Turn off linux for now - name: Build for native
name: Build for native
run: platformio run -e native run: platformio run -e native
- name: Integration test
run: |
.pio/build/native/program &
sleep 1
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'

View File

@ -2,6 +2,7 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846 // See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format // for the documentation about the extensions.json format
"recommendations": [ "recommendations": [
"platformio.platformio-ide" "platformio.platformio-ide",
"xaver.clang-format"
] ]
} }

View File

@ -77,5 +77,6 @@
"--java_out=/tmp", "--java_out=/tmp",
"-I=/home/kevinh/development/meshtastic/meshtastic-esp32/proto" "-I=/home/kevinh/development/meshtastic/meshtastic-esp32/proto"
] ]
} },
"editor.formatOnSave": true
} }

3
bin/program-1.0-tbeam.sh Executable file
View File

@ -0,0 +1,3 @@
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
esptool.py --baud 921600 erase_region 0xe000 0x2000

View File

@ -1 +1 @@
esptool.py --baud 921600 write_flash 0x10000 release/archive/firmware-tbeam-1.1.50.bin esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin

48
boards/lora_isp4520.json Normal file
View File

@ -0,0 +1,48 @@
{
"build": {
"arduino": {
"ldscript": "nrf52832_s132_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DNRF52832_XXAA -DNRF52",
"f_cpu": "64000000L",
"mcu": "nrf52832",
"variant": "lora_isp4520",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS132",
"sd_name": "s132",
"sd_version": "6.1.1",
"sd_fwid": "0x00B7"
}
},
"connectivity": [
"bluetooth"
],
"debug": {
"jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd"
},
"frameworks": [
"arduino"
],
"name": "lora ISP4520",
"upload": {
"maximum_ram_size": 65536,
"maximum_size": 524288,
"require_upload_port": true,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
]
},
"url": "",
"vendor": "PsiSoft"
}

View File

@ -2,16 +2,26 @@
You probably don't care about this section - skip to the next one. You probably don't care about this section - skip to the next one.
## 1.2 cleanup & multichannel support: ## before next release
* before next relase: test empty channel sets on android * DONE timestamps on oled screen are wrong - don't seem to be updating based on message rx (actually: this is expected behavior when no node on the mesh has GPS time)
* test link sharing on android * DONE add ch-del
* DONE channel hash suffixes are wrong on android
* DONE before next relase: test empty channel sets on android
* DONE channel sharing in android
* DONE test 1.0 firmware update on android
* DONE test 1.1 firmware update on android
* test 1.2.10 firmware update on android
* DONE test link sharing on android
* luxon bug report - seeing rx acks for nodes that are not on the network
* document how to do remote admin
* release py, android, device
## 1.2 cleanup & multichannel support:
* DONE cleanup the external notification and serial plugins * DONE cleanup the external notification and serial plugins
* non ack version of stress test fails sometimes! * non ack version of stress test fails sometimes!
* timestamps on oled screen are wrong - don't seem to be updating based on message rx
* luxon bug report - seeing rx acks for nodes that are not on the network
* channel hash suffixes are wrong on android
* tx fault test has a bug #734 * tx fault test has a bug #734
* DONE move device types into an enum in nodeinfo * DONE move device types into an enum in nodeinfo
* fix android to use new device types for firmware update * fix android to use new device types for firmware update

View File

@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[platformio] [platformio]
;default_envs = tbeam default_envs = tbeam
;default_envs = tbeam0.7 ;default_envs = tbeam0.7
;default_envs = heltec ;default_envs = heltec
;default_envs = tlora-v1 ;default_envs = tlora-v1
@ -17,7 +17,7 @@
;default_envs = lora-relay-v1 # nrf board ;default_envs = lora-relay-v1 # nrf board
;default_envs = eink ;default_envs = eink
;default_envs = nrf52840dk-geeksville ;default_envs = nrf52840dk-geeksville
default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here ;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
[common] [common]
; common is not currently used ; common is not currently used
@ -39,7 +39,7 @@ extra_scripts = bin/platformio-custom.py
; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc ; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc
build_flags = -Wno-missing-field-initializers build_flags = -Wno-missing-field-initializers
-Wno-format -Wno-format
-Isrc -Isrc/mesh -Isrc/gps -Ilib/nanopb/include -Wl,-Map,.pio/build/output.map -Isrc -Isrc/mesh -Isrc/gps -Ilib/nanopb/include -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DHW_VERSION_${sysenv.COUNTRY} -DHW_VERSION_${sysenv.COUNTRY}
-DHW_VERSION=${sysenv.HW_VERSION} -DHW_VERSION=${sysenv.HW_VERSION}
-DUSE_THREAD_NAMES -DUSE_THREAD_NAMES
@ -232,6 +232,24 @@ debug_init_break =
;debug_init_break = tbreak loop ;debug_init_break = tbreak loop
;debug_init_break = tbreak Reset_Handler ;debug_init_break = tbreak Reset_Handler
[env:lora_isp4520]
extends = nrf52_base
board = lora_isp4520
# add our variants files to the include and src paths
build_flags = ${nrf52_base.build_flags} -Ivariants/lora_isp4520
# No screen and GPS on the board. We still need RTC.cpp for the RTC clock.
src_filter = ${nrf52_base.src_filter} +<../variants/lora_isp4520> -<graphics> -<gps> +<gps/GPS.cpp> +<gps/RTC.cpp>
lib_ignore = ${nrf52_base.lib_ignore}
ESP8266_SSD1306
SparkFun Ublox Arduino Library
AXP202X_Library
TinyGPSPlus
upload_protocol = jlink
monitor_port = /dev/ttyUSB0
; The NRF52840-dk development board ; The NRF52840-dk development board
; Note: By default no lora device is created for this build - it uses a simulated interface ; Note: By default no lora device is created for this build - it uses a simulated interface
[env:nrf52840dk] [env:nrf52840dk]

2
proto

@ -1 +1 @@
Subproject commit 39bb8b26bbc107aae3586d5a5e11a06ea12680bc Subproject commit b8c0499f28f9673d1df17d04da562e30703f01cb

View File

@ -5,12 +5,35 @@
#include "sleep.h" #include "sleep.h"
#include "utils.h" #include "utils.h"
#ifdef TBEAM_V10
// FIXME. nasty hack cleanup how we load axp192 // FIXME. nasty hack cleanup how we load axp192
#undef AXP192_SLAVE_ADDRESS #undef AXP192_SLAVE_ADDRESS
#include "axp20x.h" #include "axp20x.h"
#ifdef TBEAM_V10
AXP20X_Class axp; AXP20X_Class axp;
#else
// Copy of the base class defined in axp20x.h.
// I'd rather not inlude axp20x.h as it brings Wire dependency.
class HasBatteryLevel {
public:
/**
* Battery state of charge, from 0 to 100 or -1 for unknown
*/
virtual int getBattPercentage() { return -1; }
/**
* The raw voltage of the battery or NAN if unknown
*/
virtual float getBattVoltage() { return NAN; }
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() { return false; }
virtual bool isVBUSPlug() { return false; }
virtual bool isChargeing() { return false; }
};
#endif #endif
bool pmu_irq = false; bool pmu_irq = false;
@ -51,7 +74,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
*/ */
virtual int getBattPercentage() virtual int getBattPercentage()
{ {
float v = getBattVoltage() / 1000; float v = getBattVoltage();
if (v < noBatVolt) if (v < noBatVolt)
return -1; // If voltage is super low assume no battery installed return -1; // If voltage is super low assume no battery installed
@ -67,13 +90,26 @@ class AnalogBatteryLevel : public HasBatteryLevel
*/ */
virtual float getBattVoltage() virtual float getBattVoltage()
{ {
// Tested ttgo eink nrf52 board and the reported value is perfect
// DEBUG_MSG("raw val %u", raw); #ifndef ADC_MULTIPLIER
return #define ADC_MULTIPLIER 2.0
#endif
#ifdef BATTERY_PIN #ifdef BATTERY_PIN
1000.0 * 2.0 * (AREF_VOLTAGE / 1024.0) * analogRead(BATTERY_PIN); // Do not call analogRead() often.
const uint32_t min_read_interval = 5000;
if (millis() - last_read_time_ms > min_read_interval) {
last_read_time_ms = millis();
uint32_t raw = analogRead(BATTERY_PIN);
float scaled = 1000.0 * ADC_MULTIPLIER * (AREF_VOLTAGE / 1024.0) * raw;
// DEBUG_MSG("raw val=%u scaled=%u\n", raw, (uint32_t)(scaled));
last_read_value = scaled;
return scaled;
} else {
return last_read_value;
}
#else #else
NAN; return NAN;
#endif #endif
} }
@ -93,7 +129,9 @@ class AnalogBatteryLevel : public HasBatteryLevel
private: private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping /// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power /// in power
const float fullVolt = 4.2, emptyVolt = 3.27, chargingVolt = 4.3, noBatVolt = 2.1; const float fullVolt = 4200, emptyVolt = 3270, chargingVolt = 4210, noBatVolt = 2100;
float last_read_value = 0.0;
uint32_t last_read_time_ms = 0;
} analogLevel; } analogLevel;
Power::Power() : OSThread("Power") {} Power::Power() : OSThread("Power") {}
@ -140,6 +178,8 @@ void Power::shutdown()
#ifdef TBEAM_V10 #ifdef TBEAM_V10
DEBUG_MSG("Shutting down\n"); DEBUG_MSG("Shutting down\n");
axp.shutdown(); axp.shutdown();
#elif NRF52_SERIES
doDeepSleep(DELAY_FOREVER);
#endif #endif
} }

View File

@ -97,7 +97,7 @@ static void lsIdle()
static void lsExit() static void lsExit()
{ {
// setGPSPower(true); // restore GPS power // setGPSPower(true); // restore GPS power
gps->forceWake(true); if (gps) gps->forceWake(true);
} }
static void nbEnter() static void nbEnter()

View File

@ -4,27 +4,27 @@
#include <assert.h> #include <assert.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include "RTC.h"
/** /**
* A printer that doesn't go anywhere * A printer that doesn't go anywhere
*/ */
NoopPrint noopPrint; NoopPrint noopPrint;
void RedirectablePrint::setDestination(Print *_dest) void RedirectablePrint::setDestination(Print *_dest) {
{
assert(_dest); assert(_dest);
dest = _dest; dest = _dest;
} }
size_t RedirectablePrint::write(uint8_t c) size_t RedirectablePrint::write(uint8_t c) {
{
// Always send the characters to our segger JTAG debugger // Always send the characters to our segger JTAG debugger
#ifdef SEGGER_STDOUT_CH #ifdef SEGGER_STDOUT_CH
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c); SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
#endif #endif
dest->write(c); dest->write(c);
return 1; // We always claim one was written, rather than trusting what the serial port said (which could be zero) return 1; // We always claim one was written, rather than trusting what the
// serial port said (which could be zero)
} }
size_t RedirectablePrint::vprintf(const char *format, va_list arg) size_t RedirectablePrint::vprintf(const char *format, va_list arg)
@ -38,7 +38,7 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
va_end(arg); va_end(arg);
return 0; return 0;
}; };
if (len >= (int)printBufLen) { if (len >= printBufLen) {
delete[] printBuf; delete[] printBuf;
printBufLen *= 2; printBufLen *= 2;
printBuf = new char[printBufLen]; printBuf = new char[printBufLen];
@ -68,9 +68,9 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
// If we are the first message on a report, include the header // If we are the first message on a report, include the header
if (!isContinuationMessage) { if (!isContinuationMessage) {
struct timeval tv; uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
if (!gettimeofday(&tv, NULL)) { if (rtc_sec > 0) {
long hms = tv.tv_sec % SEC_PER_DAY; long hms =rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR; // hms += tz.tz_dsttime * SEC_PER_HOUR;
// hms -= tz.tz_minuteswest * SEC_PER_MIN; // hms -= tz.tz_minuteswest * SEC_PER_MIN;
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY) // mod `hms` to ensure in positive range of [0...SEC_PER_DAY)

66
src/buzz/buzz.cpp Normal file
View File

@ -0,0 +1,66 @@
#include "buzz.h"
#include "configuration.h"
#ifdef NRF52_SERIES
#include "variant.h"
#endif
#ifndef PIN_BUZZER
// Noop methods for boards w/o buzzer
void playBeep(){};
void playStartMelody(){};
void playShutdownMelody(){};
#else
#include "Tone.h"
extern "C" void delay(uint32_t dwMs);
struct ToneDuration {
int frequency_khz;
int duration_ms;
};
// Some common frequencies.
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note
void playTones(const ToneDuration *tone_durations, int size) {
for (int i = 0; i < size; i++) {
const auto &tone_duration = tone_durations[i];
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
// to distinguish the notes, set a minimum time between them.
delay(1.3 * tone_duration.duration_ms);
}
}
void playBeep() { tone(PIN_BUZZER, NOTE_B3, DURATION_1_4); }
void playStartMelody() {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
{NOTE_B3, DURATION_1_8},
{NOTE_B3, DURATION_1_8}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playShutdownMelody() {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
{NOTE_G3, DURATION_1_8},
{NOTE_D3, DURATION_1_8}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
#endif

5
src/buzz/buzz.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void playBeep();
void playStartMelody();
void playShutdownMelody();

View File

@ -338,7 +338,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#elif defined(TLORA_V2_1_16) #elif defined(TLORA_V2_1_16)
// This string must exactly match the case used in release file names or the android updater won't work // This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TLORA_V2_1p6_ #define HW_VENDOR HardwareModel_TLORA_V2_1_1p6
#undef GPS_RX_PIN #undef GPS_RX_PIN
#undef GPS_TX_PIN #undef GPS_TX_PIN
@ -459,6 +459,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DEBUG_PORT console // Serial debug port #define DEBUG_PORT console // Serial debug port
// What platforms should use SEGGER? // What platforms should use SEGGER?
#ifdef NRF52_SERIES #ifdef NRF52_SERIES

View File

@ -308,3 +308,49 @@ int GPS::prepareDeepSleep(void *unused)
return 0; return 0;
} }
#ifdef GPS_TX_PIN
#include "UBloxGPS.h"
#endif
#ifdef HAS_AIR530_GPS
#include "Air530GPS.h"
#elif !defined(NO_GPS)
#include "NMEAGPS.h"
#endif
GPS* createGps() {
#ifdef NO_GPS
return nullptr;
#else
// If we don't have bidirectional comms, we can't even try talking to UBLOX
#ifdef GPS_TX_PIN
// Init GPS - first try ublox
UBloxGPS *ublox = new UBloxGPS();
if (!ublox->setup()) {
DEBUG_MSG("ERROR: No UBLOX GPS found\n");
delete ublox;
ublox = NULL;
} else {
return ublox;
}
#endif
if (GPS::_serial_gps) {
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
// assume NMEA at 9600 baud.
DEBUG_MSG("Hoping that NMEA might work\n");
#ifdef HAS_AIR530_GPS
GPS* new_gps = new Air530GPS();
#else
GPS* new_gps = new NMEAGPS();
#endif
new_gps->setup();
return new_gps;
}
return nullptr;
#endif
}

View File

@ -71,6 +71,9 @@ class GPS : private concurrency::OSThread
* */ * */
void forceWake(bool on); void forceWake(bool on);
// Some GPS modules (ublock) require factory reset
virtual bool factoryReset() { return true; }
protected: protected:
/// Do gps chipset specific init, return true for success /// Do gps chipset specific init, return true for success
virtual bool setupGPS(); virtual bool setupGPS();
@ -145,4 +148,8 @@ class GPS : private concurrency::OSThread
virtual int32_t runOnce(); virtual int32_t runOnce();
}; };
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
GPS* createGps();
extern GPS *gps; extern GPS *gps;

View File

@ -42,7 +42,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
} else if(q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000L)) { } else if(q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000L)) {
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift // Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
shouldSet = true; shouldSet = true;
DEBUG_MSG("Reapplying GPS time to correct clock drift %ld secs\n", tv->tv_sec); DEBUG_MSG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
} }
else else
shouldSet = false; shouldSet = false;
@ -51,10 +51,11 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
lastSetMsec = now; lastSetMsec = now;
#ifndef NO_ESP32 #ifndef NO_ESP32
settimeofday(tv, NULL); settimeofday(tv, NULL);
#else
DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n");
#endif
readFromRTC(); readFromRTC();
#else
timeStartMsec = now;
zeroOffsetSecs = tv->tv_sec;
#endif
return true; return true;
} else { } else {
return false; return false;

View File

@ -1,5 +1,23 @@
#pragma once #pragma once
#ifdef NO_SCREEN
namespace graphics
{
// Noop class for boards without screen.
class Screen
{
public:
Screen(char){}
void onPress() {}
void setup() {}
void setOn(bool) {}
void print(const char*){}
void adjustBrightness(){}
void doDeepSleep() {}
};
}
#else
#include <cstring> #include <cstring>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
@ -278,3 +296,4 @@ class Screen : public concurrency::OSThread
}; };
} // namespace graphics } // namespace graphics
#endif

View File

@ -1,11 +1,11 @@
#include "Air530GPS.h" #include "GPS.h"
#include "MeshRadio.h" #include "MeshRadio.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "UBloxGPS.h"
#include "airtime.h" #include "airtime.h"
#include "buzz.h"
#include "configuration.h" #include "configuration.h"
#include "error.h" #include "error.h"
#include "power.h" #include "power.h"
@ -67,7 +67,7 @@ Router *router = NULL; // Users of router don't care what sort of subclass imple
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Application // Application
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#ifndef NO_WIRE
void scanI2Cdevice(void) void scanI2Cdevice(void)
{ {
byte err, addr; byte err, addr;
@ -104,6 +104,9 @@ void scanI2Cdevice(void)
else else
DEBUG_MSG("done\n"); DEBUG_MSG("done\n");
} }
#else
void scanI2Cdevice(void) {}
#endif
const char *getDeviceName() const char *getDeviceName()
{ {
@ -173,7 +176,7 @@ class ButtonThread : public OSThread
#ifdef BUTTON_PIN_ALT #ifdef BUTTON_PIN_ALT
OneButton userButtonAlt; OneButton userButtonAlt;
#endif #endif
static bool shutdown_on_long_stop;
public: public:
static uint32_t longPressTime; static uint32_t longPressTime;
@ -239,13 +242,23 @@ class ButtonThread : public OSThread
// DEBUG_MSG("Long press!\n"); // DEBUG_MSG("Long press!\n");
screen->adjustBrightness(); screen->adjustBrightness();
// If user button is held down for 10 seconds, shutdown the device. // If user button is held down for 5 seconds, shutdown the device.
if (millis() - longPressTime > 10 * 1000) { if (millis() - longPressTime > 5 * 1000) {
#ifdef TBEAM_V10 #ifdef TBEAM_V10
if (axp192_found == true) { if (axp192_found == true) {
setLed(false); setLed(false);
power->shutdown(); power->shutdown();
} }
#elif NRF52_SERIES
// Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly.
if (!shutdown_on_long_stop) {
DEBUG_MSG("Shutdown from long press");
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
shutdown_on_long_stop = true;
}
#endif #endif
} else { } else {
// DEBUG_MSG("Long press %u\n", (millis() - longPressTime)); // DEBUG_MSG("Long press %u\n", (millis() - longPressTime));
@ -269,9 +282,15 @@ class ButtonThread : public OSThread
{ {
DEBUG_MSG("Long press stop!\n"); DEBUG_MSG("Long press stop!\n");
longPressTime = 0; longPressTime = 0;
if (shutdown_on_long_stop) {
playShutdownMelody();
power->shutdown();
}
} }
}; };
bool ButtonThread::shutdown_on_long_stop = false;
static Periodic *ledPeriodic; static Periodic *ledPeriodic;
static OSThread *powerFSMthread, *buttonThread; static OSThread *powerFSMthread, *buttonThread;
uint32_t ButtonThread::longPressTime = 0; uint32_t ButtonThread::longPressTime = 0;
@ -345,7 +364,7 @@ void setup()
#ifdef I2C_SDA #ifdef I2C_SDA
Wire.begin(I2C_SDA, I2C_SCL); Wire.begin(I2C_SDA, I2C_SCL);
#else #elif !defined(NO_WIRE)
Wire.begin(); Wire.begin();
#endif #endif
@ -382,7 +401,7 @@ void setup()
#ifdef NRF52_SERIES #ifdef NRF52_SERIES
nrf52Setup(); nrf52Setup();
#endif #endif
playStartMelody();
// We do this as early as possible because this loads preferences from flash // We do this as early as possible because this loads preferences from flash
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set // but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
nodeDB.init(); nodeDB.init();
@ -420,34 +439,7 @@ void setup()
pinMode(BATTERY_EN_PIN, OUTPUT); pinMode(BATTERY_EN_PIN, OUTPUT);
digitalWrite(BATTERY_EN_PIN, LOW); digitalWrite(BATTERY_EN_PIN, LOW);
#endif #endif
gps = createGps();
// If we don't have bidirectional comms, we can't even try talking to UBLOX
UBloxGPS *ublox = NULL;
#ifdef GPS_TX_PIN
// Init GPS - first try ublox
ublox = new UBloxGPS();
gps = ublox;
if (!gps->setup()) {
DEBUG_MSG("ERROR: No UBLOX GPS found\n");
delete ublox;
gps = ublox = NULL;
}
#endif
if (!gps && GPS::_serial_gps) {
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
// assume NMEA at 9600 baud.
// dumb NMEA access only work for serial GPSes)
DEBUG_MSG("Hoping that NMEA might work\n");
#ifdef HAS_AIR530_GPS
gps = new Air530GPS();
#else
gps = new NMEAGPS();
#endif
gps->setup();
}
if (gps) if (gps)
gpsStatus->observe(&gps->newStatus); gpsStatus->observe(&gps->newStatus);
@ -481,8 +473,8 @@ void setup()
// We have now loaded our saved preferences from flash // We have now loaded our saved preferences from flash
// ONCE we will factory reset the GPS for bug #327 // ONCE we will factory reset the GPS for bug #327
if (ublox && !devicestate.did_gps_reset) { if (gps && !devicestate.did_gps_reset) {
if (ublox->factoryReset()) { // If we don't succeed try again next time if (gps->factoryReset()) { // If we don't succeed try again next time
devicestate.did_gps_reset = true; devicestate.did_gps_reset = true;
nodeDB.saveToDisk(); nodeDB.saveToDisk();
} }

View File

@ -1,9 +1,13 @@
#pragma once #pragma once
#include "mesh/MeshTypes.h" #include "mesh/MeshTypes.h"
#include <vector>
#ifndef NO_SCREEN
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
#include <vector> #endif
/** A baseclass for any mesh "plugin". /** A baseclass for any mesh "plugin".
* *
* A plugin allows you to add new features to meshtastic device code, without needing to know messaging details. * A plugin allows you to add new features to meshtastic device code, without needing to know messaging details.
@ -31,9 +35,9 @@ class MeshPlugin
static void callPlugins(const MeshPacket &mp); static void callPlugins(const MeshPacket &mp);
static std::vector<MeshPlugin *> GetMeshPluginsWithUIFrames(); static std::vector<MeshPlugin *> GetMeshPluginsWithUIFrames();
#ifndef NO_SCREEN
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; } virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; }
#endif
protected: protected:
const char *name; const char *name;

View File

@ -37,8 +37,8 @@ bool SX1262Interface::init()
#ifndef SX1262_E22 #ifndef SX1262_E22
float tcxoVoltage = 0; // None - we use an XTAL float tcxoVoltage = 0; // None - we use an XTAL
#else #else
float tcxoVoltage = // Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
1.8; // E22 uses DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575 float tcxoVoltage = 1.8;
#endif #endif
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC? bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?

View File

@ -25,6 +25,7 @@ typedef struct _AdminMessage {
Channel get_channel_response; Channel get_channel_response;
bool confirm_set_channel; bool confirm_set_channel;
bool confirm_set_radio; bool confirm_set_radio;
bool exit_simulator;
}; };
} AdminMessage; } AdminMessage;
@ -47,6 +48,7 @@ extern "C" {
#define AdminMessage_get_channel_response_tag 7 #define AdminMessage_get_channel_response_tag 7
#define AdminMessage_confirm_set_channel_tag 32 #define AdminMessage_confirm_set_channel_tag 32
#define AdminMessage_confirm_set_radio_tag 33 #define AdminMessage_confirm_set_radio_tag 33
#define AdminMessage_exit_simulator_tag 34
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define AdminMessage_FIELDLIST(X, a) \ #define AdminMessage_FIELDLIST(X, a) \
@ -58,7 +60,8 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,get_radio_response,get_radio_respons
X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \ X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \ X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34)
#define AdminMessage_CALLBACK NULL #define AdminMessage_CALLBACK NULL
#define AdminMessage_DEFAULT NULL #define AdminMessage_DEFAULT NULL
#define AdminMessage_variant_set_radio_MSGTYPE RadioConfig #define AdminMessage_variant_set_radio_MSGTYPE RadioConfig

View File

@ -3,8 +3,8 @@
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#include <bluefruit.h> #include <bluefruit.h>
#include "mesh/mesh-pb-constants.h"
#include "mesh/PhoneAPI.h"
static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16)); static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16));
static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16)); static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16));
@ -213,6 +213,7 @@ void NRF52Bluetooth::setup()
{ {
// Initialise the Bluefruit module // Initialise the Bluefruit module
DEBUG_MSG("Initialise the Bluefruit nRF52 module\n"); DEBUG_MSG("Initialise the Bluefruit nRF52 module\n");
Bluefruit.autoConnLed(false);
Bluefruit.begin(); Bluefruit.begin();
// Set the advertised device name (keep it short!) // Set the advertised device name (keep it short!)

View File

@ -1,7 +1,3 @@
#include "NRF52Bluetooth.h"
#include "configuration.h"
#include "error.h"
#include "graphics/TFTDisplay.h"
#include <SPI.h> #include <SPI.h>
#include <Wire.h> #include <Wire.h>
#include <assert.h> #include <assert.h>
@ -9,53 +5,54 @@
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <stdio.h>
#ifdef NRF52840_XXAA #include "NRF52Bluetooth.h"
// #include <nrf52840.h> #include "configuration.h"
#include "error.h"
#ifdef BQ25703A_ADDR
#include "BQ25713.h"
#endif #endif
// #define USE_SOFTDEVICE
static inline void debugger_break(void) static inline void debugger_break(void) {
{ __asm volatile(
__asm volatile("bkpt #0x01\n\t" "bkpt #0x01\n\t"
"mov pc, lr\n\t"); "mov pc, lr\n\t");
} }
// handle standard gcc assert failures // handle standard gcc assert failures
void __attribute__((noreturn)) __assert_func(const char *file, int line, const char *func, const char *failedexpr) void __attribute__((noreturn))
{ __assert_func(const char *file, int line, const char *func,
DEBUG_MSG("assert failed %s: %d, %s, test=%s\n", file, line, func, failedexpr); const char *failedexpr) {
DEBUG_MSG("assert failed %s: %d, %s, test=%s\n", file, line, func,
failedexpr);
// debugger_break(); FIXME doesn't work, possibly not for segger // debugger_break(); FIXME doesn't work, possibly not for segger
while (1) while (1)
; // FIXME, reboot! ; // FIXME, reboot!
} }
void getMacAddr(uint8_t *dmac) void getMacAddr(uint8_t *dmac) {
{
ble_gap_addr_t addr; ble_gap_addr_t addr;
if (sd_ble_gap_addr_get(&addr) == NRF_SUCCESS) {
#ifdef USE_SOFTDEVICE
uint32_t res = sd_ble_gap_addr_get(&addr);
assert(res == NRF_SUCCESS);
memcpy(dmac, addr.addr, 6); memcpy(dmac, addr.addr, 6);
#else } else {
const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR; const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR;
dmac[5] = src[0]; dmac[5] = src[0];
dmac[4] = src[1]; dmac[4] = src[1];
dmac[3] = src[2]; dmac[3] = src[2];
dmac[2] = src[3]; dmac[2] = src[3];
dmac[1] = src[4]; dmac[1] = src[4];
dmac[0] = src[5] | 0xc0; // MSB high two bits get set elsewhere in the bluetooth stack dmac[0] = src[5] |
#endif 0xc0; // MSB high two bits get set elsewhere in the bluetooth stack
}
} }
NRF52Bluetooth *nrf52Bluetooth; NRF52Bluetooth *nrf52Bluetooth;
static bool bleOn = false; static bool bleOn = false;
static const bool useSoftDevice = false; // Set to false for easier debugging static const bool useSoftDevice = true; // Set to false for easier debugging
void setBluetoothEnable(bool on) void setBluetoothEnable(bool on) {
{
if (on != bleOn) { if (on != bleOn) {
if (on) { if (on) {
if (!nrf52Bluetooth) { if (!nrf52Bluetooth) {
@ -67,8 +64,7 @@ void setBluetoothEnable(bool on)
} }
} }
} else { } else {
if (nrf52Bluetooth) if (nrf52Bluetooth) nrf52Bluetooth->shutdown();
nrf52Bluetooth->shutdown();
} }
bleOn = on; bleOn = on;
} }
@ -77,8 +73,7 @@ void setBluetoothEnable(bool on)
/** /**
* Override printf to use the SEGGER output library * Override printf to use the SEGGER output library
*/ */
int printf(const char *fmt, ...) int printf(const char *fmt, ...) {
{
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
auto res = SEGGER_RTT_vprintf(0, fmt, &args); auto res = SEGGER_RTT_vprintf(0, fmt, &args);
@ -86,12 +81,8 @@ int printf(const char *fmt, ...)
return res; return res;
} }
#include "BQ25713.h" void initBrownout() {
void initBrownout()
{
auto vccthresh = POWER_POFCON_THRESHOLD_V28; auto vccthresh = POWER_POFCON_THRESHOLD_V28;
auto vcchthresh = POWER_POFCON_THRESHOLDVDDH_V27;
if (useSoftDevice) { if (useSoftDevice) {
auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled); auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled);
@ -99,17 +90,22 @@ void initBrownout()
err_code = sd_power_pof_threshold_set(vccthresh); err_code = sd_power_pof_threshold_set(vccthresh);
assert(err_code == NRF_SUCCESS); assert(err_code == NRF_SUCCESS);
} } else {
else { uint32_t pof_flags = POWER_POFCON_POF_Enabled | (vccthresh << POWER_POFCON_THRESHOLD_Pos);
NRF_POWER->POFCON = POWER_POFCON_POF_Msk | (vccthresh << POWER_POFCON_THRESHOLD_Pos) | (vcchthresh << POWER_POFCON_THRESHOLDVDDH_Pos);
#ifdef POWER_POFCON_THRESHOLDVDDH_Msk
auto vcchthresh = POWER_POFCON_THRESHOLDVDDH_V27;
pof_flags |= (vcchthresh << POWER_POFCON_THRESHOLDVDDH_Pos);
#endif
NRF_POWER->POFCON = pof_flags;
} }
} }
void checkSDEvents() void checkSDEvents() {
{
if (useSoftDevice) { if (useSoftDevice) {
uint32_t evt; uint32_t evt;
while (NRF_ERROR_NOT_FOUND == sd_evt_get(&evt)) { while (NRF_SUCCESS == sd_evt_get(&evt)) {
switch (evt) { switch (evt) {
case NRF_EVT_POWER_FAILURE_WARNING: case NRF_EVT_POWER_FAILURE_WARNING:
recordCriticalError(CriticalErrorCode_Brownout); recordCriticalError(CriticalErrorCode_Brownout);
@ -126,26 +122,22 @@ void checkSDEvents()
} }
} }
void nrf52Loop() void nrf52Loop() { checkSDEvents(); }
{
checkSDEvents();
}
void nrf52Setup()
{
void nrf52Setup() {
auto why = NRF_POWER->RESETREAS; auto why = NRF_POWER->RESETREAS;
// per https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpower.html // per
// https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpower.html
DEBUG_MSG("Reset reason: 0x%x\n", why); DEBUG_MSG("Reset reason: 0x%x\n", why);
// Per https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/monitor-mode-debugging-with-j-link-and-gdbeclipse // Per
// https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/monitor-mode-debugging-with-j-link-and-gdbeclipse
// This is the recommended setting for Monitor Mode Debugging // This is the recommended setting for Monitor Mode Debugging
NVIC_SetPriority(DebugMonitor_IRQn, 6UL); NVIC_SetPriority(DebugMonitor_IRQn, 6UL);
#ifdef BQ25703A_ADDR #ifdef BQ25703A_ADDR
auto *bq = new BQ25713(); auto *bq = new BQ25713();
if (!bq->setup()) if (!bq->setup()) DEBUG_MSG("ERROR! Charge controller init failed\n");
DEBUG_MSG("ERROR! Charge controller init failed\n");
#endif #endif
// Init random seed // Init random seed
@ -160,22 +152,29 @@ void nrf52Setup()
initBrownout(); initBrownout();
} }
void cpuDeepSleep(uint64_t msecToWake) void cpuDeepSleep(uint64_t msecToWake) {
{
// FIXME, configure RTC or button press to wake us // FIXME, configure RTC or button press to wake us
// FIXME, power down SPI, I2C, RAMs // FIXME, power down SPI, I2C, RAMs
#ifndef NO_WIRE
Wire.end(); Wire.end();
#endif
SPI.end(); SPI.end();
// This may cause crashes as debug messages continue to flow.
Serial.end(); Serial.end();
Serial1.end();
#ifdef PIN_SERIAL_RX1
Serial1.end();
#endif
setBluetoothEnable(false);
// FIXME, use system off mode with ram retention for key state? // FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per // FIXME, use non-init RAM per
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled // https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
auto ok = sd_power_system_off(); auto ok = sd_power_system_off();
if (ok != NRF_SUCCESS) { if (ok != NRF_SUCCESS) {
DEBUG_MSG("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n"); DEBUG_MSG(
"FIXME: Ignoring soft device (EasyDMA pending?) and forcing "
"system-off!\n");
NRF_POWER->SYSTEMOFF = 1; NRF_POWER->SYSTEMOFF = 1;
} }

View File

@ -6,6 +6,10 @@
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#ifdef PORTDUINO
#include "unistd.h"
#endif
AdminPlugin *adminPlugin; AdminPlugin *adminPlugin;
void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex) void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex)
@ -51,7 +55,7 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessag
break; break;
case AdminMessage_set_channel_tag: case AdminMessage_set_channel_tag:
DEBUG_MSG("Client is setting channel\n"); DEBUG_MSG("Client is setting channel %d\n", r->set_channel.index);
handleSetChannel(r->set_channel); handleSetChannel(r->set_channel);
break; break;
@ -65,6 +69,13 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessag
handleGetRadio(mp); handleGetRadio(mp);
break; break;
#ifdef PORTDUINO
case AdminMessage_exit_simulator_tag:
DEBUG_MSG("Exiting simulator\n");
_exit(0);
break;
#endif
default: default:
// Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages // Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages
DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_variant); DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_variant);
@ -102,8 +113,7 @@ void AdminPlugin::handleSetChannel(const Channel &cc)
if (cc.index == 0) { if (cc.index == 0) {
// FIXME, this updates the user preferences also, which isn't needed - we really just want to notify on configChanged // FIXME, this updates the user preferences also, which isn't needed - we really just want to notify on configChanged
service.reloadConfig(); service.reloadConfig();
} } else {
else {
channels.onConfigChanged(); // tell the radios about this change channels.onConfigChanged(); // tell the radios about this change
nodeDB.saveChannelsToDisk(); nodeDB.saveChannelsToDisk();
} }

View File

@ -0,0 +1,52 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
const uint32_t g_ADigitalPinMap[] = {
25, // D0 SPI_MISO
24, // D1 SPI_NSS
23, // D2 SPI_SCK
4, // D3 VBAT
11, // D4 DIO1
27, // D5 BUSY
19, // D6 NRESET
12, // D7 BUTTON2
22, // D8 BUTTON3
26, // D9 SPI_MOSI
31, // D10 UART_RX
2, // D11 UART_TX
10, // D12 LED1 GREEN
17, // D13 LED2 RED
9, // D14 BUZZER
7, // D15 BUTTON1
};
#include <initializer_list>
void initVariant()
{
for (int i : {PIN_LED1, PIN_LED2}) {
pinMode(i, OUTPUT);
ledOff(i);
}
}

View File

@ -0,0 +1,99 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_LORA_ISP4520_
#define _VARIANT_LORA_ISP4520_
#define HW_VERSION_US 1
#undef HW_VERSION
#define HW_VERSION "1.0"
#define USE_SEGGER
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#define USE_LFXO
//#define USE_SEGGER
// Number of pins defined in PinDescription array
#define PINS_COUNT (16)
#define NUM_DIGITAL_PINS (16)
#define NUM_ANALOG_INPUTS (1)
#define NUM_ANALOG_OUTPUTS (1)
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
// These are in arduino pin numbers,
// translation in g_ADigitalPinMap in variants.cpp
#define PIN_SPI_MISO (0)
#define PIN_SPI_MOSI (9)
#define PIN_SPI_SCK (2)
/*
* Wire Interfaces (I2C)
*/
#define WIRE_INTERFACES_COUNT 0
// GPIOs the SX1262 is connected
#define SX1262_CS 1 // aka SPI_NSS
#define SX1262_DIO1 (4)
#define SX1262_BUSY (5)
#define SX1262_RESET (6)
/*
* Serial interfaces
*/
#define PIN_SERIAL_RX (10)
#define PIN_SERIAL_TX (11)
// LEDs
#define PIN_LED1 (12)
#define PIN_LED2 (13)
#define PIN_BUZZER (14)
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
#define LED_RED PIN_LED1
#define LED_BLUE PIN_LED2
#define LED_STATE_ON 1 // State when LED is litted
/*
* Buttons
*/
#define PIN_BUTTON1 (15)
#define PIN_BUTTON2 (7)
#define PIN_BUTTON3 (8)
// ADC pin and voltage divider
#define BATTERY_PIN 3
#define ADC_MULTIPLIER 1.436
#define SX1262_E22 // Not really an E22 but this board clones using DIO3 for tcxo control
#define NO_WIRE
#define NO_GPS
#define NO_SCREEN
#endif

View File

@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 1 major = 1
minor = 2 minor = 2
build = 10 build = 11