mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-29 11:01:15 +00:00
Merge branch 'meshtastic:master' into compression
This commit is contained in:
commit
9b6b224af4
19
.github/workflows/main_matrix.yml
vendored
19
.github/workflows/main_matrix.yml
vendored
@ -34,9 +34,8 @@ jobs:
|
|||||||
- board: heltec-v2.1
|
- board: heltec-v2.1
|
||||||
- board: tbeam0.7
|
- board: tbeam0.7
|
||||||
- board: meshtastic-diy-v1
|
- board: meshtastic-diy-v1
|
||||||
- board: rak4631_5005
|
- board: rak4631
|
||||||
- board: rak4631_19003
|
- board: rak4631_eink
|
||||||
- board: rak4631_5005_eink
|
|
||||||
- board: t-echo
|
- board: t-echo
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -117,7 +116,8 @@ jobs:
|
|||||||
- name: Upgrade python tools
|
- name: Upgrade python tools
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -U platformio meshtastic adafruit-nrfutil littlefs-python
|
pip install -U platformio adafruit-nrfutil littlefs-python
|
||||||
|
pip install -U --pre meshtastic
|
||||||
|
|
||||||
- name: Upgrade platformio
|
- name: Upgrade platformio
|
||||||
run: |
|
run: |
|
||||||
@ -158,9 +158,8 @@ jobs:
|
|||||||
max-parallel: 2
|
max-parallel: 2
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- board: rak4631_5005
|
- board: rak4631
|
||||||
- board: rak4631_19003
|
- board: rak4631_eink
|
||||||
- board: rak4631_5005_eink
|
|
||||||
- board: t-echo
|
- board: t-echo
|
||||||
- board: pca10059_diy_eink
|
- board: pca10059_diy_eink
|
||||||
|
|
||||||
@ -188,7 +187,8 @@ jobs:
|
|||||||
- name: Upgrade python tools
|
- name: Upgrade python tools
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -U platformio meshtastic adafruit-nrfutil
|
pip install -U platformio adafruit-nrfutil
|
||||||
|
pip install -U --pre meshtastic
|
||||||
|
|
||||||
- name: Upgrade platformio
|
- name: Upgrade platformio
|
||||||
run: |
|
run: |
|
||||||
@ -235,7 +235,8 @@ jobs:
|
|||||||
- name: Upgrade python tools
|
- name: Upgrade python tools
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -U platformio meshtastic adafruit-nrfutil
|
pip install -U platformio adafruit-nrfutil
|
||||||
|
pip install -U --pre meshtastic
|
||||||
|
|
||||||
- name: Upgrade platformio
|
- name: Upgrade platformio
|
||||||
run: |
|
run: |
|
||||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,9 +1,6 @@
|
|||||||
[submodule "proto"]
|
[submodule "proto"]
|
||||||
path = proto
|
path = proto
|
||||||
url = https://github.com/meshtastic/Meshtastic-protobufs.git
|
url = https://github.com/meshtastic/Meshtastic-protobufs.git
|
||||||
[submodule "sdk-nrfxlib"]
|
|
||||||
path = sdk-nrfxlib
|
|
||||||
url = https://github.com/nrfconnect/sdk-nrfxlib.git
|
|
||||||
[submodule "design"]
|
[submodule "design"]
|
||||||
path = design
|
path = design
|
||||||
url = https://github.com/meshtastic/meshtastic-design.git
|
url = https://github.com/meshtastic/meshtastic-design.git
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Meshtastic-device
|
# Meshtastic-device
|
||||||
[](https://open.vscode.dev/meshtastic/Meshtastic-device)
|
[](https://open.vscode.dev/meshtastic/Meshtastic-device)
|
||||||
[](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml)
|
[](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main_matrix.yml)
|
||||||

|

|
||||||
[](https://cla-assistant.io/meshtastic/Meshtastic-device)
|
[](https://cla-assistant.io/meshtastic/Meshtastic-device)
|
||||||
[](https://opencollective.com/meshtastic/)
|
[](https://opencollective.com/meshtastic/)
|
||||||
|
@ -9,7 +9,7 @@ BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-
|
|||||||
#BOARDS_ESP32=tbeam
|
#BOARDS_ESP32=tbeam
|
||||||
|
|
||||||
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
||||||
BOARDS_NRF52="rak4631_5005 rak4631_5005_eink rak4631_19003 t-echo pca10059_diy_eink"
|
BOARDS_NRF52="rak4631 rak4631_eink t-echo pca10059_diy_eink"
|
||||||
#BOARDS_NRF52=""
|
#BOARDS_NRF52=""
|
||||||
|
|
||||||
OUTDIR=release/latest
|
OUTDIR=release/latest
|
||||||
|
@ -13,7 +13,7 @@ if [[ $# -gt 0 ]]; then
|
|||||||
# can override which environment by passing arg
|
# can override which environment by passing arg
|
||||||
BOARDS="$@"
|
BOARDS="$@"
|
||||||
else
|
else
|
||||||
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631_5005 rak4631_19003 rak11200 t-echo pca10059_diy_eink"
|
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631 rak4631_eink rak11200 t-echo pca10059_diy_eink"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "BOARDS:${BOARDS}"
|
echo "BOARDS:${BOARDS}"
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino":{
|
|
||||||
"ldscript": "nrf52832_s132_v6.ld"
|
|
||||||
},
|
|
||||||
"core": "nRF5",
|
|
||||||
"cpu": "cortex-m4",
|
|
||||||
"extra_flags": "-DNRF52832_XXAA -DNRF52",
|
|
||||||
"f_cpu": "64000000L",
|
|
||||||
"hwids": [
|
|
||||||
[
|
|
||||||
"0x10c4",
|
|
||||||
"0xea60"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"usb_product": "RAK815",
|
|
||||||
"mcu": "nrf52832",
|
|
||||||
"variant": "rak815",
|
|
||||||
"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": "RAK RAK815",
|
|
||||||
"upload": {
|
|
||||||
"maximum_ram_size": 65536,
|
|
||||||
"maximum_size": 524288,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 115200,
|
|
||||||
"protocol": "nrfutil",
|
|
||||||
"protocols": [
|
|
||||||
"jlink",
|
|
||||||
"nrfjprog",
|
|
||||||
"nrfutil",
|
|
||||||
"stlink"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"url": "https://store.rakwireless.com/products/rak815-hybrid-location-tracker",
|
|
||||||
"vendor": "RAK"
|
|
||||||
}
|
|
@ -16,9 +16,6 @@ default_envs = tbeam
|
|||||||
;default_envs = t-echo
|
;default_envs = t-echo
|
||||||
;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
|
||||||
;default_envs = rak4631_5005
|
|
||||||
;default_envs = rak4631_5005_eink
|
|
||||||
;default_envs = rak4631_19003
|
|
||||||
;default_envs = nano-g1
|
;default_envs = nano-g1
|
||||||
;default_envs = pca10059_diy_eink
|
;default_envs = pca10059_diy_eink
|
||||||
;default_envs = meshtastic-diy-v1
|
;default_envs = meshtastic-diy-v1
|
||||||
@ -133,7 +130,6 @@ build_type = debug ; I'm debugging with ICE a lot now
|
|||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags} -Wno-unused-variable
|
${arduino_base.build_flags} -Wno-unused-variable
|
||||||
-Isrc/nrf52
|
-Isrc/nrf52
|
||||||
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.7
|
|
||||||
src_filter =
|
src_filter =
|
||||||
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
|
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
@ -145,7 +141,7 @@ build_flags = ${nrf52_base.build_flags}
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${environmental.lib_deps}
|
${environmental.lib_deps}
|
||||||
Adafruit nRFCrypto
|
https://github.com/Kongduino/Adafruit_nRFCrypto.git
|
||||||
|
|
||||||
; 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]
|
||||||
@ -156,10 +152,3 @@ board = nrf52840_dk
|
|||||||
[env:feather_nrf52832]
|
[env:feather_nrf52832]
|
||||||
extends = nrf52_base
|
extends = nrf52_base
|
||||||
board = adafruit_feather_nrf52832
|
board = adafruit_feather_nrf52832
|
||||||
|
|
||||||
[env:rak815]
|
|
||||||
extends = nrf52_base
|
|
||||||
board = rak815
|
|
||||||
debug_tool = jlink
|
|
||||||
upload_protocol = jlink
|
|
||||||
monitor_speed = 115200
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Subproject commit e6e02cb83d238fae2f54f084858bd5e49a31afa1
|
|
60
src/debug/einkScan.h
Normal file
60
src/debug/einkScan.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "../configuration.h"
|
||||||
|
|
||||||
|
#ifdef RAK4630
|
||||||
|
#include "../main.h"
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
void d_writeCommand(uint8_t c)
|
||||||
|
{
|
||||||
|
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||||
|
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, LOW);
|
||||||
|
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
|
||||||
|
SPI1.transfer(c);
|
||||||
|
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
|
||||||
|
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, HIGH);
|
||||||
|
SPI1.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void d_writeData(uint8_t d)
|
||||||
|
{
|
||||||
|
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||||
|
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
|
||||||
|
SPI1.transfer(d);
|
||||||
|
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
|
||||||
|
SPI1.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long d_waitWhileBusy(uint16_t busy_time)
|
||||||
|
{
|
||||||
|
if (PIN_EINK_BUSY >= 0)
|
||||||
|
{
|
||||||
|
delay(1); // add some margin to become active
|
||||||
|
unsigned long start = micros();
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
|
||||||
|
delay(1);
|
||||||
|
if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
|
||||||
|
if (micros() - start > 10000000) break;
|
||||||
|
}
|
||||||
|
unsigned long elapsed = micros() - start;
|
||||||
|
(void) start;
|
||||||
|
return elapsed;
|
||||||
|
}
|
||||||
|
else return busy_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scanEInkDevice(void)
|
||||||
|
{
|
||||||
|
SPI1.begin();
|
||||||
|
d_writeCommand(0x22);
|
||||||
|
d_writeData(0x83);
|
||||||
|
d_writeCommand(0x20);
|
||||||
|
eink_found = (d_waitWhileBusy(150) > 0) ? true : false;
|
||||||
|
if(eink_found)
|
||||||
|
DEBUG_MSG("EInk display found\n");
|
||||||
|
else
|
||||||
|
DEBUG_MSG("EInk display not found\n");
|
||||||
|
SPI1.end();
|
||||||
|
}
|
||||||
|
#endif
|
@ -54,6 +54,7 @@ void scanI2Cdevice(void)
|
|||||||
DEBUG_MSG("unknown display found\n");
|
DEBUG_MSG("unknown display found\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr == CARDKB_ADDR) {
|
if (addr == CARDKB_ADDR) {
|
||||||
cardkb_found = addr;
|
cardkb_found = addr;
|
||||||
DEBUG_MSG("m5 cardKB found\n");
|
DEBUG_MSG("m5 cardKB found\n");
|
||||||
|
@ -16,12 +16,6 @@ HardwareSerial *GPS::_serial_gps = &Serial1;
|
|||||||
HardwareSerial *GPS::_serial_gps = NULL;
|
HardwareSerial *GPS::_serial_gps = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GPS_I2C_ADDRESS
|
|
||||||
uint8_t GPS::i2cAddress = GPS_I2C_ADDRESS;
|
|
||||||
#else
|
|
||||||
uint8_t GPS::i2cAddress = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GPS *gps;
|
GPS *gps;
|
||||||
|
|
||||||
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
||||||
@ -325,10 +319,6 @@ int GPS::prepareDeepSleep(void *unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GPS_TX_PIN
|
|
||||||
#include "UBloxGPS.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_GPS
|
#ifndef NO_GPS
|
||||||
#include "NMEAGPS.h"
|
#include "NMEAGPS.h"
|
||||||
#endif
|
#endif
|
||||||
@ -345,25 +335,9 @@ GPS *createGps()
|
|||||||
#else
|
#else
|
||||||
DEBUG_MSG("Using MSL altitude model\n");
|
DEBUG_MSG("Using MSL altitude model\n");
|
||||||
#endif
|
#endif
|
||||||
// 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 {
|
|
||||||
DEBUG_MSG("Using UBLOX Mode\n");
|
|
||||||
return ublox;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (GPS::_serial_gps) {
|
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
|
// 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.
|
// assume NMEA at 9600 baud.
|
||||||
DEBUG_MSG("Using NMEA Mode\n");
|
|
||||||
GPS *new_gps = new NMEAGPS();
|
GPS *new_gps = new NMEAGPS();
|
||||||
new_gps->setup();
|
new_gps->setup();
|
||||||
return new_gps;
|
return new_gps;
|
||||||
|
@ -40,9 +40,6 @@ class GPS : private concurrency::OSThread
|
|||||||
/** If !NULL we will use this serial port to construct our GPS */
|
/** If !NULL we will use this serial port to construct our GPS */
|
||||||
static HardwareSerial *_serial_gps;
|
static HardwareSerial *_serial_gps;
|
||||||
|
|
||||||
/** If !0 we will attempt to connect to the GPS over I2C */
|
|
||||||
static uint8_t i2cAddress;
|
|
||||||
|
|
||||||
Position p = Position_init_default;
|
Position p = Position_init_default;
|
||||||
|
|
||||||
GPS() : concurrency::OSThread("GPS") {}
|
GPS() : concurrency::OSThread("GPS") {}
|
||||||
|
@ -64,11 +64,12 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
|||||||
t.tm_mon = d.month() - 1;
|
t.tm_mon = d.month() - 1;
|
||||||
t.tm_year = d.year() - 1900;
|
t.tm_year = d.year() - 1900;
|
||||||
t.tm_isdst = false;
|
t.tm_isdst = false;
|
||||||
DEBUG_MSG("NMEA GPS time %d-%d-%d %d:%d:%d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
|
if (t.tm_mon > -1){
|
||||||
|
DEBUG_MSG("NMEA GPS time %d-%d-%d %d:%d:%d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
|
||||||
perhapsSetRTC(RTCQualityGPS, t);
|
perhapsSetRTC(RTCQualityGPS, t);
|
||||||
|
return true;
|
||||||
return true;
|
} else
|
||||||
|
return false;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -128,8 +129,10 @@ bool NMEAGPS::lookForLocation()
|
|||||||
auto loc = reader.location.value();
|
auto loc = reader.location.value();
|
||||||
|
|
||||||
// Bail out EARLY to avoid overwriting previous good data (like #857)
|
// Bail out EARLY to avoid overwriting previous good data (like #857)
|
||||||
if(toDegInt(loc.lat) == 0) {
|
if((toDegInt(loc.lat) == 0) || (toDegInt(loc.lat) > 90)) {
|
||||||
DEBUG_MSG("Ignoring bogus NMEA position\n");
|
return false;
|
||||||
|
}
|
||||||
|
if((toDegInt(loc.lng) == 0) || (toDegInt(loc.lng) > 180)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,328 +0,0 @@
|
|||||||
#include "configuration.h"
|
|
||||||
#include "UBloxGPS.h"
|
|
||||||
#include "RTC.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "sleep.h"
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
// if gps_update_interval below this value, do not powercycle the GPS
|
|
||||||
#define UBLOX_POWEROFF_THRESHOLD 90
|
|
||||||
|
|
||||||
#define PDOP_INVALID 9999
|
|
||||||
|
|
||||||
// #define UBX_MODE_NMEA
|
|
||||||
|
|
||||||
extern RadioConfig radioConfig;
|
|
||||||
|
|
||||||
UBloxGPS::UBloxGPS() {}
|
|
||||||
|
|
||||||
bool UBloxGPS::tryConnect()
|
|
||||||
{
|
|
||||||
bool c = false;
|
|
||||||
|
|
||||||
if (_serial_gps)
|
|
||||||
c = ublox.begin(*_serial_gps);
|
|
||||||
|
|
||||||
if (!c && i2cAddress) {
|
|
||||||
extern bool neo6M; // Super skanky - if we are talking to the device i2c we assume it is a neo7 on a RAK815, which
|
|
||||||
// supports the newer API
|
|
||||||
neo6M = true;
|
|
||||||
|
|
||||||
c = ublox.begin(Wire, i2cAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c)
|
|
||||||
setConnected();
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UBloxGPS::setupGPS()
|
|
||||||
{
|
|
||||||
GPS::setupGPS();
|
|
||||||
|
|
||||||
// uncomment to see debug info
|
|
||||||
// ublox.enableDebugging(Serial);
|
|
||||||
|
|
||||||
// try a second time, the ublox lib serial parsing is buggy?
|
|
||||||
// see https://github.com/meshtastic/Meshtastic-device/issues/376
|
|
||||||
for (int i = 0; (i < 3) && !tryConnect(); i++)
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
if (isConnected()) {
|
|
||||||
#ifdef UBX_MODE_NMEA
|
|
||||||
DEBUG_MSG("Connected to UBLOX GPS, downgrading to NMEA mode\n");
|
|
||||||
DEBUG_MSG("- GPS errors below are related and safe to ignore\n");
|
|
||||||
#else
|
|
||||||
DEBUG_MSG("Connected to UBLOX GPS successfully\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!setUBXMode())
|
|
||||||
RECORD_CRITICALERROR(CriticalErrorCode_UBloxInitFailed); // Don't halt the boot if saving the config fails, but do report the bug
|
|
||||||
|
|
||||||
#ifdef UBX_MODE_NMEA
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UBloxGPS::setUBXMode()
|
|
||||||
{
|
|
||||||
#ifdef UBX_MODE_NMEA
|
|
||||||
if (_serial_gps) {
|
|
||||||
ublox.setUART1Output(COM_TYPE_NMEA, 1000);
|
|
||||||
}
|
|
||||||
if (i2cAddress) {
|
|
||||||
ublox.setI2COutput(COM_TYPE_NMEA, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; // pretend initialization failed to force NMEA mode
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_serial_gps) {
|
|
||||||
if (!ublox.setUART1Output(COM_TYPE_UBX, 1000)) // Use native API
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (i2cAddress) {
|
|
||||||
if (!ublox.setI2COutput(COM_TYPE_UBX, 1000))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ublox.setNavigationFrequency(1, 1000)) // Produce 4x/sec to keep the amount of time we stall in getPVT low
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// ok = ublox.setAutoPVT(false); // Not implemented on NEO-6M
|
|
||||||
// assert(ok);
|
|
||||||
// ok = ublox.setDynamicModel(DYN_MODEL_BIKE); // probably PEDESTRIAN but just in case assume bike speeds
|
|
||||||
// assert(ok);
|
|
||||||
|
|
||||||
// per https://github.com/meshtastic/Meshtastic-device/issues/376 powerSaveMode might not work with the marginal
|
|
||||||
// TTGO antennas
|
|
||||||
// if (!ublox.powerSaveMode(true, 2000)) // use power save mode, the default timeout (1100ms seems a bit too tight)
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
if (!ublox.saveConfiguration(3000))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset our GPS back to factory settings
|
|
||||||
*
|
|
||||||
* @return true for success
|
|
||||||
*/
|
|
||||||
bool UBloxGPS::factoryReset()
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
// It is useful to force back into factory defaults (9600baud, NMEA to test the behavior of boards that don't have
|
|
||||||
// GPS_TX connected)
|
|
||||||
ublox.factoryReset();
|
|
||||||
delay(5000);
|
|
||||||
tryConnect(); // sets isConnected
|
|
||||||
|
|
||||||
// try a second time, the ublox lib serial parsing is buggy?
|
|
||||||
for (int i = 0; (i < 3) && !tryConnect(); i++)
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
DEBUG_MSG("GPS Factory reset success=%d\n", isConnected());
|
|
||||||
if (isConnected())
|
|
||||||
ok = setUBXMode();
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Idle processing while GPS is looking for lock */
|
|
||||||
void UBloxGPS::whileActive()
|
|
||||||
{
|
|
||||||
ublox.flushPVT(); // reset ALL freshness flags first
|
|
||||||
ublox.getT(maxWait()); // ask for new time data - hopefully ready when we come back
|
|
||||||
|
|
||||||
// Ask for a new position fix - hopefully it will have results ready by next time
|
|
||||||
// the order here is important, because we only check for has latitude when reading
|
|
||||||
|
|
||||||
//ublox.getSIV(maxWait()); // redundant with getPDOP below
|
|
||||||
ublox.getPDOP(maxWait()); // will trigger getSOL on NEO6, getP on others
|
|
||||||
ublox.getP(maxWait()); // will trigger getPosLLH on NEO6, getP on others
|
|
||||||
|
|
||||||
// the fixType flag will be checked and updated in lookForLocation()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a new location
|
|
||||||
*/
|
|
||||||
bool UBloxGPS::lookForTime()
|
|
||||||
{
|
|
||||||
if (ublox.moduleQueried.gpsSecond) {
|
|
||||||
/* Convert to unix time
|
|
||||||
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January
|
|
||||||
1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
|
||||||
*/
|
|
||||||
struct tm t;
|
|
||||||
t.tm_sec = ublox.getSecond(0);
|
|
||||||
t.tm_min = ublox.getMinute(0);
|
|
||||||
t.tm_hour = ublox.getHour(0);
|
|
||||||
t.tm_mday = ublox.getDay(0);
|
|
||||||
t.tm_mon = ublox.getMonth(0) - 1;
|
|
||||||
t.tm_year = ublox.getYear(0) - 1900;
|
|
||||||
t.tm_isdst = false;
|
|
||||||
perhapsSetRTC(RTCQualityGPS, t);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a new location
|
|
||||||
*/
|
|
||||||
bool UBloxGPS::lookForLocation()
|
|
||||||
{
|
|
||||||
bool foundLocation = false;
|
|
||||||
|
|
||||||
// check if a complete GPS solution set is available for reading
|
|
||||||
// (some of these, like lat/lon are redundant and can be removed)
|
|
||||||
if ( ! (ublox.moduleQueried.fixType &&
|
|
||||||
ublox.moduleQueried.latitude &&
|
|
||||||
ublox.moduleQueried.longitude &&
|
|
||||||
ublox.moduleQueried.altitude &&
|
|
||||||
ublox.moduleQueried.pDOP &&
|
|
||||||
ublox.moduleQueried.SIV &&
|
|
||||||
ublox.moduleQueried.gpsDay))
|
|
||||||
{
|
|
||||||
// Not ready? No problem! We'll try again later.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fixType = ublox.getFixType();
|
|
||||||
#ifdef UBLOX_EXTRAVERBOSE
|
|
||||||
DEBUG_MSG("FixType=%d\n", fixType);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// check if GPS has an acceptable lock
|
|
||||||
if (! hasLock()) {
|
|
||||||
ublox.flushPVT(); // reset ALL freshness flags
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read lat/lon/alt/dop data into temporary variables to avoid
|
|
||||||
// overwriting global variables with potentially invalid data
|
|
||||||
int32_t tmp_dop = ublox.getPDOP(0); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it
|
|
||||||
int32_t tmp_lat = ublox.getLatitude(0);
|
|
||||||
int32_t tmp_lon = ublox.getLongitude(0);
|
|
||||||
int32_t tmp_alt_msl = ublox.getAltitudeMSL(0);
|
|
||||||
int32_t tmp_alt_hae = ublox.getAltitude(0);
|
|
||||||
int32_t max_dop = PDOP_INVALID;
|
|
||||||
if (radioConfig.preferences.gps_max_dop)
|
|
||||||
max_dop = radioConfig.preferences.gps_max_dop * 100; // scaling
|
|
||||||
|
|
||||||
// Note: heading is only currently implmented in the ublox for the 8m chipset - therefore
|
|
||||||
// don't read it here - it will generate an ignored getPVT command on the 6ms
|
|
||||||
// heading = ublox.getHeading(0);
|
|
||||||
|
|
||||||
// read positional timestamp
|
|
||||||
struct tm t;
|
|
||||||
t.tm_sec = ublox.getSecond(0);
|
|
||||||
t.tm_min = ublox.getMinute(0);
|
|
||||||
t.tm_hour = ublox.getHour(0);
|
|
||||||
t.tm_mday = ublox.getDay(0);
|
|
||||||
t.tm_mon = ublox.getMonth(0) - 1;
|
|
||||||
t.tm_year = ublox.getYear(0) - 1900;
|
|
||||||
t.tm_isdst = false;
|
|
||||||
|
|
||||||
time_t tmp_ts = mktime(&t);
|
|
||||||
|
|
||||||
// FIXME - can opportunistically attempt to set RTC from GPS timestamp?
|
|
||||||
|
|
||||||
// bogus lat lon is reported as 0 or 0 (can be bogus just for one)
|
|
||||||
// Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg!
|
|
||||||
// FIXME - NULL ISLAND is a real location on Earth!
|
|
||||||
foundLocation = (tmp_lat != 0) && (tmp_lon != 0) &&
|
|
||||||
(tmp_lat <= 900000000) && (tmp_lat >= -900000000) &&
|
|
||||||
(tmp_dop < max_dop);
|
|
||||||
|
|
||||||
// only if entire dataset is valid, update globals from temp vars
|
|
||||||
if (foundLocation) {
|
|
||||||
p.location_source = Position_LocSource_LOCSRC_GPS_INTERNAL;
|
|
||||||
p.longitude_i = tmp_lon;
|
|
||||||
p.latitude_i = tmp_lat;
|
|
||||||
if (fixType > 2) {
|
|
||||||
// if fix is 2d, ignore altitude data
|
|
||||||
p.altitude = tmp_alt_msl / 1000;
|
|
||||||
p.altitude_hae = tmp_alt_hae / 1000;
|
|
||||||
p.alt_geoid_sep = (tmp_alt_hae - tmp_alt_msl) / 1000;
|
|
||||||
} else {
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
|
||||||
DEBUG_MSG("no altitude data (fixType=%d)\n", fixType);
|
|
||||||
#endif
|
|
||||||
// clean up old values in case it's a 3d-2d fix transition
|
|
||||||
p.altitude = p.altitude_hae = p.alt_geoid_sep = 0;
|
|
||||||
}
|
|
||||||
p.pos_timestamp = tmp_ts;
|
|
||||||
p.PDOP = tmp_dop;
|
|
||||||
p.fix_type = fixType;
|
|
||||||
p.sats_in_view = ublox.getSIV(0);
|
|
||||||
// In debug logs, identify position by @timestamp:stage (stage 1 = birth)
|
|
||||||
DEBUG_MSG("lookForLocation() new pos@%x:1\n", tmp_ts);
|
|
||||||
} else {
|
|
||||||
// INVALID solution - should never happen
|
|
||||||
DEBUG_MSG("Invalid location lat/lon/hae/dop %d/%d/%d/%d - discarded\n",
|
|
||||||
tmp_lat, tmp_lon, tmp_alt_hae, tmp_dop);
|
|
||||||
}
|
|
||||||
|
|
||||||
ublox.flushPVT(); // reset ALL freshness flags at the end
|
|
||||||
|
|
||||||
return foundLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UBloxGPS::hasLock()
|
|
||||||
{
|
|
||||||
if (radioConfig.preferences.gps_accept_2d)
|
|
||||||
return (fixType >= 2 && fixType <= 4);
|
|
||||||
else
|
|
||||||
return (fixType >= 3 && fixType <= 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UBloxGPS::whileIdle()
|
|
||||||
{
|
|
||||||
// if using i2c or serial look too see if any chars are ready
|
|
||||||
return ublox.checkUblox(); // See if new data is available. Process bytes as they come in.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If possible force the GPS into sleep/low power mode
|
|
||||||
/// Note: ublox doesn't need a wake method, because as soon as we send chars to the GPS it will wake up
|
|
||||||
void UBloxGPS::sleep()
|
|
||||||
{
|
|
||||||
if (radioConfig.preferences.gps_update_interval > UBLOX_POWEROFF_THRESHOLD) {
|
|
||||||
// Tell GPS to power down until we send it characters on serial port (we leave vcc connected)
|
|
||||||
ublox.powerOff();
|
|
||||||
// setGPSPower(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UBloxGPS::wake()
|
|
||||||
{
|
|
||||||
if (radioConfig.preferences.gps_update_interval > UBLOX_POWEROFF_THRESHOLD) {
|
|
||||||
fixType = 0; // assume we have no fix yet
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is idempotent
|
|
||||||
setGPSPower(true);
|
|
||||||
|
|
||||||
// Note: no delay needed because now we leave gps power on always and instead use ublox.powerOff()
|
|
||||||
// Give time for the GPS to boot
|
|
||||||
// delay(200);
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GPS.h"
|
|
||||||
#include "Observer.h"
|
|
||||||
#include "SparkFun_Ublox_Arduino_Library.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A gps class that only reads from the GPS periodically (and FIXME - eventually keeps the gps powered down except when reading)
|
|
||||||
*
|
|
||||||
* When new data is available it will notify observers.
|
|
||||||
*/
|
|
||||||
class UBloxGPS : public GPS
|
|
||||||
{
|
|
||||||
SFE_UBLOX_GPS ublox;
|
|
||||||
uint8_t fixType = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
UBloxGPS();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset our GPS back to factory settings
|
|
||||||
*
|
|
||||||
* @return true for success
|
|
||||||
*/
|
|
||||||
bool factoryReset() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* Returns true if we succeeded
|
|
||||||
*/
|
|
||||||
virtual bool setupGPS() override;
|
|
||||||
|
|
||||||
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
|
|
||||||
*
|
|
||||||
* Return true if we received a valid message from the GPS
|
|
||||||
*/
|
|
||||||
virtual bool whileIdle() override;
|
|
||||||
|
|
||||||
/** Idle processing while GPS is looking for lock */
|
|
||||||
virtual void whileActive() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a time
|
|
||||||
*/
|
|
||||||
virtual bool lookForTime() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a new location
|
|
||||||
*/
|
|
||||||
virtual bool lookForLocation() override;
|
|
||||||
virtual bool hasLock() override;
|
|
||||||
|
|
||||||
/// If possible force the GPS into sleep/low power mode
|
|
||||||
virtual void sleep() override;
|
|
||||||
virtual void wake() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Attempt to connect to our GPS, returns false if no gps is present
|
|
||||||
bool tryConnect();
|
|
||||||
|
|
||||||
/// Switch to our desired operating mode and save the settings to flash
|
|
||||||
/// returns true for success
|
|
||||||
bool setUBXMode();
|
|
||||||
|
|
||||||
uint16_t maxWait() const { return i2cAddress ? 300 : 0; /*If using i2c we must poll with wait */ }
|
|
||||||
};
|
|
@ -1,6 +1,7 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#ifdef HAS_EINK
|
#ifdef HAS_EINK
|
||||||
|
#include "main.h"
|
||||||
#include "EInkDisplay2.h"
|
#include "EInkDisplay2.h"
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
@ -171,18 +172,46 @@ bool EInkDisplay::connect()
|
|||||||
}
|
}
|
||||||
#elif defined(RAK4630)
|
#elif defined(RAK4630)
|
||||||
{
|
{
|
||||||
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
|
if (eink_found) {
|
||||||
|
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
|
||||||
|
|
||||||
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
||||||
|
|
||||||
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||||
|
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
adafruitDisplay->setRotation(3);
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
//For 1.54, 2.9 and 4.2
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
//adafruitDisplay->setRotation(1);
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||||
|
adafruitDisplay->setRotation(3);
|
||||||
|
//For 1.54, 2.9 and 4.2
|
||||||
|
//adafruitDisplay->setRotation(1);
|
||||||
|
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
} else {
|
||||||
|
(void)adafruitDisplay;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif defined(PCA10059)
|
#elif defined(PCA10059)
|
||||||
{
|
{
|
||||||
|
@ -815,12 +815,25 @@ void _screen_header()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// #ifdef RAK4630
|
||||||
|
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), dispdev_oled(address, sda, scl), ui(&dispdev)
|
||||||
|
// {
|
||||||
|
// address_found = address;
|
||||||
|
// cmdQueue.setReader(this);
|
||||||
|
// if (screen_found) {
|
||||||
|
// (void)dispdev;
|
||||||
|
// AutoOLEDWire dispdev = dispdev_oled;
|
||||||
|
// (void)ui;
|
||||||
|
// OLEDDisplayUi ui(&dispdev);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// #else
|
||||||
Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev)
|
Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev)
|
||||||
{
|
{
|
||||||
address_found = address;
|
address_found = address;
|
||||||
cmdQueue.setReader(this);
|
cmdQueue.setReader(this);
|
||||||
}
|
}
|
||||||
|
// #endif
|
||||||
/**
|
/**
|
||||||
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
|
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
|
||||||
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
|
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
|
||||||
|
@ -27,6 +27,10 @@ class Screen
|
|||||||
|
|
||||||
#ifdef USE_ST7567
|
#ifdef USE_ST7567
|
||||||
#include <ST7567Wire.h>
|
#include <ST7567Wire.h>
|
||||||
|
#elif defined(USE_SH1106)
|
||||||
|
#include <SH1106Wire.h>
|
||||||
|
#elif defined(USE_SSD1306)
|
||||||
|
#include <SSD1306Wire.h>
|
||||||
#else
|
#else
|
||||||
// the SH1106/SSD1306 variant is auto-detected
|
// the SH1106/SSD1306 variant is auto-detected
|
||||||
#include <AutoOLEDWire.h>
|
#include <AutoOLEDWire.h>
|
||||||
@ -297,9 +301,16 @@ class Screen : public concurrency::OSThread
|
|||||||
/// Holds state for debug information
|
/// Holds state for debug information
|
||||||
DebugInfo debugInfo;
|
DebugInfo debugInfo;
|
||||||
|
|
||||||
/// Display device
|
/// Display device
|
||||||
/** FIXME cleanup display abstraction */
|
|
||||||
#ifdef ST7735_CS
|
// #ifdef RAK4630
|
||||||
|
// EInkDisplay dispdev;
|
||||||
|
// AutoOLEDWire dispdev_oled;
|
||||||
|
#ifdef USE_SH1106
|
||||||
|
SH1106Wire dispdev;
|
||||||
|
#elif defined(USE_SSD1306)
|
||||||
|
SSD1306Wire dispdev;
|
||||||
|
#elif defined(ST7735_CS)
|
||||||
TFTDisplay dispdev;
|
TFTDisplay dispdev;
|
||||||
#elif defined(HAS_EINK)
|
#elif defined(HAS_EINK)
|
||||||
EInkDisplay dispdev;
|
EInkDisplay dispdev;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "shutdown.h"
|
#include "shutdown.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include "debug/i2cScan.h"
|
#include "debug/i2cScan.h"
|
||||||
|
#include "debug/einkScan.h"
|
||||||
#include "debug/axpDebug.h"
|
#include "debug/axpDebug.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
// #include <driver/rtc_io.h>
|
// #include <driver/rtc_io.h>
|
||||||
@ -78,6 +79,8 @@ uint8_t cardkb_found;
|
|||||||
// The I2C address of the Faces Keyboard (if found)
|
// The I2C address of the Faces Keyboard (if found)
|
||||||
uint8_t faceskb_found;
|
uint8_t faceskb_found;
|
||||||
|
|
||||||
|
bool eink_found = true;
|
||||||
|
|
||||||
uint32_t serialSinceMsec;
|
uint32_t serialSinceMsec;
|
||||||
|
|
||||||
bool axp192_found;
|
bool axp192_found;
|
||||||
@ -208,6 +211,9 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
scanI2Cdevice();
|
scanI2Cdevice();
|
||||||
|
#ifdef RAK4630
|
||||||
|
// scanEInkDevice();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Buttons & LED
|
// Buttons & LED
|
||||||
buttonThread = new ButtonThread();
|
buttonThread = new ButtonThread();
|
||||||
|
@ -10,6 +10,7 @@ extern uint8_t screen_model;
|
|||||||
extern uint8_t cardkb_found;
|
extern uint8_t cardkb_found;
|
||||||
extern uint8_t faceskb_found;
|
extern uint8_t faceskb_found;
|
||||||
|
|
||||||
|
extern bool eink_found;
|
||||||
extern bool axp192_found;
|
extern bool axp192_found;
|
||||||
extern bool isCharging;
|
extern bool isCharging;
|
||||||
extern bool isUSBPowered;
|
extern bool isUSBPowered;
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "ocrypto_aes_ctr.h"
|
#include <Adafruit_nRFCrypto.h>
|
||||||
|
|
||||||
class NRF52CryptoEngine : public CryptoEngine
|
class NRF52CryptoEngine : public CryptoEngine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NRF52CryptoEngine() {}
|
NRF52CryptoEngine() {}
|
||||||
|
|
||||||
@ -19,29 +16,37 @@ class NRF52CryptoEngine : public CryptoEngine
|
|||||||
*/
|
*/
|
||||||
virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
|
virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
|
||||||
{
|
{
|
||||||
// DEBUG_MSG("NRF52 encrypt!\n");
|
// DEBUG_MSG("NRF52 encrypt!\n");
|
||||||
|
|
||||||
if (key.length > 0) {
|
if (key.length > 0) {
|
||||||
ocrypto_aes_ctr_ctx ctx;
|
nRFCrypto.begin();
|
||||||
|
nRFCrypto_AES ctx;
|
||||||
|
uint8_t myLen = ctx.blockLen(numBytes);
|
||||||
|
char encBuf[myLen] = {0};
|
||||||
|
memcpy(encBuf, bytes, numBytes);
|
||||||
initNonce(fromNode, packetId);
|
initNonce(fromNode, packetId);
|
||||||
ocrypto_aes_ctr_init(&ctx, key.bytes, key.length, nonce);
|
ctx.begin();
|
||||||
|
ctx.Process(encBuf, numBytes, nonce, key.bytes, key.length, (char*)bytes, ctx.encryptFlag, ctx.ctrMode);
|
||||||
ocrypto_aes_ctr_encrypt(&ctx, bytes, bytes, numBytes);
|
ctx.end();
|
||||||
|
nRFCrypto.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
|
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
|
||||||
{
|
{
|
||||||
// DEBUG_MSG("NRF52 decrypt!\n");
|
// DEBUG_MSG("NRF52 decrypt!\n");
|
||||||
|
|
||||||
if (key.length > 0) {
|
if (key.length > 0) {
|
||||||
ocrypto_aes_ctr_ctx ctx;
|
nRFCrypto.begin();
|
||||||
|
nRFCrypto_AES ctx;
|
||||||
|
uint8_t myLen = ctx.blockLen(numBytes);
|
||||||
|
char decBuf[myLen] = {0};
|
||||||
|
memcpy(decBuf, bytes, numBytes);
|
||||||
initNonce(fromNode, packetId);
|
initNonce(fromNode, packetId);
|
||||||
ocrypto_aes_ctr_init(&ctx, key.bytes, key.length, nonce);
|
ctx.begin();
|
||||||
|
ctx.Process(decBuf, numBytes, nonce, key.bytes, key.length, (char*)bytes, ctx.decryptFlag, ctx.ctrMode);
|
||||||
ocrypto_aes_ctr_decrypt(&ctx, bytes, bytes, numBytes);
|
ctx.end();
|
||||||
|
nRFCrypto.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <ble_gap.h>
|
#include <ble_gap.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <Adafruit_nRFCrypto.h>
|
||||||
// #include <Adafruit_USBD_Device.h>
|
// #include <Adafruit_USBD_Device.h>
|
||||||
|
|
||||||
#include "NRF52Bluetooth.h"
|
#include "NRF52Bluetooth.h"
|
||||||
@ -145,13 +146,15 @@ void nrf52Setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init random seed
|
// Init random seed
|
||||||
// FIXME - use this to get random numbers
|
union seedParts {
|
||||||
// #include "nrf_rng.h"
|
uint32_t seed32;
|
||||||
// uint32_t r;
|
uint8_t seed8[4];
|
||||||
// ble_controller_rand_vector_get_blocking(&r, sizeof(r));
|
} seed;
|
||||||
// randomSeed(r);
|
nRFCrypto.begin();
|
||||||
DEBUG_MSG("FIXME, call randomSeed\n");
|
nRFCrypto.Random.generate(seed.seed8, sizeof(seed.seed8));
|
||||||
// ::printf("TESTING PRINTF\n");
|
DEBUG_MSG("Setting random seed %u\n", seed.seed32);
|
||||||
|
randomSeed(seed.seed32);
|
||||||
|
nRFCrypto.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpuDeepSleep(uint64_t msecToWake)
|
void cpuDeepSleep(uint64_t msecToWake)
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
; The very slick RAK wireless RAK 4631 / 4630 board
|
|
||||||
[env:rak4631_5005]
|
|
||||||
extends = nrf52840_base
|
|
||||||
board = wiscore_rak4631
|
|
||||||
# add our variants files to the include and src paths
|
|
||||||
# define build flags for the TFT_eSPI library
|
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_5005
|
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
|
|
||||||
debug_tool = jlink
|
|
||||||
|
|
||||||
[env:rak4631_19003]
|
|
||||||
extends = nrf52840_base
|
|
||||||
board = wiscore_rak4631
|
|
||||||
# add our variants files to the include and src paths
|
|
||||||
# define build flags for the TFT_eSPI library
|
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_19003
|
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
|
|
||||||
debug_tool = jlink
|
|
||||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
|
||||||
;upload_protocol = jlink
|
|
@ -1,9 +0,0 @@
|
|||||||
[env:rak4631_5005_eink]
|
|
||||||
extends = nrf52840_base
|
|
||||||
board = wiscore_rak4631
|
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_E-Paper_Board -D RAK_BASE_5005
|
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_E-Paper_Board>
|
|
||||||
lib_deps =
|
|
||||||
${nrf52840_base.lib_deps}
|
|
||||||
https://github.com/ZinggJM/GxEPD2.git
|
|
||||||
debug_tool = jlink
|
|
11
variants/rak4631/platformio.ini
Normal file
11
variants/rak4631/platformio.ini
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmare for 5005/19003, with or without OLED RAK 1921
|
||||||
|
[env:rak4631]
|
||||||
|
extends = nrf52840_base
|
||||||
|
board = wiscore_rak4631
|
||||||
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
|
||||||
|
src_filter = ${nrf52_base.src_filter} +<../variants/rak4631>
|
||||||
|
lib_deps =
|
||||||
|
${nrf52840_base.lib_deps}
|
||||||
|
debug_tool = jlink
|
||||||
|
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||||
|
;upload_protocol = jlink
|
@ -59,10 +59,8 @@ extern "C" {
|
|||||||
* Buttons
|
* Buttons
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef RAK_BASE_5005
|
|
||||||
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
|
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
|
||||||
#define BUTTON_NEED_PULLUP
|
#define BUTTON_NEED_PULLUP
|
||||||
#endif
|
|
||||||
#define PIN_BUTTON2 12
|
#define PIN_BUTTON2 12
|
||||||
#define PIN_BUTTON3 24
|
#define PIN_BUTTON3 24
|
||||||
#define PIN_BUTTON4 25
|
#define PIN_BUTTON4 25
|
||||||
@ -110,17 +108,39 @@ static const uint8_t AREF = PIN_AREF;
|
|||||||
/*
|
/*
|
||||||
* SPI Interfaces
|
* SPI Interfaces
|
||||||
*/
|
*/
|
||||||
#define SPI_INTERFACES_COUNT 1
|
#define SPI_INTERFACES_COUNT 2
|
||||||
|
|
||||||
#define PIN_SPI_MISO (45)
|
#define PIN_SPI_MISO (45)
|
||||||
#define PIN_SPI_MOSI (44)
|
#define PIN_SPI_MOSI (44)
|
||||||
#define PIN_SPI_SCK (43)
|
#define PIN_SPI_SCK (43)
|
||||||
|
|
||||||
|
#define PIN_SPI1_MISO (29) // (0 + 29)
|
||||||
|
#define PIN_SPI1_MOSI (30) // (0 + 30)
|
||||||
|
#define PIN_SPI1_SCK (3) // (0 + 3)
|
||||||
|
|
||||||
static const uint8_t SS = 42;
|
static const uint8_t SS = 42;
|
||||||
static const uint8_t MOSI = PIN_SPI_MOSI;
|
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||||
static const uint8_t MISO = PIN_SPI_MISO;
|
static const uint8_t MISO = PIN_SPI_MISO;
|
||||||
static const uint8_t SCK = PIN_SPI_SCK;
|
static const uint8_t SCK = PIN_SPI_SCK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* eink display pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_EINK_EN (0 + 2) // (0 + 2) Note: this is really just backlight power
|
||||||
|
#define PIN_EINK_CS (0 + 26)
|
||||||
|
#define PIN_EINK_BUSY (0 + 4)
|
||||||
|
#define PIN_EINK_DC (0 + 17)
|
||||||
|
#define PIN_EINK_RES (-1)
|
||||||
|
#define PIN_EINK_SCLK (0 + 3)
|
||||||
|
#define PIN_EINK_MOSI (0 + 30) // also called SDI
|
||||||
|
|
||||||
|
// Controls power for the eink display - Board power is enabled either by VBUS from USB or the CPU asserting PWR_ON
|
||||||
|
// FIXME - I think this is actually just the board power enable - it enables power to the CPU also
|
||||||
|
//#define PIN_EINK_PWR_ON (-1)
|
||||||
|
|
||||||
|
// #define HAS_EINK
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wire Interfaces
|
* Wire Interfaces
|
||||||
*/
|
*/
|
||||||
@ -175,10 +195,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
|||||||
#define PIN_GPS_EN (34)
|
#define PIN_GPS_EN (34)
|
||||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||||
|
|
||||||
#ifdef RAK_BASE_5005
|
|
||||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||||
#define GPS_TX_PIN PIN_SERIAL1_TX
|
#define GPS_TX_PIN PIN_SERIAL1_TX
|
||||||
#endif
|
|
||||||
|
|
||||||
// Battery
|
// Battery
|
||||||
// The battery sense is hooked to pin A0 (5)
|
// The battery sense is hooked to pin A0 (5)
|
12
variants/rak4631_epaper/platformio.ini
Normal file
12
variants/rak4631_epaper/platformio.ini
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
; The very slick RAK wireless RAK 4631 / 4630 board - Firmware for 5005 with the RAK 14000 ePaper
|
||||||
|
[env:rak4631_eink]
|
||||||
|
extends = nrf52840_base
|
||||||
|
board = wiscore_rak4631
|
||||||
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_epaper -D RAK_4631
|
||||||
|
src_filter = ${nrf52_base.src_filter} +<../variants/rak4631_epaper>
|
||||||
|
lib_deps =
|
||||||
|
${nrf52840_base.lib_deps}
|
||||||
|
https://github.com/ZinggJM/GxEPD2.git
|
||||||
|
debug_tool = jlink
|
||||||
|
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||||
|
;upload_protocol = jlink
|
@ -2,14 +2,17 @@
|
|||||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
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,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
See the GNU Lesser General Public License for more details.
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
@ -2,6 +2,7 @@
|
|||||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
@ -58,10 +59,8 @@ extern "C" {
|
|||||||
* Buttons
|
* Buttons
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef RAK_BASE_5005
|
|
||||||
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
|
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
|
||||||
#define BUTTON_NEED_PULLUP
|
#define BUTTON_NEED_PULLUP
|
||||||
#endif
|
|
||||||
#define PIN_BUTTON2 12
|
#define PIN_BUTTON2 12
|
||||||
#define PIN_BUTTON3 24
|
#define PIN_BUTTON3 24
|
||||||
#define PIN_BUTTON4 25
|
#define PIN_BUTTON4 25
|
||||||
@ -196,10 +195,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
|||||||
#define PIN_GPS_EN (34)
|
#define PIN_GPS_EN (34)
|
||||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||||
|
|
||||||
#ifdef RAK_BASE_5005
|
|
||||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||||
#define GPS_TX_PIN PIN_SERIAL1_TX
|
#define GPS_TX_PIN PIN_SERIAL1_TX
|
||||||
#endif
|
|
||||||
|
|
||||||
// Battery
|
// Battery
|
||||||
// The battery sense is hooked to pin A0 (5)
|
// The battery sense is hooked to pin A0 (5)
|
Loading…
Reference in New Issue
Block a user