mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-01 15:40:49 +00:00
Compare commits
34 Commits
v1.2.62.3d
...
v1.2.65.0a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0adc5ce3de | ||
|
|
1d5e079fa2 | ||
|
|
33fac6d0f5 | ||
|
|
8e8158ebbc | ||
|
|
a9fcc775d9 | ||
|
|
cf465a3d34 | ||
|
|
6520c51b66 | ||
|
|
98552b6d9d | ||
|
|
7f9c07ae37 | ||
|
|
bfd97558d4 | ||
|
|
44159f75f1 | ||
|
|
dfa9c32665 | ||
|
|
c600135b70 | ||
|
|
179a2624a1 | ||
|
|
3fded9aaa9 | ||
|
|
f423d943a8 | ||
|
|
f251727524 | ||
|
|
f3cc732e7d | ||
|
|
8d74c41802 | ||
|
|
89f7968ca2 | ||
|
|
3b2375a27b | ||
|
|
959962530b | ||
|
|
77816f8f68 | ||
|
|
ee8e544ce2 | ||
|
|
887e6fd761 | ||
|
|
d06aa73947 | ||
|
|
72bfee34ee | ||
|
|
fc48fcde96 | ||
|
|
f0965e2ac4 | ||
|
|
7c253bfc3c | ||
|
|
ba894ae95b | ||
|
|
9879494fc6 | ||
|
|
5088940751 | ||
|
|
888af31d4f |
2
.github/workflows/main_matrix.yml
vendored
2
.github/workflows/main_matrix.yml
vendored
@@ -39,6 +39,7 @@ jobs:
|
|||||||
- board: rak4631_19003
|
- board: rak4631_19003
|
||||||
- board: t-echo
|
- board: t-echo
|
||||||
- board: nano-g1
|
- board: nano-g1
|
||||||
|
- board: meshtastic-dr-dev
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -105,6 +106,7 @@ jobs:
|
|||||||
- board: tbeam0.7
|
- board: tbeam0.7
|
||||||
- board: meshtastic-diy-v1
|
- board: meshtastic-diy-v1
|
||||||
- board: nano-g1
|
- board: nano-g1
|
||||||
|
- board: meshtastic-dr-dev
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -29,3 +29,4 @@ __pycache__
|
|||||||
|
|
||||||
venv/
|
venv/
|
||||||
release/
|
release/
|
||||||
|
.vscode/extensions.json
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ set -e
|
|||||||
VERSION=`bin/buildinfo.py long`
|
VERSION=`bin/buildinfo.py long`
|
||||||
SHORT_VERSION=`bin/buildinfo.py short`
|
SHORT_VERSION=`bin/buildinfo.py short`
|
||||||
|
|
||||||
BOARDS_ESP32="rak11200 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 nano-g1"
|
BOARDS_ESP32="rak11200 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 nano-g1 meshtastic-dr-dev"
|
||||||
#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
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ default_envs = tbeam
|
|||||||
;default_envs = nano-g1
|
;default_envs = nano-g1
|
||||||
;default_envs = meshtastic-diy-v1
|
;default_envs = meshtastic-diy-v1
|
||||||
;default_envs = meshtastic-diy-v1.1
|
;default_envs = meshtastic-diy-v1.1
|
||||||
|
;default_envs = meshtastic-dr-dev
|
||||||
|
|
||||||
; board specific config can be moved to the respective 'variants' file.
|
; board specific config can be moved to the respective 'variants' file.
|
||||||
; See https://docs.platformio.org/en/latest/projectconf/section_platformio.html#extra-configs
|
; See https://docs.platformio.org/en/latest/projectconf/section_platformio.html#extra-configs
|
||||||
@@ -83,9 +84,8 @@ lib_deps =
|
|||||||
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
||||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
||||||
https://github.com/meshtastic/arduino-fsm.git
|
https://github.com/meshtastic/arduino-fsm.git
|
||||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
|
||||||
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
|
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79
|
https://github.com/meshtastic/TinyGPSPlus.git
|
||||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||||
SPI
|
SPI
|
||||||
@@ -107,7 +107,7 @@ lib_deps =
|
|||||||
build_flags = ${env.build_flags} -Os
|
build_flags = ${env.build_flags} -Os
|
||||||
# -DRADIOLIB_GODMODE
|
# -DRADIOLIB_GODMODE
|
||||||
|
|
||||||
src_filter = ${env.src_filter} -<portduino/>
|
build_src_filter = ${env.build_src_filter} -<portduino/>
|
||||||
|
|
||||||
; Common libs for environmental measurements (not included in native / portduino)
|
; Common libs for environmental measurements (not included in native / portduino)
|
||||||
[environmental]
|
[environmental]
|
||||||
@@ -124,8 +124,8 @@ lib_deps =
|
|||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = espressif32@3.5.0
|
platform = espressif32@3.5.0
|
||||||
src_filter =
|
build_src_filter =
|
||||||
${arduino_base.src_filter} -<nrf52/>
|
${arduino_base.build_src_filter} -<nrf52/>
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
debug_init_break = tbreak setup
|
debug_init_break = tbreak setup
|
||||||
|
|
||||||
@@ -179,8 +179,8 @@ board_build.partitions = partition-table.csv
|
|||||||
;board = cubecell_board_plus
|
;board = cubecell_board_plus
|
||||||
; FIXME, bug in cubecell arduino - they are supposed to set ARDUINO
|
; FIXME, bug in cubecell arduino - they are supposed to set ARDUINO
|
||||||
;build_flags = ${arduino_base.build_flags} -DARDUINO=100 -Isrc/cubecell
|
;build_flags = ${arduino_base.build_flags} -DARDUINO=100 -Isrc/cubecell
|
||||||
;src_filter =
|
;build_src_filter =
|
||||||
; ${arduino_base.src_filter} -<esp32/> -<nrf52/>
|
; ${arduino_base.build_src_filter} -<esp32/> -<nrf52/>
|
||||||
|
|
||||||
; Common settings for NRF52 based targets
|
; Common settings for NRF52 based targets
|
||||||
[nrf52_base]
|
[nrf52_base]
|
||||||
@@ -195,8 +195,8 @@ build_flags =
|
|||||||
-Isrc/nrf52
|
-Isrc/nrf52
|
||||||
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.7
|
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.7
|
||||||
;-DCFG_DEBUG=3
|
;-DCFG_DEBUG=3
|
||||||
src_filter =
|
build_src_filter =
|
||||||
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<plugins/esp32> -<mqtt/>
|
${arduino_base.build_src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<plugins/esp32> -<mqtt/>
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
; monitor_port = /dev/ttyACM1
|
; monitor_port = /dev/ttyACM1
|
||||||
|
|||||||
2
proto
2
proto
Submodule proto updated: c851209e0b...f1476bf2f6
@@ -63,7 +63,7 @@ class GPSStatus : public Status
|
|||||||
|
|
||||||
int32_t getLatitude() const {
|
int32_t getLatitude() const {
|
||||||
if (radioConfig.preferences.fixed_position){
|
if (radioConfig.preferences.fixed_position){
|
||||||
#if GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
DEBUG_MSG("WARNING: Using fixed latitude\n");
|
DEBUG_MSG("WARNING: Using fixed latitude\n");
|
||||||
#endif
|
#endif
|
||||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||||
@@ -75,7 +75,7 @@ class GPSStatus : public Status
|
|||||||
|
|
||||||
int32_t getLongitude() const {
|
int32_t getLongitude() const {
|
||||||
if (radioConfig.preferences.fixed_position){
|
if (radioConfig.preferences.fixed_position){
|
||||||
#if GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
DEBUG_MSG("WARNING: Using fixed longitude\n");
|
DEBUG_MSG("WARNING: Using fixed longitude\n");
|
||||||
#endif
|
#endif
|
||||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||||
@@ -87,7 +87,7 @@ class GPSStatus : public Status
|
|||||||
|
|
||||||
int32_t getAltitude() const {
|
int32_t getAltitude() const {
|
||||||
if (radioConfig.preferences.fixed_position){
|
if (radioConfig.preferences.fixed_position){
|
||||||
#if GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
DEBUG_MSG("WARNING: Using fixed altitude\n");
|
DEBUG_MSG("WARNING: Using fixed altitude\n");
|
||||||
#endif
|
#endif
|
||||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||||
@@ -105,7 +105,7 @@ class GPSStatus : public Status
|
|||||||
|
|
||||||
bool matches(const GPSStatus *newStatus) const
|
bool matches(const GPSStatus *newStatus) const
|
||||||
{
|
{
|
||||||
#if GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n",
|
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n",
|
||||||
newStatus->p.pos_timestamp, p.pos_timestamp);
|
newStatus->p.pos_timestamp, p.pos_timestamp);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef TTGO_T_ECHO
|
||||||
|
#define GPS_UBLOX
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Standard definitions for !ESP32 targets
|
// Standard definitions for !ESP32 targets
|
||||||
//
|
//
|
||||||
@@ -149,6 +153,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#define GPS_BAUDRATE 9600
|
#define GPS_BAUDRATE 9600
|
||||||
|
|
||||||
|
#ifndef GPS_THREAD_INTERVAL
|
||||||
|
#define GPS_THREAD_INTERVAL 100
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TBEAM_V10)
|
#if defined(TBEAM_V10)
|
||||||
// This string must exactly match the case used in release file names or the android updater won't work
|
// This string must exactly match the case used in release file names or the android updater won't work
|
||||||
#define HW_VENDOR HardwareModel_TBEAM
|
#define HW_VENDOR HardwareModel_TBEAM
|
||||||
@@ -161,6 +169,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// This string must exactly match the case used in release file names or the android updater won't work
|
// This string must exactly match the case used in release file names or the android updater won't work
|
||||||
#define HW_VENDOR HardwareModel_DIY_V1
|
#define HW_VENDOR HardwareModel_DIY_V1
|
||||||
|
|
||||||
|
#elif defined(DR_DEV)
|
||||||
|
// This string must exactly match the case used in release file names or the android updater won't work
|
||||||
|
#define HW_VENDOR HardwareModel_DR_DEV
|
||||||
|
|
||||||
#elif defined(RAK_11200)
|
#elif defined(RAK_11200)
|
||||||
// This string must exactly match the case used in release file names or the android updater won't work
|
// This string must exactly match the case used in release file names or the android updater won't work
|
||||||
#define HW_VENDOR HardwareModel_RAK11200
|
#define HW_VENDOR HardwareModel_RAK11200
|
||||||
@@ -246,4 +258,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
#include "RF95Configuration.h"
|
#include "RF95Configuration.h"
|
||||||
#include "DebugConfiguration.h"
|
#include "DebugConfiguration.h"
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
#include "configuration.h"
|
|
||||||
#include "Air530GPS.h"
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
Helpful translations from the Air530 GPS datasheet
|
|
||||||
|
|
||||||
Sat acquision mode
|
|
||||||
捕获电流值@3.3v 42.6 mA
|
|
||||||
|
|
||||||
sat tracking mode
|
|
||||||
跟踪电流值@3.3v 36.7 mA
|
|
||||||
|
|
||||||
Low power mode
|
|
||||||
低功耗模式@3.3V 0.85 mA
|
|
||||||
(发送指令:$PGKC051,0)
|
|
||||||
|
|
||||||
Super low power mode
|
|
||||||
超低功耗模式@3.3V 31 uA
|
|
||||||
(发送指令:$PGKC105,4)
|
|
||||||
|
|
||||||
To exit sleep use WAKE pin
|
|
||||||
|
|
||||||
Commands to enter sleep
|
|
||||||
6、Command: 105
|
|
||||||
进入周期性低功耗模式
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
Arg1: “0”,正常运行模式 (normal mode)
|
|
||||||
“1”,周期超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (periodic low power tracking mode - keeps sat positions, use wake to wake up)
|
|
||||||
“2”,周期低功耗模式 (periodic low power mode)
|
|
||||||
“4”,直接进入超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (super low power consumption mode immediately, need WAKE to resume)
|
|
||||||
“8”,自动低功耗模式,可以通过串口唤醒 (automatic low power mode, wake by sending characters to serial port)
|
|
||||||
“9”, 自动超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (automatic low power tracking when possible, need wake pin to resume)
|
|
||||||
|
|
||||||
(Arg 2 & 3 only valid if Arg1 is "1" or "2")
|
|
||||||
Arg2:运行时间(毫秒),在 Arg1 为 1、2 的周期模式下,此参数起作用
|
|
||||||
ON time in msecs
|
|
||||||
|
|
||||||
Arg3:睡眠时间(毫秒),在 Arg1 为 1、2 的周期模式下,此参数起作用
|
|
||||||
Sleep time in msecs
|
|
||||||
|
|
||||||
Example:
|
|
||||||
$PGKC105,8*3F<CR><LF>
|
|
||||||
This will set automatic low power mode with waking when we send chars to the serial port. Possibly do this as soon as we get a
|
|
||||||
new location. When we wake again in a minute we send a character to wake up.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
void Air530GPS::sendCommand(const char *cmd) {
|
|
||||||
uint8_t sum = 0;
|
|
||||||
|
|
||||||
// Skip the $
|
|
||||||
assert(cmd[0] == '$');
|
|
||||||
const char *p = cmd + 1;
|
|
||||||
while(*p)
|
|
||||||
sum ^= *p++;
|
|
||||||
|
|
||||||
assert(_serial_gps);
|
|
||||||
|
|
||||||
_serial_gps->write(cmd);
|
|
||||||
_serial_gps->printf("*%02x\r\n", sum);
|
|
||||||
|
|
||||||
// DEBUG_MSG("xsum %02x\n", sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Air530GPS::sleep() {
|
|
||||||
NMEAGPS::sleep();
|
|
||||||
#ifdef PIN_GPS_WAKE
|
|
||||||
sendCommand("$PGKC105,4");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// wake the GPS into normal operation mode
|
|
||||||
void Air530GPS::wake()
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
NMEAGPS::wake();
|
|
||||||
#else
|
|
||||||
// For power testing - keep GPS sleeping forever
|
|
||||||
sleep();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "NMEAGPS.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A gps class thatreads from a NMEA GPS stream (and FIXME - eventually keeps the gps powered down except when reading)
|
|
||||||
*
|
|
||||||
* When new data is available it will notify observers.
|
|
||||||
*/
|
|
||||||
class Air530GPS : public NMEAGPS
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
/// If possible force the GPS into sleep/low power mode
|
|
||||||
virtual void sleep() override;
|
|
||||||
|
|
||||||
/// wake the GPS into normal operation mode
|
|
||||||
virtual void wake() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Send a NMEA cmd with checksum
|
|
||||||
void sendCommand(const char *str);
|
|
||||||
};
|
|
||||||
178
src/gps/GPS.cpp
178
src/gps/GPS.cpp
@@ -16,18 +16,49 @@ 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
|
||||||
/// only init that port once.
|
/// only init that port once.
|
||||||
static bool didSerialInit;
|
static bool didSerialInit;
|
||||||
|
|
||||||
|
bool GPS::getACK(uint8_t c, uint8_t i) {
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t ack = 0;
|
||||||
|
const uint8_t ackP[2] = {c, i};
|
||||||
|
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
unsigned long startTime = millis();
|
||||||
|
|
||||||
|
for (int j = 2; j < 6; j++) {
|
||||||
|
buf[8] += buf[j];
|
||||||
|
buf[9] += buf[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
buf[6 + j] = ackP[j];
|
||||||
|
buf[8] += buf[6 + j];
|
||||||
|
buf[9] += buf[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (ack > 9) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (millis() - startTime > 1000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (_serial_gps->available()) {
|
||||||
|
b = _serial_gps->read();
|
||||||
|
if (b == buf[ack]) {
|
||||||
|
ack++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ack = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool GPS::setupGPS()
|
bool GPS::setupGPS()
|
||||||
{
|
{
|
||||||
if (_serial_gps && !didSerialInit) {
|
if (_serial_gps && !didSerialInit) {
|
||||||
@@ -41,6 +72,96 @@ bool GPS::setupGPS()
|
|||||||
#endif
|
#endif
|
||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
_serial_gps->setRxBufferSize(2048); // the default is 256
|
_serial_gps->setRxBufferSize(2048); // the default is 256
|
||||||
|
#endif
|
||||||
|
#ifdef TTGO_T_ECHO
|
||||||
|
// Switch to 9600 baud, then close and reopen port
|
||||||
|
_serial_gps->end();
|
||||||
|
delay(250);
|
||||||
|
_serial_gps->begin(4800);
|
||||||
|
delay(250);
|
||||||
|
_serial_gps->write("$PCAS01,1*1D\r\n");
|
||||||
|
delay(250);
|
||||||
|
_serial_gps->end();
|
||||||
|
delay(250);
|
||||||
|
_serial_gps->begin(9600);
|
||||||
|
delay(250);
|
||||||
|
// Initialize the L76K Chip, use GPS + GLONASS
|
||||||
|
_serial_gps->write("$PCAS04,5*1C\r\n");
|
||||||
|
delay(250);
|
||||||
|
// only ask for RMC and GGA
|
||||||
|
_serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
|
||||||
|
delay(250);
|
||||||
|
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||||
|
_serial_gps->write("$PCAS11,3*1E\r\n");
|
||||||
|
delay(250);
|
||||||
|
#endif
|
||||||
|
#ifdef GPS_UBLOX
|
||||||
|
delay(250);
|
||||||
|
// Set the UART port to output NMEA only
|
||||||
|
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x91, 0xAF};
|
||||||
|
_serial_gps->write(_message_nmea,sizeof(_message_nmea));
|
||||||
|
if (!getACK(0x06, 0x00)) {
|
||||||
|
DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// disable GGL
|
||||||
|
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||||
|
0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x05,0x3A};
|
||||||
|
_serial_gps->write(_message_GGL,sizeof(_message_GGL));
|
||||||
|
if (!getACK(0x06, 0x01)) {
|
||||||
|
DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable GSA
|
||||||
|
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||||
|
0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x06,0x41};
|
||||||
|
_serial_gps->write(_message_GSA,sizeof(_message_GSA));
|
||||||
|
if (!getACK(0x06, 0x01)) {
|
||||||
|
DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable GSV
|
||||||
|
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||||
|
0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x07,0x48};
|
||||||
|
_serial_gps->write(_message_GSV,sizeof(_message_GSV));
|
||||||
|
if (!getACK(0x06, 0x01)) {
|
||||||
|
DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable VTG
|
||||||
|
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||||
|
0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x09,0x56};
|
||||||
|
_serial_gps->write(_message_VTG,sizeof(_message_VTG));
|
||||||
|
if (!getACK(0x06, 0x01)) {
|
||||||
|
DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable RMC
|
||||||
|
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||||
|
0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x09,0x54};
|
||||||
|
_serial_gps->write(_message_RMC,sizeof(_message_RMC));
|
||||||
|
if (!getACK(0x06, 0x01)) {
|
||||||
|
DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable GGA
|
||||||
|
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||||
|
0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x05, 0x38};
|
||||||
|
_serial_gps->write(_message_GGA,sizeof(_message_GGA));
|
||||||
|
if (!getACK(0x06, 0x01)) DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +172,7 @@ bool GPS::setup()
|
|||||||
{
|
{
|
||||||
// Master power for the GPS
|
// Master power for the GPS
|
||||||
#ifdef PIN_GPS_EN
|
#ifdef PIN_GPS_EN
|
||||||
digitalWrite(PIN_GPS_EN, PIN_GPS_EN);
|
digitalWrite(PIN_GPS_EN, 1);
|
||||||
pinMode(PIN_GPS_EN, OUTPUT);
|
pinMode(PIN_GPS_EN, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -82,6 +203,11 @@ GPS::~GPS()
|
|||||||
|
|
||||||
bool GPS::hasLock() { return hasValidLocation; }
|
bool GPS::hasLock() { return hasValidLocation; }
|
||||||
|
|
||||||
|
bool GPS::hasFlow()
|
||||||
|
{
|
||||||
|
return hasGPS;
|
||||||
|
}
|
||||||
|
|
||||||
// Allow defining the polarity of the WAKE output. default is active high
|
// Allow defining the polarity of the WAKE output. default is active high
|
||||||
#ifndef GPS_WAKE_ACTIVE
|
#ifndef GPS_WAKE_ACTIVE
|
||||||
#define GPS_WAKE_ACTIVE 1
|
#define GPS_WAKE_ACTIVE 1
|
||||||
@@ -218,6 +344,15 @@ int32_t GPS::runOnce()
|
|||||||
if (whileIdle()) {
|
if (whileIdle()) {
|
||||||
// if we have received valid NMEA claim we are connected
|
// if we have received valid NMEA claim we are connected
|
||||||
setConnected();
|
setConnected();
|
||||||
|
} else {
|
||||||
|
#ifdef GPS_UBLOX
|
||||||
|
// reset the GPS on next bootup
|
||||||
|
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
||||||
|
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||||
|
devicestate.did_gps_reset = false;
|
||||||
|
nodeDB.saveToDisk();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are overdue for an update, turn on the GPS and at least publish the current status
|
// If we are overdue for an update, turn on the GPS and at least publish the current status
|
||||||
@@ -257,7 +392,6 @@ int32_t GPS::runOnce()
|
|||||||
bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime;
|
bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime;
|
||||||
|
|
||||||
// Once we get a location we no longer desperately want an update
|
// Once we get a location we no longer desperately want an update
|
||||||
// or if we got a time and we are in GpsOpTimeOnly mode
|
|
||||||
// DEBUG_MSG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
|
// DEBUG_MSG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
|
||||||
if ((gotLoc && gotTime) || tooLong || (gotTime && getGpsOp() == GpsOperation_GpsOpTimeOnly)) {
|
if ((gotLoc && gotTime) || tooLong || (gotTime && getGpsOp() == GpsOperation_GpsOpTimeOnly)) {
|
||||||
|
|
||||||
@@ -280,7 +414,7 @@ int32_t GPS::runOnce()
|
|||||||
|
|
||||||
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
|
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
|
||||||
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
|
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
|
||||||
return isAwake ? 100 : 5000;
|
return isAwake ? GPS_THREAD_INTERVAL : 5000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPS::forceWake(bool on)
|
void GPS::forceWake(bool on)
|
||||||
@@ -318,13 +452,7 @@ int GPS::prepareDeepSleep(void *unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GPS_TX_PIN
|
#ifndef NO_GPS
|
||||||
#include "UBloxGPS.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAS_AIR530_GPS
|
|
||||||
#include "Air530GPS.h"
|
|
||||||
#elif !defined(NO_GPS)
|
|
||||||
#include "NMEAGPS.h"
|
#include "NMEAGPS.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -339,29 +467,11 @@ 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 {
|
|
||||||
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("Hoping that NMEA might work\n");
|
DEBUG_MSG("Hoping that NMEA might work\n");
|
||||||
#ifdef HAS_AIR530_GPS
|
|
||||||
GPS *new_gps = new Air530GPS();
|
|
||||||
#else
|
|
||||||
GPS *new_gps = new NMEAGPS();
|
GPS *new_gps = new NMEAGPS();
|
||||||
#endif
|
|
||||||
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") {}
|
||||||
@@ -60,6 +57,9 @@ class GPS : private concurrency::OSThread
|
|||||||
/// Returns true if we have acquired GPS lock.
|
/// Returns true if we have acquired GPS lock.
|
||||||
virtual bool hasLock();
|
virtual bool hasLock();
|
||||||
|
|
||||||
|
/// Returns true if there's valid data flow with the chip.
|
||||||
|
virtual bool hasFlow();
|
||||||
|
|
||||||
/// Return true if we are connected to a GPS
|
/// Return true if we are connected to a GPS
|
||||||
bool isConnected() const { return hasGPS; }
|
bool isConnected() const { return hasGPS; }
|
||||||
|
|
||||||
@@ -140,6 +140,8 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
GpsOperation getGpsOp() const;
|
GpsOperation getGpsOp() const;
|
||||||
|
|
||||||
|
bool getACK(uint8_t c, uint8_t i);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell users we have new GPS readings
|
* Tell users we have new GPS readings
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <TinyGPS++.h>
|
#include <TinyGPS++.h>
|
||||||
|
|
||||||
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
|
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
|
||||||
#define GPS_SOL_EXPIRY_MS 300 // in millis
|
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
|
||||||
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
|
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
|
||||||
|
|
||||||
static int32_t toDegInt(RawDegrees d)
|
static int32_t toDegInt(RawDegrees d)
|
||||||
@@ -17,6 +17,19 @@ static int32_t toDegInt(RawDegrees d)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NMEAGPS::factoryReset()
|
||||||
|
{
|
||||||
|
#ifdef GPS_UBLOX
|
||||||
|
// Factory Reset
|
||||||
|
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
|
||||||
|
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||||
|
_serial_gps->write(_message_reset,sizeof(_message_reset));
|
||||||
|
delay(1000);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool NMEAGPS::setupGPS()
|
bool NMEAGPS::setupGPS()
|
||||||
{
|
{
|
||||||
GPS::setupGPS();
|
GPS::setupGPS();
|
||||||
@@ -64,11 +77,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\n", t.tm_sec);
|
if (t.tm_mon > -1){
|
||||||
|
DEBUG_MSG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\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;
|
||||||
}
|
}
|
||||||
@@ -116,7 +130,7 @@ bool NMEAGPS::lookForLocation()
|
|||||||
(reader.time.age() < GPS_SOL_EXPIRY_MS) &&
|
(reader.time.age() < GPS_SOL_EXPIRY_MS) &&
|
||||||
(reader.date.age() < GPS_SOL_EXPIRY_MS)))
|
(reader.date.age() < GPS_SOL_EXPIRY_MS)))
|
||||||
{
|
{
|
||||||
DEBUG_MSG("SOME data is TOO OLD\n");
|
DEBUG_MSG("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +141,17 @@ bool NMEAGPS::lookForLocation()
|
|||||||
// We know the solution is fresh and valid, so just read the data
|
// We know the solution is fresh and valid, so just read the data
|
||||||
auto loc = reader.location.value();
|
auto loc = reader.location.value();
|
||||||
|
|
||||||
// Some GPSes (Air530) seem to send a zero longitude when the current fix is bogus
|
|
||||||
// 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) > 900000000) {
|
||||||
DEBUG_MSG("Ignoring bogus NMEA position\n");
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
|
DEBUG_MSG("Bail out EARLY on LAT %i\n",toDegInt(loc.lat));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (toDegInt(loc.lng) > 1800000000) {
|
||||||
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
|
DEBUG_MSG("Bail out EARLY on LNG %i\n",toDegInt(loc.lng));
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +235,10 @@ bool NMEAGPS::hasLock()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NMEAGPS::hasFlow()
|
||||||
|
{
|
||||||
|
return reader.passedChecksum() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool NMEAGPS::whileIdle()
|
bool NMEAGPS::whileIdle()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ class NMEAGPS : public GPS
|
|||||||
public:
|
public:
|
||||||
virtual bool setupGPS() override;
|
virtual bool setupGPS() override;
|
||||||
|
|
||||||
|
virtual bool factoryReset() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
|
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
|
||||||
*
|
*
|
||||||
@@ -49,4 +51,6 @@ class NMEAGPS : public GPS
|
|||||||
virtual bool lookForLocation() override;
|
virtual bool lookForLocation() override;
|
||||||
|
|
||||||
virtual bool hasLock() override;
|
virtual bool hasLock() override;
|
||||||
|
|
||||||
|
virtual bool hasFlow() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 */ }
|
|
||||||
};
|
|
||||||
11
src/main.cpp
11
src/main.cpp
@@ -226,10 +226,6 @@ class ButtonThread : public OSThread
|
|||||||
|
|
||||||
#ifdef BUTTON_PIN_TOUCH
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
|
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
|
||||||
#ifdef INPUT_PULLUP_SENSE
|
|
||||||
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
|
|
||||||
pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE);
|
|
||||||
#endif
|
|
||||||
userButtonTouch.attachClick(touchPressed);
|
userButtonTouch.attachClick(touchPressed);
|
||||||
userButtonTouch.attachDuringLongPress(touchPressedLong);
|
userButtonTouch.attachDuringLongPress(touchPressedLong);
|
||||||
userButtonTouch.attachDoubleClick(touchDoublePressed);
|
userButtonTouch.attachDoubleClick(touchDoublePressed);
|
||||||
@@ -408,6 +404,12 @@ void setup()
|
|||||||
|
|
||||||
initDeepSleep();
|
initDeepSleep();
|
||||||
|
|
||||||
|
// Testing this fix für erratic T-Echo boot behaviour
|
||||||
|
#if defined(TTGO_T_ECHO) && defined(PIN_EINK_PWR_ON)
|
||||||
|
pinMode(PIN_EINK_PWR_ON, OUTPUT);
|
||||||
|
digitalWrite(PIN_EINK_PWR_ON, HIGH);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VEXT_ENABLE
|
#ifdef VEXT_ENABLE
|
||||||
pinMode(VEXT_ENABLE, OUTPUT);
|
pinMode(VEXT_ENABLE, OUTPUT);
|
||||||
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
||||||
@@ -565,6 +567,7 @@ void setup()
|
|||||||
|
|
||||||
// ONCE we will factory reset the GPS for bug #327
|
// ONCE we will factory reset the GPS for bug #327
|
||||||
if (gps && !devicestate.did_gps_reset) {
|
if (gps && !devicestate.did_gps_reset) {
|
||||||
|
DEBUG_MSG("GPS FactoryReset requested\n");
|
||||||
if (gps->factoryReset()) { // If we don't succeed try again next time
|
if (gps->factoryReset()) { // If we don't succeed try again next time
|
||||||
devicestate.did_gps_reset = true;
|
devicestate.did_gps_reset = true;
|
||||||
nodeDB.saveToDisk();
|
nodeDB.saveToDisk();
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ bool SX126xInterface<T>::init()
|
|||||||
#ifdef SX126X_TXEN
|
#ifdef SX126X_TXEN
|
||||||
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
||||||
if (res == ERR_NONE)
|
if (res == ERR_NONE)
|
||||||
res = lora.setDio2AsRfSwitch(false);
|
res = lora.setDio2AsRfSwitch(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -129,9 +129,6 @@ bool SX126xInterface<T>::reconfigure()
|
|||||||
err = lora.setSyncWord(syncWord);
|
err = lora.setSyncWord(syncWord);
|
||||||
assert(err == ERR_NONE);
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
err = lora.setCurrentLimit(currentLimit);
|
|
||||||
assert(err == ERR_NONE);
|
|
||||||
|
|
||||||
err = lora.setPreambleLength(preambleLength);
|
err = lora.setPreambleLength(preambleLength);
|
||||||
assert(err == ERR_NONE);
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
@@ -139,11 +136,11 @@ bool SX126xInterface<T>::reconfigure()
|
|||||||
if (err != ERR_NONE)
|
if (err != ERR_NONE)
|
||||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||||
|
|
||||||
if (power > 22) // This chip has lower power limits than some
|
if (power > SX126X_MAX_POWER) // This chip has lower power limits than some
|
||||||
power = 22;
|
power = SX126X_MAX_POWER;
|
||||||
err = lora.setOutputPower(power);
|
err = lora.setOutputPower(power);
|
||||||
assert(err == ERR_NONE);
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
startReceive(); // restart receiving
|
startReceive(); // restart receiving
|
||||||
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
@@ -191,7 +188,11 @@ void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void SX126xInterface<T>::configHardwareForSend()
|
void SX126xInterface<T>::configHardwareForSend()
|
||||||
{
|
{
|
||||||
#ifdef SX126X_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
|
// If we have RXEN/TXEN control - turn on TX power / off RX power
|
||||||
|
#ifdef SX126X_RXEN
|
||||||
|
digitalWrite(SX126X_RXEN, LOW);
|
||||||
|
#endif
|
||||||
|
#ifdef SX126X_TXEN
|
||||||
digitalWrite(SX126X_TXEN, HIGH);
|
digitalWrite(SX126X_TXEN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -210,7 +211,11 @@ void SX126xInterface<T>::startReceive()
|
|||||||
|
|
||||||
setStandby();
|
setStandby();
|
||||||
|
|
||||||
#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
|
// If we have RXEN/TXEN control - turn on RX power / off TX power
|
||||||
|
#ifdef SX126X_TXEN
|
||||||
|
digitalWrite(SX126X_TXEN, LOW);
|
||||||
|
#endif
|
||||||
|
#ifdef SX126X_RXEN
|
||||||
digitalWrite(SX126X_RXEN, HIGH);
|
digitalWrite(SX126X_RXEN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ typedef enum _HardwareModel {
|
|||||||
HardwareModel_DIY_V1 = 39,
|
HardwareModel_DIY_V1 = 39,
|
||||||
HardwareModel_RAK11200 = 40,
|
HardwareModel_RAK11200 = 40,
|
||||||
HardwareModel_NANO_G1 = 41,
|
HardwareModel_NANO_G1 = 41,
|
||||||
|
HardwareModel_DR_DEV = 43,
|
||||||
HardwareModel_PRIVATE_HW = 255
|
HardwareModel_PRIVATE_HW = 255
|
||||||
} HardwareModel;
|
} HardwareModel;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ board = wiscore_rak4631
|
|||||||
# add our variants files to the include and src paths
|
# add our variants files to the include and src paths
|
||||||
# define build flags for the TFT_eSPI library
|
# define build flags for the TFT_eSPI library
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_5005
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_5005
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/WisCore_RAK4631_Board>
|
||||||
debug_tool = jlink
|
debug_tool = jlink
|
||||||
|
|
||||||
[env:rak4631_19003]
|
[env:rak4631_19003]
|
||||||
@@ -14,7 +14,7 @@ board = wiscore_rak4631
|
|||||||
# add our variants files to the include and src paths
|
# add our variants files to the include and src paths
|
||||||
# define build flags for the TFT_eSPI library
|
# define build flags for the TFT_eSPI library
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_19003
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_19003
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/WisCore_RAK4631_Board>
|
||||||
debug_tool = jlink
|
debug_tool = jlink
|
||||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||||
;upload_protocol = jlink
|
;upload_protocol = jlink
|
||||||
68
variants/diy/dr-dev/variant.h
Normal file
68
variants/diy/dr-dev/variant.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// For OLED LCD
|
||||||
|
#define I2C_SDA 21
|
||||||
|
#define I2C_SCL 22
|
||||||
|
|
||||||
|
// GPS
|
||||||
|
#undef GPS_RX_PIN
|
||||||
|
#define GPS_RX_PIN NOT_A_PIN
|
||||||
|
|
||||||
|
#define BUTTON_PIN 2 // The middle button GPIO on the T-Beam
|
||||||
|
#define BUTTON_NEED_PULLUP
|
||||||
|
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
|
||||||
|
|
||||||
|
#define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
|
||||||
|
#define LORA_RESET -1 // RST for SX1276, and for SX1262/SX1268
|
||||||
|
#define LORA_DIO1 27 // IRQ for SX1262/SX1268 (IO26 FOR 22S)
|
||||||
|
#define LORA_DIO2 NOT_A_PIN // BUSY for SX1262/SX1268
|
||||||
|
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||||
|
|
||||||
|
// In transmitting, set TXEN as high communication level,RXEN pin is low level;
|
||||||
|
// In receiving, set RXEN as high communication level, TXEN is lowlevel;
|
||||||
|
// Before powering off, set TXEN、RXEN as low level.
|
||||||
|
#define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level
|
||||||
|
#define LORA_TXEN -1 // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
|
||||||
|
/* --PINS FOR THE 900M22S
|
||||||
|
#undef RF95_SCK
|
||||||
|
#define RF95_SCK 18
|
||||||
|
#undef RF95_MISO
|
||||||
|
#define RF95_MISO 19
|
||||||
|
#undef RF95_MOSI
|
||||||
|
#define RF95_MOSI 23
|
||||||
|
#undef RF95_NSS
|
||||||
|
#define RF95_NSS 16
|
||||||
|
*/
|
||||||
|
|
||||||
|
// PINS FOR THE 900M30S
|
||||||
|
#undef RF95_SCK
|
||||||
|
#define RF95_SCK 18
|
||||||
|
#undef RF95_MISO
|
||||||
|
#define RF95_MISO 19
|
||||||
|
#undef RF95_MOSI
|
||||||
|
#define RF95_MOSI 23
|
||||||
|
#undef RF95_NSS
|
||||||
|
#define RF95_NSS 33
|
||||||
|
|
||||||
|
// RX/TX for RFM95/SX127x
|
||||||
|
#define RF95_RXEN LORA_RXEN
|
||||||
|
#define RF95_TXEN LORA_TXEN
|
||||||
|
// #define RF95_TCXO <GPIO#>
|
||||||
|
|
||||||
|
// common pinouts for SX126X modules
|
||||||
|
#define SX126X_CS 33
|
||||||
|
#define SX126X_DIO1 LORA_DIO1
|
||||||
|
#define SX126X_BUSY 35
|
||||||
|
#define SX126X_RESET LORA_RESET
|
||||||
|
#define SX126X_RXEN LORA_RXEN
|
||||||
|
#define SX126X_TXEN LORA_TXEN
|
||||||
|
|
||||||
|
// supported modules list
|
||||||
|
#define USE_RF95 // RFM95/SX127x
|
||||||
|
#define USE_SX1262
|
||||||
|
#define USE_SX1268
|
||||||
|
#define USE_LLCC68
|
||||||
|
|
||||||
|
#ifdef EBYTE_E22
|
||||||
|
// Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch
|
||||||
|
// (which is the default for the sx1262interface code)
|
||||||
|
#define SX126X_E22
|
||||||
|
#endif
|
||||||
@@ -16,4 +16,16 @@ build_flags =
|
|||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D DIY_V1
|
-D DIY_V1
|
||||||
-D EBYTE_E22
|
-D EBYTE_E22
|
||||||
-I variants/diy/v1_1
|
-I variants/diy/v1_1
|
||||||
|
|
||||||
|
; Port to Disaster Radio's ESP32-v3 Dev Board
|
||||||
|
[env:meshtastic-dr-dev]
|
||||||
|
extends = esp32_base
|
||||||
|
board = esp32doit-devkit-v1
|
||||||
|
board_upload.maximum_size = 4194304
|
||||||
|
board_upload.maximum_ram_size = 532480
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D DR_DEV
|
||||||
|
-D EBYTE_E22
|
||||||
|
-I variants/diy/dr-dev
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ board = lora_isp4520
|
|||||||
build_flags = ${nrf52_base.build_flags} -Ivariants/lora_isp4520
|
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.
|
# No screen and GPS on the board. We still need RTC.cpp for the RTC clock.
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/lora_isp4520> -<graphics> -<gps> +<gps/GPS.cpp> +<gps/RTC.cpp>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_isp4520> -<graphics> -<gps> +<gps/GPS.cpp> +<gps/RTC.cpp>
|
||||||
lib_ignore = ${nrf52_base.lib_ignore}
|
lib_ignore = ${nrf52_base.lib_ignore}
|
||||||
ESP8266_SSD1306
|
ESP8266_SSD1306
|
||||||
SparkFun Ublox Arduino Library
|
SparkFun Ublox Arduino Library
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v1
|
|||||||
-DTFT_DC=ST7735_RS
|
-DTFT_DC=ST7735_RS
|
||||||
-DTFT_RST=ST7735_RESET
|
-DTFT_RST=ST7735_RESET
|
||||||
-DSPI_FREQUENCY=27000000
|
-DSPI_FREQUENCY=27000000
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v1>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_relay_v1>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52840_base.lib_deps}
|
${nrf52840_base.lib_deps}
|
||||||
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
|
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v2
|
|||||||
-DSPI_FREQUENCY=27000000
|
-DSPI_FREQUENCY=27000000
|
||||||
-DTFT_WR=ST7735_SDA
|
-DTFT_WR=ST7735_SDA
|
||||||
-DTFT_SCLK=ST7735_SCK
|
-DTFT_SCLK=ST7735_SCK
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v2>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_relay_v2>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52840_base.lib_deps}
|
${nrf52840_base.lib_deps}
|
||||||
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
|
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ extends = nrf52840_base
|
|||||||
board = nrf52840_dk_modified
|
board = nrf52840_dk_modified
|
||||||
# add our variants files to the include and src paths
|
# add our variants files to the include and src paths
|
||||||
build_flags = ${nrf52_base.build_flags} -Ivariants/pca10056-rc-clock
|
build_flags = ${nrf52_base.build_flags} -Ivariants/pca10056-rc-clock
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/pca10056-rc-clock>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/pca10056-rc-clock>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||||
[env:native]
|
[env:native]
|
||||||
platform = https://github.com/geeksville/platform-native.git
|
platform = https://github.com/geeksville/platform-native.git
|
||||||
src_filter =
|
build_src_filter =
|
||||||
${env.src_filter}
|
${env.build_src_filter}
|
||||||
-<esp32/>
|
-<esp32/>
|
||||||
-<nimble/>
|
-<nimble/>
|
||||||
-<nrf52/>
|
-<nrf52/>
|
||||||
@@ -20,8 +20,8 @@ lib_deps =
|
|||||||
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
|
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
|
||||||
[env:linux]
|
[env:linux]
|
||||||
platform = https://github.com/geeksville/platform-native.git
|
platform = https://github.com/geeksville/platform-native.git
|
||||||
src_filter =
|
build_src_filter =
|
||||||
${env.src_filter}
|
${env.build_src_filter}
|
||||||
-<esp32/>
|
-<esp32/>
|
||||||
-<nimble/>
|
-<nimble/>
|
||||||
-<nrf52/>
|
-<nrf52/>
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
extends = nrf52_base
|
extends = nrf52_base
|
||||||
board = ppr1
|
board = ppr1
|
||||||
build_flags = ${nrf52_base.build_flags} -Ivariants/ppr1
|
build_flags = ${nrf52_base.build_flags} -Ivariants/ppr1
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/ppr1>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/ppr1>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
@@ -9,7 +9,7 @@ upload_protocol = jlink
|
|||||||
# -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
|
# -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
|
||||||
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
|
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo
|
||||||
src_filter = ${nrf52_base.src_filter} +<../variants/t-echo>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/t-echo>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52840_base.lib_deps}
|
${nrf52840_base.lib_deps}
|
||||||
https://github.com/geeksville/GxEPD2.git
|
https://github.com/geeksville/GxEPD2.git
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ External serial flash WP25R1635FZUIL0
|
|||||||
#define PIN_SPI1_SCK PIN_EINK_SCLK
|
#define PIN_SPI1_SCK PIN_EINK_SCLK
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Air530 GPS pins
|
* GPS pins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PIN_GPS_WAKE (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
|
#define PIN_GPS_WAKE (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
|
||||||
@@ -235,6 +235,8 @@ External serial flash WP25R1635FZUIL0
|
|||||||
#define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU
|
#define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU
|
||||||
#define PIN_GPS_RX (32 + 8) // This is for bits going TOWARDS the GPS
|
#define PIN_GPS_RX (32 + 8) // This is for bits going TOWARDS the GPS
|
||||||
|
|
||||||
|
#define GPS_THREAD_INTERVAL 50
|
||||||
|
|
||||||
#define PIN_SERIAL1_RX PIN_GPS_TX
|
#define PIN_SERIAL1_RX PIN_GPS_TX
|
||||||
#define PIN_SERIAL1_TX PIN_GPS_RX
|
#define PIN_SERIAL1_TX PIN_GPS_RX
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 1
|
major = 1
|
||||||
minor = 2
|
minor = 2
|
||||||
build = 62
|
build = 65
|
||||||
|
|||||||
Reference in New Issue
Block a user