From 98d878cdfe7c320a87165d251db91419d5114246 Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Sun, 14 Mar 2021 19:00:20 -0700 Subject: [PATCH 1/6] Port to lora_isp4520 board --- boards/lora_isp4520.json | 48 ++++++++++++ platformio.ini | 22 +++++- src/Power.cpp | 60 +++++++++++--- src/PowerFSM.cpp | 2 +- src/RedirectablePrint.cpp | 126 +++++++++++++++--------------- src/buzz/buzz.cpp | 52 ++++++++++++ src/buzz/buzz.h | 5 ++ src/buzz/pitches.h | 91 +++++++++++++++++++++ src/configuration.h | 4 + src/gps/GPS.cpp | 46 +++++++++++ src/gps/GPS.h | 7 ++ src/gps/RTC.cpp | 15 ++-- src/graphics/Screen.h | 19 +++++ src/main.cpp | 68 +++++++--------- src/mesh/SX1262Interface.cpp | 6 +- src/nrf52/NRF52Bluetooth.cpp | 5 +- src/nrf52/main-nrf52.cpp | 6 +- variants/lora_isp4520/variant.cpp | 52 ++++++++++++ variants/lora_isp4520/variant.h | 98 +++++++++++++++++++++++ 19 files changed, 604 insertions(+), 128 deletions(-) create mode 100644 boards/lora_isp4520.json create mode 100644 src/buzz/buzz.cpp create mode 100644 src/buzz/buzz.h create mode 100644 src/buzz/pitches.h create mode 100644 variants/lora_isp4520/variant.cpp create mode 100644 variants/lora_isp4520/variant.h diff --git a/boards/lora_isp4520.json b/boards/lora_isp4520.json new file mode 100644 index 000000000..180cd2fe7 --- /dev/null +++ b/boards/lora_isp4520.json @@ -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" +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 2033b2faf..155242b81 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,7 +33,7 @@ extra_scripts = bin/platformio-custom.py ; note: we add src to our include search path so that lmic_project_config can override ; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc -build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/nanopb/include -Wl,-Map,.pio/build/output.map +build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Ilib/nanopb/include -Wl,-Map,.pio/build/output.map -DHW_VERSION_${sysenv.COUNTRY} -DHW_VERSION=${sysenv.HW_VERSION} -DUSE_THREAD_NAMES @@ -65,7 +65,6 @@ debug_tool = jlink ; monitor adapter_khz 10000 lib_deps = - https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306 https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39 @@ -104,6 +103,7 @@ build_flags = lib_deps = ${arduino_base.lib_deps} https://github.com/meshtastic/esp32_https_server.git + https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306 # Hmm - this doesn't work yet # board_build.ldscript = linker/esp32.extram.bss.ld lib_ignore = segger_rtt @@ -204,6 +204,24 @@ debug_init_break = ;debug_init_break = tbreak loop ;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> - - + + +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 ; Note: By default no lora device is created for this build - it uses a simulated interface [env:nrf52840dk] diff --git a/src/Power.cpp b/src/Power.cpp index 26c40f926..f709fb22e 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -5,12 +5,35 @@ #include "sleep.h" #include "utils.h" +#ifdef TBEAM_V10 // FIXME. nasty hack cleanup how we load axp192 #undef AXP192_SLAVE_ADDRESS #include "axp20x.h" -#ifdef TBEAM_V10 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 isCharging() { return false; } +}; #endif bool pmu_irq = false; @@ -51,7 +74,7 @@ class AnalogBatteryLevel : public HasBatteryLevel */ virtual int getBattPercentage() { - float v = getBattVoltage() / 1000; + float v = getBattVoltage(); if (v < noBatVolt) return -1; // If voltage is super low assume no battery installed @@ -67,13 +90,26 @@ class AnalogBatteryLevel : public HasBatteryLevel */ virtual float getBattVoltage() { - // Tested ttgo eink nrf52 board and the reported value is perfect - // DEBUG_MSG("raw val %u", raw); - return + +#ifndef ADC_MULTIPLIER +#define ADC_MULTIPLIER 2.0 +#endif + #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 - NAN; + return NAN; #endif } @@ -88,12 +124,14 @@ class AnalogBatteryLevel : public HasBatteryLevel /// Assume charging if we have a battery and external power is connected. /// we can't be smart enough to say 'full'? - virtual bool isChargeing() { return isBatteryConnect() && isVBUSPlug(); } + virtual bool isCharging() { return isBatteryConnect() && isVBUSPlug(); } private: /// If we see a battery voltage higher than physics allows - assume charger is pumping /// 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; Power::Power() : OSThread("Power") {} @@ -140,6 +178,8 @@ void Power::shutdown() #ifdef TBEAM_V10 DEBUG_MSG("Shutting down\n"); axp.shutdown(); +#elif NRF52_SERIES + doDeepSleep(DELAY_FOREVER); #endif } @@ -170,7 +210,7 @@ void Power::readPowerStatus() // Notify any status instances that are observing us const PowerStatus powerStatus = PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse, - batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent); + batteryLevel->isCharging() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent); DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus.getHasUSB(), powerStatus.getIsCharging(), powerStatus.getBatteryVoltageMv(), powerStatus.getBatteryChargePercent()); newStatus.notifyObservers(&powerStatus); diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 85e08f536..4857ae07d 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -97,7 +97,7 @@ static void lsIdle() static void lsExit() { // setGPSPower(true); // restore GPS power - gps->forceWake(true); + if (gps) gps->forceWake(true); } static void nbEnter() diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 541b55c78..585b3a9a0 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -1,99 +1,97 @@ #include "RedirectablePrint.h" -#include "configuration.h" + #include -#include -#include + +#include "RTC.h" #include "concurrency/OSThread.h" +#include "configuration.h" /** * A printer that doesn't go anywhere */ NoopPrint noopPrint; -void RedirectablePrint::setDestination(Print *_dest) -{ - assert(_dest); - dest = _dest; +void RedirectablePrint::setDestination(Print *_dest) { + assert(_dest); + dest = _dest; } -size_t RedirectablePrint::write(uint8_t c) -{ - // Always send the characters to our segger JTAG debugger +size_t RedirectablePrint::write(uint8_t c) { + // Always send the characters to our segger JTAG debugger #ifdef SEGGER_STDOUT_CH - SEGGER_RTT_PutCharSkip(SEGGER_STDOUT_CH, c); + SEGGER_RTT_PutCharSkip(SEGGER_STDOUT_CH, c); #endif - dest->write(c); - return 1; // We always claim one was written, rather than trusting what the serial port said (which could be zero) + dest->write(c); + 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) -{ - va_list copy; +size_t RedirectablePrint::vprintf(const char *format, va_list arg) { + va_list copy; - va_copy(copy, arg); - int len = vsnprintf(printBuf, printBufLen, format, copy); - va_end(copy); - if (len < 0) { - va_end(arg); - return 0; - }; - if (len >= printBufLen) { - delete[] printBuf; - printBufLen *= 2; - printBuf = new char[printBufLen]; - len = vsnprintf(printBuf, printBufLen, format, arg); - } + va_copy(copy, arg); + int len = vsnprintf(printBuf, printBufLen, format, copy); + va_end(copy); + if (len < 0) { + va_end(arg); + return 0; + }; + if (len >= printBufLen) { + delete[] printBuf; + printBufLen *= 2; + printBuf = new char[printBufLen]; + len = vsnprintf(printBuf, printBufLen, format, arg); + } - len = Print::write(printBuf, len); - return len; + len = Print::write(printBuf, len); + return len; } #define SEC_PER_DAY 86400 #define SEC_PER_HOUR 3600 #define SEC_PER_MIN 60 -size_t RedirectablePrint::logDebug(const char *format, ...) -{ - va_list arg; - va_start(arg, format); +size_t RedirectablePrint::logDebug(const char *format, ...) { + va_list arg; + va_start(arg, format); - // Cope with 0 len format strings, but look for new line terminator - bool hasNewline = *format && format[strlen(format) - 1] == '\n'; + // Cope with 0 len format strings, but look for new line terminator + bool hasNewline = *format && format[strlen(format) - 1] == '\n'; - size_t r = 0; + size_t r = 0; - // If we are the first message on a report, include the header - if (!isContinuationMessage) { - struct timeval tv; - if (!gettimeofday(&tv, NULL)) { - long hms = tv.tv_sec % SEC_PER_DAY; - //hms += tz.tz_dsttime * SEC_PER_HOUR; - //hms -= tz.tz_minuteswest * SEC_PER_MIN; - // mod `hms` to ensure in positive range of [0...SEC_PER_DAY) - hms = (hms + SEC_PER_DAY) % SEC_PER_DAY; + // If we are the first message on a report, include the header + if (!isContinuationMessage) { + uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet); + if (rtc_sec > 0) { + long hms = rtc_sec % SEC_PER_DAY; + // hms += tz.tz_dsttime * SEC_PER_HOUR; + // hms -= tz.tz_minuteswest * SEC_PER_MIN; + // mod `hms` to ensure in positive range of [0...SEC_PER_DAY) + hms = (hms + SEC_PER_DAY) % SEC_PER_DAY; - // Tear apart hms into h:m:s - int hour = hms / SEC_PER_HOUR; - int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; - int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN + // Tear apart hms into h:m:s + int hour = hms / SEC_PER_HOUR; + int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; + int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN - r += printf("%02d:%02d:%02d ", hour, min, sec); - } else - r += printf("??:??:?? "); + r += printf("%02d:%02d:%02d ", hour, min, sec); + } else + r += printf("??:??:?? "); - auto thread = concurrency::OSThread::currentThread; - if(thread) { - print("["); - print(thread->ThreadName); - print("] "); - } + auto thread = concurrency::OSThread::currentThread; + if (thread) { + print("["); + print(thread->ThreadName); + print("] "); } + } - r += vprintf(format, arg); - va_end(arg); + r += vprintf(format, arg); + va_end(arg); - isContinuationMessage = !hasNewline; + isContinuationMessage = !hasNewline; - return r; + return r; } \ No newline at end of file diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp new file mode 100644 index 000000000..f9f6ba414 --- /dev/null +++ b/src/buzz/buzz.cpp @@ -0,0 +1,52 @@ +#include "buzz.h" +#include "configuration.h" + +#ifdef NRF52_SERIES +#include "variant.h" +#endif + +#ifndef PIN_BUZZER + +void playBeep(){}; +void playStartMelody(){}; +void playShutdownMelody(){}; + +#else +#include "Tone.h" +#include "pitches.h" + +extern "C" void delay(uint32_t dwMs); + +struct ToneDuration { + int frequency_khz; + int duration_ms; +}; + +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 \ No newline at end of file diff --git a/src/buzz/buzz.h b/src/buzz/buzz.h new file mode 100644 index 000000000..3883bd057 --- /dev/null +++ b/src/buzz/buzz.h @@ -0,0 +1,5 @@ +#pragma once + +void playBeep(); +void playStartMelody(); +void playShutdownMelody(); diff --git a/src/buzz/pitches.h b/src/buzz/pitches.h new file mode 100644 index 000000000..3acf0db82 --- /dev/null +++ b/src/buzz/pitches.h @@ -0,0 +1,91 @@ +#pragma once + +#define NOTE_B0 31 +#define NOTE_C1 33 +#define NOTE_CS1 35 +#define NOTE_D1 37 +#define NOTE_DS1 39 +#define NOTE_E1 41 +#define NOTE_F1 44 +#define NOTE_FS1 46 +#define NOTE_G1 49 +#define NOTE_GS1 52 +#define NOTE_A1 55 +#define NOTE_AS1 58 +#define NOTE_B1 62 +#define NOTE_C2 65 +#define NOTE_CS2 69 +#define NOTE_D2 73 +#define NOTE_DS2 78 +#define NOTE_E2 82 +#define NOTE_F2 87 +#define NOTE_FS2 93 +#define NOTE_G2 98 +#define NOTE_GS2 104 +#define NOTE_A2 110 +#define NOTE_AS2 117 +#define NOTE_B2 123 +#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 +#define NOTE_C4 262 +#define NOTE_CS4 277 +#define NOTE_D4 294 +#define NOTE_DS4 311 +#define NOTE_E4 330 +#define NOTE_F4 349 +#define NOTE_FS4 370 +#define NOTE_G4 392 +#define NOTE_GS4 415 +#define NOTE_A4 440 +#define NOTE_AS4 466 +#define NOTE_B4 494 +#define NOTE_C5 523 +#define NOTE_CS5 554 +#define NOTE_D5 587 +#define NOTE_DS5 622 +#define NOTE_E5 659 +#define NOTE_F5 698 +#define NOTE_FS5 740 +#define NOTE_G5 784 +#define NOTE_GS5 831 +#define NOTE_A5 880 +#define NOTE_AS5 932 +#define NOTE_B5 988 +#define NOTE_C6 1047 +#define NOTE_CS6 1109 +#define NOTE_D6 1175 +#define NOTE_DS6 1245 +#define NOTE_E6 1319 +#define NOTE_F6 1397 +#define NOTE_FS6 1480 +#define NOTE_G6 1568 +#define NOTE_GS6 1661 +#define NOTE_A6 1760 +#define NOTE_AS6 1865 +#define NOTE_B6 1976 +#define NOTE_C7 2093 +#define NOTE_CS7 2217 +#define NOTE_D7 2349 +#define NOTE_DS7 2489 +#define NOTE_E7 2637 +#define NOTE_F7 2794 +#define NOTE_FS7 2960 +#define NOTE_G7 3136 +#define NOTE_GS7 3322 +#define NOTE_A7 3520 +#define NOTE_AS7 3729 +#define NOTE_B7 3951 +#define NOTE_C8 4186 +#define NOTE_CS8 4435 +#define NOTE_D8 4699 +#define NOTE_DS8 4978 \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index 79d1009ca..6ba24f1c9 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -384,7 +384,9 @@ along with this program. If not, see . #elif NRF52_SERIES +#ifndef HW_VENDOR #define HW_VENDOR "nrf52unknown" // FIXME - unknown nrf52 board +#endif #elif PORTDUINO @@ -432,6 +434,8 @@ along with this program. If not, see . #define DEBUG_PORT console // Serial debug port + + // What platforms should use SEGGER? #ifdef NRF52_SERIES diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 04aa2c7af..4a6fca7c4 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -300,3 +300,49 @@ int GPS::prepareDeepSleep(void *unused) 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 +} \ No newline at end of file diff --git a/src/gps/GPS.h b/src/gps/GPS.h index eca2962d2..50cb07f2b 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -71,6 +71,9 @@ class GPS : private concurrency::OSThread * */ void forceWake(bool on); + // Some GPS modules (ublock) require factory reset + virtual bool factoryReset() { return true; } + protected: /// Do gps chipset specific init, return true for success virtual bool setupGPS(); @@ -145,4 +148,8 @@ class GPS : private concurrency::OSThread 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; diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 56b51e0af..1508aef60 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -39,22 +39,23 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv) currentQuality = q; shouldSet = true; DEBUG_MSG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q); - } 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 + } else if(q > RTCQualityNone && q == currentQuality && (now - lastSetMsec) > (12 * 60 * 60 * 1000L)) { + // Every 12 hrs we will slam in a new time, to correct for local RTC clock drift 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 shouldSet = false; if (shouldSet) { - lastSetMsec = now; + lastSetMsec = now; #ifndef NO_ESP32 settimeofday(tv, NULL); -#else - DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n"); -#endif readFromRTC(); +#else + timeStartMsec = now; + zeroOffsetSecs = tv->tv_sec; +#endif return true; } else { return false; diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 888f31011..d629c2d0a 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -1,5 +1,23 @@ #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 #include @@ -278,3 +296,4 @@ class Screen : public concurrency::OSThread }; } // namespace graphics +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index aa7b191d9..9997d9e11 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,11 @@ -#include "Air530GPS.h" +#include "GPS.h" #include "MeshRadio.h" #include "MeshService.h" #include "NodeDB.h" #include "PowerFSM.h" -#include "UBloxGPS.h" #include "airtime.h" +#include "buzz.h" #include "configuration.h" #include "error.h" #include "power.h" @@ -63,7 +63,7 @@ Router *router = NULL; // Users of router don't care what sort of subclass imple // ----------------------------------------------------------------------------- // Application // ----------------------------------------------------------------------------- - +#if WIRE_INTERFACES_COUNT > 0 void scanI2Cdevice(void) { byte err, addr; @@ -100,6 +100,9 @@ void scanI2Cdevice(void) else DEBUG_MSG("done\n"); } +#else +void scanI2Cdevice(void) {} +#endif const char *getDeviceName() { @@ -169,7 +172,7 @@ class ButtonThread : public OSThread #ifdef BUTTON_PIN_ALT OneButton userButtonAlt; #endif - + static bool shutdown_on_long_stop; public: static uint32_t longPressTime; @@ -235,13 +238,23 @@ class ButtonThread : public OSThread // DEBUG_MSG("Long press!\n"); screen->adjustBrightness(); - // If user button is held down for 10 seconds, shutdown the device. - if (millis() - longPressTime > 10 * 1000) { + // If user button is held down for 5 seconds, shutdown the device. + if (millis() - longPressTime > 5 * 1000) { #ifdef TBEAM_V10 if (axp192_found == true) { setLed(false); 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 } else { // DEBUG_MSG("Long press %u\n", (millis() - longPressTime)); @@ -265,9 +278,15 @@ class ButtonThread : public OSThread { DEBUG_MSG("Long press stop!\n"); longPressTime = 0; + if (shutdown_on_long_stop) { + playShutdownMelody(); + power->shutdown(); + } } }; +bool ButtonThread::shutdown_on_long_stop = false; + static Periodic *ledPeriodic; static OSThread *powerFSMthread, *buttonThread; uint32_t ButtonThread::longPressTime = 0; @@ -332,7 +351,7 @@ void setup() #ifdef I2C_SDA Wire.begin(I2C_SDA, I2C_SCL); -#else +#elif WIRE_INTERFACES_COUNT > 0 Wire.begin(); #endif @@ -369,7 +388,7 @@ void setup() #ifdef NRF52_SERIES nrf52Setup(); #endif - + playStartMelody(); // 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 nodeDB.init(); @@ -407,34 +426,7 @@ void setup() pinMode(BATTERY_EN_PIN, OUTPUT); digitalWrite(BATTERY_EN_PIN, LOW); #endif - - // 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(); - } + gps = createGps(); if (gps) gpsStatus->observe(&gps->newStatus); @@ -468,8 +460,8 @@ void setup() // We have now loaded our saved preferences from flash // ONCE we will factory reset the GPS for bug #327 - if (ublox && !devicestate.did_gps_reset) { - if (ublox->factoryReset()) { // If we don't succeed try again next time + if (gps && !devicestate.did_gps_reset) { + if (gps->factoryReset()) { // If we don't succeed try again next time devicestate.did_gps_reset = true; nodeDB.saveToDisk(); } diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp index 0bff47365..a99787475 100644 --- a/src/mesh/SX1262Interface.cpp +++ b/src/mesh/SX1262Interface.cpp @@ -34,11 +34,11 @@ bool SX1262Interface::init() pinMode(SX1262_TXEN, OUTPUT); #endif -#ifndef SX1262_E22 +#if !defined(SX1262_E22) && !defined(SX1262_USE_DIO3_FOR_TCXO) float tcxoVoltage = 0; // None - we use an XTAL #else - float tcxoVoltage = - 1.8; // E22 uses DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575 + // Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575 + float tcxoVoltage = 1.8; #endif bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC? diff --git a/src/nrf52/NRF52Bluetooth.cpp b/src/nrf52/NRF52Bluetooth.cpp index 35093ff17..53edd136d 100644 --- a/src/nrf52/NRF52Bluetooth.cpp +++ b/src/nrf52/NRF52Bluetooth.cpp @@ -3,8 +3,8 @@ #include "configuration.h" #include "main.h" #include - - +#include "mesh/mesh-pb-constants.h" +#include "mesh/PhoneAPI.h" static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16)); static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16)); @@ -213,6 +213,7 @@ void NRF52Bluetooth::setup() { // Initialise the Bluefruit module DEBUG_MSG("Initialise the Bluefruit nRF52 module\n"); + Bluefruit.autoConnLed(false); Bluefruit.begin(); // Set the advertised device name (keep it short!) diff --git a/src/nrf52/main-nrf52.cpp b/src/nrf52/main-nrf52.cpp index a1a96f3b9..d35b4269b 100644 --- a/src/nrf52/main-nrf52.cpp +++ b/src/nrf52/main-nrf52.cpp @@ -1,6 +1,5 @@ #include "NRF52Bluetooth.h" #include "configuration.h" -#include "graphics/TFTDisplay.h" #include #include #include @@ -118,10 +117,15 @@ void cpuDeepSleep(uint64_t msecToWake) { // FIXME, configure RTC or button press to wake us // FIXME, power down SPI, I2C, RAMs + #if WIRE_INTERFACES_COUNT > 0 Wire.end(); + #endif SPI.end(); Serial.end(); + + #ifdef PIN_SERIAL_RX1 Serial1.end(); + #endif // FIXME, use system off mode with ram retention for key state? // FIXME, use non-init RAM per diff --git a/variants/lora_isp4520/variant.cpp b/variants/lora_isp4520/variant.cpp new file mode 100644 index 000000000..cf1320f4f --- /dev/null +++ b/variants/lora_isp4520/variant.cpp @@ -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 +void initVariant() +{ + for (int i : {PIN_LED1, PIN_LED2}) { + pinMode(i, OUTPUT); + ledOff(i); + } +} diff --git a/variants/lora_isp4520/variant.h b/variants/lora_isp4520/variant.h new file mode 100644 index 000000000..a5b38fde8 --- /dev/null +++ b/variants/lora_isp4520/variant.h @@ -0,0 +1,98 @@ +/* + 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 +#undef HW_VERSION +#define HW_VERSION "0.1.0" +#undef HW_VENDOR +#define HW_VENDOR "lora_ISP4520" + +/*---------------------------------------------------------------------------- + * 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_USE_DIO3_FOR_TCXO +#define NO_GPS +#define NO_SCREEN +#endif From 8505a0f2608018cfcdf9179032bca4316cfea2c8 Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Sun, 14 Mar 2021 19:17:28 -0700 Subject: [PATCH 2/6] Chargeing... --- src/Power.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index f709fb22e..2ff783ad9 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -32,7 +32,7 @@ public: virtual bool isBatteryConnect() { return false; } virtual bool isVBUSPlug() { return false; } - virtual bool isCharging() { return false; } + virtual bool isChargeing() { return false; } }; #endif @@ -124,7 +124,7 @@ class AnalogBatteryLevel : public HasBatteryLevel /// Assume charging if we have a battery and external power is connected. /// we can't be smart enough to say 'full'? - virtual bool isCharging() { return isBatteryConnect() && isVBUSPlug(); } + virtual bool isChargeing() { return isBatteryConnect() && isVBUSPlug(); } private: /// If we see a battery voltage higher than physics allows - assume charger is pumping @@ -210,7 +210,7 @@ void Power::readPowerStatus() // Notify any status instances that are observing us const PowerStatus powerStatus = PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse, - batteryLevel->isCharging() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent); + batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent); DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus.getHasUSB(), powerStatus.getIsCharging(), powerStatus.getBatteryVoltageMv(), powerStatus.getBatteryChargePercent()); newStatus.notifyObservers(&powerStatus); From b20b21c5534e4a715dd1af73350473aefd6f9c49 Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Sun, 14 Mar 2021 20:46:58 -0700 Subject: [PATCH 3/6] pitches.h no more --- src/buzz/buzz.cpp | 16 +++++++- src/buzz/pitches.h | 91 ---------------------------------------------- 2 files changed, 15 insertions(+), 92 deletions(-) delete mode 100644 src/buzz/pitches.h diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp index f9f6ba414..a667df004 100644 --- a/src/buzz/buzz.cpp +++ b/src/buzz/buzz.cpp @@ -7,13 +7,13 @@ #ifndef PIN_BUZZER +// Noop methods for boards w/o buzzer void playBeep(){}; void playStartMelody(){}; void playShutdownMelody(){}; #else #include "Tone.h" -#include "pitches.h" extern "C" void delay(uint32_t dwMs); @@ -22,6 +22,20 @@ struct ToneDuration { 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 diff --git a/src/buzz/pitches.h b/src/buzz/pitches.h deleted file mode 100644 index 3acf0db82..000000000 --- a/src/buzz/pitches.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#define NOTE_B0 31 -#define NOTE_C1 33 -#define NOTE_CS1 35 -#define NOTE_D1 37 -#define NOTE_DS1 39 -#define NOTE_E1 41 -#define NOTE_F1 44 -#define NOTE_FS1 46 -#define NOTE_G1 49 -#define NOTE_GS1 52 -#define NOTE_A1 55 -#define NOTE_AS1 58 -#define NOTE_B1 62 -#define NOTE_C2 65 -#define NOTE_CS2 69 -#define NOTE_D2 73 -#define NOTE_DS2 78 -#define NOTE_E2 82 -#define NOTE_F2 87 -#define NOTE_FS2 93 -#define NOTE_G2 98 -#define NOTE_GS2 104 -#define NOTE_A2 110 -#define NOTE_AS2 117 -#define NOTE_B2 123 -#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 -#define NOTE_C4 262 -#define NOTE_CS4 277 -#define NOTE_D4 294 -#define NOTE_DS4 311 -#define NOTE_E4 330 -#define NOTE_F4 349 -#define NOTE_FS4 370 -#define NOTE_G4 392 -#define NOTE_GS4 415 -#define NOTE_A4 440 -#define NOTE_AS4 466 -#define NOTE_B4 494 -#define NOTE_C5 523 -#define NOTE_CS5 554 -#define NOTE_D5 587 -#define NOTE_DS5 622 -#define NOTE_E5 659 -#define NOTE_F5 698 -#define NOTE_FS5 740 -#define NOTE_G5 784 -#define NOTE_GS5 831 -#define NOTE_A5 880 -#define NOTE_AS5 932 -#define NOTE_B5 988 -#define NOTE_C6 1047 -#define NOTE_CS6 1109 -#define NOTE_D6 1175 -#define NOTE_DS6 1245 -#define NOTE_E6 1319 -#define NOTE_F6 1397 -#define NOTE_FS6 1480 -#define NOTE_G6 1568 -#define NOTE_GS6 1661 -#define NOTE_A6 1760 -#define NOTE_AS6 1865 -#define NOTE_B6 1976 -#define NOTE_C7 2093 -#define NOTE_CS7 2217 -#define NOTE_D7 2349 -#define NOTE_DS7 2489 -#define NOTE_E7 2637 -#define NOTE_F7 2794 -#define NOTE_FS7 2960 -#define NOTE_G7 3136 -#define NOTE_GS7 3322 -#define NOTE_A7 3520 -#define NOTE_AS7 3729 -#define NOTE_B7 3951 -#define NOTE_C8 4186 -#define NOTE_CS8 4435 -#define NOTE_D8 4699 -#define NOTE_DS8 4978 \ No newline at end of file From ddcfff3b59c9b6697746faf4dd9e03e2af8dc77b Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Wed, 17 Mar 2021 10:44:42 -0700 Subject: [PATCH 4/6] Fixed compilation on nrf52 and brownout code --- platformio.ini | 2 +- src/mesh/MeshPlugin.h | 10 +- src/nrf52/main-nrf52.cpp | 261 ++++++++++++++++---------------- variants/lora_isp4520/variant.h | 7 +- 4 files changed, 140 insertions(+), 140 deletions(-) diff --git a/platformio.ini b/platformio.ini index ba7682c76..d190bd410 100644 --- a/platformio.ini +++ b/platformio.ini @@ -64,6 +64,7 @@ debug_tool = jlink ; monitor adapter_khz 10000 lib_deps = + https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306 https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib https://github.com/meshtastic/arduino-fsm.git#55c47b6cded91645aff05a27b6e5821d8d0f64be @@ -102,7 +103,6 @@ build_flags = lib_deps = ${arduino_base.lib_deps} https://github.com/meshtastic/esp32_https_server.git - https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306 adafruit/DHT sensor library@^1.4.1 adafruit/Adafruit Unified Sensor@^1.1.4 # Hmm - this doesn't work yet diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h index dc905a0e5..2295d1224 100644 --- a/src/mesh/MeshPlugin.h +++ b/src/mesh/MeshPlugin.h @@ -1,9 +1,13 @@ #pragma once #include "mesh/MeshTypes.h" +#include + +#ifndef NO_SCREEN #include #include -#include +#endif + /** A baseclass for any mesh "plugin". * * 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 std::vector GetMeshPluginsWithUIFrames(); - +#ifndef NO_SCREEN virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; } - +#endif protected: const char *name; diff --git a/src/nrf52/main-nrf52.cpp b/src/nrf52/main-nrf52.cpp index a9b586f16..b948d20a1 100644 --- a/src/nrf52/main-nrf52.cpp +++ b/src/nrf52/main-nrf52.cpp @@ -1,6 +1,3 @@ -#include "NRF52Bluetooth.h" -#include "configuration.h" -#include "error.h" #include #include #include @@ -8,184 +5,182 @@ #include #include -#ifdef NRF52840_XXAA -// #include +#include "NRF52Bluetooth.h" +#include "configuration.h" +#include "error.h" + +#ifdef BQ25703A_ADDR +#include "BQ25713.h" #endif -// #define USE_SOFTDEVICE -static inline void debugger_break(void) -{ - __asm volatile("bkpt #0x01\n\t" - "mov pc, lr\n\t"); +static inline void debugger_break(void) { + __asm volatile( + "bkpt #0x01\n\t" + "mov pc, lr\n\t"); } // handle standard gcc assert failures -void __attribute__((noreturn)) __assert_func(const char *file, int line, const char *func, 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 - while (1) - ; // FIXME, reboot! +void __attribute__((noreturn)) +__assert_func(const char *file, int line, const char *func, + 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 + while (1) + ; // FIXME, reboot! } -void getMacAddr(uint8_t *dmac) -{ - ble_gap_addr_t addr; - -#ifdef USE_SOFTDEVICE - uint32_t res = sd_ble_gap_addr_get(&addr); - assert(res == NRF_SUCCESS); +void getMacAddr(uint8_t *dmac) { + ble_gap_addr_t addr; + if (sd_ble_gap_addr_get(&addr) == NRF_SUCCESS) { memcpy(dmac, addr.addr, 6); -#else + } else { const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR; dmac[5] = src[0]; dmac[4] = src[1]; dmac[3] = src[2]; dmac[2] = src[3]; dmac[1] = src[4]; - dmac[0] = src[5] | 0xc0; // MSB high two bits get set elsewhere in the bluetooth stack -#endif + dmac[0] = src[5] | + 0xc0; // MSB high two bits get set elsewhere in the bluetooth stack + } } NRF52Bluetooth *nrf52Bluetooth; 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) -{ - if (on != bleOn) { - if (on) { - if (!nrf52Bluetooth) { - if (!useSoftDevice) - DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n"); - else { - nrf52Bluetooth = new NRF52Bluetooth(); - nrf52Bluetooth->setup(); - } - } - } else { - if (nrf52Bluetooth) - nrf52Bluetooth->shutdown(); +void setBluetoothEnable(bool on) { + if (on != bleOn) { + if (on) { + if (!nrf52Bluetooth) { + if (!useSoftDevice) + DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n"); + else { + nrf52Bluetooth = new NRF52Bluetooth(); + nrf52Bluetooth->setup(); } - bleOn = on; + } + } else { + if (nrf52Bluetooth) nrf52Bluetooth->shutdown(); } + bleOn = on; + } } /** * Override printf to use the SEGGER output library */ -int printf(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - auto res = SEGGER_RTT_vprintf(0, fmt, &args); - va_end(args); - return res; +int printf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + auto res = SEGGER_RTT_vprintf(0, fmt, &args); + va_end(args); + return res; } -#include "BQ25713.h" +void initBrownout() { + auto vccthresh = POWER_POFCON_THRESHOLD_V28; -void initBrownout() -{ - auto vccthresh = POWER_POFCON_THRESHOLD_V28; + if (useSoftDevice) { + auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled); + assert(err_code == NRF_SUCCESS); + + err_code = sd_power_pof_threshold_set(vccthresh); + assert(err_code == NRF_SUCCESS); + } else { + uint32_t pof_flags = POWER_POFCON_POF_Enabled | (vccthresh << POWER_POFCON_THRESHOLD_Pos); + + #ifdef POWER_POFCON_THRESHOLDVDDH_Msk auto vcchthresh = POWER_POFCON_THRESHOLDVDDH_V27; - - if (useSoftDevice) { - auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled); - assert(err_code == NRF_SUCCESS); - - err_code = sd_power_pof_threshold_set(vccthresh); - assert(err_code == NRF_SUCCESS); - } - else { - NRF_POWER->POFCON = POWER_POFCON_POF_Msk | (vccthresh << POWER_POFCON_THRESHOLD_Pos) | (vcchthresh << POWER_POFCON_THRESHOLDVDDH_Pos); - } + pof_flags |= (vcchthresh << POWER_POFCON_THRESHOLDVDDH_Pos); + #endif + + NRF_POWER->POFCON = pof_flags; + } } -void checkSDEvents() -{ - if (useSoftDevice) { - uint32_t evt; - while (NRF_ERROR_NOT_FOUND == sd_evt_get(&evt)) { - switch (evt) { - case NRF_EVT_POWER_FAILURE_WARNING: - recordCriticalError(CriticalErrorCode_Brownout); - break; +void checkSDEvents() { + if (useSoftDevice) { + uint32_t evt; + while (NRF_SUCCESS == sd_evt_get(&evt)) { + switch (evt) { + case NRF_EVT_POWER_FAILURE_WARNING: + recordCriticalError(CriticalErrorCode_Brownout); + break; - default: - DEBUG_MSG("Unexpected SDevt %d\n", evt); - break; - } - } - } else { - if(NRF_POWER->EVENTS_POFWARN) - recordCriticalError(CriticalErrorCode_Brownout); + default: + DEBUG_MSG("Unexpected SDevt %d\n", evt); + break; + } } + } else { + if (NRF_POWER->EVENTS_POFWARN) + recordCriticalError(CriticalErrorCode_Brownout); + } } -void nrf52Loop() -{ - checkSDEvents(); -} +void nrf52Loop() { checkSDEvents(); } -void nrf52Setup() -{ +void nrf52Setup() { + auto why = NRF_POWER->RESETREAS; + // 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); - auto why = NRF_POWER->RESETREAS; - // 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); - - // 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 - NVIC_SetPriority(DebugMonitor_IRQn, 6UL); + // 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 + NVIC_SetPriority(DebugMonitor_IRQn, 6UL); #ifdef BQ25703A_ADDR - auto *bq = new BQ25713(); - if (!bq->setup()) - DEBUG_MSG("ERROR! Charge controller init failed\n"); + auto *bq = new BQ25713(); + if (!bq->setup()) DEBUG_MSG("ERROR! Charge controller init failed\n"); #endif - // Init random seed - // FIXME - use this to get random numbers - // #include "nrf_rng.h" - // uint32_t r; - // ble_controller_rand_vector_get_blocking(&r, sizeof(r)); - // randomSeed(r); - DEBUG_MSG("FIXME, call randomSeed\n"); - // ::printf("TESTING PRINTF\n"); + // Init random seed + // FIXME - use this to get random numbers + // #include "nrf_rng.h" + // uint32_t r; + // ble_controller_rand_vector_get_blocking(&r, sizeof(r)); + // randomSeed(r); + DEBUG_MSG("FIXME, call randomSeed\n"); + // ::printf("TESTING PRINTF\n"); - initBrownout(); + initBrownout(); } -void cpuDeepSleep(uint64_t msecToWake) -{ - // FIXME, configure RTC or button press to wake us - // FIXME, power down SPI, I2C, RAMs - #if WIRE_INTERFACES_COUNT > 0 - Wire.end(); - #endif - SPI.end(); - Serial.end(); - - #ifdef PIN_SERIAL_RX1 - Serial1.end(); - #endif +void cpuDeepSleep(uint64_t msecToWake) { + // FIXME, configure RTC or button press to wake us + // FIXME, power down SPI, I2C, RAMs +#if WIRE_INTERFACES_COUNT > 0 + Wire.end(); +#endif + SPI.end(); + // This may cause crashes as debug messages continue to flow. + Serial.end(); - // FIXME, use system off mode with ram retention for key state? - // FIXME, use non-init RAM per - // https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled +#ifdef PIN_SERIAL_RX1 + Serial1.end(); +#endif + setBluetoothEnable(false); + // FIXME, use system off mode with ram retention for key state? + // FIXME, use non-init RAM per + // https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled - auto ok = sd_power_system_off(); - if (ok != NRF_SUCCESS) { - DEBUG_MSG("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n"); - NRF_POWER->SYSTEMOFF = 1; - } + auto ok = sd_power_system_off(); + if (ok != NRF_SUCCESS) { + DEBUG_MSG( + "FIXME: Ignoring soft device (EasyDMA pending?) and forcing " + "system-off!\n"); + NRF_POWER->SYSTEMOFF = 1; + } - // The following code should not be run, because we are off - while (1) { - delay(5000); - DEBUG_MSG("."); - } + // The following code should not be run, because we are off + while (1) { + delay(5000); + DEBUG_MSG("."); + } } \ No newline at end of file diff --git a/variants/lora_isp4520/variant.h b/variants/lora_isp4520/variant.h index a5b38fde8..025f5a039 100644 --- a/variants/lora_isp4520/variant.h +++ b/variants/lora_isp4520/variant.h @@ -19,12 +19,13 @@ #ifndef _VARIANT_LORA_ISP4520_ #define _VARIANT_LORA_ISP4520_ -#define HW_VERSION_US +#define HW_VERSION_US 1 #undef HW_VERSION -#define HW_VERSION "0.1.0" +#define HW_VERSION "1.0" #undef HW_VENDOR #define HW_VENDOR "lora_ISP4520" +#define USE_SEGGER /*---------------------------------------------------------------------------- * Headers *----------------------------------------------------------------------------*/ @@ -33,7 +34,7 @@ #define USE_LFXO -#define USE_SEGGER +//#define USE_SEGGER // Number of pins defined in PinDescription array #define PINS_COUNT (16) From 0c51cc37386a219a1ced3db327e1feb0d2f9456f Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Wed, 17 Mar 2021 10:56:45 -0700 Subject: [PATCH 5/6] Fix hardware model --- src/configuration.h | 2 -- variants/lora_isp4520/variant.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index 194a37909..627b6aae4 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -411,9 +411,7 @@ along with this program. If not, see . #elif NRF52_SERIES -#ifndef HW_VENDOR #define HW_VENDOR HardwareModel_NRF52_UNKNOWN -#endif #elif PORTDUINO diff --git a/variants/lora_isp4520/variant.h b/variants/lora_isp4520/variant.h index 025f5a039..fbc0b0d96 100644 --- a/variants/lora_isp4520/variant.h +++ b/variants/lora_isp4520/variant.h @@ -22,8 +22,6 @@ #define HW_VERSION_US 1 #undef HW_VERSION #define HW_VERSION "1.0" -#undef HW_VENDOR -#define HW_VENDOR "lora_ISP4520" #define USE_SEGGER /*---------------------------------------------------------------------------- From d93d5d2e37e5c1f4136bd15122682e8d54b7e4f2 Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Fri, 19 Mar 2021 17:21:08 -0700 Subject: [PATCH 6/6] Revert clock update for Net quality clocks --- src/gps/RTC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 1508aef60..87b73ce89 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -39,8 +39,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv) currentQuality = q; shouldSet = true; DEBUG_MSG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q); - } else if(q > RTCQualityNone && q == currentQuality && (now - lastSetMsec) > (12 * 60 * 60 * 1000L)) { - // Every 12 hrs we will slam in a new time, to correct for local RTC clock drift + } 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 shouldSet = true; DEBUG_MSG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec); }