Compare commits

...

28 Commits
0.2.0 ... 0.2.3

Author SHA1 Message Date
Kevin Hester
e32b41938a Merge pull request #78 from geeksville/master
Fix #77: bluetooth is supposed to be on in DARK state
2020-04-05 14:41:52 -07:00
geeksville
ef395a1596 0.2.3 2020-04-05 14:39:42 -07:00
geeksville
af35f3006c force other devs to update for
fix https://github.com/meshtastic/Meshtastic-esp32/issues/76
2020-04-05 14:13:04 -07:00
geeksville
13ac686c96 minor doc cleanups 2020-04-05 13:58:38 -07:00
geeksville
05a0266fc4 Fix #77: bluetooth is supposed to be on in DARK state 2020-04-05 13:09:46 -07:00
Kevin Hester
3acbf31198 Merge pull request #75 from geeksville/master
fix bugs I noticed while testing a virgin tbeam
2020-04-04 20:55:06 -07:00
geeksville
2e82bf3ca1 Merge remote-tracking branch 'root/master' 2020-04-04 20:51:31 -07:00
geeksville
63e1a3f47e always set time from GPS if we can 2020-04-04 19:16:30 -07:00
geeksville
07a8972aea NEO-6M gps with empty backup batteries give super invalid times 2020-04-04 18:47:41 -07:00
geeksville
d1cb45aa5d string typo 2020-04-04 18:46:19 -07:00
Kevin Hester
1b3610d0fa Merge pull request #74 from geeksville/master
begin cleanup on radio abstraction - so we can support different radio chips and libraries
2020-04-02 08:10:12 -07:00
geeksville
2fcdc2c09f Merge remote-tracking branch 'root/master' 2020-04-01 11:51:15 -07:00
geeksville
da74803ffb begin cleanup on radio abstraction, details below:
* to allow changing to new mesh transport
* to allow a different chipset for the radio
* to allow testing on hardware with a SimRadio
* new "bare" build env for a devboard with virtually no hardware
* make buttons optional
2020-03-31 21:56:35 -07:00
Kevin Hester
890511615f Merge pull request #72 from geeksville/master
kevin's monday bug queue ;-)
2020-03-31 10:40:13 -07:00
geeksville
17de6f9532 fix #73: allow hw-model to be longer (16 bytes including terminator) 2020-03-30 19:58:06 -07:00
Kevin Hester
2a15195c32 Merge branch 'master' into master 2020-03-30 18:52:29 -07:00
geeksville
1b050a6c3d stop distributing the (enormous) elf files in the zip file 2020-03-30 18:51:15 -07:00
geeksville
1da62e5ba1 oops - we were previously not marking these protobuf structs as valid 2020-03-30 17:02:41 -07:00
geeksville
feb6f2e59e extra debug output for radio config, and bump up bax handles for BLE 2020-03-30 17:02:09 -07:00
geeksville
7dabad1b70 don't let phones send down fatally invalid RadioConfig records
and if a phone did in the past, fixup the garbage we saved in flash
2020-03-30 16:10:11 -07:00
geeksville
a73f466473 Add GPL statement 2020-03-30 13:46:46 -07:00
geeksville
1fd92cf8eb fix build for Windows based on tip from @moinars 2020-03-29 12:33:14 -07:00
Kevin Hester
dd671ceca6 Merge pull request #71 from geeksville/master
add OS-X instructions from @android606
2020-03-29 11:50:13 -07:00
geeksville
8a76931b37 add OS-X instructions from @android606 2020-03-29 11:40:18 -07:00
Kevin Hester
b071eecce1 Merge pull request #70 from geeksville/fix68
Fix68
2020-03-29 11:16:15 -07:00
geeksville
81734f75c8 fix review comments (don't let commands queue up if we are missing a display) 2020-03-29 11:13:53 -07:00
geeksville
11d57e721a fix #68 (@girtsf, pls review - ps: no worries ;-) )
// We don't set useDisplay until setup() is called, because some boards have a declaration of this object but the device
// is never found when probing i2c and therefore we don't call setup and never want to do (invalid) accesses to this device.
2020-03-29 11:00:25 -07:00
geeksville
9b0e329bb9 update credits 2020-03-28 20:33:21 -07:00
24 changed files with 350 additions and 128 deletions

View File

@@ -1,4 +1,5 @@
# Meshtastic-esp32 # Meshtastic-esp32
This is the device side code for the [meshtastic.org](https://www.meshtastic.org) project. This is the device side code for the [meshtastic.org](https://www.meshtastic.org) project.
![Continuous Integration](https://github.com/meshtastic/Meshtastic-esp32/workflows/Continuous%20Integration/badge.svg) ![Continuous Integration](https://github.com/meshtastic/Meshtastic-esp32/workflows/Continuous%20Integration/badge.svg)
@@ -18,22 +19,25 @@ This project is currently early-alpha, but if you have questions please [join ou
This software is 100% open source and developed by a group of hobbyist experimenters. No warranty is provided, if you'd like to improve it - we'd love your help. Please post in the chat. This software is 100% open source and developed by a group of hobbyist experimenters. No warranty is provided, if you'd like to improve it - we'd love your help. Please post in the chat.
## Supported hardware ## Supported hardware
We currently support three models of radios. The [TTGO T-Beam](https://www.aliexpress.com/item/4000119152086.html), [TTGO LORA32](https://www.banggood.com/LILYGO-TTGO-LORA32-868Mhz-SX1276-ESP32-Oled-Display-bluetooth-WIFI-Lora-Development-Module-Board-p-1248652.html?cur_warehouse=UK) and the [Heltec LoRa 32](https://heltec.org/project/wifi-lora-32/). Most users should buy the T-Beam and a 18650 battery (total cost less than $35). Make
We currently support three models of radios. The [TTGO T-Beam](https://www.aliexpress.com/item/4000119152086.html), [TTGO LORA32](https://www.banggood.com/LILYGO-TTGO-LORA32-868Mhz-SX1276-ESP32-Oled-Display-bluetooth-WIFI-Lora-Development-Module-Board-p-1248652.html?cur_warehouse=UK) and the [Heltec LoRa 32](https://heltec.org/project/wifi-lora-32/). Most users should buy the T-Beam and a 18650 battery (total cost less than \$35). Make
sure to buy the frequency range which is legal for your country. For the USA, you should buy the 915MHz version. Getting a version that include a screen sure to buy the frequency range which is legal for your country. For the USA, you should buy the 915MHz version. Getting a version that include a screen
is optional, but highly recommended. is optional, but highly recommended.
See (meshtastic.org) for 3D printable cases. See (meshtastic.org) for 3D printable cases.
## Installing the firmware ## Installing the firmware
Prebuilt binaries for the supported radios is available in our [releases](https://github.com/meshtastic/Meshtastic-esp32/releases). Your initial installation has to happen over USB from your Mac, Windows or Linux PC. Once our software is installed, all future software updates happen over bluetooth from your phone. Prebuilt binaries for the supported radios is available in our [releases](https://github.com/meshtastic/Meshtastic-esp32/releases). Your initial installation has to happen over USB from your Mac, Windows or Linux PC. Once our software is installed, all future software updates happen over bluetooth from your phone.
The instructions currently require a few commmand lines, but it should be pretty straightforward. Please post comments on our group chat if you have problems or successes. Steps to install: The instructions currently require a few commmand lines, but it should be pretty straightforward. Please post comments on our group chat if you have problems or successes. Steps to install:
1. Purchase a radio (see above) with the correct frequencies for your country (915MHz for US or JP, 470MHz for CN, 433MHz and 870MHz for EU). 1. Purchase a radio (see above) with the correct frequencies for your country (915MHz for US or JP, 470MHz for CN, 433MHz and 870MHz for EU).
2. Install "pip". Pip is the python package manager we use to get the esptool installer app. Instructions [here](https://www.makeuseof.com/tag/install-pip-for-python/). 2. Install "pip". Pip is the python package manager we use to get the esptool installer app. Instructions [here](https://www.makeuseof.com/tag/install-pip-for-python/). If you are using OS-X, see these [special instructions](docs/software/install-OSX.md).
3. Run "pip install --upgrade esptool" to get esptool installed on your machine 3. Run "pip install --upgrade esptool" to get esptool installed on your machine
4. Connect your radio to your USB port 4. Connect your radio to your USB port
5. Confirm that your device is talking to your PC by running "esptool.py chip_id". The Heltec build also works on the TTGO LORA32 radio. You should see something like: 5. Confirm that your device is talking to your PC by running "esptool.py chip_id". The Heltec build also works on the TTGO LORA32 radio. You should see something like:
``` ```
mydir$ esptool.py chip_id mydir$ esptool.py chip_id
esptool.py v2.6 esptool.py v2.6
@@ -51,12 +55,14 @@ Warning: ESP32 has no Chip ID. Reading MAC instead.
MAC: 24:6f:28:b5:36:71 MAC: 24:6f:28:b5:36:71
Hard resetting via RTS pin... Hard resetting via RTS pin...
``` ```
6. cd into the directory where the release zip file was expanded. 6. cd into the directory where the release zip file was expanded.
7. Install the correct firmware for your board with "device-install.sh firmware-_board_-_country_.bin". For instance "./device-install.sh firmware-HELTEC-US-0.0.3.bin". 7. Install the correct firmware for your board with "device-install.sh firmware-_board_-_country_.bin". For instance "./device-install.sh firmware-HELTEC-US-0.0.3.bin".
Note: If you have previously installed meshtastic, you don't need to run this full script instead just run "esptool.py --baud 921600 write_flash 0x10000 firmware-_board_-_country_.bin". This will be faster, also all of your current preferences will be preserved. Note: If you have previously installed meshtastic, you don't need to run this full script instead just run "esptool.py --baud 921600 write*flash 0x10000 firmware-\_board*-_country_.bin". This will be faster, also all of your current preferences will be preserved.
You should see something like this: You should see something like this:
``` ```
kevinh@kevin-server:~/development/meshtastic/meshtastic-esp32/release/latest$ ./device-install.sh firmware-TBEAM-US-0.1.8.bin kevinh@kevin-server:~/development/meshtastic/meshtastic-esp32/release/latest$ ./device-install.sh firmware-TBEAM-US-0.1.8.bin
Trying to flash firmware-TBEAM-US-0.1.8.bin, but first erasing and writing system information Trying to flash firmware-TBEAM-US-0.1.8.bin, but first erasing and writing system information
@@ -120,10 +126,12 @@ Hash of data verified.
Leaving... Leaving...
Hard resetting via RTS pin... Hard resetting via RTS pin...
``` ```
8. The board will boot and show the Meshtastic logo. 8. The board will boot and show the Meshtastic logo.
9. Please post a comment on our chat so we know if these instructions worked for you ;-). If you find bugs/have-questions post there also - we will be rapidly iterating over the next few weeks. 9. Please post a comment on our chat so we know if these instructions worked for you ;-). If you find bugs/have-questions post there also - we will be rapidly iterating over the next few weeks.
## Meshtastic Android app ## Meshtastic Android app
The source code for the (optional) Meshtastic Android app is [here](https://github.com/meshtastic/Meshtastic-Android). The source code for the (optional) Meshtastic Android app is [here](https://github.com/meshtastic/Meshtastic-Android).
Alpha test builds are current available by opting into our alpha test group. See (www.meshtastic.org) for instructions. Alpha test builds are current available by opting into our alpha test group. See (www.meshtastic.org) for instructions.
@@ -139,10 +147,13 @@ We'd love to have you join us on this merry little project. Please see our [dev
This project is run by volunteers. Past contributors include: This project is run by volunteers. Past contributors include:
* @astro-arphid: Added support for 433MHz radios in europe. - @astro-arphid: Added support for 433MHz radios in europe.
* @claesg: Various documentation fixes and 3D print enclosures - @claesg: Various documentation fixes and 3D print enclosures
* @girtsf: So far our CI system, but soon lots of device improvements - @girtsf: Lots of improvements
- @spattinson: Fixed interrupt handling for the AXP192 part
# IMPORTANT DISCLAIMERS AND FAQ # IMPORTANT DISCLAIMERS AND FAQ
For a listing of currently missing features and a FAQ click [here](docs/faq.md). For a listing of currently missing features and a FAQ click [here](docs/faq.md).
Copyright 2019 Geeksville Industries, LLC. GPL V3 Licensed.

View File

@@ -14,6 +14,9 @@ ARCHIVEDIR=release/archive
rm -f $OUTDIR/firmware* rm -f $OUTDIR/firmware*
mkdir -p $OUTDIR/bins $OUTDIR/elfs
rm -f $OUTDIR/bins/*
# build the named environment and copy the bins to the release directory # build the named environment and copy the bins to the release directory
function do_build { function do_build {
ENV_NAME=$1 ENV_NAME=$1
@@ -22,8 +25,8 @@ function do_build {
SRCELF=.pio/build/$ENV_NAME/firmware.elf SRCELF=.pio/build/$ENV_NAME/firmware.elf
rm -f $SRCBIN rm -f $SRCBIN
pio run --environment $ENV_NAME # -v pio run --environment $ENV_NAME # -v
cp $SRCBIN $OUTDIR/firmware-$ENV_NAME-$COUNTRY-$VERSION.bin cp $SRCBIN $OUTDIR/bins/firmware-$ENV_NAME-$COUNTRY-$VERSION.bin
cp $SRCELF $OUTDIR/firmware-$ENV_NAME-$COUNTRY-$VERSION.elf cp $SRCELF $OUTDIR/elfs/firmware-$ENV_NAME-$COUNTRY-$VERSION.elf
} }
for COUNTRY in $COUNTRIES; do for COUNTRY in $COUNTRIES; do
@@ -41,7 +44,7 @@ for COUNTRY in $COUNTRIES; do
done done
# keep the bins in archive also # keep the bins in archive also
cp $OUTDIR/firmware* $ARCHIVEDIR cp $OUTDIR/bins/firmware* $OUTDIR/elfs/firmware* $ARCHIVEDIR
cat >$OUTDIR/curfirmwareversion.xml <<XML cat >$OUTDIR/curfirmwareversion.xml <<XML
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
@@ -56,6 +59,6 @@ Generated by bin/buildall.sh -->
XML XML
rm -f $ARCHIVEDIR/firmware-$VERSION.zip rm -f $ARCHIVEDIR/firmware-$VERSION.zip
zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $OUTDIR/firmware-*-$VERSION.* images/system-info.bin bin/device-install.sh zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $OUTDIR/bins/firmware-*-$VERSION.* images/system-info.bin bin/device-install.sh
echo BUILT ALL echo BUILT ALL

View File

@@ -1,3 +1,3 @@
export VERSION=0.2.0 export VERSION=0.2.3

View File

@@ -0,0 +1,27 @@
(Here's some quick tips on installing the device code from OS-X, thanks to @android606)
First time using LoRa for anything, just checking it out.
I bought a T-Beam on eBay, followed the instructions to install the firmware here:
[https://github.com/meshtastic/Meshtastic-esp32](https://github.com/meshtastic/Meshtastic-esp32)
I'm using a Mac for this, so that might account for differences in the steps to get it working. I just swapped out my SSD last month, I'm using a pretty fresh install of OS X 10.15.3/Catalina.
I got it working fairly smoothly, but there were two hang-ups I thought I'd mention:
1. I am about 0% familiar with Python, so there were some issues getting esptool.py working. Basically, this OS X comes with Python 2.7 and no pip. Pip installed okay, so I used it to install esptool. Esptool appeared to install correctly, but I couldn't get it to work to save my life. Simply typing "esptool.py" doesn't work, and I just don't know enough python to figure out why. For some reason, it installs but isn't in the \$PATH anywhere, and I don't know where it went. Python 2.7 kept giving me warning messages about being old and unsupported, so I figured that might be a hint that I should upgrade.
I ended up doing this:
- brew install pyenv (to install pyenv)
- pyenv install 3.7.7 (to install and select python 3.7.7)
- pyenv global 3.7.7 (to select the new version of python)
- brew install pip (to install pip3)
- pip3 install --upgrade esptool (note I specifically had to use "pip3", not "pip")
...then I was able to execute esptool.py
2. esptool.py didn't work though, because the virtual com port wasn't showing up as a device. I had to install a driver from Silicon Labs, which I got here:
[driver for the CP210X USB to UART bridge from Silicon Labs](https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers)
After I installed that, esptool.py was completely happy and the firmware loaded right up.

View File

@@ -34,13 +34,15 @@ build_flags = -Wall -Wextra -Wno-missing-field-initializers -Isrc -Os -Wl,-Map,.
; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG ; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; leave this commented out to avoid breaking Windows
;upload_port = /dev/ttyUSB0
;monitor_port = /dev/ttyUSB0
upload_speed = 921600 upload_speed = 921600
upload_port = /dev/ttyUSB0
; the default is esptool ; the default is esptool
; upload_protocol = esp-prog ; upload_protocol = esp-prog
monitor_port = /dev/ttyUSB0
monitor_speed = 115200 monitor_speed = 115200
# debug_tool = esp-prog # debug_tool = esp-prog
@@ -58,7 +60,7 @@ debug_tool = jlink
debug_init_break = tbreak setup debug_init_break = tbreak setup
lib_deps = lib_deps =
https://github.com/meshtastic/RadioHead.git https://github.com/meshtastic/RadioHead.git#a87518beacfff53bc2eec5ae33c607713e9596e6
https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306 https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306
AXP202X_Library AXP202X_Library
SPI SPI
@@ -97,3 +99,10 @@ build_flags =
board = ttgo-lora32-v1 board = ttgo-lora32-v1
build_flags = build_flags =
${env.build_flags} -D TTGO_LORA_V2 ${env.build_flags} -D TTGO_LORA_V2
; This is a temporary build target to test turning off particular hardare bits in the build (to improve modularity)
[env:bare]
board = ttgo-lora32-v1
build_flags =
${env.build_flags} -D BARE_BOARD

2
proto

Submodule proto updated: 1b2449b50d...d13d741a98

View File

@@ -5,12 +5,14 @@
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.h> #include <pb_encode.h>
#ifdef RF95_IRQ_GPIO
/// A temporary buffer used for sending/receving packets, sized to hold the biggest buffer we might need /// A temporary buffer used for sending/receving packets, sized to hold the biggest buffer we might need
#define MAX_RHPACKETLEN 251 #define MAX_RHPACKETLEN 251
static uint8_t radiobuf[MAX_RHPACKETLEN]; static uint8_t radiobuf[MAX_RHPACKETLEN];
CustomRF95::CustomRF95(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest) CustomRF95::CustomRF95(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest)
: RH_RF95(NSS_GPIO, DIO0_GPIO), pool(_pool), rxDest(_rxDest), txQueue(MAX_TX_QUEUE), sendingPacket(NULL) : RH_RF95(NSS_GPIO, RF95_IRQ_GPIO), RadioInterface(_pool, _rxDest), txQueue(MAX_TX_QUEUE)
{ {
} }
@@ -173,3 +175,5 @@ void CustomRF95::startSend(MeshPacket *txp)
int res = RH_RF95::send(radiobuf, numbytes); int res = RH_RF95::send(radiobuf, numbytes);
assert(res); assert(res);
} }
#endif

View File

@@ -1,8 +1,6 @@
#pragma once #pragma once
#include "MemoryPool.h" #include "RadioInterface.h"
#include "MeshTypes.h"
#include "PointerQueue.h"
#include "mesh.pb.h" #include "mesh.pb.h"
#include <RHMesh.h> #include <RHMesh.h>
#include <RH_RF95.h> #include <RH_RF95.h>
@@ -12,15 +10,12 @@
/** /**
* A version of the RF95 driver which is smart enough to manage packets via queues (no polling or blocking in user threads!) * A version of the RF95 driver which is smart enough to manage packets via queues (no polling or blocking in user threads!)
*/ */
class CustomRF95 : public RH_RF95 class CustomRF95 : public RH_RF95, public RadioInterface
{ {
friend class MeshRadio; // for debugging we let that class touch pool friend class MeshRadio; // for debugging we let that class touch pool
MemoryPool<MeshPacket> &pool;
PointerQueue<MeshPacket> &rxDest;
PointerQueue<MeshPacket> txQueue; PointerQueue<MeshPacket> txQueue;
MeshPacket *sendingPacket; // The packet we are currently sending
public: public:
/** pool is the pool we will alloc our rx packets from /** pool is the pool we will alloc our rx packets from
* rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool * rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool

View File

@@ -6,8 +6,7 @@
HardwareSerial _serial_gps(GPS_SERIAL_NUM); HardwareSerial _serial_gps(GPS_SERIAL_NUM);
RTC_DATA_ATTR bool timeSetFromGPS; // We only reset our time once per _boot_ after that point just run from the internal clock bool timeSetFromGPS; // We try to set our time from GPS each time we wake from sleep
// (even across sleeps)
GPS gps; GPS gps;
@@ -176,7 +175,9 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
tv.tv_usec = 0; // time.centisecond() * (10 / 1000); tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec); DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
if (t.tm_year < 0 || t.tm_year >= 300)
DEBUG_MSG("Ignoring invalid GPS time\n");
else
perhapsSetRTC(&tv); perhapsSetRTC(&tv);
} }

View File

@@ -106,12 +106,13 @@ class RadioCharacteristic : public ProtobufCharacteristic
void onRead(BLECharacteristic *c) void onRead(BLECharacteristic *c)
{ {
DEBUG_MSG("Reading radio config\n"); DEBUG_MSG("Reading radio config, sdsecs %u\n", radioConfig.preferences.sds_secs);
ProtobufCharacteristic::onRead(c); ProtobufCharacteristic::onRead(c);
} }
void onWrite(BLECharacteristic *c) void onWrite(BLECharacteristic *c)
{ {
DEBUG_MSG("Writing radio config\n");
ProtobufCharacteristic::onWrite(c); ProtobufCharacteristic::onWrite(c);
service.reloadConfig(); service.reloadConfig();
} }
@@ -263,7 +264,7 @@ See bluetooth-api.md for documentation.
BLEService *createMeshBluetoothService(BLEServer *server) BLEService *createMeshBluetoothService(BLEServer *server)
{ {
// Create the BLE Service, we need more than the default of 15 handles // Create the BLE Service, we need more than the default of 15 handles
BLEService *service = server->createService(BLEUUID("6ba1b218-15a8-461f-9fa8-5dcae273eafd"), 25, 0); BLEService *service = server->createService(BLEUUID("6ba1b218-15a8-461f-9fa8-5dcae273eafd"), 30, 0);
assert(!meshFromNumCharacteristic); assert(!meshFromNumCharacteristic);
meshFromNumCharacteristic = new FromNumCharacteristic; meshFromNumCharacteristic = new FromNumCharacteristic;

View File

@@ -10,10 +10,6 @@
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.h> #include <pb_encode.h>
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on
static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf};
/** /**
* ## LoRaWAN for North America * ## LoRaWAN for North America
@@ -28,18 +24,11 @@ separated by 2.16 MHz with respect to the adjacent channels. Channel zero starts
/// Sometimes while debugging it is useful to set this false, to disable rf95 accesses /// Sometimes while debugging it is useful to set this false, to disable rf95 accesses
bool useHardware = true; bool useHardware = true;
MeshRadio::MeshRadio(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest) : rf95(_pool, _rxDest), manager(rf95) MeshRadio::MeshRadio(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest)
: radioIf(_pool, _rxDest) // , manager(radioIf)
{ {
myNodeInfo.num_channels = NUM_CHANNELS; myNodeInfo.num_channels = NUM_CHANNELS;
// radioConfig.modem_config = RadioConfig_ModemConfig_Bw125Cr45Sf128; // medium range and fast
// channelSettings.modem_config = ChannelSettings_ModemConfig_Bw500Cr45Sf128; // short range and fast, but wide bandwidth so
// incompatible radios can talk together
channelSettings.modem_config = ChannelSettings_ModemConfig_Bw125Cr48Sf4096; // slow and long range
channelSettings.tx_power = 23;
memcpy(&channelSettings.psk, &defaultpsk, sizeof(channelSettings.psk));
strcpy(channelSettings.name, "Default");
// Can't print strings this early - serial not setup yet // Can't print strings this early - serial not setup yet
// DEBUG_MSG("Set meshradio defaults name=%s\n", channelSettings.name); // DEBUG_MSG("Set meshradio defaults name=%s\n", channelSettings.name);
} }
@@ -62,10 +51,10 @@ bool MeshRadio::init()
delay(10); delay(10);
#endif #endif
manager.setThisAddress( radioIf.setThisAddress(
nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor time. nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor time.
if (!manager.init()) { if (!radioIf.init()) {
DEBUG_MSG("LoRa radio init failed\n"); DEBUG_MSG("LoRa radio init failed\n");
DEBUG_MSG("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info\n"); DEBUG_MSG("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info\n");
return false; return false;
@@ -97,11 +86,11 @@ unsigned long hash(char *str)
void MeshRadio::reloadConfig() void MeshRadio::reloadConfig()
{ {
rf95.setModeIdle(); // Need to be idle before doing init radioIf.setModeIdle(); // Need to be idle before doing init
// Set up default configuration // Set up default configuration
// No Sync Words in LORA mode. // No Sync Words in LORA mode.
rf95.setModemConfig( radioIf.setModemConfig(
(RH_RF95::ModemConfigChoice)channelSettings.modem_config); // Radio default (RH_RF95::ModemConfigChoice)channelSettings.modem_config); // Radio default
// setModemConfig(Bw125Cr48Sf4096); // slow and reliable? // setModemConfig(Bw125Cr48Sf4096); // slow and reliable?
// rf95.setPreambleLength(8); // Default is 8 // rf95.setPreambleLength(8); // Default is 8
@@ -109,7 +98,7 @@ void MeshRadio::reloadConfig()
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
int channel_num = hash(channelSettings.name) % NUM_CHANNELS; int channel_num = hash(channelSettings.name) % NUM_CHANNELS;
float center_freq = CH0 + CH_SPACING * channel_num; float center_freq = CH0 + CH_SPACING * channel_num;
if (!rf95.setFrequency(center_freq)) { if (!radioIf.setFrequency(center_freq)) {
DEBUG_MSG("setFrequency failed\n"); DEBUG_MSG("setFrequency failed\n");
assert(0); // fixme panic assert(0); // fixme panic
} }
@@ -120,13 +109,13 @@ void MeshRadio::reloadConfig()
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm: // you can set transmitter powers from 5 to 23 dBm:
// FIXME - can we do this? It seems to be in the Heltec board. // FIXME - can we do this? It seems to be in the Heltec board.
rf95.setTxPower(channelSettings.tx_power, false); radioIf.setTxPower(channelSettings.tx_power, false);
DEBUG_MSG("Set radio: name=%s. config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config, DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config,
channel_num, channelSettings.tx_power); channel_num, channelSettings.tx_power);
// Done with init tell radio to start receiving // Done with init tell radio to start receiving
rf95.setModeRx(); radioIf.setModeRx();
} }
ErrorCode MeshRadio::send(MeshPacket *p) ErrorCode MeshRadio::send(MeshPacket *p)
@@ -134,9 +123,9 @@ ErrorCode MeshRadio::send(MeshPacket *p)
lastTxStart = millis(); lastTxStart = millis();
if (useHardware) if (useHardware)
return rf95.send(p); return radioIf.send(p);
else { else {
rf95.pool.release(p); radioIf.pool.release(p);
return ERRNO_OK; return ERRNO_OK;
} }
} }
@@ -148,12 +137,12 @@ void MeshRadio::loop()
// It should never take us more than 30 secs to send a packet, if it does, we have a bug, FIXME, move most of this // It should never take us more than 30 secs to send a packet, if it does, we have a bug, FIXME, move most of this
// into CustomRF95 // into CustomRF95
uint32_t now = millis(); uint32_t now = millis();
if (lastTxStart != 0 && (now - lastTxStart) > TX_WATCHDOG_TIMEOUT && rf95.mode() == RHGenericDriver::RHModeTx) { if (lastTxStart != 0 && (now - lastTxStart) > TX_WATCHDOG_TIMEOUT && radioIf.mode() == RHGenericDriver::RHModeTx) {
DEBUG_MSG("ERROR! Bug! Tx packet took too long to send, forcing radio into rx mode"); DEBUG_MSG("ERROR! Bug! Tx packet took too long to send, forcing radio into rx mode\n");
rf95.setModeRx(); radioIf.setModeRx();
if (rf95.sendingPacket) { // There was probably a packet we were trying to send, free it if (radioIf.sendingPacket) { // There was probably a packet we were trying to send, free it
rf95.pool.release(rf95.sendingPacket); radioIf.pool.release(radioIf.sendingPacket);
rf95.sendingPacket = NULL; radioIf.sendingPacket = NULL;
} }
recordCriticalError(ErrTxWatchdog); recordCriticalError(ErrTxWatchdog);
lastTxStart = 0; // Stop checking for now, because we just warned the developer lastTxStart = 0; // Stop checking for now, because we just warned the developer

View File

@@ -64,8 +64,14 @@
class MeshRadio class MeshRadio
{ {
public: public:
// Kinda ugly way of selecting different radio implementations, but soon this MeshRadio class will be going away
// entirely. At that point we can make things pretty.
#ifdef RF95_IRQ_GPIO
CustomRF95 CustomRF95
rf95; // the raw radio interface - for now I'm leaving public - because this class is shrinking to be almost nothing radioIf; // the raw radio interface - for now I'm leaving public - because this class is shrinking to be almost nothing
#else
SimRadio radioIf;
#endif
/** pool is the pool we will alloc our rx packets from /** pool is the pool we will alloc our rx packets from
* rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool * rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool
@@ -88,14 +94,8 @@ class MeshRadio
private: private:
// RHReliableDatagram manager; // don't use mesh yet // RHReliableDatagram manager; // don't use mesh yet
RHMesh manager; // RHMesh manager;
/// Used for the tx timer watchdog, to check for bugs in our transmit code, msec of last time we did a send /// Used for the tx timer watchdog, to check for bugs in our transmit code, msec of last time we did a send
uint32_t lastTxStart = 0; uint32_t lastTxStart = 0;
/// low level send, might block for mutiple seconds
ErrorCode sendTo(NodeNum dest, const uint8_t *buf, size_t len);
/// enqueue a received packet in rxDest
void handleReceive(MeshPacket *p);
}; };

View File

@@ -97,7 +97,7 @@ MeshPacket *MeshService::handleFromRadioUser(MeshPacket *mp)
if (weWin) { if (weWin) {
DEBUG_MSG("NOTE! Received a nodenum collision and we are vetoing\n"); DEBUG_MSG("NOTE! Received a nodenum collision and we are vetoing\n");
packetPool.release(mp); // discard it releaseToPool(mp); // discard it
mp = NULL; mp = NULL;
sendOurOwner(); // send our owner as a _broadcast_ because that other guy is mistakenly using our nodenum sendOurOwner(); // send our owner as a _broadcast_ because that other guy is mistakenly using our nodenum
@@ -178,8 +178,9 @@ void MeshService::handleFromRadio(MeshPacket *mp)
if (mp->payload.want_response) if (mp->payload.want_response)
sendNetworkPing(mp->from); sendNetworkPing(mp->from);
} else } else {
DEBUG_MSG("Dropping vetoed User message\n"); DEBUG_MSG("Not delivering vetoed User message\n");
}
} }
void MeshService::handleFromRadio() void MeshService::handleFromRadio()
@@ -217,6 +218,7 @@ void MeshService::loop()
void MeshService::reloadConfig() void MeshService::reloadConfig()
{ {
// If we can successfully set this radio to these settings, save them to disk // If we can successfully set this radio to these settings, save them to disk
nodeDB.resetRadioConfig(); // Don't let the phone send us fatally bad settings
radio.reloadConfig(); radio.reloadConfig();
nodeDB.saveToDisk(); nodeDB.saveToDisk();
} }

View File

@@ -83,7 +83,7 @@ class MeshService : private Observer
/// handle all the packets that just arrived from the mesh radio /// handle all the packets that just arrived from the mesh radio
void handleFromRadio(); void handleFromRadio();
/// Handle a packet that just arrived from the radio /// Handle a packet that just arrived from the radio. We will either eventually enqueue the message to the phone or return it to the free pool
void handleFromRadio(MeshPacket *p); void handleFromRadio(MeshPacket *p);
/// handle a user packet that just arrived on the radio, return NULL if we should not process this packet at all /// handle a user packet that just arrived on the radio, return NULL if we should not process this packet at all

View File

@@ -44,9 +44,39 @@ static uint8_t ourMacAddr[6];
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {} NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
void NodeDB::resetRadioConfig()
{
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on
static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf};
if (radioConfig.preferences.sds_secs == 0) {
DEBUG_MSG("RadioConfig reset!\n");
radioConfig.preferences.send_owner_interval = 4; // per sw-design.md
radioConfig.preferences.position_broadcast_secs = 15 * 60;
radioConfig.preferences.wait_bluetooth_secs = 120;
radioConfig.preferences.screen_on_secs = 30;
radioConfig.preferences.mesh_sds_timeout_secs = 2 * 60 * 60;
radioConfig.preferences.phone_sds_timeout_sec = 2 * 60 * 60;
radioConfig.preferences.sds_secs = 365 * 24 * 60 * 60; // one year
radioConfig.preferences.ls_secs = 60 * 60;
radioConfig.preferences.phone_timeout_secs = 15 * 60;
radioConfig.has_channel_settings = true;
radioConfig.has_preferences = true;
// radioConfig.modem_config = RadioConfig_ModemConfig_Bw125Cr45Sf128; // medium range and fast
// channelSettings.modem_config = ChannelSettings_ModemConfig_Bw500Cr45Sf128; // short range and fast, but wide bandwidth
// so incompatible radios can talk together
channelSettings.modem_config = ChannelSettings_ModemConfig_Bw125Cr48Sf4096; // slow and long range
channelSettings.tx_power = 23;
memcpy(&channelSettings.psk, &defaultpsk, sizeof(channelSettings.psk));
strcpy(channelSettings.name, "Default");
}
}
void NodeDB::init() void NodeDB::init()
{ {
// init our devicestate with valid flags so protobuf writing/reading will work // init our devicestate with valid flags so protobuf writing/reading will work
devicestate.has_my_node = true; devicestate.has_my_node = true;
devicestate.has_radio = true; devicestate.has_radio = true;
@@ -57,15 +87,7 @@ void NodeDB::init()
devicestate.node_db_count = 0; devicestate.node_db_count = 0;
devicestate.receive_queue_count = 0; devicestate.receive_queue_count = 0;
radioConfig.preferences.send_owner_interval = 4; // per sw-design.md resetRadioConfig();
radioConfig.preferences.position_broadcast_secs = 15 * 60;
radioConfig.preferences.wait_bluetooth_secs = 120;
radioConfig.preferences.screen_on_secs = 30;
radioConfig.preferences.mesh_sds_timeout_secs = 2 * 60 * 60;
radioConfig.preferences.phone_sds_timeout_sec = 2 * 60 * 60;
radioConfig.preferences.sds_secs = 365 * 24 * 60 * 60; // one year
radioConfig.preferences.ls_secs = 60 * 60;
radioConfig.preferences.phone_timeout_secs = 15 * 60;
// default to no GPS, until one has been found by probing // default to no GPS, until one has been found by probing
myNodeInfo.has_gps = false; myNodeInfo.has_gps = false;
@@ -102,6 +124,7 @@ void NodeDB::init()
// saveToDisk(); // saveToDisk();
loadFromDisk(); loadFromDisk();
resetRadioConfig(); // If bogus settings got saved, then fix them
DEBUG_MSG("NODENUM=0x%x, dbsize=%d\n", myNodeInfo.my_node_num, *numNodes); DEBUG_MSG("NODENUM=0x%x, dbsize=%d\n", myNodeInfo.my_node_num, *numNodes);
} }

View File

@@ -43,6 +43,9 @@ class NodeDB
/// write to flash /// write to flash
void saveToDisk(); void saveToDisk();
// Reinit radio config if needed, because sometimes a buggy android app might send us bogus settings
void resetRadioConfig();
/// given a subpacket sniffed from the network, update our DB state /// given a subpacket sniffed from the network, update our DB state
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw /// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
void updateFrom(const MeshPacket &p); void updateFrom(const MeshPacket &p);

View File

@@ -31,7 +31,7 @@ static void lsEnter()
screen.setOn(false); screen.setOn(false);
uint32_t now = millis(); uint32_t now = millis();
while (!service.radio.rf95.canSleep()) { while (!service.radio.radioIf.canSleep()) {
delay(10); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives) delay(10); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives)
if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep
@@ -82,7 +82,12 @@ static void lsIdle()
} else { } else {
DEBUG_MSG("wakeCause %d\n", wakeCause); DEBUG_MSG("wakeCause %d\n", wakeCause);
if (!digitalRead(BUTTON_PIN)) // If we woke because of press, instead generate a PRESS event. #ifdef BUTTON_PIN
bool pressed = !digitalRead(BUTTON_PIN);
#else
bool pressed = false;
#endif
if (pressed) // If we woke because of press, instead generate a PRESS event.
{ {
powerFSM.trigger(EVENT_PRESS); powerFSM.trigger(EVENT_PRESS);
} else { } else {
@@ -108,6 +113,7 @@ static void nbEnter()
static void darkEnter() static void darkEnter()
{ {
setBluetoothEnable(true);
screen.setOn(false); screen.setOn(false);
} }

15
src/RadioInterface.cpp Normal file
View File

@@ -0,0 +1,15 @@
#include "CustomRF95.h"
#include "NodeDB.h"
#include "assert.h"
#include "configuration.h"
#include <pb_decode.h>
#include <pb_encode.h>
RadioInterface::RadioInterface(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest) : pool(_pool), rxDest(_rxDest) {}
ErrorCode SimRadio::send(MeshPacket *p)
{
DEBUG_MSG("SimRadio.send\n");
pool.release(p);
return ERRNO_OK;
}

123
src/RadioInterface.h Normal file
View File

@@ -0,0 +1,123 @@
#pragma once
#include "MemoryPool.h"
#include "MeshTypes.h"
#include "PointerQueue.h"
#include "mesh.pb.h"
#include <RH_RF95.h>
#define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission
/**
* Basic operations all radio chipsets must implement.
*
* This defines the SOLE API for talking to radios (because soon we will have alternate radio implementations)
*/
class RadioInterface
{
friend class MeshRadio; // for debugging we let that class touch pool
protected:
MemoryPool<MeshPacket> &pool;
PointerQueue<MeshPacket> &rxDest;
MeshPacket *sendingPacket = NULL; // The packet we are currently sending
public:
/** pool is the pool we will alloc our rx packets from
* rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool
*/
RadioInterface(MemoryPool<MeshPacket> &pool, PointerQueue<MeshPacket> &rxDest);
/**
* Return true if we think the board can go to sleep (i.e. our tx queue is empty, we are not sending or receiving)
*
* This method must be used before putting the CPU into deep or light sleep.
*/
virtual bool canSleep() { return true; }
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
/// return true for success
virtual bool sleep() { return true; }
/// Send a packet (possibly by enquing in a private fifo). This routine will
/// later free() the packet to pool. This routine is not allowed to stall because it is called from
/// bluetooth comms code. If the txmit queue is empty it might return an error
virtual ErrorCode send(MeshPacket *p) = 0;
};
class SimRadio : public RadioInterface
{
public:
/** pool is the pool we will alloc our rx packets from
* rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool
*/
SimRadio(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest) : RadioInterface(_pool, _rxDest) {}
virtual ErrorCode send(MeshPacket *p);
// methods from radiohead
/// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.
/// This will be used to test the adddress in incoming messages. In non-promiscuous mode,
/// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.
/// In promiscuous mode, all messages will be accepted regardless of the TO header.
/// In a conventional multinode system, all nodes will have a unique address
/// (which you could store in EEPROM).
/// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,
/// allowing the possibilty of address spoofing).
/// \param[in] thisAddress The address of this node.
virtual void setThisAddress(uint8_t thisAddress) {}
/// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded.
virtual bool init() { return true; }
/// Sets the transmitter and receiver
/// centre frequency.
/// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several
/// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
/// \return true if the selected frquency centre is within range
bool setFrequency(float centre) { return true; }
/// Select one of the predefined modem configurations. If you need a modem configuration not provided
/// here, use setModemRegisters() with your own ModemConfig.
/// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator
/// for reliable operation.
/// \param[in] index The configuration choice.
/// \return true if index is a valid choice.
bool setModemConfig(RH_RF95::ModemConfigChoice index) { return true; }
/// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
/// disables them.
void setModeIdle() {}
/// If current mode is Tx or Idle, changes it to Rx.
/// Starts the receiver in the RF95/96/97/98.
void setModeRx() {}
/// Returns the operating mode of the library.
/// \return the current mode, one of RF69_MODE_*
virtual RHGenericDriver::RHMode mode() { return RHGenericDriver::RHModeIdle; }
/// Sets the transmitter power output level, and configures the transmitter pin.
/// Be a good neighbour and set the lowest power level you need.
/// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98)
/// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC)
/// while some (such as the Modtronix inAir4 and inAir9)
/// use the RFO transmitter pin for lower power but higher efficiency.
/// You must set the appropriate power level and useRFO argument for your module.
/// Check with your module manufacturer which transmtter pin is used on your module
/// to ensure you are setting useRFO correctly.
/// Failure to do so will result in very low
/// transmitter power output.
/// Caution: legal power limits may apply in certain countries.
/// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled).
/// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false,
/// valid values are from +5 to +23.
/// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use),
/// valid values are from -1 to 14.
/// \param[in] useRFO If true, enables the use of the RFO transmitter pins instead of
/// the PA_BOOST pin (false). Choose the correct setting for your module.
void setTxPower(int8_t power, bool useRFO = false) {}
};

View File

@@ -110,7 +110,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef USE_JTAG #ifndef USE_JTAG
#define RESET_GPIO 14 #define RESET_GPIO 14
#endif #endif
#define DIO0_GPIO 26 #define RF95_IRQ_GPIO 26
#define DIO1_GPIO 33 // Note: not really used on this board #define DIO1_GPIO 33 // Note: not really used on this board
#define DIO2_GPIO 32 // Note: not really used on this board #define DIO2_GPIO 32 // Note: not really used on this board
@@ -131,7 +131,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef USE_JTAG #ifndef USE_JTAG
#define RESET_GPIO 23 #define RESET_GPIO 23
#endif #endif
#define DIO0_GPIO 26 #define RF95_IRQ_GPIO 26
#define DIO1_GPIO 33 // Note: not really used on this board #define DIO1_GPIO 33 // Note: not really used on this board
#define DIO2_GPIO 32 // Note: not really used on this board #define DIO2_GPIO 32 // Note: not really used on this board
@@ -159,7 +159,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef USE_JTAG #ifndef USE_JTAG
#define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio #define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio
#endif #endif
#define DIO0_GPIO 26 #define RF95_IRQ_GPIO 26
#define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number #define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
#define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number #define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
#elif defined(TTGO_LORA_V1) #elif defined(TTGO_LORA_V1)
@@ -176,7 +176,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define BUTTON_PIN 0 // If defined, this will be used for user button presses #define BUTTON_PIN 0 // If defined, this will be used for user button presses
#define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio #define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio
#define DIO0_GPIO 26 // IRQ line for the LORA radio #define RF95_IRQ_GPIO 26 // IRQ line for the LORA radio
#define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number #define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
#define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number #define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
#elif defined(TTGO_LORA_V2) #elif defined(TTGO_LORA_V2)
@@ -195,9 +195,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// between this pin and ground // between this pin and ground
#define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio #define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio
#define DIO0_GPIO 26 // IRQ line for the LORA radio #define RF95_IRQ_GPIO 26 // IRQ line for the LORA radio
#define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number #define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
#define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number #define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
#elif defined(BARE_BOARD)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR "bare"
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -50,7 +50,7 @@ typedef struct _MyNodeInfo {
bool has_gps; bool has_gps;
int32_t num_channels; int32_t num_channels;
char region[12]; char region[12];
char hw_model[12]; char hw_model[16];
char firmware_version[12]; char firmware_version[12];
uint32_t error_code; uint32_t error_code;
uint32_t error_address; uint32_t error_address;
@@ -431,8 +431,8 @@ extern const pb_msgdesc_t ToRadio_msg;
#define RadioConfig_size 120 #define RadioConfig_size 120
#define RadioConfig_UserPreferences_size 72 #define RadioConfig_UserPreferences_size 72
#define NodeInfo_size 155 #define NodeInfo_size 155
#define MyNodeInfo_size 81 #define MyNodeInfo_size 85
#define DeviceState_size 15076 #define DeviceState_size 15080
#define FromRadio_size 301 #define FromRadio_size 301
#define ToRadio_size 295 #define ToRadio_size 295

View File

@@ -401,10 +401,7 @@ void _screen_header()
} }
#endif #endif
Screen::Screen(uint8_t address, uint8_t sda, uint8_t scl) Screen::Screen(uint8_t address, uint8_t sda, uint8_t scl) : cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev) {}
: cmdQueue(32), useDisplay(sda || scl), dispdev(address, sda, scl), ui(&dispdev)
{
}
void Screen::handleSetOn(bool on) void Screen::handleSetOn(bool on)
{ {
@@ -425,8 +422,9 @@ void Screen::handleSetOn(bool on)
void Screen::setup() void Screen::setup()
{ {
if (!useDisplay) // We don't set useDisplay until setup() is called, because some boards have a declaration of this object but the device
return; // is never found when probing i2c and therefore we don't call setup and never want to do (invalid) accesses to this device.
useDisplay = true;
dispdev.resetOrientation(); dispdev.resetOrientation();

View File

@@ -169,10 +169,14 @@ class Screen : public PeriodicTask
/// Enques given command item to be processed by main loop(). /// Enques given command item to be processed by main loop().
bool enqueueCmd(const CmdItem &cmd) bool enqueueCmd(const CmdItem &cmd)
{ {
if (!useDisplay)
return true; // claim success if our display is not in use
else {
bool success = cmdQueue.enqueue(cmd, 0); bool success = cmdQueue.enqueue(cmd, 0);
setPeriod(1); // handle ASAP setPeriod(1); // handle ASAP
return success; return success;
} }
}
// Implementations of various commands, called from doTask(). // Implementations of various commands, called from doTask().
void handleSetOn(bool on); void handleSetOn(bool on);

View File

@@ -110,7 +110,7 @@ void doDeepSleep(uint64_t msecToWake)
screen.setOn(false); // datasheet says this will draw only 10ua screen.setOn(false); // datasheet says this will draw only 10ua
// Put radio in sleep mode (will still draw power but only 0.2uA) // Put radio in sleep mode (will still draw power but only 0.2uA)
service.radio.rf95.sleep(); service.radio.radioIf.sleep();
nodeDB.saveToDisk(); nodeDB.saveToDisk();
@@ -213,8 +213,12 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
gpio_pullup_en((gpio_num_t)BUTTON_PIN); gpio_pullup_en((gpio_num_t)BUTTON_PIN);
#endif #endif
#ifdef BUTTON_PIN
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); // when user presses, this button goes low gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); // when user presses, this button goes low
gpio_wakeup_enable((gpio_num_t)DIO0_GPIO, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high #endif
#ifdef RF95_IRQ_GPIO
gpio_wakeup_enable((gpio_num_t)RF95_IRQ_GPIO, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
#endif
#ifdef PMU_IRQ #ifdef PMU_IRQ
// FIXME, disable wake due to PMU because it seems to fire all the time? // FIXME, disable wake due to PMU because it seems to fire all the time?
if (axp192_found) if (axp192_found)
@@ -223,7 +227,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
assert(esp_sleep_enable_gpio_wakeup() == ESP_OK); assert(esp_sleep_enable_gpio_wakeup() == ESP_OK);
assert(esp_sleep_enable_timer_wakeup(sleepUsec) == ESP_OK); assert(esp_sleep_enable_timer_wakeup(sleepUsec) == ESP_OK);
assert(esp_light_sleep_start() == ESP_OK); assert(esp_light_sleep_start() == ESP_OK);
// DEBUG_MSG("Exit light sleep b=%d, rf95=%d, pmu=%d\n", digitalRead(BUTTON_PIN), digitalRead(DIO0_GPIO), // DEBUG_MSG("Exit light sleep b=%d, rf95=%d, pmu=%d\n", digitalRead(BUTTON_PIN), digitalRead(RF95_IRQ_GPIO),
// digitalRead(PMU_IRQ)); // digitalRead(PMU_IRQ));
return esp_sleep_get_wakeup_cause(); return esp_sleep_get_wakeup_cause();
} }