mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-10 11:57:25 +00:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7beec4728 | ||
|
|
ccf3450864 | ||
|
|
86553a4fc9 | ||
|
|
55349ea570 | ||
|
|
486b03e985 | ||
|
|
ccb232b6ac | ||
|
|
e7af338c31 | ||
|
|
9069e5b33e | ||
|
|
399fbc5d65 | ||
|
|
48b38ed94b | ||
|
|
c0444ef16f | ||
|
|
1719a8e764 | ||
|
|
092af0f9f9 | ||
|
|
133a7ff166 | ||
|
|
5df08410e7 | ||
|
|
9f9787bc03 | ||
|
|
7129a19f35 | ||
|
|
f45ffc8773 | ||
|
|
3162f74945 | ||
|
|
6cef3e41e7 | ||
|
|
c0e2ec8dec | ||
|
|
aee81c8dcd | ||
|
|
9e736ab0d7 | ||
|
|
85752b0fc7 | ||
|
|
c6f34c59b4 | ||
|
|
7f07725840 | ||
|
|
c81d090464 | ||
|
|
c524732849 | ||
|
|
5e303f8a1f | ||
|
|
2246564279 | ||
|
|
eff0c1fe89 | ||
|
|
ad322476d2 | ||
|
|
2561742683 | ||
|
|
fa9e31fe03 | ||
|
|
3ac5b045c4 | ||
|
|
6a593e01e1 | ||
|
|
6f6dd2291e | ||
|
|
2b4ddc07f5 | ||
|
|
63c650c33e | ||
|
|
dc29161f37 | ||
|
|
8a6fdafc79 | ||
|
|
a8480d1eaf | ||
|
|
dd511588a2 | ||
|
|
79dad8ec8c | ||
|
|
fd9ffbbb88 | ||
|
|
d1be7cf142 | ||
|
|
d1f0be215b | ||
|
|
3a2c17998e | ||
|
|
a0dd051511 | ||
|
|
4faff3ec6f | ||
|
|
f110225173 | ||
|
|
2684257e7e | ||
|
|
51fb1021df | ||
|
|
51d0d0d6c5 | ||
|
|
047df76373 |
14
.github/workflows/main.yml
vendored
14
.github/workflows/main.yml
vendored
@@ -22,5 +22,15 @@ jobs:
|
|||||||
- name: Install extra python tools
|
- name: Install extra python tools
|
||||||
run: |
|
run: |
|
||||||
pip install -U adafruit-nrfutil
|
pip install -U adafruit-nrfutil
|
||||||
- name: Build
|
- name: Install libs needed for linux build
|
||||||
run: platformio run -e tbeam -e heltec -e lora-relay-v1 -e linux
|
run: |
|
||||||
|
sudo apt install -y libpsocksxx-dev
|
||||||
|
- name: Build for tbeam
|
||||||
|
run: platformio run -e tbeam
|
||||||
|
- name: Build for heltec
|
||||||
|
run: platformio run -e heltec
|
||||||
|
- name: Build for lora-relay-v1
|
||||||
|
run: platformio run -e lora-relay-v1
|
||||||
|
- name: Build for linux
|
||||||
|
run: platformio run -e linux
|
||||||
|
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
|||||||
[submodule "sdk-nrfxlib"]
|
[submodule "sdk-nrfxlib"]
|
||||||
path = sdk-nrfxlib
|
path = sdk-nrfxlib
|
||||||
url = https://github.com/nrfconnect/sdk-nrfxlib.git
|
url = https://github.com/nrfconnect/sdk-nrfxlib.git
|
||||||
|
[submodule "design"]
|
||||||
|
path = design
|
||||||
|
url = https://github.com/meshtastic/meshtastic-design.git
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ This is the device side code for the [meshtastic.org](https://www.meshtastic.org
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Meshtastic™ is a project that lets you use
|
Meshtastic® is a project that lets you use
|
||||||
inexpensive GPS mesh radios as an extensible, super long battery life mesh GPS communicator. These radios are great for hiking, skiing, paragliding -
|
inexpensive GPS mesh radios as an extensible, super long battery life mesh GPS communicator. These radios are great for hiking, skiing, paragliding -
|
||||||
essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other
|
essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other
|
||||||
members and any text messages sent to your group chat.
|
members and any text messages sent to your group chat.
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ BOARDS_ESP32="tlora-v2 tlora-v1 tlora-v2-1-1.6 tbeam heltec tbeam0.7"
|
|||||||
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
||||||
BOARDS_NRF52="lora-relay-v1"
|
BOARDS_NRF52="lora-relay-v1"
|
||||||
|
|
||||||
NUM_JOBS=2 || true
|
|
||||||
|
|
||||||
OUTDIR=release/latest
|
OUTDIR=release/latest
|
||||||
|
|
||||||
# We keep all old builds (and their map files in the archive dir)
|
# We keep all old builds (and their map files in the archive dir)
|
||||||
@@ -51,7 +49,7 @@ function do_build() {
|
|||||||
basename=universal/firmware-$BOARD-$VERSION
|
basename=universal/firmware-$BOARD-$VERSION
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pio run --jobs $NUM_JOBS --environment $BOARD # -v
|
pio run --environment $BOARD # -v
|
||||||
SRCELF=.pio/build/$BOARD/firmware.elf
|
SRCELF=.pio/build/$BOARD/firmware.elf
|
||||||
cp $SRCELF $OUTDIR/elfs/$basename.elf
|
cp $SRCELF $OUTDIR/elfs/$basename.elf
|
||||||
|
|
||||||
|
|||||||
19
bin/gen-images.sh
Executable file
19
bin/gen-images.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# regen the design bins first
|
||||||
|
cd design
|
||||||
|
bin/generate-pngs.sh
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# assumes 50 wide, 28 high
|
||||||
|
convert design/logo/png/Mesh_Logo_Black_Small.png -background white -alpha Background src/graphics/img/icon.xbm
|
||||||
|
|
||||||
|
inkscape --batch-process -o images/compass.png -w 48 -h 48 images/location_searching-24px.svg
|
||||||
|
convert compass.png -background white -alpha Background src/graphics/img/compass.xbm
|
||||||
|
|
||||||
|
inkscape --batch-process -o images/face.png -w 13 -h 13 images/face-24px.svg
|
||||||
|
|
||||||
|
inkscape --batch-process -o images/pin.png -w 13 -h 13 images/room-24px.svg
|
||||||
|
convert pin.png -background white -alpha Background src/graphics/img/pin.xbm
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# You probably don't need this - it is a basic test of the serial flash on the TTGO eink board
|
# You probably don't need this - it is a basic test of the serial flash on the TTGO eink board
|
||||||
|
|
||||||
nrfjprog -qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall
|
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall
|
||||||
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --memwr 0x12000000 --val 0xdeadbeef --verify
|
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --memwr 0x12000000 --val 0xdeadbeef --verify
|
||||||
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --readqspi spi.hex
|
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --readqspi spi.hex
|
||||||
objdump -s spi.hex | less
|
objdump -s spi.hex | less
|
||||||
|
|||||||
61
boards/eink0.1.json
Normal file
61
boards/eink0.1.json
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "nrf52840_s140_v6.ld"
|
||||||
|
},
|
||||||
|
"core": "nRF5",
|
||||||
|
"cpu": "cortex-m4",
|
||||||
|
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
|
||||||
|
"f_cpu": "64000000L",
|
||||||
|
"hwids": [
|
||||||
|
[
|
||||||
|
"0x239A",
|
||||||
|
"0x4405"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"usb_product": "TTGO_eink",
|
||||||
|
"mcu": "nrf52840",
|
||||||
|
"variant": "eink0.1",
|
||||||
|
"variants_dir": "variants",
|
||||||
|
"bsp": {
|
||||||
|
"name": "adafruit"
|
||||||
|
},
|
||||||
|
"softdevice": {
|
||||||
|
"sd_flags": "-DS140",
|
||||||
|
"sd_name": "s140",
|
||||||
|
"sd_version": "6.1.1",
|
||||||
|
"sd_fwid": "0x00B6"
|
||||||
|
},
|
||||||
|
"bootloader": {
|
||||||
|
"settings_addr": "0xFF000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectivity": [
|
||||||
|
"bluetooth"
|
||||||
|
],
|
||||||
|
"debug": {
|
||||||
|
"jlink_device": "nRF52840_xxAA",
|
||||||
|
"onboard_tools": [
|
||||||
|
"jlink"
|
||||||
|
],
|
||||||
|
"svd_path": "nrf52840.svd"
|
||||||
|
},
|
||||||
|
"frameworks": [
|
||||||
|
"arduino"
|
||||||
|
],
|
||||||
|
"name": "TTGO eink (Adafruit BSP)",
|
||||||
|
"upload": {
|
||||||
|
"maximum_ram_size": 248832,
|
||||||
|
"maximum_size": 815104,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 115200,
|
||||||
|
"protocol": "jlink",
|
||||||
|
"protocols": [
|
||||||
|
"jlink",
|
||||||
|
"nrfjprog",
|
||||||
|
"stlink"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"url": "FIXME",
|
||||||
|
"vendor": "TTGO"
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 532 B After Width: | Height: | Size: 532 B |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
1
design
Submodule
1
design
Submodule
Submodule design added at 73ba05ceef
@@ -1,13 +1,13 @@
|
|||||||
# What is Meshtastic?
|
# What is Meshtastic?
|
||||||
|
|
||||||
Meshtastic™ is a project that lets you use
|
Meshtastic® is a project that lets you use
|
||||||
inexpensive (\$30 ish) GPS radios as an extensible, long battery life, secure, mesh GPS communicator. These radios are great for hiking, skiing, paragliding - essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other members and any text messages sent to your group chat.
|
inexpensive (\$30 ish) GPS radios as an extensible, long battery life, secure, mesh GPS communicator. These radios are great for hiking, skiing, paragliding - essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other members and any text messages sent to your group chat.
|
||||||
|
|
||||||
The radios automatically create a mesh to forward packets as needed, so everyone in the group can receive messages from even the furthest member. The radios will optionally work with your phone, but no phone is required.
|
The radios automatically create a mesh to forward packets as needed, so everyone in the group can receive messages from even the furthest member. The radios will optionally work with your phone, but no phone is required.
|
||||||
|
|
||||||
Note: Questions after reading this? See our new [forum](https://meshtastic.discourse.group/).
|
Note: Questions after reading this? See our new [forum](https://meshtastic.discourse.group/).
|
||||||
|
|
||||||
### Uses
|
## Uses
|
||||||
|
|
||||||
- Outdoor sports where cellular coverage is limited. (Hiking, Skiing, Boating, Paragliding, Gliders etc..)
|
- Outdoor sports where cellular coverage is limited. (Hiking, Skiing, Boating, Paragliding, Gliders etc..)
|
||||||
- Applications where closed source GPS communicators just won't cut it (it is easy to add features for glider pilots etc...)
|
- Applications where closed source GPS communicators just won't cut it (it is easy to add features for glider pilots etc...)
|
||||||
@@ -17,7 +17,7 @@ Note: Questions after reading this? See our new [forum](https://meshtastic.disco
|
|||||||
|
|
||||||
[](https://www.youtube.com/watch?v=WlNbMbVZlHI "Meshtastic early demo")
|
[](https://www.youtube.com/watch?v=WlNbMbVZlHI "Meshtastic early demo")
|
||||||
|
|
||||||
### Features
|
## Features
|
||||||
|
|
||||||
Not all of these features are fully implemented yet - see **important** disclaimers below. But they should be in by the time we decide to call this project beta (three months?)
|
Not all of these features are fully implemented yet - see **important** disclaimers below. But they should be in by the time we decide to call this project beta (three months?)
|
||||||
|
|
||||||
|
|||||||
@@ -28,3 +28,14 @@ The maximum output power for North America is +30 dBm ERP.
|
|||||||
|
|
||||||
The band is from 902 to 928 MHz. It mentions channel number and its respective channel frequency. All the 13 channels are separated by 2.16 MHz with respect to the adjacent channels.
|
The band is from 902 to 928 MHz. It mentions channel number and its respective channel frequency. All the 13 channels are separated by 2.16 MHz with respect to the adjacent channels.
|
||||||
Channel zero starts at 903.08 MHz center frequency.
|
Channel zero starts at 903.08 MHz center frequency.
|
||||||
|
|
||||||
|
## Data-rates
|
||||||
|
|
||||||
|
Various data-rates are selectable when configuring a channel and are inversely proportional to the theoretical range of the devices:
|
||||||
|
|
||||||
|
| Channel setting | Data-rate |
|
||||||
|
|----------------------------|----------------------|
|
||||||
|
| Short range (but fast) | 21.875 kbps |
|
||||||
|
| Medium range (but fast) | 5.469 kbps |
|
||||||
|
| Long range (but slower) | 0.275 kbps |
|
||||||
|
| Very long range (but slow) | 0.183 kbps (default) |
|
||||||
|
|||||||
@@ -2,6 +2,27 @@
|
|||||||
|
|
||||||
You probably don't care about this section - skip to the next one.
|
You probably don't care about this section - skip to the next one.
|
||||||
|
|
||||||
|
eink:
|
||||||
|
|
||||||
|
* new battery level sensing
|
||||||
|
* measure current draw
|
||||||
|
* DONE: fix backlight
|
||||||
|
* USB is busted because of power enable mode?
|
||||||
|
* OHH BME280! THAT IS GREAT!
|
||||||
|
* make new screen work, ask for datasheet
|
||||||
|
* say I think you could ship this
|
||||||
|
* leds seem busted
|
||||||
|
* usb doesn't stay connected
|
||||||
|
* check GPS works
|
||||||
|
* check GPS fast locking
|
||||||
|
* send email about variants & faster flash programming - https://github.com/geeksville/Meshtastic-esp32/commit/f110225173a77326aac029321cdb6491bfa640f6
|
||||||
|
* send PR for bootloader
|
||||||
|
* fix nrf52 time/date
|
||||||
|
* send new master bin file
|
||||||
|
* send email about low power mode problems
|
||||||
|
* support new flash chip in appload, possibly use low power mode
|
||||||
|
* swbug! stuck busy tx occurred!
|
||||||
|
|
||||||
For app cleanup:
|
For app cleanup:
|
||||||
|
|
||||||
* use structured logging to kep logs in ram. Also send logs as packets to api clients
|
* use structured logging to kep logs in ram. Also send logs as packets to api clients
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ the project developers are not cryptography experts. Therefore we ask two things
|
|||||||
Based on comments from reviewers (see below), here's some tips for usage of these radios. So you can know the level of protection offered:
|
Based on comments from reviewers (see below), here's some tips for usage of these radios. So you can know the level of protection offered:
|
||||||
|
|
||||||
* It is pretty likely that the AES256 security is implemented 'correctly' and an observer will not be able to decode your messages.
|
* It is pretty likely that the AES256 security is implemented 'correctly' and an observer will not be able to decode your messages.
|
||||||
* Warning: If an attacker is able to get one of the radios in their position, they could either a) extract the channel key from that device or b) use that radio to listen to new communications.
|
* Warning: If an attacker is able to get one of the radios in their posession, they could either a) extract the channel key from that device or b) use that radio to listen to new communications.
|
||||||
* Warning: If an attacker is able to get the "Channel QR code/URL" that you share with others - that attacker could then be able to read any messages sent on the channel (either tomorrow or in the past - if they kept a raw copy of those broadcast packets)
|
* Warning: If an attacker is able to get the "Channel QR code/URL" that you share with others - that attacker could then be able to read any messages sent on the channel (either tomorrow or in the past - if they kept a raw copy of those broadcast packets)
|
||||||
|
|
||||||
Possible future areas of work (if there is enough interest - post in our [forum](https://meshtastic.discourse.group) if you want this):
|
Possible future areas of work (if there is enough interest - post in our [forum](https://meshtastic.discourse.group) if you want this):
|
||||||
@@ -48,4 +48,4 @@ I'm assuming that meshtastic is being used to hike in places where someone capab
|
|||||||
* I think the bigger encryption question is "what does the encryption need to do"? As it stands, an attacker who has yet to capture any of the devices cannot reasonably capture text or location data. An attacker who captures any device in the channel/mesh can read everything going to that device, everything stored on that device, and any other communication within the channel that they captured in encrypted form. If that capability basically matches your expectations, it is suitable for whatever adventures this was intended for, then, based on information publicly available or widely disclosed, the encryption is good. If those properties are distressing (like, device history is deliberately limited and you don't want a device captured today to endanger the information sent over the channel yesterday) we could talk about ways to achieve that (most likely synchronizing time and replacing the key with its own SHA256 every X hours, and ensuring the old key is not retained unnecessarily).
|
* I think the bigger encryption question is "what does the encryption need to do"? As it stands, an attacker who has yet to capture any of the devices cannot reasonably capture text or location data. An attacker who captures any device in the channel/mesh can read everything going to that device, everything stored on that device, and any other communication within the channel that they captured in encrypted form. If that capability basically matches your expectations, it is suitable for whatever adventures this was intended for, then, based on information publicly available or widely disclosed, the encryption is good. If those properties are distressing (like, device history is deliberately limited and you don't want a device captured today to endanger the information sent over the channel yesterday) we could talk about ways to achieve that (most likely synchronizing time and replacing the key with its own SHA256 every X hours, and ensuring the old key is not retained unnecessarily).
|
||||||
* Two other things to keep in mind are that AES-CTR does not itself provide authenticity (e.g. an attacker can flip bits in replaying data and scramble the resulting plaintext), and that the current scheme gives some hints about transmission in the size. So, if you worry about an adversary deliberately messing-up messages or knowing the length of a text message, it looks like those might be possible.
|
* Two other things to keep in mind are that AES-CTR does not itself provide authenticity (e.g. an attacker can flip bits in replaying data and scramble the resulting plaintext), and that the current scheme gives some hints about transmission in the size. So, if you worry about an adversary deliberately messing-up messages or knowing the length of a text message, it looks like those might be possible.
|
||||||
|
|
||||||
I'm guessing that the network behaves somewhat like a store-and-forward network - or, at least, that the goal is to avoid establishing a two-way connection to transmit data. I'm afraid I haven't worked with mesh networks much, but remember studying them briefly in school about ten years ago.
|
I'm guessing that the network behaves somewhat like a store-and-forward network - or, at least, that the goal is to avoid establishing a two-way connection to transmit data. I'm afraid I haven't worked with mesh networks much, but remember studying them briefly in school about ten years ago.
|
||||||
|
|||||||
89
docs/software/plugins/ExternalNotificationPlugin.md
Normal file
89
docs/software/plugins/ExternalNotificationPlugin.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# About
|
||||||
|
|
||||||
|
The ExternalNotification Plugin will allow you to connect a speaker, LED or other device to notify you when a message has been received from the mesh network.
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
These are the settings that can be configured.
|
||||||
|
|
||||||
|
ext_notification_plugin_enabled
|
||||||
|
Is the plugin enabled?
|
||||||
|
|
||||||
|
0 = Disabled (Default)
|
||||||
|
1 = Enabled
|
||||||
|
|
||||||
|
ext_notification_plugin_active
|
||||||
|
Is your external circuit triggered when our GPIO is low or high?
|
||||||
|
|
||||||
|
0 = Active Low (Default)
|
||||||
|
1 = Active High
|
||||||
|
|
||||||
|
ext_notification_plugin_alert_message
|
||||||
|
Do you want to be notified on an incoming message?
|
||||||
|
|
||||||
|
0 = Disabled (Default)
|
||||||
|
1 = Alert when a text message comes
|
||||||
|
|
||||||
|
ext_notification_plugin_alert_bell
|
||||||
|
Do you want to be notified on an incoming bell?
|
||||||
|
|
||||||
|
0 = Disabled (Default)
|
||||||
|
1 = Alert when the bell character is received
|
||||||
|
|
||||||
|
ext_notification_plugin_output
|
||||||
|
What GPIO is your external circuit attached?
|
||||||
|
|
||||||
|
GPIO of the output. (Default = 13)
|
||||||
|
|
||||||
|
ext_notification_plugin_output_ms
|
||||||
|
How long do you want us to trigger your external circuit?
|
||||||
|
|
||||||
|
Amount of time in ms for the alert. Default is 1000.
|
||||||
|
|
||||||
|
|
||||||
|
# Usage Notes
|
||||||
|
|
||||||
|
For basic usage, start with:
|
||||||
|
|
||||||
|
ext_notification_plugin_enabled = 1
|
||||||
|
ext_notification_plugin_alert_message = 1
|
||||||
|
|
||||||
|
Depending on how your external cirtcuit configured is configured, you may need to set the active state to true.
|
||||||
|
|
||||||
|
ext_notification_plugin_active = 1
|
||||||
|
|
||||||
|
## Alert Types
|
||||||
|
|
||||||
|
We support being alerted on two events:
|
||||||
|
|
||||||
|
1) Incoming Text Message
|
||||||
|
|
||||||
|
2) Incoming Text Message that contains the ascii bell character. At present, only the Python API can send an ascii bell character, but more support may be added in the future.
|
||||||
|
|
||||||
|
### Bell Character
|
||||||
|
|
||||||
|
The bell character is ASCII 0x07. Include 0x07 anywhere in the text message and with ext_notification_plugin_alert_bell enabled, we will issue an external notification.
|
||||||
|
|
||||||
|
# External Hardware
|
||||||
|
|
||||||
|
Be mindful of the max current sink and source of the esp32 GPIO. The easiest devices to interface with would be either an LED or Active Buzzer.
|
||||||
|
|
||||||
|
Ideas for external hardware:
|
||||||
|
|
||||||
|
* LED
|
||||||
|
* Active Buzzer
|
||||||
|
* Flame thrower
|
||||||
|
* Strobe Light
|
||||||
|
* Siren
|
||||||
|
|
||||||
|
# Known Problems
|
||||||
|
|
||||||
|
* This won't directly support an passive (normal) speaker as it does not generate any audio wave forms.
|
||||||
|
* This currently only supports the esp32. Other targets may be possible, I just don't have to test with.
|
||||||
|
* This plugin only monitors text messages. We won't trigger on any other packet types.
|
||||||
|
|
||||||
|
# Need more help?
|
||||||
|
|
||||||
|
Go to the Meshtastic Discourse Group if you have any questions or to share how you have used this.
|
||||||
|
|
||||||
|
https://meshtastic.discourse.group
|
||||||
40
docs/software/plugins/SerialPlugin.md
Normal file
40
docs/software/plugins/SerialPlugin.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# About
|
||||||
|
|
||||||
|
A simple interface to send messages over the mesh network by sending strings
|
||||||
|
over a serial port.
|
||||||
|
|
||||||
|
Default is to use RX GPIO 16 and TX GPIO 17.
|
||||||
|
|
||||||
|
|
||||||
|
# Basic Usage:
|
||||||
|
|
||||||
|
1) Enable the plugin by setting serialplugin_enabled to 1.
|
||||||
|
2) Set the pins (serialplugin_rxd / serialplugin_rxd) for your preferred RX and TX GPIO pins.
|
||||||
|
On tbeam, recommend to use:
|
||||||
|
RXD 35
|
||||||
|
TXD 15
|
||||||
|
3) Set serialplugin_timeout to the amount of time to wait before we consider
|
||||||
|
your packet as "done".
|
||||||
|
4) (Optional) In SerialPlugin.h set the port to PortNum_TEXT_MESSAGE_APP if you want to
|
||||||
|
send messages to/from the general text message channel.
|
||||||
|
5) Connect to your device over the serial interface at 38400 8N1.
|
||||||
|
6) Send a packet up to 240 bytes in length. This will get relayed over the mesh network.
|
||||||
|
7) (Optional) Set serialplugin_echo to 1 and any message you send out will be echoed back
|
||||||
|
to your device.
|
||||||
|
|
||||||
|
# TODO (in this order):
|
||||||
|
|
||||||
|
* Define a verbose RX mode to report on mesh and packet infomration.
|
||||||
|
- This won't happen any time soon.
|
||||||
|
|
||||||
|
# Known Problems
|
||||||
|
|
||||||
|
* Until the plugin is initilized by the startup sequence, the TX pin is in a floating
|
||||||
|
state. Device connected to that pin may see this as "noise".
|
||||||
|
* Will not work on NRF and the Linux device targets.
|
||||||
|
|
||||||
|
# Need help?
|
||||||
|
|
||||||
|
Need help with this plugin? Post your question on the Meshtastic Discourse:
|
||||||
|
|
||||||
|
https://meshtastic.discourse.group
|
||||||
6
docs/software/plugins/StoreRequestPlugin.md
Normal file
6
docs/software/plugins/StoreRequestPlugin.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# About
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Running notes
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# using height of 50 to have 14 pixels beneath icon for text
|
|
||||||
inkscape -z -e icon.png -w 50 -h 50 icon-24px.svg
|
|
||||||
convert icon.png -background white -alpha Background ../src/icon.xbm
|
|
||||||
|
|
||||||
inkscape -z -e compass.png -w 48 -h 48 location_searching-24px.svg
|
|
||||||
convert compass.png -background white -alpha Background ../src/compass.xbm
|
|
||||||
|
|
||||||
inkscape -z -e face.png -w 13 -h 13 face-24px.svg
|
|
||||||
|
|
||||||
inkscape -z -e pin.png -w 13 -h 13 room-24px.svg
|
|
||||||
convert pin.png -background white -alpha Background ../src/pin.xbm
|
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
MemSize = 0x200000
|
MemSize = 0x200000
|
||||||
|
|
||||||
; Define the desired ReadMode. Valid options are FASTREAD, READ2O, READ2IO, READ4O and READ4IO
|
; Define the desired ReadMode. Valid options are FASTREAD, READ2O, READ2IO, READ4O and READ4IO
|
||||||
ReadMode = READ2IO
|
ReadMode = READ4IO
|
||||||
|
|
||||||
; Define the desired WriteMode. Valid options are PP, PP2O, PP4O and PP4IO
|
; Define the desired WriteMode. Valid options are PP, PP2O, PP4O and PP4IO
|
||||||
WriteMode = PP
|
WriteMode = PP4IO
|
||||||
|
|
||||||
; Define the desired AddressMode. Valid options are BIT24 and BIT32
|
; Define the desired AddressMode. Valid options are BIT24 and BIT32
|
||||||
AddressMode = BIT24
|
AddressMode = BIT24
|
||||||
@@ -38,12 +38,10 @@ DIO0Pin = 12
|
|||||||
DIO0Port = 1
|
DIO0Port = 1
|
||||||
DIO1Pin = 13
|
DIO1Pin = 13
|
||||||
DIO1Port = 1
|
DIO1Port = 1
|
||||||
|
DIO2Pin = 7
|
||||||
;These two pins are not connected, but we must name something
|
DIO2Port = 0
|
||||||
DIO2Pin = 3
|
|
||||||
DIO2Port = 1
|
|
||||||
DIO3Pin = 5
|
DIO3Pin = 5
|
||||||
DIO3Port = 1
|
DIO3Port = 0
|
||||||
|
|
||||||
; Define the Index of the Write In Progress (WIP) bit in the status register. Valid options are in the range of 0 to 7.
|
; Define the Index of the Write In Progress (WIP) bit in the status register. Valid options are in the range of 0 to 7.
|
||||||
WIPIndex = 0
|
WIPIndex = 0
|
||||||
@@ -57,13 +55,8 @@ PPSize = PAGE256
|
|||||||
; Numbers can be given in decimal, hex (starting with either 0x or 0X) and binary (starting with either 0b or 0B) formats.
|
; Numbers can be given in decimal, hex (starting with either 0x or 0X) and binary (starting with either 0b or 0B) formats.
|
||||||
; The custom instructions will be executed in the order found.
|
; The custom instructions will be executed in the order found.
|
||||||
|
|
||||||
; This example includes two commands, first a WREN (WRite ENable) and then a WRSR (WRite Satus Register) enabling the Quad Operation and the High Performance
|
|
||||||
; mode for the MX25R6435F memory present in the nRF52840 DK.
|
|
||||||
;InitializationCustomInstruction = 0x06
|
|
||||||
;InitializationCustomInstruction = 0x01, [0x40, 0, 0x2]
|
|
||||||
|
|
||||||
; For MX25R1635F on TTGO board, only two data lines are connected
|
; For MX25R1635F on TTGO board, only two data lines are connected
|
||||||
; This example includes two commands, first a WREN (WRite ENable) and then a WRSR (WRite Satus Register) disabling Quad Operation and the High Performance
|
; This example includes two commands, first a WREN (WRite ENable) and then a WRSR (WRite Satus Register) enabling Quad Operation and the High Performance
|
||||||
; mode. For normal operation you might want low power mode instead.
|
; mode. For normal operation you might want low power mode instead.
|
||||||
InitializationCustomInstruction = 0x06
|
InitializationCustomInstruction = 0x06
|
||||||
InitializationCustomInstruction = 0x01, [0x00, 0, 0x2]
|
InitializationCustomInstruction = 0x01, [0x40, 0, 0x2]
|
||||||
|
|||||||
69
nrf52/ttgo_eink_qpsi0.1.ini
Normal file
69
nrf52/ttgo_eink_qpsi0.1.ini
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
; nrfjprog.exe configuration file.
|
||||||
|
|
||||||
|
; Note: QSPI flash is mapped into memory at address 0x12000000
|
||||||
|
|
||||||
|
[DEFAULT_CONFIGURATION]
|
||||||
|
; Define the capacity of the flash memory device in bytes. Set to 0 if no external memory device is present in your board.
|
||||||
|
; MX25R1635F is 16Mbit/2Mbyte
|
||||||
|
MemSize = 0x200000
|
||||||
|
|
||||||
|
; Define the desired ReadMode. Valid options are FASTREAD, READ2O, READ2IO, READ4O and READ4IO
|
||||||
|
ReadMode = READ2IO
|
||||||
|
|
||||||
|
; Define the desired WriteMode. Valid options are PP, PP2O, PP4O and PP4IO
|
||||||
|
WriteMode = PP
|
||||||
|
|
||||||
|
; Define the desired AddressMode. Valid options are BIT24 and BIT32
|
||||||
|
AddressMode = BIT24
|
||||||
|
|
||||||
|
; Define the desired Frequency. Valid options are M2, M4, M8, M16 and M32
|
||||||
|
Frequency = M16
|
||||||
|
|
||||||
|
; Define the desired SPI mode. Valid options are MODE0 and MODE3
|
||||||
|
SpiMode = MODE0
|
||||||
|
|
||||||
|
; Define the desired SckDelay. Valid options are in the range 0 to 255
|
||||||
|
SckDelay = 0x80
|
||||||
|
|
||||||
|
; Define the desired IO level for DIO2 and DIO3 during a custom instruction. Valid options are LEVEL_HIGH and LEVEL_LOW
|
||||||
|
CustomInstructionIO2Level = LEVEL_LOW
|
||||||
|
CustomInstructionIO3Level = LEVEL_HIGH
|
||||||
|
|
||||||
|
; Define the assigned pins for the QSPI peripheral. Valid options are those existing in your device
|
||||||
|
CSNPin = 15
|
||||||
|
CSNPort = 1
|
||||||
|
SCKPin = 14
|
||||||
|
SCKPort = 1
|
||||||
|
DIO0Pin = 12
|
||||||
|
DIO0Port = 1
|
||||||
|
DIO1Pin = 13
|
||||||
|
DIO1Port = 1
|
||||||
|
|
||||||
|
;These two pins are not connected, but we must name something
|
||||||
|
DIO2Pin = 3
|
||||||
|
DIO2Port = 1
|
||||||
|
DIO3Pin = 5
|
||||||
|
DIO3Port = 1
|
||||||
|
|
||||||
|
; Define the Index of the Write In Progress (WIP) bit in the status register. Valid options are in the range of 0 to 7.
|
||||||
|
WIPIndex = 0
|
||||||
|
|
||||||
|
; Define page size for commands. Valid sizes are PAGE256 and PAGE512.
|
||||||
|
PPSize = PAGE256
|
||||||
|
|
||||||
|
; Custom instructions to send to the external memory after initialization. Format is instruction code plus data to send in between optional brakets.
|
||||||
|
; These instructions will be executed each time the qspi peripheral is initiated by nrfjprog.
|
||||||
|
; To improve execution speed on consecutive interations with QSPI, you can run nrfjprog once with custom initialization, and then comment out the lines below.
|
||||||
|
; Numbers can be given in decimal, hex (starting with either 0x or 0X) and binary (starting with either 0b or 0B) formats.
|
||||||
|
; The custom instructions will be executed in the order found.
|
||||||
|
|
||||||
|
; This example includes two commands, first a WREN (WRite ENable) and then a WRSR (WRite Satus Register) enabling the Quad Operation and the High Performance
|
||||||
|
; mode for the MX25R6435F memory present in the nRF52840 DK.
|
||||||
|
;InitializationCustomInstruction = 0x06
|
||||||
|
;InitializationCustomInstruction = 0x01, [0x40, 0, 0x2]
|
||||||
|
|
||||||
|
; For MX25R1635F on TTGO board, only two data lines are connected
|
||||||
|
; This example includes two commands, first a WREN (WRite ENable) and then a WRSR (WRite Satus Register) disabling Quad Operation and the High Performance
|
||||||
|
; mode. For normal operation you might want low power mode instead.
|
||||||
|
InitializationCustomInstruction = 0x06
|
||||||
|
InitializationCustomInstruction = 0x01, [0x00, 0, 0x2]
|
||||||
@@ -252,7 +252,7 @@ src_filter = ${nrf52_base.src_filter} +<../variants/ppr1>
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
|
|
||||||
; Prototype eink/nrf52840/sx1262 device
|
; First prototype eink/nrf52840/sx1262 device
|
||||||
[env:eink]
|
[env:eink]
|
||||||
extends = nrf52_base
|
extends = nrf52_base
|
||||||
board = eink
|
board = eink
|
||||||
@@ -266,6 +266,20 @@ lib_deps =
|
|||||||
https://github.com/geeksville/EPD_Libraries.git
|
https://github.com/geeksville/EPD_Libraries.git
|
||||||
TFT_eSPI
|
TFT_eSPI
|
||||||
|
|
||||||
|
; First prototype eink/nrf52840/sx1262 device
|
||||||
|
[env:eink0.1]
|
||||||
|
extends = nrf52_base
|
||||||
|
board = eink0.1
|
||||||
|
# add our variants files to the include and src paths
|
||||||
|
# define build flags for the TFT_eSPI library
|
||||||
|
build_flags = ${nrf52_base.build_flags} -Ivariants/eink0.1
|
||||||
|
-DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
|
||||||
|
src_filter = ${nrf52_base.src_filter} +<../variants/eink0.1>
|
||||||
|
lib_deps =
|
||||||
|
${arduino_base.lib_deps}
|
||||||
|
https://github.com/geeksville/EPD_Libraries.git
|
||||||
|
TFT_eSPI
|
||||||
|
|
||||||
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
|
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
|
||||||
[env:lora-relay-v1]
|
[env:lora-relay-v1]
|
||||||
extends = nrf52_base
|
extends = nrf52_base
|
||||||
|
|||||||
2
proto
2
proto
Submodule proto updated: 855da8701e...106f4bfdeb
@@ -84,7 +84,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
|
|
||||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||||
/// in power
|
/// in power
|
||||||
virtual bool isVBUSPlug() { return getBattVoltage() > chargingVolt; }
|
virtual bool isVBUSPlug() { return getBattVoltage() > 1000 * chargingVolt; }
|
||||||
|
|
||||||
/// Assume charging if we have a battery and external power is connected.
|
/// Assume charging if we have a battery and external power is connected.
|
||||||
/// we can't be smart enough to say 'full'?
|
/// we can't be smart enough to say 'full'?
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ 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);
|
||||||
|
|
||||||
perhapsSetRTC(RTCQualityGPS, t);
|
perhapsSetRTC(RTCQualityGPS, t);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -87,11 +89,17 @@ bool NMEAGPS::lookForLocation()
|
|||||||
auto loc = reader.location.value();
|
auto loc = reader.location.value();
|
||||||
latitude = toDegInt(loc.lat);
|
latitude = toDegInt(loc.lat);
|
||||||
longitude = toDegInt(loc.lng);
|
longitude = toDegInt(loc.lng);
|
||||||
foundLocation = true;
|
|
||||||
|
|
||||||
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
|
// Some GPSes (Air530) seem to send a zero longitude when the current fix is bogus
|
||||||
DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, hdop=%g, heading=%f\n", latitude * 1e-7, longitude * 1e-7, altitude,
|
if(longitude == 0)
|
||||||
dop * 1e-2, heading * 1e-5);
|
DEBUG_MSG("Ignoring bogus NMEA position\n");
|
||||||
|
else {
|
||||||
|
foundLocation = true;
|
||||||
|
|
||||||
|
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
|
||||||
|
DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, hdop=%g, heading=%f\n", latitude * 1e-7, longitude * 1e-7, altitude,
|
||||||
|
dop * 1e-2, heading * 1e-5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundLocation;
|
return foundLocation;
|
||||||
|
|||||||
@@ -122,7 +122,8 @@ bool EInkDisplay::connect()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PIN_EINK_EN
|
#ifdef PIN_EINK_EN
|
||||||
digitalWrite(PIN_EINK_EN, HIGH);
|
// backlight power, HIGH is backlight on, LOW is off
|
||||||
|
digitalWrite(PIN_EINK_EN, LOW);
|
||||||
pinMode(PIN_EINK_EN, OUTPUT);
|
pinMode(PIN_EINK_EN, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,20 @@
|
|||||||
#define icon_width 50
|
#define icon_width 50
|
||||||
#define icon_height 50
|
#define icon_height 28
|
||||||
static char icon_bits[] = {
|
static char icon_bits[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x03,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF,
|
0x00, 0x00, 0x00, 0x80, 0x07, 0xC0, 0x07, 0x00, 0x00, 0x00, 0xC0, 0x1F,
|
||||||
0xFF, 0x07, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00,
|
0xC0, 0x0F, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0xE0, 0x0F, 0x00, 0x00, 0x00,
|
||||||
0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x00,
|
0xE0, 0x0F, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0xF0, 0x07, 0xF0, 0x3F, 0x00,
|
||||||
0x00, 0x00, 0xFE, 0x0F, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0xFF, 0x03, 0x00,
|
0x00, 0x00, 0xF8, 0x03, 0xF8, 0x7F, 0x00, 0x00, 0x00, 0xF8, 0x03, 0xFC,
|
||||||
0xFF, 0x03, 0x00, 0x80, 0xFF, 0x00, 0x00, 0xFC, 0x07, 0x00, 0xC0, 0x3F,
|
0x7F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0xFC, 0xFE, 0x00, 0x00, 0x00, 0xFE,
|
||||||
0xE0, 0x1F, 0xF0, 0x0F, 0x00, 0xC0, 0x1F, 0xFC, 0xFF, 0xE0, 0x0F, 0x00,
|
0x00, 0xFE, 0xFC, 0x01, 0x00, 0x00, 0xFE, 0x00, 0x7F, 0xFC, 0x01, 0x00,
|
||||||
0xE0, 0x0F, 0xFF, 0xFF, 0xC3, 0x1F, 0x00, 0xF0, 0x87, 0xFF, 0xFF, 0x87,
|
0x00, 0x7F, 0x00, 0x3F, 0xF8, 0x03, 0x00, 0x80, 0x3F, 0x80, 0x3F, 0xF0,
|
||||||
0x3F, 0x00, 0xF0, 0xC3, 0xFF, 0xFF, 0x0F, 0x3F, 0x00, 0xF8, 0xE3, 0x7F,
|
0x07, 0x00, 0x80, 0x3F, 0xC0, 0x1F, 0xF0, 0x07, 0x00, 0xC0, 0x1F, 0xC0,
|
||||||
0xF8, 0x1F, 0x7F, 0x00, 0xF8, 0xF1, 0x0F, 0xC0, 0x3F, 0x7E, 0x00, 0xF8,
|
0x0F, 0xE0, 0x0F, 0x00, 0xE0, 0x0F, 0xE0, 0x0F, 0xC0, 0x1F, 0x00, 0xE0,
|
||||||
0xF1, 0x07, 0x80, 0x3F, 0x7E, 0x00, 0xFC, 0xF8, 0x03, 0x00, 0x7F, 0xFC,
|
0x0F, 0xF0, 0x07, 0x80, 0x1F, 0x00, 0xF0, 0x07, 0xF8, 0x03, 0x80, 0x3F,
|
||||||
0x00, 0xFC, 0xF8, 0x81, 0x07, 0x7E, 0xFC, 0x00, 0x7C, 0xF8, 0xE0, 0x1F,
|
0x00, 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x7F, 0x00, 0xFC, 0x03, 0xFC, 0x01,
|
||||||
0x7C, 0xF8, 0x00, 0x7C, 0xFC, 0xF0, 0x3F, 0xFC, 0xF8, 0x00, 0x7C, 0xFC,
|
0x00, 0x7E, 0x00, 0xFC, 0x01, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00,
|
||||||
0xF0, 0x3F, 0xFC, 0xF8, 0x00, 0x7C, 0x7C, 0xF8, 0x7F, 0xF8, 0xF8, 0x00,
|
0xFE, 0x00, 0x00, 0xFC, 0x01, 0x7E, 0x00, 0x7F, 0x00, 0x00, 0xF8, 0x01,
|
||||||
0x7C, 0x7C, 0xF8, 0x7F, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00,
|
0x7E, 0x00, 0x3E, 0x00, 0x00, 0xF8, 0x01, 0x38, 0x00, 0x3C, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
|
0x70, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, };
|
||||||
0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
|
|
||||||
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0xFE, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x03, 0x00,
|
|
||||||
0x00, 0x00, 0x80, 0x7F, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0,
|
|
||||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x0C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, };
|
|
||||||
|
|||||||
@@ -490,6 +490,8 @@ void setup()
|
|||||||
DEBUG_MSG("Warning: Failed to find RF95 radio\n");
|
DEBUG_MSG("Warning: Failed to find RF95 radio\n");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("Radio init succeeded, using RF95 radio\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -501,6 +503,8 @@ void setup()
|
|||||||
DEBUG_MSG("Warning: Failed to find SX1262 radio\n");
|
DEBUG_MSG("Warning: Failed to find SX1262 radio\n");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("Radio init succeeded, using SX1262 radio\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -512,6 +516,8 @@ void setup()
|
|||||||
DEBUG_MSG("Warning: Failed to find simulated radio\n");
|
DEBUG_MSG("Warning: Failed to find simulated radio\n");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("Using SIMULATED radio!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
|
|||||||
// packets until ack arrives)
|
// packets until ack arrives)
|
||||||
// FIXME, if we don't get a route reply at all (or a route error), timeout and generate a routeerror TIMEOUT on our own...
|
// FIXME, if we don't get a route reply at all (or a route error), timeout and generate a routeerror TIMEOUT on our own...
|
||||||
break;
|
break;
|
||||||
case SubPacket_route_error_tag:
|
case SubPacket_error_reason_tag:
|
||||||
removeRoute(p->decoded.dest);
|
removeRoute(p->decoded.dest);
|
||||||
|
|
||||||
// FIXME: if any pending packets were waiting on this route, delete them
|
// FIXME: if any pending packets were waiting on this route, delete them
|
||||||
@@ -131,7 +131,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
|
|||||||
assert(p->decoded.source); // I think this is guaranteed by now
|
assert(p->decoded.source); // I think this is guaranteed by now
|
||||||
|
|
||||||
// FIXME - what if the current packet _is_ a route error packet?
|
// FIXME - what if the current packet _is_ a route error packet?
|
||||||
sendRouteError(p, RouteError_NO_ROUTE);
|
sendRouteError(p, ErrorReason_NO_ROUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME, stop local processing of this packet
|
// FIXME, stop local processing of this packet
|
||||||
@@ -145,7 +145,7 @@ void DSRRouter::sniffReceived(const MeshPacket *p)
|
|||||||
if (pending && pending->packet->decoded.source) { // if source not set, this was not a multihop packet, just ignore
|
if (pending && pending->packet->decoded.source) { // if source not set, this was not a multihop packet, just ignore
|
||||||
removeRoute(pending->packet->decoded.dest); // We no longer have a route to the specified node
|
removeRoute(pending->packet->decoded.dest); // We no longer have a route to the specified node
|
||||||
|
|
||||||
sendRouteError(p, RouteError_GOT_NAK);
|
sendRouteError(p, ErrorReason_GOT_NAK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,7 @@ void DSRRouter::sendNextHop(NodeNum n, const MeshPacket *p)
|
|||||||
/**
|
/**
|
||||||
* Send a route error packet towards whoever originally sent this message
|
* Send a route error packet towards whoever originally sent this message
|
||||||
*/
|
*/
|
||||||
void DSRRouter::sendRouteError(const MeshPacket *p, RouteError err)
|
void DSRRouter::sendRouteError(const MeshPacket *p, ErrorReason err)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("FIXME not implemented sendRouteError\n");
|
DEBUG_MSG("FIXME not implemented sendRouteError\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class DSRRouter : public ReliableRouter
|
|||||||
/**
|
/**
|
||||||
* Send a route error packet towards whoever originally sent this message
|
* Send a route error packet towards whoever originally sent this message
|
||||||
*/
|
*/
|
||||||
void sendRouteError(const MeshPacket *p, RouteError err);
|
void sendRouteError(const MeshPacket *p, ErrorReason err);
|
||||||
|
|
||||||
/** make a copy of p, start discovery, but only if we don't
|
/** make a copy of p, start discovery, but only if we don't
|
||||||
* already a discovery in progress for that node number. Caller has already scheduled this message for retransmission
|
* already a discovery in progress for that node number. Caller has already scheduled this message for retransmission
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
|
#include "main.h"
|
||||||
#include "MeshRadio.h"
|
#include "MeshRadio.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PacketHistory.h"
|
#include "PacketHistory.h"
|
||||||
@@ -179,10 +180,14 @@ bool NodeDB::resetRadioConfig()
|
|||||||
channelSettings.psk.size = 1;
|
channelSettings.psk.size = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the short single byte variants of psk into variant that can be used more generally
|
memset(activePSK, 0, sizeof(activePSK)); // In case the user provided a short key, we want to pad the rest with zeros
|
||||||
memcpy(activePSK, channelSettings.psk.bytes, channelSettings.psk.size);
|
memcpy(activePSK, channelSettings.psk.bytes, channelSettings.psk.size);
|
||||||
activePSKSize = channelSettings.psk.size;
|
activePSKSize = channelSettings.psk.size;
|
||||||
if (activePSKSize == 1) {
|
if(activePSKSize == 0)
|
||||||
|
DEBUG_MSG("Warning: User disabled encryption\n");
|
||||||
|
else if (activePSKSize == 1) {
|
||||||
|
// Convert the short single byte variants of psk into variant that can be used more generally
|
||||||
|
|
||||||
uint8_t pskIndex = activePSK[0];
|
uint8_t pskIndex = activePSK[0];
|
||||||
DEBUG_MSG("Expanding short PSK #%d\n", pskIndex);
|
DEBUG_MSG("Expanding short PSK #%d\n", pskIndex);
|
||||||
if (pskIndex == 0)
|
if (pskIndex == 0)
|
||||||
@@ -194,6 +199,16 @@ bool NodeDB::resetRadioConfig()
|
|||||||
uint8_t *last = activePSK + sizeof(defaultpsk) - 1;
|
uint8_t *last = activePSK + sizeof(defaultpsk) - 1;
|
||||||
*last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
|
*last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
|
||||||
}
|
}
|
||||||
|
} else if(activePSKSize < 16) {
|
||||||
|
// Error! The user specified only the first few bits of an AES128 key. So by convention we just pad the rest of the key
|
||||||
|
// with zeros
|
||||||
|
DEBUG_MSG("Warning: User provided a too short AES128 key - padding\n");
|
||||||
|
activePSKSize = 16;
|
||||||
|
} else if(activePSKSize < 32 && activePSKSize != 16) {
|
||||||
|
// Error! The user specified only the first few bits of an AES256 key. So by convention we just pad the rest of the key
|
||||||
|
// with zeros
|
||||||
|
DEBUG_MSG("Warning: User provided a too short AES256 key - padding\n");
|
||||||
|
activePSKSize = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell our crypto engine about the psk
|
// Tell our crypto engine about the psk
|
||||||
@@ -583,8 +598,14 @@ NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
|
|||||||
/// Record an error that should be reported via analytics
|
/// Record an error that should be reported via analytics
|
||||||
void recordCriticalError(CriticalErrorCode code, uint32_t address)
|
void recordCriticalError(CriticalErrorCode code, uint32_t address)
|
||||||
{
|
{
|
||||||
|
// Print error to screen and serial port
|
||||||
|
String lcd = String("Critical error ") + code + "!\n";
|
||||||
|
screen->print(lcd.c_str());
|
||||||
DEBUG_MSG("NOTE! Recording critical error %d, address=%x\n", code, address);
|
DEBUG_MSG("NOTE! Recording critical error %d, address=%x\n", code, address);
|
||||||
|
|
||||||
|
// Record error to DB
|
||||||
myNodeInfo.error_code = code;
|
myNodeInfo.error_code = code;
|
||||||
myNodeInfo.error_address = address;
|
myNodeInfo.error_address = address;
|
||||||
myNodeInfo.error_count++;
|
myNodeInfo.error_count++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
|
#include "error.h"
|
||||||
#include <configuration.h>
|
#include <configuration.h>
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
#include <pb_encode.h>
|
#include <pb_encode.h>
|
||||||
@@ -67,9 +68,20 @@ bool RadioLibInterface::canSendImmediately()
|
|||||||
bool busyTx = sendingPacket != NULL;
|
bool busyTx = sendingPacket != NULL;
|
||||||
bool busyRx = isReceiving && isActivelyReceiving();
|
bool busyRx = isReceiving && isActivelyReceiving();
|
||||||
|
|
||||||
|
|
||||||
if (busyTx || busyRx) {
|
if (busyTx || busyRx) {
|
||||||
if (busyTx)
|
if (busyTx)
|
||||||
DEBUG_MSG("Can not send yet, busyTx\n");
|
DEBUG_MSG("Can not send yet, busyTx\n");
|
||||||
|
// If we've been trying to send the same packet more than one minute and we haven't gotten a
|
||||||
|
// TX IRQ from the radio, the radio is probably broken.
|
||||||
|
if (busyTx && (millis() - lastTxStart > 60000)){
|
||||||
|
DEBUG_MSG("Hardware Failure! busyTx for more than 60s\n");
|
||||||
|
recordCriticalError(CriticalErrorCode_TransmitFailed);
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
if (busyTx && (millis() - lastTxStart > 65000)) // After 5s more, reboot
|
||||||
|
ESP.restart();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (busyRx)
|
if (busyRx)
|
||||||
DEBUG_MSG("Can not send yet, busyRx\n");
|
DEBUG_MSG("Can not send yet, busyRx\n");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
|
|||||||
// the original sending process.
|
// the original sending process.
|
||||||
if (stopRetransmission(p->from, p->id)) {
|
if (stopRetransmission(p->from, p->id)) {
|
||||||
DEBUG_MSG("Someone is retransmitting for us, generate implicit ack\n");
|
DEBUG_MSG("Someone is retransmitting for us, generate implicit ack\n");
|
||||||
sendAckNak(true, p->from, p->id);
|
sendAckNak(ErrorReason_NONE, p->from, p->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p)
|
|||||||
if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability
|
if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability
|
||||||
// - not DSR routing)
|
// - not DSR routing)
|
||||||
if (p->want_ack) {
|
if (p->want_ack) {
|
||||||
sendAckNak(true, p->from, p->id);
|
sendAckNak(ErrorReason_NONE, p->from, p->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the payload is valid, look for ack/nak
|
// If the payload is valid, look for ack/nak
|
||||||
@@ -84,27 +84,6 @@ void ReliableRouter::sniffReceived(const MeshPacket *p)
|
|||||||
FloodingRouter::sniffReceived(p);
|
FloodingRouter::sniffReceived(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an ack or a nak packet back towards whoever sent idFrom
|
|
||||||
*/
|
|
||||||
void ReliableRouter::sendAckNak(bool isAck, NodeNum to, PacketId idFrom)
|
|
||||||
{
|
|
||||||
auto p = allocForSending();
|
|
||||||
p->hop_limit = 0; // Assume just immediate neighbors for now
|
|
||||||
p->to = to;
|
|
||||||
DEBUG_MSG("Sending an ack=0x%x,to=0x%x,idFrom=0x%x,id=0x%x\n", isAck, to, idFrom, p->id);
|
|
||||||
|
|
||||||
if (isAck) {
|
|
||||||
p->decoded.ack.success_id = idFrom;
|
|
||||||
p->decoded.which_ack = SubPacket_success_id_tag;
|
|
||||||
} else {
|
|
||||||
p->decoded.ack.fail_id = idFrom;
|
|
||||||
p->decoded.which_ack = SubPacket_fail_id_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendLocal(p); // we sometimes send directly to the local node
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NUM_RETRANSMISSIONS 3
|
#define NUM_RETRANSMISSIONS 3
|
||||||
|
|
||||||
PendingPacket::PendingPacket(MeshPacket *p)
|
PendingPacket::PendingPacket(MeshPacket *p)
|
||||||
@@ -176,7 +155,7 @@ int32_t ReliableRouter::doRetransmissions()
|
|||||||
if (p.numRetransmissions == 0) {
|
if (p.numRetransmissions == 0) {
|
||||||
DEBUG_MSG("Reliable send failed, returning a nak fr=0x%x,to=0x%x,id=%d\n", p.packet->from, p.packet->to,
|
DEBUG_MSG("Reliable send failed, returning a nak fr=0x%x,to=0x%x,id=%d\n", p.packet->from, p.packet->to,
|
||||||
p.packet->id);
|
p.packet->id);
|
||||||
sendAckNak(false, p.packet->from, p.packet->id);
|
sendAckNak(ErrorReason_MAX_RETRANSMIT, p.packet->from, p.packet->id);
|
||||||
// Note: we don't stop retransmission here, instead the Nak packet gets processed in sniffReceived - which
|
// Note: we don't stop retransmission here, instead the Nak packet gets processed in sniffReceived - which
|
||||||
// allows the DSR version to still be able to look at the PendingPacket
|
// allows the DSR version to still be able to look at the PendingPacket
|
||||||
stopRetransmission(it->first);
|
stopRetransmission(it->first);
|
||||||
|
|||||||
@@ -109,10 +109,6 @@ class ReliableRouter : public FloodingRouter
|
|||||||
PendingPacket *startRetransmission(MeshPacket *p);
|
PendingPacket *startRetransmission(MeshPacket *p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* Send an ack or a nak packet back towards whoever sent idFrom
|
|
||||||
*/
|
|
||||||
void sendAckNak(bool isAck, NodeNum to, PacketId idFrom);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop any retransmissions we are doing of the specified node/packet ID pair
|
* Stop any retransmissions we are doing of the specified node/packet ID pair
|
||||||
|
|||||||
@@ -99,6 +99,31 @@ MeshPacket *Router::allocForSending()
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an ack or a nak packet back towards whoever sent idFrom
|
||||||
|
*/
|
||||||
|
void Router::sendAckNak(ErrorReason err, NodeNum to, PacketId idFrom)
|
||||||
|
{
|
||||||
|
auto p = allocForSending();
|
||||||
|
p->hop_limit = 0; // Assume just immediate neighbors for now
|
||||||
|
p->to = to;
|
||||||
|
DEBUG_MSG("Sending an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
p->decoded.ack.success_id = idFrom;
|
||||||
|
p->decoded.which_ack = SubPacket_success_id_tag;
|
||||||
|
} else {
|
||||||
|
p->decoded.ack.fail_id = idFrom;
|
||||||
|
p->decoded.which_ack = SubPacket_fail_id_tag;
|
||||||
|
|
||||||
|
// Also send back the error reason
|
||||||
|
p->decoded.which_payload = SubPacket_error_reason_tag;
|
||||||
|
p->decoded.error_reason = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendLocal(p); // we sometimes send directly to the local node
|
||||||
|
}
|
||||||
|
|
||||||
ErrorCode Router::sendLocal(MeshPacket *p)
|
ErrorCode Router::sendLocal(MeshPacket *p)
|
||||||
{
|
{
|
||||||
// No need to deliver externally if the destination is the local node
|
// No need to deliver externally if the destination is the local node
|
||||||
@@ -106,15 +131,24 @@ ErrorCode Router::sendLocal(MeshPacket *p)
|
|||||||
printPacket("Enqueuing local", p);
|
printPacket("Enqueuing local", p);
|
||||||
fromRadioQueue.enqueue(p);
|
fromRadioQueue.enqueue(p);
|
||||||
return ERRNO_OK;
|
return ERRNO_OK;
|
||||||
}
|
} else if (!iface) {
|
||||||
|
// We must be sending to remote nodes also, fail if no interface found
|
||||||
|
|
||||||
// If we are sending a broadcast, we also treat it as if we just received it ourself
|
// ERROR! no radio found, report failure back to the client and drop the packet
|
||||||
// this allows local apps (and PCs) to see broadcasts sourced locally
|
DEBUG_MSG("Error: No interface, returning NAK and dropping packet.\n");
|
||||||
if (p->to == NODENUM_BROADCAST) {
|
sendAckNak(ErrorReason_NO_INTERFACE, p->from, p->id);
|
||||||
handleReceived(p);
|
packetPool.release(p);
|
||||||
}
|
|
||||||
|
|
||||||
return send(p);
|
return ERRNO_NO_INTERFACES;
|
||||||
|
} else {
|
||||||
|
// If we are sending a broadcast, we also treat it as if we just received it ourself
|
||||||
|
// this allows local apps (and PCs) to see broadcasts sourced locally
|
||||||
|
if (p->to == NODENUM_BROADCAST) {
|
||||||
|
handleReceived(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return send(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,14 +188,15 @@ ErrorCode Router::send(MeshPacket *p)
|
|||||||
p->which_payload = MeshPacket_encrypted_tag;
|
p->which_payload = MeshPacket_encrypted_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iface) {
|
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
|
||||||
// DEBUG_MSG("Sending packet via interface fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
// if (iface) {
|
||||||
return iface->send(p);
|
// DEBUG_MSG("Sending packet via interface fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
||||||
} else {
|
return iface->send(p);
|
||||||
|
/* } else {
|
||||||
DEBUG_MSG("Dropping packet - no interfaces - fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
DEBUG_MSG("Dropping packet - no interfaces - fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
||||||
packetPool.release(p);
|
packetPool.release(p);
|
||||||
return ERRNO_NO_INTERFACES;
|
return ERRNO_NO_INTERFACES;
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ class Router : protected concurrency::OSThread
|
|||||||
virtual int32_t runOnce();
|
virtual int32_t runOnce();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works like send, but if we are sending to the local node, we directly put the message in the receive queue
|
* Works like send, but if we are sending to the local node, we directly put the message in the receive queue.
|
||||||
|
* This is the primary method used for sending packets, because it handles both the remote and local cases.
|
||||||
*
|
*
|
||||||
* NOTE: This method will free the provided packet (even if we return an error code)
|
* NOTE: This method will free the provided packet (even if we return an error code)
|
||||||
*/
|
*/
|
||||||
@@ -92,6 +93,11 @@ class Router : protected concurrency::OSThread
|
|||||||
*/
|
*/
|
||||||
bool perhapsDecode(MeshPacket *p);
|
bool perhapsDecode(MeshPacket *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an ack or a nak packet back towards whoever sent idFrom
|
||||||
|
*/
|
||||||
|
void sendAckNak(ErrorReason err, NodeNum to, PacketId idFrom);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Called from loop()
|
* Called from loop()
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ extern const pb_msgdesc_t DeviceState_msg;
|
|||||||
#define DeviceState_fields &DeviceState_msg
|
#define DeviceState_fields &DeviceState_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define DeviceState_size 6206
|
#define DeviceState_size 6239
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -11,12 +11,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enum definitions */
|
/* Enum definitions */
|
||||||
typedef enum _RouteError {
|
typedef enum _ErrorReason {
|
||||||
RouteError_NONE = 0,
|
ErrorReason_NONE = 0,
|
||||||
RouteError_NO_ROUTE = 1,
|
ErrorReason_NO_ROUTE = 1,
|
||||||
RouteError_GOT_NAK = 2,
|
ErrorReason_GOT_NAK = 2,
|
||||||
RouteError_TIMEOUT = 3
|
ErrorReason_TIMEOUT = 3,
|
||||||
} RouteError;
|
ErrorReason_NO_INTERFACE = 4,
|
||||||
|
ErrorReason_MAX_RETRANSMIT = 5
|
||||||
|
} ErrorReason;
|
||||||
|
|
||||||
typedef enum _Constants {
|
typedef enum _Constants {
|
||||||
Constants_Unused = 0,
|
Constants_Unused = 0,
|
||||||
@@ -57,6 +59,7 @@ typedef enum _ChargeCurrent {
|
|||||||
|
|
||||||
typedef enum _GpsOperation {
|
typedef enum _GpsOperation {
|
||||||
GpsOperation_GpsOpUnset = 0,
|
GpsOperation_GpsOpUnset = 0,
|
||||||
|
GpsOperation_GpsOpStationary = 1,
|
||||||
GpsOperation_GpsOpMobile = 2,
|
GpsOperation_GpsOpMobile = 2,
|
||||||
GpsOperation_GpsOpTimeOnly = 3,
|
GpsOperation_GpsOpTimeOnly = 3,
|
||||||
GpsOperation_GpsOpDisabled = 4
|
GpsOperation_GpsOpDisabled = 4
|
||||||
@@ -76,7 +79,8 @@ typedef enum _CriticalErrorCode {
|
|||||||
CriticalErrorCode_Unspecified = 4,
|
CriticalErrorCode_Unspecified = 4,
|
||||||
CriticalErrorCode_UBloxInitFailed = 5,
|
CriticalErrorCode_UBloxInitFailed = 5,
|
||||||
CriticalErrorCode_NoAXP192 = 6,
|
CriticalErrorCode_NoAXP192 = 6,
|
||||||
CriticalErrorCode_InvalidRadioSetting = 7
|
CriticalErrorCode_InvalidRadioSetting = 7,
|
||||||
|
CriticalErrorCode_TransmitFailed = 8
|
||||||
} CriticalErrorCode;
|
} CriticalErrorCode;
|
||||||
|
|
||||||
typedef enum _ChannelSettings_ModemConfig {
|
typedef enum _ChannelSettings_ModemConfig {
|
||||||
@@ -182,6 +186,13 @@ typedef struct _RadioConfig_UserPreferences {
|
|||||||
uint32_t serialplugin_rxd;
|
uint32_t serialplugin_rxd;
|
||||||
uint32_t serialplugin_txd;
|
uint32_t serialplugin_txd;
|
||||||
uint32_t serialplugin_timeout;
|
uint32_t serialplugin_timeout;
|
||||||
|
uint32_t serialplugin_mode;
|
||||||
|
bool ext_notification_plugin_enabled;
|
||||||
|
uint32_t ext_notification_plugin_output_ms;
|
||||||
|
uint32_t ext_notification_plugin_output;
|
||||||
|
bool ext_notification_plugin_active;
|
||||||
|
bool ext_notification_plugin_alert_message;
|
||||||
|
bool ext_notification_plugin_alert_bell;
|
||||||
} RadioConfig_UserPreferences;
|
} RadioConfig_UserPreferences;
|
||||||
|
|
||||||
typedef struct _RouteDiscovery {
|
typedef struct _RouteDiscovery {
|
||||||
@@ -221,7 +232,7 @@ typedef struct _SubPacket {
|
|||||||
User user;
|
User user;
|
||||||
RouteDiscovery route_request;
|
RouteDiscovery route_request;
|
||||||
RouteDiscovery route_reply;
|
RouteDiscovery route_reply;
|
||||||
RouteError route_error;
|
ErrorReason error_reason;
|
||||||
};
|
};
|
||||||
uint32_t original_id;
|
uint32_t original_id;
|
||||||
bool want_response;
|
bool want_response;
|
||||||
@@ -279,9 +290,9 @@ typedef struct _ToRadio {
|
|||||||
|
|
||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _RouteError_MIN RouteError_NONE
|
#define _ErrorReason_MIN ErrorReason_NONE
|
||||||
#define _RouteError_MAX RouteError_TIMEOUT
|
#define _ErrorReason_MAX ErrorReason_MAX_RETRANSMIT
|
||||||
#define _RouteError_ARRAYSIZE ((RouteError)(RouteError_TIMEOUT+1))
|
#define _ErrorReason_ARRAYSIZE ((ErrorReason)(ErrorReason_MAX_RETRANSMIT+1))
|
||||||
|
|
||||||
#define _Constants_MIN Constants_Unused
|
#define _Constants_MIN Constants_Unused
|
||||||
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
|
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
|
||||||
@@ -304,8 +315,8 @@ typedef struct _ToRadio {
|
|||||||
#define _LocationSharing_ARRAYSIZE ((LocationSharing)(LocationSharing_LocDisabled+1))
|
#define _LocationSharing_ARRAYSIZE ((LocationSharing)(LocationSharing_LocDisabled+1))
|
||||||
|
|
||||||
#define _CriticalErrorCode_MIN CriticalErrorCode_None
|
#define _CriticalErrorCode_MIN CriticalErrorCode_None
|
||||||
#define _CriticalErrorCode_MAX CriticalErrorCode_InvalidRadioSetting
|
#define _CriticalErrorCode_MAX CriticalErrorCode_TransmitFailed
|
||||||
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_InvalidRadioSetting+1))
|
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_TransmitFailed+1))
|
||||||
|
|
||||||
#define _ChannelSettings_ModemConfig_MIN ChannelSettings_ModemConfig_Bw125Cr45Sf128
|
#define _ChannelSettings_ModemConfig_MIN ChannelSettings_ModemConfig_Bw125Cr45Sf128
|
||||||
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_Bw125Cr48Sf4096
|
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_Bw125Cr48Sf4096
|
||||||
@@ -329,7 +340,7 @@ extern "C" {
|
|||||||
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0, 0}
|
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0, 0}
|
||||||
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
|
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
|
||||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0}
|
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
|
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
|
||||||
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0}
|
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
||||||
@@ -343,7 +354,7 @@ extern "C" {
|
|||||||
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0, 0}
|
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0, 0}
|
||||||
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
|
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
|
||||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0}
|
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
|
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
|
||||||
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0}
|
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
||||||
@@ -417,6 +428,13 @@ extern "C" {
|
|||||||
#define RadioConfig_UserPreferences_serialplugin_rxd_tag 122
|
#define RadioConfig_UserPreferences_serialplugin_rxd_tag 122
|
||||||
#define RadioConfig_UserPreferences_serialplugin_txd_tag 123
|
#define RadioConfig_UserPreferences_serialplugin_txd_tag 123
|
||||||
#define RadioConfig_UserPreferences_serialplugin_timeout_tag 124
|
#define RadioConfig_UserPreferences_serialplugin_timeout_tag 124
|
||||||
|
#define RadioConfig_UserPreferences_serialplugin_mode_tag 125
|
||||||
|
#define RadioConfig_UserPreferences_ext_notification_plugin_enabled_tag 126
|
||||||
|
#define RadioConfig_UserPreferences_ext_notification_plugin_output_ms_tag 127
|
||||||
|
#define RadioConfig_UserPreferences_ext_notification_plugin_output_tag 128
|
||||||
|
#define RadioConfig_UserPreferences_ext_notification_plugin_active_tag 129
|
||||||
|
#define RadioConfig_UserPreferences_ext_notification_plugin_alert_message_tag 130
|
||||||
|
#define RadioConfig_UserPreferences_ext_notification_plugin_alert_bell_tag 131
|
||||||
#define RouteDiscovery_route_tag 2
|
#define RouteDiscovery_route_tag 2
|
||||||
#define User_id_tag 1
|
#define User_id_tag 1
|
||||||
#define User_long_name_tag 2
|
#define User_long_name_tag 2
|
||||||
@@ -434,7 +452,7 @@ extern "C" {
|
|||||||
#define SubPacket_user_tag 4
|
#define SubPacket_user_tag 4
|
||||||
#define SubPacket_route_request_tag 6
|
#define SubPacket_route_request_tag 6
|
||||||
#define SubPacket_route_reply_tag 7
|
#define SubPacket_route_reply_tag 7
|
||||||
#define SubPacket_route_error_tag 13
|
#define SubPacket_error_reason_tag 13
|
||||||
#define SubPacket_original_id_tag 2
|
#define SubPacket_original_id_tag 2
|
||||||
#define SubPacket_want_response_tag 5
|
#define SubPacket_want_response_tag 5
|
||||||
#define SubPacket_dest_tag 9
|
#define SubPacket_dest_tag 9
|
||||||
@@ -501,7 +519,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,data,data), 3) \
|
|||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,user,user), 4) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload,user,user), 4) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,route_request,route_request), 6) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload,route_request,route_request), 6) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload,route_reply,route_reply), 7) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload,route_reply,route_reply), 7) \
|
||||||
X(a, STATIC, ONEOF, UENUM, (payload,route_error,route_error), 13) \
|
X(a, STATIC, ONEOF, UENUM, (payload,error_reason,error_reason), 13) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, original_id, 2) \
|
X(a, STATIC, SINGULAR, UINT32, original_id, 2) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, want_response, 5) \
|
X(a, STATIC, SINGULAR, BOOL, want_response, 5) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, dest, 9) \
|
X(a, STATIC, SINGULAR, UINT32, dest, 9) \
|
||||||
@@ -584,7 +602,14 @@ X(a, STATIC, SINGULAR, BOOL, serialplugin_enabled, 120) \
|
|||||||
X(a, STATIC, SINGULAR, BOOL, serialplugin_echo, 121) \
|
X(a, STATIC, SINGULAR, BOOL, serialplugin_echo, 121) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, serialplugin_rxd, 122) \
|
X(a, STATIC, SINGULAR, UINT32, serialplugin_rxd, 122) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, serialplugin_txd, 123) \
|
X(a, STATIC, SINGULAR, UINT32, serialplugin_txd, 123) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, serialplugin_timeout, 124)
|
X(a, STATIC, SINGULAR, UINT32, serialplugin_timeout, 124) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, serialplugin_mode, 125) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_enabled, 126) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, ext_notification_plugin_output_ms, 127) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, ext_notification_plugin_output, 128) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_active, 129) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_alert_message, 130) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_alert_bell, 131)
|
||||||
#define RadioConfig_UserPreferences_CALLBACK NULL
|
#define RadioConfig_UserPreferences_CALLBACK NULL
|
||||||
#define RadioConfig_UserPreferences_DEFAULT NULL
|
#define RadioConfig_UserPreferences_DEFAULT NULL
|
||||||
|
|
||||||
@@ -696,13 +721,13 @@ extern const pb_msgdesc_t ToRadio_msg;
|
|||||||
#define SubPacket_size 275
|
#define SubPacket_size 275
|
||||||
#define MeshPacket_size 320
|
#define MeshPacket_size 320
|
||||||
#define ChannelSettings_size 95
|
#define ChannelSettings_size 95
|
||||||
#define RadioConfig_size 349
|
#define RadioConfig_size 382
|
||||||
#define RadioConfig_UserPreferences_size 249
|
#define RadioConfig_UserPreferences_size 282
|
||||||
#define NodeInfo_size 132
|
#define NodeInfo_size 132
|
||||||
#define MyNodeInfo_size 106
|
#define MyNodeInfo_size 106
|
||||||
#define LogRecord_size 81
|
#define LogRecord_size 81
|
||||||
#define FromRadio_size 358
|
#define FromRadio_size 391
|
||||||
#define ToRadio_size 353
|
#define ToRadio_size 386
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ typedef enum _PortNum {
|
|||||||
PortNum_REPLY_APP = 32,
|
PortNum_REPLY_APP = 32,
|
||||||
PortNum_IP_TUNNEL_APP = 33,
|
PortNum_IP_TUNNEL_APP = 33,
|
||||||
PortNum_SERIAL_APP = 64,
|
PortNum_SERIAL_APP = 64,
|
||||||
|
PortNum_STORE_FORWARD_APP = 65,
|
||||||
PortNum_PRIVATE_APP = 256,
|
PortNum_PRIVATE_APP = 256,
|
||||||
PortNum_ATAK_FORWARDER = 257
|
PortNum_ATAK_FORWARDER = 257
|
||||||
} PortNum;
|
} PortNum;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "nimble/NimbleDefs.h"
|
#include "nimble/NimbleDefs.h"
|
||||||
#include "services/gap/ble_svc_gap.h"
|
#include "services/gap/ble_svc_gap.h"
|
||||||
#include "services/gatt/ble_svc_gatt.h"
|
#include "services/gatt/ble_svc_gatt.h"
|
||||||
|
#include "sleep.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
|
||||||
@@ -226,16 +227,14 @@ static int gap_event(struct ble_gap_event *event, void *arg)
|
|||||||
|
|
||||||
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
|
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
|
||||||
pkey.action = event->passkey.params.action;
|
pkey.action = event->passkey.params.action;
|
||||||
DEBUG_MSG("dp: %d now:%d\n",doublepressed, now);
|
DEBUG_MSG("dp: %d now:%d\n", doublepressed, now);
|
||||||
if (doublepressed > 0 && (doublepressed + (30*1000)) > now)
|
if (doublepressed > 0 && (doublepressed + (30 * 1000)) > now) {
|
||||||
{
|
|
||||||
DEBUG_MSG("User has overridden passkey or no display available\n");
|
DEBUG_MSG("User has overridden passkey or no display available\n");
|
||||||
pkey.passkey = defaultBLEPin;
|
pkey.passkey = defaultBLEPin;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
DEBUG_MSG("Using random passkey\n");
|
DEBUG_MSG("Using random passkey\n");
|
||||||
pkey.passkey = random(
|
pkey.passkey = random(
|
||||||
100000, 999999); // This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
|
100000, 999999); // This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
|
||||||
}
|
}
|
||||||
DEBUG_MSG("*** Enter passkey %d on the peer side ***\n", pkey.passkey);
|
DEBUG_MSG("*** Enter passkey %d on the peer side ***\n", pkey.passkey);
|
||||||
|
|
||||||
@@ -395,7 +394,6 @@ void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper function that implements simple read and write handling for a uint32_t
|
* A helper function that implements simple read and write handling for a uint32_t
|
||||||
*
|
*
|
||||||
@@ -449,8 +447,7 @@ int chr_readwrite8(uint8_t *v, size_t vlen, struct ble_gatt_access_ctxt *ctxt)
|
|||||||
if (len < vlen) {
|
if (len < vlen) {
|
||||||
DEBUG_MSG("Error: wrongsized write\n");
|
DEBUG_MSG("Error: wrongsized write\n");
|
||||||
return BLE_ATT_ERR_UNLIKELY;
|
return BLE_ATT_ERR_UNLIKELY;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
DEBUG_MSG("BLE writing bytes\n");
|
DEBUG_MSG("BLE writing bytes\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -465,7 +462,21 @@ void disablePin()
|
|||||||
{
|
{
|
||||||
DEBUG_MSG("User Override, disabling bluetooth pin requirement\n");
|
DEBUG_MSG("User Override, disabling bluetooth pin requirement\n");
|
||||||
// keep track of when it was pressed, so we know it was within X seconds
|
// keep track of when it was pressed, so we know it was within X seconds
|
||||||
doublepressed = millis();
|
|
||||||
|
// Flash the LED
|
||||||
|
setLed(true);
|
||||||
|
delay(100);
|
||||||
|
setLed(false);
|
||||||
|
delay(100);
|
||||||
|
setLed(true);
|
||||||
|
delay(100);
|
||||||
|
setLed(false);
|
||||||
|
delay(100);
|
||||||
|
setLed(true);
|
||||||
|
delay(100);
|
||||||
|
setLed(false);
|
||||||
|
|
||||||
|
doublepressed = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This routine is called multiple times, once each time we come back from sleep
|
// This routine is called multiple times, once each time we come back from sleep
|
||||||
@@ -549,7 +560,7 @@ void setBluetoothEnable(bool on)
|
|||||||
firstTime = 0;
|
firstTime = 0;
|
||||||
} else {
|
} else {
|
||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
initWifi(0);
|
initWifi(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,8 +16,14 @@ static void printUsageErrorMsg(uint32_t cfsr)
|
|||||||
cfsr >>= SCB_CFSR_USGFAULTSR_Pos; // right shift to lsb
|
cfsr >>= SCB_CFSR_USGFAULTSR_Pos; // right shift to lsb
|
||||||
if ((cfsr & (1 << 9)) != 0)
|
if ((cfsr & (1 << 9)) != 0)
|
||||||
FAULT_MSG("Divide by zero\n");
|
FAULT_MSG("Divide by zero\n");
|
||||||
if ((cfsr & (1 << 8)) != 0)
|
else if ((cfsr & (1 << 8)) != 0)
|
||||||
FAULT_MSG("Unaligned\n");
|
FAULT_MSG("Unaligned\n");
|
||||||
|
else if ((cfsr & (1 << 1)) != 0)
|
||||||
|
FAULT_MSG("Invalid state\n");
|
||||||
|
else if ((cfsr & (1 << 0)) != 0)
|
||||||
|
FAULT_MSG("Invalid instruction\n");
|
||||||
|
else
|
||||||
|
FAULT_MSG("FIXME add to printUsageErrorMsg!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printBusErrorMsg(uint32_t cfsr)
|
static void printBusErrorMsg(uint32_t cfsr)
|
||||||
@@ -71,8 +77,9 @@ extern "C" void HardFault_Impl(uint32_t stack[])
|
|||||||
|
|
||||||
FAULT_MSG("Done with fault report - Waiting to reboot\n");
|
FAULT_MSG("Done with fault report - Waiting to reboot\n");
|
||||||
asm volatile("bkpt #01"); // Enter the debugger if one is connected
|
asm volatile("bkpt #01"); // Enter the debugger if one is connected
|
||||||
while (1)
|
|
||||||
;
|
// Don't spin, so that the debugger will let the user step to next instruction
|
||||||
|
// while (1) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void HardFault_Handler(void)
|
extern "C" void HardFault_Handler(void)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ void getMacAddr(uint8_t *dmac)
|
|||||||
NRF52Bluetooth *nrf52Bluetooth;
|
NRF52Bluetooth *nrf52Bluetooth;
|
||||||
|
|
||||||
static bool bleOn = false;
|
static bool bleOn = false;
|
||||||
static const bool enableBle = true; // Set to false for easier debugging
|
static const bool enableBle = false; // Set to false for easier debugging
|
||||||
|
|
||||||
void setBluetoothEnable(bool on)
|
void setBluetoothEnable(bool on)
|
||||||
{
|
{
|
||||||
|
|||||||
176
src/plugins/ExternalNotificationPlugin.cpp
Normal file
176
src/plugins/ExternalNotificationPlugin.cpp
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#include "ExternalNotificationPlugin.h"
|
||||||
|
#include "MeshService.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
#include "Router.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Documentation:
|
||||||
|
https://github.com/mc-hamster/Meshtastic-device/blob/master/docs/software/plugins/ExternalNotificationPlugin.md
|
||||||
|
|
||||||
|
This plugin supports:
|
||||||
|
https://github.com/meshtastic/Meshtastic-device/issues/654
|
||||||
|
|
||||||
|
|
||||||
|
Quick reference:
|
||||||
|
|
||||||
|
radioConfig.preferences.ext_notification_plugin_enabled
|
||||||
|
0 = Disabled (Default)
|
||||||
|
1 = Enabled
|
||||||
|
|
||||||
|
radioConfig.preferences.ext_notification_plugin_active
|
||||||
|
0 = Active Low (Default)
|
||||||
|
1 = Active High
|
||||||
|
|
||||||
|
radioConfig.preferences.ext_notification_plugin_alert_message
|
||||||
|
0 = Disabled (Default)
|
||||||
|
1 = Alert when a text message comes
|
||||||
|
|
||||||
|
radioConfig.preferences.ext_notification_plugin_alert_bell
|
||||||
|
0 = Disabled (Default)
|
||||||
|
1 = Alert when the bell character is received
|
||||||
|
|
||||||
|
radioConfig.preferences.ext_notification_plugin_output
|
||||||
|
GPIO of the output. (Default = 13)
|
||||||
|
|
||||||
|
radioConfig.preferences.ext_notification_plugin_output_ms
|
||||||
|
Amount of time in ms for the alert. Default is 1000.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default configurations
|
||||||
|
#define EXT_NOTIFICATION_PLUGIN_OUTPUT 13
|
||||||
|
#define EXT_NOTIFICATION_PLUGIN_OUTPUT_MS 1000
|
||||||
|
|
||||||
|
#define ASCII_BELL 0x07
|
||||||
|
|
||||||
|
ExternalNotificationPlugin *externalNotificationPlugin;
|
||||||
|
ExternalNotificationPluginRadio *externalNotificationPluginRadio;
|
||||||
|
|
||||||
|
ExternalNotificationPlugin::ExternalNotificationPlugin() : concurrency::OSThread("ExternalNotificationPlugin") {}
|
||||||
|
|
||||||
|
bool externalCurrentState = 0;
|
||||||
|
uint32_t externalTurnedOn = 0;
|
||||||
|
|
||||||
|
int32_t ExternalNotificationPlugin::runOnce()
|
||||||
|
{
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
|
||||||
|
/*
|
||||||
|
Uncomment the preferences below if you want to use the plugin
|
||||||
|
without having to configure it from the PythonAPI or WebUI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// radioConfig.preferences.ext_notification_plugin_enabled = 1;
|
||||||
|
// radioConfig.preferences.ext_notification_plugin_alert_message = 1;
|
||||||
|
|
||||||
|
// radioConfig.preferences.ext_notification_plugin_active = 1;
|
||||||
|
// radioConfig.preferences.ext_notification_plugin_alert_bell = 1;
|
||||||
|
// radioConfig.preferences.ext_notification_plugin_output_ms = 1000;
|
||||||
|
// radioConfig.preferences.ext_notification_plugin_output = 13;
|
||||||
|
|
||||||
|
if (radioConfig.preferences.ext_notification_plugin_enabled) {
|
||||||
|
|
||||||
|
if (firstTime) {
|
||||||
|
|
||||||
|
DEBUG_MSG("Initializing External Notification Plugin\n");
|
||||||
|
|
||||||
|
// Set the direction of a pin
|
||||||
|
pinMode((radioConfig.preferences.ext_notification_plugin_output
|
||||||
|
? radioConfig.preferences.ext_notification_plugin_output
|
||||||
|
: EXT_NOTIFICATION_PLUGIN_OUTPUT),
|
||||||
|
OUTPUT);
|
||||||
|
|
||||||
|
// Turn off the pin
|
||||||
|
setExternalOff();
|
||||||
|
|
||||||
|
externalNotificationPluginRadio = new ExternalNotificationPluginRadio();
|
||||||
|
|
||||||
|
firstTime = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (externalCurrentState) {
|
||||||
|
|
||||||
|
// If the output is turned on, turn it back off after the given period of time.
|
||||||
|
if (externalTurnedOn + (radioConfig.preferences.ext_notification_plugin_output_ms
|
||||||
|
? radioConfig.preferences.ext_notification_plugin_output_ms
|
||||||
|
: EXT_NOTIFICATION_PLUGIN_OUTPUT_MS) <
|
||||||
|
millis()) {
|
||||||
|
DEBUG_MSG("Turning off external notification\n");
|
||||||
|
setExternalOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (25);
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("External Notification Plugin Disabled\n");
|
||||||
|
|
||||||
|
return (INT32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalNotificationPlugin::setExternalOn()
|
||||||
|
{
|
||||||
|
externalCurrentState = 1;
|
||||||
|
externalTurnedOn = millis();
|
||||||
|
|
||||||
|
digitalWrite((radioConfig.preferences.ext_notification_plugin_output ? radioConfig.preferences.ext_notification_plugin_output
|
||||||
|
: EXT_NOTIFICATION_PLUGIN_OUTPUT),
|
||||||
|
(radioConfig.preferences.ext_notification_plugin_active ? true : false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalNotificationPlugin::setExternalOff()
|
||||||
|
{
|
||||||
|
externalCurrentState = 0;
|
||||||
|
|
||||||
|
digitalWrite((radioConfig.preferences.ext_notification_plugin_output ? radioConfig.preferences.ext_notification_plugin_output
|
||||||
|
: EXT_NOTIFICATION_PLUGIN_OUTPUT),
|
||||||
|
(radioConfig.preferences.ext_notification_plugin_active ? false : true));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------
|
||||||
|
|
||||||
|
bool ExternalNotificationPluginRadio::handleReceived(const MeshPacket &mp)
|
||||||
|
{
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
|
||||||
|
if (radioConfig.preferences.ext_notification_plugin_enabled) {
|
||||||
|
|
||||||
|
auto &p = mp.decoded.data;
|
||||||
|
|
||||||
|
if (mp.from != nodeDB.getNodeNum()) {
|
||||||
|
|
||||||
|
// TODO: This may be a problem if messages are sent in unicide, but I'm not sure if it will.
|
||||||
|
// Need to know if and how this could be a problem.
|
||||||
|
if (radioConfig.preferences.ext_notification_plugin_alert_bell) {
|
||||||
|
DEBUG_MSG("externalNotificationPlugin - Notification Bell\n");
|
||||||
|
for (int i = 0; i < p.payload.size; i++) {
|
||||||
|
if (p.payload.bytes[i] == ASCII_BELL) {
|
||||||
|
externalNotificationPlugin->setExternalOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radioConfig.preferences.ext_notification_plugin_alert_message) {
|
||||||
|
DEBUG_MSG("externalNotificationPlugin - Notification Plugin\n");
|
||||||
|
externalNotificationPlugin->setExternalOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("External Notification Plugin Disabled\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true; // Let others look at this message also if they want
|
||||||
|
}
|
||||||
47
src/plugins/ExternalNotificationPlugin.h
Normal file
47
src/plugins/ExternalNotificationPlugin.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SinglePortPlugin.h"
|
||||||
|
#include "concurrency/OSThread.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
|
class ExternalNotificationPlugin : private concurrency::OSThread
|
||||||
|
{
|
||||||
|
bool firstTime = 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExternalNotificationPlugin();
|
||||||
|
|
||||||
|
void setExternalOn();
|
||||||
|
void setExternalOff();
|
||||||
|
void getExternal();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual int32_t runOnce();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ExternalNotificationPlugin *externalNotificationPlugin;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Radio interface for ExternalNotificationPlugin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ExternalNotificationPluginRadio : public SinglePortPlugin
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExternalNotificationPluginRadio() : SinglePortPlugin("ExternalNotificationPluginRadio", PortNum_TEXT_MESSAGE_APP) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//virtual MeshPacket *allocReply();
|
||||||
|
|
||||||
|
/** Called to handle a particular incoming message
|
||||||
|
|
||||||
|
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||||
|
*/
|
||||||
|
virtual bool handleReceived(const MeshPacket &mp);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ExternalNotificationPluginRadio *externalNotificationPluginRadio;
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "plugins/ExternalNotificationPlugin.h"
|
||||||
#include "plugins/NodeInfoPlugin.h"
|
#include "plugins/NodeInfoPlugin.h"
|
||||||
#include "plugins/PositionPlugin.h"
|
#include "plugins/PositionPlugin.h"
|
||||||
#include "plugins/RemoteHardwarePlugin.h"
|
#include "plugins/RemoteHardwarePlugin.h"
|
||||||
@@ -23,7 +24,7 @@ void setupPlugins()
|
|||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
// Only run on an esp32 based device.
|
// Only run on an esp32 based device.
|
||||||
|
|
||||||
new SerialPlugin(); // Maintained by MC Hamster (Jm Casler) jm@casler.org
|
new SerialPlugin(); // Maintained by MC Hamster (Jm Casler) jm@casler.org
|
||||||
|
new ExternalNotificationPlugin(); // Maintained by MC Hamster (Jm Casler) jm@casler.org
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _VARIANT_TTGO_EINK_V1_
|
#ifndef _VARIANT_TTGO_EINK_V1_0_
|
||||||
#define _VARIANT_TTGO_EINK_V1_
|
#define _VARIANT_TTGO_EINK_V1_0_
|
||||||
|
|
||||||
/** Master clock frequency */
|
/** Master clock frequency */
|
||||||
#define VARIANT_MCK (64000000ul)
|
#define VARIANT_MCK (64000000ul)
|
||||||
@@ -99,9 +99,9 @@ extern "C" {
|
|||||||
#define NUM_ANALOG_OUTPUTS (0)
|
#define NUM_ANALOG_OUTPUTS (0)
|
||||||
|
|
||||||
// LEDs
|
// LEDs
|
||||||
#define PIN_LED1 (0 + 13) // green (but red on my prototype)
|
#define PIN_LED1 (0 + 13) // red (confirmed on 1.0 board)
|
||||||
#define PIN_LED2 (0 + 15) // blue (but red on my prototype)
|
#define PIN_LED2 (0 + 14) // blue (seems busted!)
|
||||||
#define PIN_LED3 (0 + 14) // red (not functional on my prototype)
|
#define PIN_LED3 (0 + 15) // green (seems busted!)
|
||||||
|
|
||||||
#define LED_RED PIN_LED3
|
#define LED_RED PIN_LED3
|
||||||
#define LED_GREEN PIN_LED1
|
#define LED_GREEN PIN_LED1
|
||||||
@@ -149,7 +149,7 @@ No longer populated on PCB
|
|||||||
*/
|
*/
|
||||||
#define WIRE_INTERFACES_COUNT 1
|
#define WIRE_INTERFACES_COUNT 1
|
||||||
|
|
||||||
#define PIN_WIRE_SDA (26) // Not connected on board?
|
#define PIN_WIRE_SDA (26)
|
||||||
#define PIN_WIRE_SCL (27)
|
#define PIN_WIRE_SCL (27)
|
||||||
|
|
||||||
/* touch sensor, active high */
|
/* touch sensor, active high */
|
||||||
@@ -167,8 +167,8 @@ External serial flash WP25R1635FZUIL0
|
|||||||
#define PIN_QSPI_CS (32 + 15)
|
#define PIN_QSPI_CS (32 + 15)
|
||||||
#define PIN_QSPI_IO0 (32 + 12) // MOSI if using two bit interface
|
#define PIN_QSPI_IO0 (32 + 12) // MOSI if using two bit interface
|
||||||
#define PIN_QSPI_IO1 (32 + 13) // MISO if using two bit interface
|
#define PIN_QSPI_IO1 (32 + 13) // MISO if using two bit interface
|
||||||
//#define PIN_QSPI_IO2 22 // WP if using two bit interface (i.e. not used)
|
#define PIN_QSPI_IO2 (0 + 7) // WP if using two bit interface (i.e. not used)
|
||||||
//#define PIN_QSPI_IO3 23 // HOLD if using two bit interface (i.e. not used)
|
#define PIN_QSPI_IO3 (0 + 5) // HOLD if using two bit interface (i.e. not used)
|
||||||
|
|
||||||
// On-board QSPI Flash
|
// On-board QSPI Flash
|
||||||
#define EXTERNAL_FLASH_DEVICES MX25R1635F
|
#define EXTERNAL_FLASH_DEVICES MX25R1635F
|
||||||
@@ -196,7 +196,7 @@ External serial flash WP25R1635FZUIL0
|
|||||||
* eink display pins
|
* eink display pins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PIN_EINK_EN (32 + 11)
|
#define PIN_EINK_EN (32 + 11) // Note: this is really just backlight power
|
||||||
#define PIN_EINK_CS (0 + 30)
|
#define PIN_EINK_CS (0 + 30)
|
||||||
#define PIN_EINK_BUSY (0 + 3)
|
#define PIN_EINK_BUSY (0 + 3)
|
||||||
#define PIN_EINK_DC (0 + 28)
|
#define PIN_EINK_DC (0 + 28)
|
||||||
@@ -223,7 +223,8 @@ External serial flash WP25R1635FZUIL0
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#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
|
||||||
#define PIN_GPS_PPS (32 + 4) // Pulse per second input from the GPS
|
// Seems to be missing on this new board
|
||||||
|
// #define PIN_GPS_PPS (32 + 4) // Pulse per second input from the GPS
|
||||||
#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
|
||||||
|
|
||||||
@@ -242,6 +243,8 @@ External serial flash WP25R1635FZUIL0
|
|||||||
#define PIN_SPI_MOSI (0 + 22)
|
#define PIN_SPI_MOSI (0 + 22)
|
||||||
#define PIN_SPI_SCK (0 + 19)
|
#define PIN_SPI_SCK (0 + 19)
|
||||||
|
|
||||||
|
#define PIN_PWR_EN (0 + 6)
|
||||||
|
|
||||||
// To debug via the segger JLINK console rather than the CDC-ACM serial device
|
// To debug via the segger JLINK console rather than the CDC-ACM serial device
|
||||||
// #define USE_SEGGER
|
// #define USE_SEGGER
|
||||||
|
|
||||||
|
|||||||
44
variants/eink0.1/variant.cpp
Normal file
44
variants/eink0.1/variant.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "variant.h"
|
||||||
|
#include "nrf.h"
|
||||||
|
#include "wiring_constants.h"
|
||||||
|
#include "wiring_digital.h"
|
||||||
|
|
||||||
|
const uint32_t g_ADigitalPinMap[] = {
|
||||||
|
// P0 - pins 0 and 1 are hardwired for xtal and should never be enabled
|
||||||
|
0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
|
||||||
|
// P1
|
||||||
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||||
|
|
||||||
|
void initVariant()
|
||||||
|
{
|
||||||
|
// LED1 & LED2
|
||||||
|
pinMode(PIN_LED1, OUTPUT);
|
||||||
|
ledOff(PIN_LED1);
|
||||||
|
|
||||||
|
pinMode(PIN_LED2, OUTPUT);
|
||||||
|
ledOff(PIN_LED2);
|
||||||
|
|
||||||
|
pinMode(PIN_LED3, OUTPUT);
|
||||||
|
ledOff(PIN_LED3);
|
||||||
|
}
|
||||||
256
variants/eink0.1/variant.h
Normal file
256
variants/eink0.1/variant.h
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VARIANT_TTGO_EINK_V0_1_
|
||||||
|
#define _VARIANT_TTGO_EINK_V0_1_
|
||||||
|
|
||||||
|
/** Master clock frequency */
|
||||||
|
#define VARIANT_MCK (64000000ul)
|
||||||
|
|
||||||
|
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||||
|
|
||||||
|
/*
|
||||||
|
@geeksville eink TODO:
|
||||||
|
|
||||||
|
soonish:
|
||||||
|
DONE hook cdc acm device to debug output
|
||||||
|
DONE fix bootloader to use two buttons - remove bootloader hacks
|
||||||
|
DONE get second button working in app load
|
||||||
|
DONE use tp_ser_io as a button, it goes high when pressed unify eink display classes
|
||||||
|
fix display width and height
|
||||||
|
clean up eink drawing to not have the nasty timeout hack
|
||||||
|
measure current draws
|
||||||
|
DONE put eink to sleep when we think the screen is off
|
||||||
|
enable gps sleep mode
|
||||||
|
turn off txco on lora?
|
||||||
|
make screen.adjustBrightness() a nop on eink screens
|
||||||
|
|
||||||
|
later:
|
||||||
|
enable flash on qspi.
|
||||||
|
fix floating point SEGGER printf on nrf52 - see "new NMEA GPS pos"
|
||||||
|
add factory/power on self test
|
||||||
|
|
||||||
|
feedback to give:
|
||||||
|
|
||||||
|
* bootloader is finished
|
||||||
|
|
||||||
|
* the capacitive touch sensor works, though I'm not sure what use you are intending for it
|
||||||
|
|
||||||
|
* remove ipx connector for nfc, instead use two caps and loop traces on the back of the board as an antenna?
|
||||||
|
|
||||||
|
* the i2c RTC seems to talk fine on the i2c bus. However, I'm not sure of the utility of that part. Instead I'd be in favor of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
* move BAT1 to power the GPS VBACKUP instead per page 6 of the Air530 datasheet. And remove the i2c RTC entirely.
|
||||||
|
|
||||||
|
* remove the cp2014 chip.
|
||||||
|
|
||||||
|
* I've made the serial flash chip work, but if you do a new spin of the board I recommend:
|
||||||
|
connect pin 3 and pin 7 of U4 to spare GPIOs on the processor (instead of their current connections),
|
||||||
|
This would allow using 4 bit wide interface mode to the serial flash - doubling the transfer speed! see example here:
|
||||||
|
https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/nrf52840_DK/hw_external_memory.html?cp=4_0_4_7_4
|
||||||
|
Once again - I'm glad you added that external flash chip.
|
||||||
|
|
||||||
|
* Power measurements
|
||||||
|
When powered by 4V battery
|
||||||
|
|
||||||
|
CPU on, lora radio RX mode, bluetooth enabled, GPS trying to lock. total draw 43mA
|
||||||
|
CPU on, lora radio RX mode, bluetooth enabled, GPS super low power sleep mode. Total draw 20mA
|
||||||
|
CPU on, lora radio TX mode, bluetooth enabled, GPS super low power sleep mode. Total draw 132mA
|
||||||
|
|
||||||
|
Note: power consumption while connected via BLE to a phone almost identical.
|
||||||
|
|
||||||
|
Note: eink display for all tests was in sleep mode most of the time. Current draw during the brief periods while the eink was being drawn was not
|
||||||
|
measured (but it was low).
|
||||||
|
|
||||||
|
Note: Turning off EINK PWR_ON produces no noticeable power savings over just putting the eink display into sleep mode.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "WVariant.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// Number of pins defined in PinDescription array
|
||||||
|
#define PINS_COUNT (48)
|
||||||
|
#define NUM_DIGITAL_PINS (48)
|
||||||
|
#define NUM_ANALOG_INPUTS (1)
|
||||||
|
#define NUM_ANALOG_OUTPUTS (0)
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
#define PIN_LED1 (0 + 13) // green (but red on my prototype)
|
||||||
|
#define PIN_LED2 (0 + 15) // blue (but red on my prototype)
|
||||||
|
#define PIN_LED3 (0 + 14) // red (not functional on my prototype)
|
||||||
|
|
||||||
|
#define LED_RED PIN_LED3
|
||||||
|
#define LED_GREEN PIN_LED1
|
||||||
|
#define LED_BLUE PIN_LED2
|
||||||
|
|
||||||
|
#define LED_BUILTIN LED_GREEN
|
||||||
|
#define LED_CONN PIN_BLUE
|
||||||
|
|
||||||
|
#define LED_STATE_ON 0 // State when LED is lit
|
||||||
|
#define LED_INVERTED 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buttons
|
||||||
|
*/
|
||||||
|
#define PIN_BUTTON1 (32 + 10)
|
||||||
|
#define PIN_BUTTON2 (0 + 18) // 0.18 is labeled on the board as RESET but we configure it in the bootloader as a regular GPIO
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analog pins
|
||||||
|
*/
|
||||||
|
#define PIN_A0 (4) // Battery ADC
|
||||||
|
|
||||||
|
#define BATTERY_PIN PIN_A0
|
||||||
|
|
||||||
|
static const uint8_t A0 = PIN_A0;
|
||||||
|
|
||||||
|
#define ADC_RESOLUTION 14
|
||||||
|
|
||||||
|
#define PIN_NFC1 (9)
|
||||||
|
#define PIN_NFC2 (10)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial interfaces
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
No longer populated on PCB
|
||||||
|
*/
|
||||||
|
//#define PIN_SERIAL2_RX (0 + 6)
|
||||||
|
//#define PIN_SERIAL2_TX (0 + 8)
|
||||||
|
// #define PIN_SERIAL2_EN (0 + 17)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Wire Interfaces
|
||||||
|
*/
|
||||||
|
#define WIRE_INTERFACES_COUNT 1
|
||||||
|
|
||||||
|
#define PIN_WIRE_SDA (26) // Not connected on board?
|
||||||
|
#define PIN_WIRE_SCL (27)
|
||||||
|
|
||||||
|
/* touch sensor, active high */
|
||||||
|
|
||||||
|
#define TP_SER_IO (0 + 11)
|
||||||
|
|
||||||
|
#define PIN_RTC_INT (0 + 16) // Interrupt from the PCF8563 RTC
|
||||||
|
|
||||||
|
/*
|
||||||
|
External serial flash WP25R1635FZUIL0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// QSPI Pins
|
||||||
|
#define PIN_QSPI_SCK (32 + 14)
|
||||||
|
#define PIN_QSPI_CS (32 + 15)
|
||||||
|
#define PIN_QSPI_IO0 (32 + 12) // MOSI if using two bit interface
|
||||||
|
#define PIN_QSPI_IO1 (32 + 13) // MISO if using two bit interface
|
||||||
|
//#define PIN_QSPI_IO2 22 // WP if using two bit interface (i.e. not used)
|
||||||
|
//#define PIN_QSPI_IO3 23 // HOLD if using two bit interface (i.e. not used)
|
||||||
|
|
||||||
|
// On-board QSPI Flash
|
||||||
|
#define EXTERNAL_FLASH_DEVICES MX25R1635F
|
||||||
|
#define EXTERNAL_FLASH_USE_QSPI
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lora radio
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SX1262_CS (0 + 24) // FIXME - we really should define LORA_CS instead
|
||||||
|
#define SX1262_DIO1 (0 + 20)
|
||||||
|
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
|
||||||
|
#define SX1262_DIO3 \
|
||||||
|
(0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main
|
||||||
|
// CPU?
|
||||||
|
#define SX1262_BUSY (0 + 17)
|
||||||
|
#define SX1262_RESET (0 + 25)
|
||||||
|
#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that
|
||||||
|
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
|
||||||
|
// code)
|
||||||
|
|
||||||
|
// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* eink display pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_EINK_EN (32 + 11)
|
||||||
|
#define PIN_EINK_CS (0 + 30)
|
||||||
|
#define PIN_EINK_BUSY (0 + 3)
|
||||||
|
#define PIN_EINK_DC (0 + 28)
|
||||||
|
#define PIN_EINK_RES (0 + 2)
|
||||||
|
#define PIN_EINK_SCLK (0 + 31)
|
||||||
|
#define PIN_EINK_MOSI (0 + 29) // also called SDI
|
||||||
|
|
||||||
|
// Controls power for the eink display - Board power is enabled either by VBUS from USB or the CPU asserting PWR_ON
|
||||||
|
// FIXME - I think this is actually just the board power enable - it enables power to the CPU also
|
||||||
|
#define PIN_EINK_PWR_ON (0 + 12)
|
||||||
|
|
||||||
|
#define HAS_EINK
|
||||||
|
|
||||||
|
// No screen wipes on eink
|
||||||
|
#define SCREEN_TRANSITION_MSECS 0
|
||||||
|
|
||||||
|
#define PIN_SPI1_MISO \
|
||||||
|
(32 + 7) // FIXME not really needed, but for now the SPI code requires something to be defined, pick an used GPIO
|
||||||
|
#define PIN_SPI1_MOSI PIN_EINK_MOSI
|
||||||
|
#define PIN_SPI1_SCK PIN_EINK_SCLK
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Air530 GPS pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_GPS_WAKE (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
|
||||||
|
#define PIN_GPS_PPS (32 + 4) // Pulse per second input from the GPS
|
||||||
|
#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 HAS_AIR530_GPS
|
||||||
|
|
||||||
|
#define PIN_SERIAL1_RX PIN_GPS_TX
|
||||||
|
#define PIN_SERIAL1_TX PIN_GPS_RX
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI Interfaces
|
||||||
|
*/
|
||||||
|
#define SPI_INTERFACES_COUNT 2
|
||||||
|
|
||||||
|
// For LORA, spi 0
|
||||||
|
#define PIN_SPI_MISO (0 + 23)
|
||||||
|
#define PIN_SPI_MOSI (0 + 22)
|
||||||
|
#define PIN_SPI_SCK (0 + 19)
|
||||||
|
|
||||||
|
// To debug via the segger JLINK console rather than the CDC-ACM serial device
|
||||||
|
// #define USE_SEGGER
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Arduino objects - C++ only
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 1
|
major = 1
|
||||||
minor = 1
|
minor = 1
|
||||||
build = 33
|
build = 42
|
||||||
|
|||||||
Reference in New Issue
Block a user