mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-07-28 09:29:23 +00:00
Merge branch 'PowerSaving-v16-iotthinks' into halo-direct-path-retries
# Conflicts: # examples/simple_repeater/MyMesh.cpp # examples/simple_repeater/MyMesh.h # src/Mesh.cpp # src/helpers/CommonCLI.cpp # src/helpers/CommonCLI.h # src/helpers/ESP32Board.h
This commit is contained in:
@@ -0,0 +1 @@
|
||||
github: meshcore-dev
|
||||
@@ -4,7 +4,7 @@ runs:
|
||||
steps:
|
||||
|
||||
- name: Init Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pip
|
||||
@@ -12,9 +12,9 @@ runs:
|
||||
key: ${{ runner.os }}-pio
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Install PlatformIO
|
||||
shell: bash
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Clone Repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/actions/setup-build-environment
|
||||
@@ -27,13 +27,13 @@ jobs:
|
||||
run: /usr/bin/env bash build.sh build-companion-firmwares
|
||||
|
||||
- name: Upload Workflow Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: companion-firmwares
|
||||
path: out
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v3
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
name: Companion Firmware ${{ env.GIT_TAG_VERSION }}
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Clone Repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/actions/setup-build-environment
|
||||
@@ -27,13 +27,13 @@ jobs:
|
||||
run: /usr/bin/env bash build.sh build-repeater-firmwares
|
||||
|
||||
- name: Upload Workflow Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: repeater-firmwares
|
||||
path: out
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v3
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
name: Repeater Firmware ${{ env.GIT_TAG_VERSION }}
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Clone Repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/actions/setup-build-environment
|
||||
@@ -27,13 +27,13 @@ jobs:
|
||||
run: /usr/bin/env bash build.sh build-room-server-firmwares
|
||||
|
||||
- name: Upload Workflow Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: room-server-firmwares
|
||||
path: out
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v3
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
name: Room Server Firmware ${{ env.GIT_TAG_VERSION }}
|
||||
|
||||
@@ -15,12 +15,12 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
ruby-version: 3.x
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
mkdocs build
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
uses: peaceiris/actions-gh-pages@v4.1.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
cname: docs.meshcore.io
|
||||
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone Repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/actions/setup-build-environment
|
||||
|
||||
Vendored
+1
-2
@@ -1,7 +1,6 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"pioarduino.pioarduino-ide",
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
|
||||
@@ -28,7 +28,7 @@ MeshCore provides the ability to create wireless mesh networks, similar to Mesht
|
||||
|
||||
## 🚀 How to Get Started
|
||||
|
||||
- Watch the [MeshCore Intro Video](https://www.youtube.com/watch?v=t1qne8uJBAc) by Andy Kirby.
|
||||
- Watch the [MeshCore QuickStart Playlist](https://www.youtube.com/watch?v=iaFltojJrAc&list=PLshzThxhw4O4WU_iZo3NmNZOv6KMrUuF9) by The Comms Channel
|
||||
- Watch the [MeshCore Technical Presentation](https://www.youtube.com/watch?v=OwmkVkZQTf4) by Liam Cottle.
|
||||
- Read through our [Frequently Asked Questions](./docs/faq.md) and [Documentation](https://docs.meshcore.io).
|
||||
- Flash the MeshCore firmware on a supported device.
|
||||
|
||||
@@ -7,6 +7,9 @@ MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000
|
||||
|
||||
/* To keep data in RAM across resets */
|
||||
PERSISTENT_RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 8
|
||||
|
||||
/* SRAM required by Softdevice depend on
|
||||
* - Attribute Table Size (Number of Services and Characteristics)
|
||||
* - Vendor UUID count
|
||||
@@ -14,11 +17,19 @@ MEMORY
|
||||
* - Concurrent connection peripheral + central + secure links
|
||||
* - Event Len, HVN queue, Write CMD queue
|
||||
*/
|
||||
RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000
|
||||
RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = ALIGN(4);
|
||||
.persistent (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.persistent_magic))
|
||||
KEEP(*(.persistent_data))
|
||||
. = ALIGN(4);
|
||||
} > PERSISTENT_RAM
|
||||
|
||||
. = ALIGN(4);
|
||||
.svc_data :
|
||||
{
|
||||
@@ -33,6 +44,6 @@ SECTIONS
|
||||
KEEP(*(.fs_data))
|
||||
PROVIDE(__stop_fs_data = .);
|
||||
} > RAM
|
||||
} INSERT AFTER .data;
|
||||
}
|
||||
|
||||
INCLUDE "nrf52_common.ld"
|
||||
|
||||
@@ -7,6 +7,9 @@ MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xD4000 - 0x26000
|
||||
|
||||
/* To keep data in RAM across resets */
|
||||
PERSISTENT_RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 8
|
||||
|
||||
/* SRAM required by Softdevice depend on
|
||||
* - Attribute Table Size (Number of Services and Characteristics)
|
||||
* - Vendor UUID count
|
||||
@@ -14,11 +17,19 @@ MEMORY
|
||||
* - Concurrent connection peripheral + central + secure links
|
||||
* - Event Len, HVN queue, Write CMD queue
|
||||
*/
|
||||
RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000
|
||||
RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = ALIGN(4);
|
||||
.persistent (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.persistent_magic))
|
||||
KEEP(*(.persistent_data))
|
||||
. = ALIGN(4);
|
||||
} > PERSISTENT_RAM
|
||||
|
||||
. = ALIGN(4);
|
||||
.svc_data :
|
||||
{
|
||||
@@ -33,6 +44,6 @@ SECTIONS
|
||||
KEEP(*(.fs_data))
|
||||
PROVIDE(__stop_fs_data = .);
|
||||
} > RAM
|
||||
} INSERT AFTER .data;
|
||||
}
|
||||
|
||||
INCLUDE "nrf52_common.ld"
|
||||
|
||||
@@ -7,6 +7,9 @@ MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xED000 - 0x27000
|
||||
|
||||
/* To keep data in RAM across resets */
|
||||
PERSISTENT_RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 8
|
||||
|
||||
/* SRAM required by Softdevice depend on
|
||||
* - Attribute Table Size (Number of Services and Characteristics)
|
||||
* - Vendor UUID count
|
||||
@@ -14,11 +17,19 @@ MEMORY
|
||||
* - Concurrent connection peripheral + central + secure links
|
||||
* - Event Len, HVN queue, Write CMD queue
|
||||
*/
|
||||
RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000
|
||||
RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = ALIGN(4);
|
||||
.persistent (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.persistent_magic))
|
||||
KEEP(*(.persistent_data))
|
||||
. = ALIGN(4);
|
||||
} > PERSISTENT_RAM
|
||||
|
||||
. = ALIGN(4);
|
||||
.svc_data :
|
||||
{
|
||||
@@ -33,6 +44,6 @@ SECTIONS
|
||||
KEEP(*(.fs_data))
|
||||
PROVIDE(__stop_fs_data = .);
|
||||
} > RAM
|
||||
} INSERT AFTER .data;
|
||||
}
|
||||
|
||||
INCLUDE "nrf52_common.ld"
|
||||
|
||||
@@ -14,11 +14,19 @@ MEMORY
|
||||
* - Concurrent connection peripheral + central + secure links
|
||||
* - Event Len, HVN queue, Write CMD queue
|
||||
*/
|
||||
RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000
|
||||
RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = ALIGN(4);
|
||||
.persistent (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.persistent_magic))
|
||||
KEEP(*(.persistent_data))
|
||||
. = ALIGN(4);
|
||||
} > PERSISTENT_RAM
|
||||
|
||||
. = ALIGN(4);
|
||||
.svc_data :
|
||||
{
|
||||
@@ -33,6 +41,6 @@ SECTIONS
|
||||
KEEP(*(.fs_data))
|
||||
PROVIDE(__stop_fs_data = .);
|
||||
} > RAM
|
||||
} INSERT AFTER .data;
|
||||
}
|
||||
|
||||
INCLUDE "nrf52_common.ld"
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
# sh ./build-repeaters-iotthinks.sh
|
||||
export FIRMWARE_VERSION="PowerSaving16"
|
||||
|
||||
############# Repeaters #############
|
||||
# Commonly-used boards
|
||||
## ESP32 - 17 boards
|
||||
sh build.sh build-firmware \
|
||||
Heltec_v3_repeater \
|
||||
Heltec_WSL3_repeater \
|
||||
heltec_v4_repeater \
|
||||
Station_G2_repeater \
|
||||
T_Beam_S3_Supreme_SX1262_repeater \
|
||||
Tbeam_SX1262_repeater \
|
||||
LilyGo_T3S3_sx1262_repeater \
|
||||
Xiao_S3_WIO_repeater \
|
||||
Xiao_C3_repeater \
|
||||
Xiao_C6_repeater_ \
|
||||
Heltec_E290_repeater \
|
||||
Heltec_Wireless_Tracker_repeater \
|
||||
LilyGo_TBeam_1W_repeater \
|
||||
Xiao_S3_repeater \
|
||||
heltec_tracker_v2_repeater \
|
||||
Heltec_Wireless_Paper_repeater \
|
||||
Heltec_ct62_repeater
|
||||
|
||||
## NRF52 - 17 boards
|
||||
sh build.sh build-firmware \
|
||||
RAK_4631_repeater \
|
||||
Heltec_t114_repeater \
|
||||
Xiao_nrf52_repeater \
|
||||
Heltec_mesh_solar_repeater \
|
||||
ProMicro_repeater \
|
||||
SenseCap_Solar_repeater \
|
||||
t1000e_repeater \
|
||||
LilyGo_T-Echo_repeater \
|
||||
WioTrackerL1_repeater \
|
||||
RAK_3401_repeater \
|
||||
RAK_WisMesh_Tag_repeater \
|
||||
GAT562_30S_Mesh_Kit_repeater \
|
||||
GAT562_Mesh_Tracker_Pro_repeater \
|
||||
ikoka_nano_nrf_22dbm_repeater \
|
||||
ikoka_nano_nrf_30dbm_repeater \
|
||||
ikoka_nano_nrf_33dbm_repeater \
|
||||
ThinkNode_M1_repeater \
|
||||
Heltec_t096_repeater
|
||||
|
||||
## ESP32, SX1276 - 3 boards
|
||||
sh build.sh build-firmware \
|
||||
Heltec_v2_repeater \
|
||||
LilyGo_TLora_V2_1_1_6_repeater \
|
||||
Tbeam_SX1276_repeater
|
||||
|
||||
############# Room Server #############
|
||||
# ESP32 - 7 boards
|
||||
sh build.sh build-firmware \
|
||||
Heltec_v3_room_server \
|
||||
heltec_v4_room_server \
|
||||
LilyGo_TBeam_1W_room_server \
|
||||
Heltec_WSL3_room_server \
|
||||
Xiao_S3_room_server \
|
||||
heltec_tracker_v2_room_server \
|
||||
Heltec_Wireless_Paper_room_server
|
||||
|
||||
# NRF52 - 6 boards
|
||||
sh build.sh build-firmware \
|
||||
RAK_4631_room_server \
|
||||
Heltec_t114_room_server \
|
||||
Xiao_nrf52_room_server \
|
||||
t1000e_room_server \
|
||||
WioTrackerL1_room_server \
|
||||
RAK_3401_room_server \
|
||||
Heltec_t096_room_server
|
||||
|
||||
############# Companions BLE #############
|
||||
# NRF52 - 12 boards
|
||||
sh build.sh build-firmware \
|
||||
RAK_4631_companion_radio_ble \
|
||||
Heltec_t114_companion_radio_ble \
|
||||
Xiao_nrf52_companion_radio_ble \
|
||||
t1000e_companion_radio_ble \
|
||||
LilyGo_T-Echo_companion_radio_ble \
|
||||
WioTrackerL1_companion_radio_ble \
|
||||
RAK_3401_companion_radio_ble \
|
||||
RAK_WisMesh_Tag_companion_radio_ble \
|
||||
SenseCap_Solar_companion_radio_ble \
|
||||
ThinkNode_M1_companion_radio_ble \
|
||||
Heltec_t096_companion_radio_ble \
|
||||
Heltec_t096_companion_radio_ble_femoff
|
||||
|
||||
############# Companions BLE PS #############
|
||||
# ESP32 - 18 boards
|
||||
sh build.sh build-firmware \
|
||||
Heltec_v3_companion_radio_ble_ps \
|
||||
heltec_v4_companion_radio_ble_ps \
|
||||
heltec_v4_3_companion_radio_ble_ps_femoff \
|
||||
Xiao_C3_companion_radio_ble_ps \
|
||||
Xiao_S3_companion_radio_ble_ps \
|
||||
Xiao_S3_WIO_companion_radio_ble_ps \
|
||||
Heltec_v2_companion_radio_ble_ps \
|
||||
LilyGo_TBeam_1W_companion_radio_ble_ps \
|
||||
Heltec_WSL3_companion_radio_ble_ps \
|
||||
Heltec_Wireless_Tracker_companion_radio_ble_ps \
|
||||
heltec_tracker_v2_companion_radio_ble_ps \
|
||||
Heltec_Wireless_Paper_companion_radio_ble_ps \
|
||||
LilyGo_TLora_V2_1_1_6_companion_radio_ble_ps \
|
||||
Heltec_ct62_companion_radio_ble_ps \
|
||||
T_Beam_S3_Supreme_SX1262_companion_radio_ble_ps \
|
||||
Tbeam_SX1262_companion_radio_ble_ps \
|
||||
heltec_v4_expansionkit_tft_companion_radio_ble_ps \
|
||||
LilyGo_T3S3_sx1262_companion_radio_ble_ps
|
||||
|
||||
# Not working
|
||||
Tbeam_SX1276_companion_radio_ble_ps \
|
||||
|
||||
############# Companions USB #############
|
||||
sh build.sh build-firmware \
|
||||
Heltec_t096_companion_radio_usb
|
||||
|
||||
############# Sample builds #############
|
||||
# 14 boards
|
||||
sh build.sh build-firmware \
|
||||
Heltec_v3_repeater \
|
||||
heltec_v4_repeater \
|
||||
Xiao_C3_repeater \
|
||||
Xiao_C6_repeater_ \
|
||||
RAK_4631_repeater \
|
||||
Heltec_t096_repeater \
|
||||
Heltec_v3_companion_radio_ble_ps \
|
||||
heltec_v4_companion_radio_ble_ps \
|
||||
heltec_v4_3_companion_radio_ble_ps_femoff \
|
||||
Xiao_C3_companion_radio_ble_ps \
|
||||
Xiao_C6_companion_radio_ble_ \
|
||||
RAK_4631_companion_radio_ble \
|
||||
Heltec_t096_companion_radio_ble \
|
||||
Heltec_t096_companion_radio_ble_femoff
|
||||
@@ -134,7 +134,8 @@ build_firmware() {
|
||||
|
||||
# set firmware version string
|
||||
# e.g: v1.0.0-abcdef
|
||||
FIRMWARE_VERSION_STRING="${FIRMWARE_VERSION}-${COMMIT_HASH}"
|
||||
# FIRMWARE_VERSION_STRING="${FIRMWARE_VERSION}-${COMMIT_HASH}"
|
||||
FIRMWARE_VERSION_STRING="${FIRMWARE_VERSION}"
|
||||
|
||||
# craft filename
|
||||
# e.g: RAK_4631_Repeater-v1.0.0-SHA
|
||||
@@ -152,8 +153,8 @@ build_firmware() {
|
||||
# build merge-bin for esp32 fresh install, copy .bins to out folder (e.g: Heltec_v3_room_server-v1.0.0-SHA.bin)
|
||||
if [ "$ENV_PLATFORM" == "ESP32_PLATFORM" ]; then
|
||||
pio run -t mergebin -e $1
|
||||
cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}.bin 2>/dev/null || true
|
||||
cp .pio/build/$1/firmware-merged.bin out/${FIRMWARE_FILENAME}-merged.bin 2>/dev/null || true
|
||||
cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}-upgrade.bin 2>/dev/null || true
|
||||
cp .pio/build/$1/firmware-merged.bin out/${FIRMWARE_FILENAME}-freshInstall-merged.bin 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# build .uf2 for nrf52 boards, copy .uf2 and .zip to out folder (e.g: RAK_4631_Repeater-v1.0.0-SHA.uf2)
|
||||
|
||||
@@ -505,6 +505,18 @@ This document provides an overview of CLI commands that can be sent to MeshCore
|
||||
|
||||
---
|
||||
|
||||
#### View or set reboot interval (Repeater and room server)
|
||||
**Usage:**
|
||||
- `get reboot.interval`
|
||||
- `set reboot.interval <hours>`
|
||||
|
||||
**Parameters:**
|
||||
- `hours`: 0-255. 0 is disabled
|
||||
|
||||
**Default:** `0` (disabled)
|
||||
|
||||
---
|
||||
|
||||
### Routing
|
||||
|
||||
#### View or change this node's repeat flag
|
||||
@@ -1053,6 +1065,27 @@ This document provides an overview of CLI commands that can be sent to MeshCore
|
||||
|
||||
---
|
||||
|
||||
#### View or set the direct path override for the current remote client
|
||||
**Usage:**
|
||||
- `get outpath`
|
||||
- `set outpath <hop1_hex,hop2_hex,...>`
|
||||
- `set outpath direct`
|
||||
- `set outpath clear`
|
||||
- `set outpath flood`
|
||||
|
||||
**Parameters:**
|
||||
- `hopN_hex`: Hop hash, `2`, `4`, or `6` hex characters. All hops must use the same width.
|
||||
|
||||
**Notes:**
|
||||
- These commands require remote client context (they target the caller's ACL entry).
|
||||
- The path hash size is inferred from the hop hash width.
|
||||
- `outpath` overrides the primary direct route used for replies to the caller.
|
||||
- `direct` sets a zero-hop direct route for a caller reachable without repeaters.
|
||||
- `clear` forgets the current direct path and allows normal path discovery to repopulate it.
|
||||
- `flood` forces replies to use flood packets until the client logs in again.
|
||||
|
||||
---
|
||||
|
||||
#### Create a new region
|
||||
**Usage:**
|
||||
- `region put <name> [parent_name]`
|
||||
|
||||
+1
-9
@@ -111,7 +111,6 @@ Anyone is able to build anything they like on top of MeshCore without paying any
|
||||
- MeshCore Firmware on GitHub: [https://github.com/meshcore-dev/MeshCore](https://github.com/meshcore-dev/MeshCore)
|
||||
- MeshCore Companion Web App: [https://app.meshcore.nz](https://app.meshcore.nz)
|
||||
- MeshCore Map: [https://map.meshcore.io](https://map.meshcore.io)
|
||||
- Andy Kirby's [MeshCore Intro Video](https://www.youtube.com/watch?v=t1qne8uJBAc)
|
||||
- Liam Cottle's [MeshCore Technical Presentation](https://www.youtube.com/watch?v=OwmkVkZQTf4)
|
||||
|
||||
You need LoRa hardware devices to run MeshCore firmware as clients or server (repeater and room server).
|
||||
@@ -392,10 +391,7 @@ Another way to download map tiles is to use this Python script to get the tiles
|
||||
<https://github.com/fistulareffigy/MTD-Script>
|
||||
|
||||
There is also a modified script that adds additional error handling and parallel downloads:
|
||||
<https://discord.com/channels/826570251612323860/1330643963501351004/1338775811548905572>
|
||||
|
||||
UK map tiles are available separately from Andy Kirby on his discord server:
|
||||
<https://discord.com/channels/826570251612323860/1330643963501351004/1331346597367386224>
|
||||
<https://github.com/TheBestJohn/MTD-Script>
|
||||
|
||||
### 4.8. Q: Where do the map tiles go?
|
||||
Once you have the tiles downloaded, copy the `\tiles` folder to the root of your T-Deck's SD card.
|
||||
@@ -553,10 +549,6 @@ pio run -e RAK_4631_Repeater
|
||||
```
|
||||
then you'll find `firmware.zip` in `.pio/build/RAK_4631_Repeater`
|
||||
|
||||
Andy also has a video on how to build using VS Code:
|
||||
*How to build and flash Meshcore repeater firmware | Heltec V3*
|
||||
<https://www.youtube.com/watch?v=WJvg6dt13hk> *(Link referenced in the Discord post)*
|
||||
|
||||
### 5.10. Q: Are there other MeshCore related open source projects?
|
||||
|
||||
**A:** [Liam Cottle](https://liamcottle.net)'s MeshCore web client and MeshCore JavaScript library are open source under MIT license.
|
||||
|
||||
@@ -16,6 +16,7 @@ Once you have a working app/project, you need to be able to demonstrate it exist
|
||||
|-----------------|-----------------------------|-------------------------------------------------------------------|
|
||||
| 0000 - 00FF | -reserved for internal use- | |
|
||||
| 0100 | MeshCore Open | zsylvester@monitormx.com — https://github.com/zjs81/meshcore-open |
|
||||
| 0110 - 011F | Ripple | ripple_biz@protonmail.com — https://buymeacoffee.com/ripplebiz |
|
||||
| FF00 - FFFF | -reserved for testing/dev- | |
|
||||
|
||||
(add rows, inside the range 0100 - FEFF for custom apps)
|
||||
|
||||
@@ -233,6 +233,7 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
||||
file.read((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89
|
||||
file.read((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 90
|
||||
file.read((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 121
|
||||
file.read((uint8_t *)&_prefs.radio_fem_rxgain, sizeof(_prefs.radio_fem_rxgain)); // 122
|
||||
|
||||
file.close();
|
||||
}
|
||||
@@ -273,6 +274,7 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
|
||||
file.write((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89
|
||||
file.write((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 90
|
||||
file.write((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 121
|
||||
file.write((uint8_t *)&_prefs.radio_fem_rxgain, sizeof(_prefs.radio_fem_rxgain)); // 122
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
#define CMD_SET_DEFAULT_FLOOD_SCOPE 63
|
||||
#define CMD_GET_DEFAULT_FLOOD_SCOPE 64
|
||||
#define CMD_SEND_RAW_PACKET 65
|
||||
#define CMD_GET_RADIO_FEM_RXGAIN 66
|
||||
#define CMD_SET_RADIO_FEM_RXGAIN 67
|
||||
|
||||
// Stats sub-types for CMD_GET_STATS
|
||||
#define STATS_TYPE_CORE 0
|
||||
@@ -886,6 +888,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
_prefs.rx_boosted_gain = 1; // enabled by default
|
||||
#endif
|
||||
#endif
|
||||
_prefs.radio_fem_rxgain = 1;
|
||||
}
|
||||
|
||||
void MyMesh::begin(bool has_display) {
|
||||
@@ -935,6 +938,7 @@ void MyMesh::begin(bool has_display) {
|
||||
_prefs.tx_power_dbm = constrain(_prefs.tx_power_dbm, -9, MAX_LORA_TX_POWER);
|
||||
_prefs.gps_enabled = constrain(_prefs.gps_enabled, 0, 1); // Ensure boolean 0 or 1
|
||||
_prefs.gps_interval = constrain(_prefs.gps_interval, 0, 86400); // Max 24 hours
|
||||
_prefs.radio_fem_rxgain = constrain(_prefs.radio_fem_rxgain, 0, 1);
|
||||
|
||||
#ifdef BLE_PIN_CODE // 123456 by default
|
||||
if (_prefs.ble_pin == 0) {
|
||||
@@ -964,6 +968,7 @@ void MyMesh::begin(bool has_display) {
|
||||
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
||||
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
|
||||
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
||||
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
|
||||
}
|
||||
@@ -1821,6 +1826,30 @@ void MyMesh::handleCmdFrame(size_t len) {
|
||||
} else {
|
||||
writeErrFrame(ERR_CODE_ILLEGAL_ARG);
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_GET_RADIO_FEM_RXGAIN) {
|
||||
if (!board.canControlLoRaFemLna()) {
|
||||
writeErrFrame(ERR_CODE_UNSUPPORTED_CMD);
|
||||
} else {
|
||||
out_frame[0] = RESP_CODE_OK;
|
||||
uint8_t value = board.isLoRaFemLnaEnabled() ? 1 : 0;
|
||||
memcpy(&out_frame[1], &value, 1);
|
||||
_serial->writeFrame(out_frame, 2);
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_SET_RADIO_FEM_RXGAIN && len >= 2) {
|
||||
uint8_t value = cmd_frame[1];
|
||||
if (!board.canControlLoRaFemLna()) {
|
||||
writeErrFrame(ERR_CODE_UNSUPPORTED_CMD);
|
||||
} else if (value <= 1) {
|
||||
_prefs.radio_fem_rxgain = value;
|
||||
if (board.setLoRaFemLnaEnabled(value != 0)) {
|
||||
savePrefs();
|
||||
writeOKFrame();
|
||||
} else {
|
||||
writeErrFrame(ERR_CODE_UNSUPPORTED_CMD);
|
||||
}
|
||||
} else {
|
||||
writeErrFrame(ERR_CODE_ILLEGAL_ARG);
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_GET_ADVERT_PATH && len >= PUB_KEY_SIZE+2) {
|
||||
// FUTURE use: uint8_t reserved = cmd_frame[1];
|
||||
uint8_t *pub_key = &cmd_frame[2];
|
||||
@@ -1981,6 +2010,7 @@ void MyMesh::handleCmdFrame(size_t len) {
|
||||
sendPacket(pkt, priority, 0);
|
||||
writeOKFrame();
|
||||
} else {
|
||||
releasePacket(pkt);
|
||||
writeErrFrame(ERR_CODE_ILLEGAL_ARG);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#define FIRMWARE_VER_CODE 13
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "19 Apr 2026"
|
||||
#define FIRMWARE_BUILD_DATE "6 Jun 2026"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.15.0"
|
||||
#define FIRMWARE_VERSION "v1.16.0"
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
|
||||
@@ -29,6 +29,7 @@ struct NodePrefs { // persisted to file
|
||||
uint32_t gps_interval; // GPS read interval in seconds
|
||||
uint8_t autoadd_config; // bitmask for auto-add contacts config
|
||||
uint8_t rx_boosted_gain; // SX126x RX boosted gain mode (0=power saving, 1=boosted)
|
||||
uint8_t radio_fem_rxgain; // LoRa FEM RX gain setting
|
||||
uint8_t client_repeat;
|
||||
uint8_t path_hash_mode; // which path mode to use when sending
|
||||
uint8_t autoadd_max_hops; // 0 = no limit, 1 = direct (0 hops), N = up to N-1 hops (max 64)
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
#include <Mesh.h>
|
||||
#include "MyMesh.h"
|
||||
|
||||
#ifdef ESP32_PLATFORM
|
||||
#include "esp_pm.h"
|
||||
#include "esp_bt.h"
|
||||
#endif
|
||||
|
||||
// Believe it or not, this std C function is busted on some platforms!
|
||||
static uint32_t _atoi(const char* sp) {
|
||||
uint32_t n = 0;
|
||||
@@ -240,6 +245,37 @@ void setup() {
|
||||
#endif
|
||||
|
||||
board.onBootComplete();
|
||||
|
||||
#ifdef ESP32_PLATFORM
|
||||
#if !CONFIG_IDF_TARGET_ESP32C6
|
||||
// Enable BLE sleep
|
||||
esp_err_t errBLESleep = esp_bt_sleep_enable();
|
||||
if (errBLESleep == ESP_OK) {
|
||||
Serial.println("Bluetooth sleep enabled successfully");
|
||||
} else {
|
||||
Serial.printf("Bluetooth sleep enable failed: %s\n", esp_err_to_name(errBLESleep));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
esp_pm_config_esp32c3_t pm_config;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
esp_pm_config_esp32s3_t pm_config;
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
esp_pm_config_esp32_t pm_config;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
esp_pm_config_t pm_config;
|
||||
#endif
|
||||
|
||||
// Configure Power Management
|
||||
pm_config = { .max_freq_mhz = 80, .min_freq_mhz = 40, .light_sleep_enable = true };
|
||||
esp_err_t errPM = esp_pm_configure(&pm_config);
|
||||
if (errPM == ESP_OK) {
|
||||
Serial.println("Power Management configured successfully");
|
||||
} else {
|
||||
Serial.printf("Power Management failed to configure: %d\r\n", errPM);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@@ -253,6 +289,10 @@ void loop() {
|
||||
if (!the_mesh.hasPendingWork()) {
|
||||
#if defined(NRF52_PLATFORM)
|
||||
board.sleep(0); // nrf ignores seconds param, sleeps whenever possible
|
||||
#elif defined(ESP32_PLATFORM)
|
||||
if (!serial_interface.isReadBusy() && !serial_interface.isWriteBusy()) { // BLE is not busy
|
||||
vTaskDelay(pdMS_TO_TICKS(10)); // attempt to sleep
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -705,6 +705,12 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
||||
}
|
||||
}
|
||||
|
||||
if (packet->isRouteFlood()) {
|
||||
if (packet->getPathHashCount() >= _prefs.flood_max) return false;
|
||||
if (packet->getRouteType() == ROUTE_TYPE_FLOOD && packet->getPathHashCount() >= _prefs.flood_max_unscoped) return false;
|
||||
if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->getPathHashCount() >= _prefs.flood_max_advert) return false;
|
||||
}
|
||||
|
||||
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
|
||||
if (packet->isRouteFlood() && recv_pkt_region == NULL) {
|
||||
MESH_DEBUG_PRINTLN("allowPacketForward: unknown transport code, or wildcard not allowed for FLOOD packet");
|
||||
@@ -1851,9 +1857,11 @@ void MyMesh::onPeerDataRecv(mesh::Packet *packet, uint8_t type, int sender_idx,
|
||||
mesh::Packet *reply =
|
||||
createDatagram(PAYLOAD_TYPE_RESPONSE, client->id, secret, reply_data, reply_len);
|
||||
if (reply) {
|
||||
|
||||
if (hasUsablePath(client->out_path, client->out_path_len)) { // we have an out_path, so send DIRECT
|
||||
sendDirectWithAltPath(reply, client->out_path, client->out_path_len,
|
||||
client->alt_path, client->alt_path_len, SERVER_RESPONSE_DELAY);
|
||||
|
||||
} else {
|
||||
sendFloodReply(reply, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
}
|
||||
@@ -1885,9 +1893,11 @@ void MyMesh::onPeerDataRecv(mesh::Packet *packet, uint8_t type, int sender_idx,
|
||||
|
||||
mesh::Packet *ack = createAck(ack_hash);
|
||||
if (ack) {
|
||||
|
||||
if (hasUsablePath(client->out_path, client->out_path_len)) {
|
||||
sendDirectWithAltPath(ack, client->out_path, client->out_path_len,
|
||||
client->alt_path, client->alt_path_len, TXT_ACK_DELAY);
|
||||
|
||||
} else {
|
||||
sendFloodReply(ack, TXT_ACK_DELAY, packet->getPathHashSize());
|
||||
}
|
||||
@@ -1914,9 +1924,11 @@ void MyMesh::onPeerDataRecv(mesh::Packet *packet, uint8_t type, int sender_idx,
|
||||
|
||||
auto reply = createDatagram(PAYLOAD_TYPE_TXT_MSG, client->id, secret, temp, 5 + text_len);
|
||||
if (reply) {
|
||||
|
||||
if (hasUsablePath(client->out_path, client->out_path_len)) {
|
||||
sendDirectWithAltPath(reply, client->out_path, client->out_path_len,
|
||||
client->alt_path, client->alt_path_len, CLI_REPLY_DELAY_MILLIS);
|
||||
|
||||
} else {
|
||||
sendFloodReply(reply, CLI_REPLY_DELAY_MILLIS, packet->getPathHashSize());
|
||||
}
|
||||
@@ -2091,6 +2103,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.advert_interval = DEFAULT_ADVERT_INTERVAL;
|
||||
_prefs.flood_advert_interval = DEFAULT_FLOOD_ADVERT_INTERVAL;
|
||||
_prefs.flood_max = 64;
|
||||
_prefs.flood_max_unscoped = 64;
|
||||
_prefs.flood_max_advert = 8;
|
||||
_prefs.interference_threshold = 0; // disabled
|
||||
_prefs.agc_reset_interval = DEFAULT_AGC_RESET_INTERVAL;
|
||||
_prefs.multi_acks = DEFAULT_MULTI_ACKS;
|
||||
@@ -2544,7 +2558,9 @@ static bool parsePathCommand(char* raw, uint8_t* out_path, uint8_t& out_path_len
|
||||
|
||||
int hex_len = strlen(token);
|
||||
if (!(hex_len == 2 || hex_len == 4 || hex_len == 6)) {
|
||||
|
||||
err = "Err - each hop must be 1/2/3 bytes hex";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2552,12 +2568,16 @@ static bool parsePathCommand(char* raw, uint8_t* out_path, uint8_t& out_path_len
|
||||
if (hash_size == 0) {
|
||||
hash_size = hop_hash_size;
|
||||
} else if (hash_size != hop_hash_size) {
|
||||
|
||||
err = "Err - mixed hash sizes in path";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hop_count >= 63 || (hop_count + 1) * hash_size > MAX_PATH_SIZE) {
|
||||
|
||||
err = "Err - path too long";
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!mesh::Utils::fromHex(&out_path[hop_count * hash_size], hash_size, token)) {
|
||||
@@ -2682,6 +2702,7 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char *
|
||||
reply[0] = 0;
|
||||
} else if (strcmp(command, "get outpath") == 0
|
||||
|| strcmp(command, "set outpath") == 0
|
||||
|
||||
|| strncmp(command, "set outpath ", 12) == 0
|
||||
|| strcmp(command, "get altpath") == 0
|
||||
|| strcmp(command, "set altpath") == 0
|
||||
@@ -2696,6 +2717,7 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char *
|
||||
reply, 160);
|
||||
} else {
|
||||
char* spec = command + 11; // length of "set outpath"/"set altpath"
|
||||
|
||||
if (*spec == ' ') spec++;
|
||||
|
||||
uint8_t path[MAX_PATH_SIZE];
|
||||
@@ -2703,6 +2725,7 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char *
|
||||
const char* err = NULL;
|
||||
if (!parsePathCommand(spec, path, path_len, err)) {
|
||||
strcpy(reply, err ? err : "Err - invalid path");
|
||||
|
||||
} else if (is_alt && path_len == OUT_PATH_FORCE_FLOOD) {
|
||||
strcpy(reply, "Err - bad params");
|
||||
} else {
|
||||
@@ -2961,6 +2984,7 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char *
|
||||
}
|
||||
free(sorted_recent);
|
||||
}
|
||||
|
||||
} else if (memcmp(command, "discover.neighbors", 18) == 0) {
|
||||
const char* sub = command + 18;
|
||||
while (*sub == ' ') sub++;
|
||||
|
||||
@@ -69,11 +69,11 @@ struct NeighbourInfo {
|
||||
};
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "19 Apr 2026"
|
||||
#define FIRMWARE_BUILD_DATE "6 Jun 2026"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.15.0"
|
||||
#define FIRMWARE_VERSION "v1.16.0"
|
||||
#endif
|
||||
|
||||
#define FIRMWARE_ROLE "repeater"
|
||||
|
||||
@@ -120,7 +120,7 @@ void loop() {
|
||||
Serial.print('\n');
|
||||
command[len - 1] = 0; // replace newline with C string null terminator
|
||||
char reply[160];
|
||||
the_mesh.handleCommand(0, command, reply); // NOTE: there is no sender_timestamp via serial!
|
||||
the_mesh.handleCommand(0, NULL, command, reply); // NOTE: there is no sender_timestamp via serial!
|
||||
if (reply[0]) {
|
||||
Serial.print(" -> "); Serial.println(reply);
|
||||
}
|
||||
@@ -159,4 +159,9 @@ void loop() {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (the_mesh.getNodePrefs()->reboot_interval > 0 &&
|
||||
the_mesh.millisHasNowPassed(the_mesh.getNodePrefs()->reboot_interval * 3600000)) {
|
||||
board.reboot();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,6 +285,7 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
||||
if (packet->isRouteFlood()) {
|
||||
if (packet->getPathHashCount() >= _prefs.flood_max) return false;
|
||||
if (packet->getRouteType() == ROUTE_TYPE_FLOOD && packet->getPathHashCount() >= _prefs.flood_max_unscoped) return false;
|
||||
if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->getPathHashCount() >= _prefs.flood_max_advert) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -647,6 +648,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.flood_advert_interval = 47; // 47 hours
|
||||
_prefs.flood_max = 64;
|
||||
_prefs.flood_max_unscoped = 64;
|
||||
_prefs.flood_max_advert = 8;
|
||||
_prefs.interference_threshold = 0; // disabled
|
||||
#ifdef ROOM_PASSWORD
|
||||
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
|
||||
@@ -656,6 +658,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.gps_enabled = 0;
|
||||
_prefs.gps_interval = 0;
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
_prefs.radio_fem_rxgain = 1;
|
||||
|
||||
next_post_idx = 0;
|
||||
next_client_idx = 0;
|
||||
@@ -697,6 +700,7 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
|
||||
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
@@ -1026,3 +1030,11 @@ void MyMesh::loop() {
|
||||
uptime_millis += now - last_millis;
|
||||
last_millis = now;
|
||||
}
|
||||
|
||||
// To check if there is pending work
|
||||
bool MyMesh::hasPendingWork() const {
|
||||
#if defined(WITH_BRIDGE)
|
||||
if (bridge.isRunning()) return true; // bridge needs WiFi radio, can't sleep
|
||||
#endif
|
||||
return _mgr->getOutboundTotal() > 0;
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "19 Apr 2026"
|
||||
#define FIRMWARE_BUILD_DATE "6 Jun 2026"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.15.0"
|
||||
#define FIRMWARE_VERSION "v1.16.0"
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
@@ -222,4 +222,7 @@ public:
|
||||
void clearStats() override;
|
||||
void handleCommand(uint32_t sender_timestamp, char* command, char* reply);
|
||||
void loop();
|
||||
|
||||
// To check if there is pending work
|
||||
bool hasPendingWork() const;
|
||||
};
|
||||
|
||||
@@ -18,6 +18,9 @@ void halt() {
|
||||
|
||||
static char command[MAX_POST_TEXT_LEN+1];
|
||||
|
||||
// For power saving
|
||||
unsigned long POWERSAVING_FIRSTSLEEP_SECS = 120; // The first sleep (if enabled) from boot
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
@@ -115,4 +118,14 @@ void loop() {
|
||||
ui_task.loop();
|
||||
#endif
|
||||
rtc_clock.tick();
|
||||
|
||||
if (the_mesh.getNodePrefs()->powersaving_enabled && !the_mesh.hasPendingWork()) {
|
||||
#if defined(NRF52_PLATFORM)
|
||||
board.sleep(0); // nrf ignores seconds param, sleeps whenever possible
|
||||
#else
|
||||
if (the_mesh.millisHasNowPassed(POWERSAVING_FIRSTSLEEP_SECS * 1000)) { // To check if it is time to sleep
|
||||
board.sleep(30); // Sleep. Wake up after a while or when receiving a LoRa packet
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
#define PERM_RECV_ALERTS_HI (1 << 7) // high priority alerts
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "19 Apr 2026"
|
||||
#define FIRMWARE_BUILD_DATE "6 Jun 2026"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.15.0"
|
||||
#define FIRMWARE_VERSION "v1.16.0"
|
||||
#endif
|
||||
|
||||
#define FIRMWARE_ROLE "sensor"
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ lib_deps =
|
||||
extends = arduino_base
|
||||
upload_protocol = picotool
|
||||
board_build.core = earlephilhower
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#4e22a0d ; framework-arduinopico @ 1.50600.0+sha.6a1d13e9
|
||||
build_flags = ${arduino_base.build_flags}
|
||||
-D RP2040_PLATFORM
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_HASH_SIZE 8
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
__attribute__((section(".persistent_magic"))) uint32_t persistent_magic;
|
||||
__attribute__((section(".persistent_data"))) uint32_t persistent_time;
|
||||
}
|
||||
@@ -3,19 +3,57 @@
|
||||
#include <Mesh.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef NRF52_PLATFORM
|
||||
#define CLOCK_MAGIC_NUM 0xAA55CC33
|
||||
#define RTC_TIME_MIN 1772323200 // 1 Mar 2026
|
||||
|
||||
extern uint32_t persistent_magic;
|
||||
extern uint32_t persistent_time;
|
||||
#endif
|
||||
|
||||
class VolatileRTCClock : public mesh::RTCClock {
|
||||
uint32_t base_time;
|
||||
uint64_t accumulator;
|
||||
unsigned long prev_millis;
|
||||
|
||||
public:
|
||||
VolatileRTCClock() { base_time = 1715770351; accumulator = 0; prev_millis = millis(); } // 15 May 2024, 8:50pm
|
||||
VolatileRTCClock() {
|
||||
#ifdef NRF52_PLATFORM
|
||||
if (persistent_magic == CLOCK_MAGIC_NUM && persistent_time >= RTC_TIME_MIN) {
|
||||
base_time = persistent_time;
|
||||
} else {
|
||||
base_time = RTC_TIME_MIN;
|
||||
}
|
||||
#else
|
||||
base_time = 1715770351;
|
||||
#endif
|
||||
|
||||
accumulator = 0;
|
||||
prev_millis = millis();
|
||||
}
|
||||
|
||||
uint32_t getCurrentTime() override { return base_time + accumulator/1000; }
|
||||
void setCurrentTime(uint32_t time) override { base_time = time; accumulator = 0; prev_millis = millis(); }
|
||||
|
||||
void setCurrentTime(uint32_t time) override {
|
||||
base_time = time;
|
||||
accumulator = 0;
|
||||
prev_millis = millis();
|
||||
|
||||
#ifdef NRF52_PLATFORM
|
||||
persistent_magic = CLOCK_MAGIC_NUM;
|
||||
persistent_time = time;
|
||||
#endif
|
||||
}
|
||||
|
||||
void tick() override {
|
||||
unsigned long now = millis();
|
||||
accumulator += (now - prev_millis);
|
||||
prev_millis = now;
|
||||
|
||||
#ifdef NRF52_PLATFORM
|
||||
persistent_magic = CLOCK_MAGIC_NUM;
|
||||
persistent_time = getCurrentTime();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ bool ArduinoSerialInterface::isConnected() const {
|
||||
return true; // no way of knowing, so assume yes
|
||||
}
|
||||
|
||||
bool ArduinoSerialInterface::isReadBusy() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ArduinoSerialInterface::isWriteBusy() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
bool isConnected() const override;
|
||||
|
||||
bool isReadBusy() const override;
|
||||
bool isWriteBusy() const override;
|
||||
size_t writeFrame(const uint8_t src[], size_t len) override;
|
||||
size_t checkRecvFrame(uint8_t dest[]) override;
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
|
||||
virtual bool isConnected() const = 0;
|
||||
|
||||
virtual bool isReadBusy() const = 0;
|
||||
virtual bool isWriteBusy() const = 0;
|
||||
virtual size_t writeFrame(const uint8_t src[], size_t len) = 0;
|
||||
virtual size_t checkRecvFrame(uint8_t dest[]) = 0;
|
||||
|
||||
@@ -512,7 +512,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.read((uint8_t *)&_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled)); // 152
|
||||
file.read(pad, 3); // 153
|
||||
file.read((uint8_t *)&_prefs->reboot_interval, sizeof(_prefs->reboot_interval)); // 153
|
||||
file.read(pad, 2); // 154
|
||||
file.read((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.read((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
file.read((uint8_t *)&_prefs->advert_loc_policy, sizeof (_prefs->advert_loc_policy)); // 161
|
||||
@@ -565,6 +566,12 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
sizeof(_prefs->battery_alert_low_percent)); // 665
|
||||
size_t battery_alert_critical_read = file.read((uint8_t *)&_prefs->battery_alert_critical_percent,
|
||||
sizeof(_prefs->battery_alert_critical_percent)); // 666
|
||||
_prefs->flood_max_unscoped = 64;
|
||||
size_t flood_max_unscoped_read = file.read((uint8_t *)&_prefs->flood_max_unscoped,
|
||||
sizeof(_prefs->flood_max_unscoped)); // 667
|
||||
_prefs->flood_max_advert = 8;
|
||||
size_t flood_max_advert_read = file.read((uint8_t *)&_prefs->flood_max_advert,
|
||||
sizeof(_prefs->flood_max_advert)); // 668
|
||||
// PowerSaving-only prefs stored radio_fem_rxgain at 291, before direct retry timing existed.
|
||||
if (radio_fem_rxgain_read != sizeof(_prefs->radio_fem_rxgain)
|
||||
&& legacy_retry_attempts_read == sizeof(legacy_retry_attempts_or_radio_fem_rxgain)
|
||||
@@ -572,7 +579,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
|| _prefs->direct_retry_timing_magic[1] != DIRECT_RETRY_TIMING_MAGIC_1)) {
|
||||
_prefs->radio_fem_rxgain = constrain(legacy_retry_attempts_or_radio_fem_rxgain, 0, 1);
|
||||
}
|
||||
// next: 667
|
||||
// next: 669
|
||||
|
||||
// sanitise bad pref values
|
||||
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
|
||||
@@ -613,6 +620,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
_prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);
|
||||
|
||||
_prefs->powersaving_enabled = constrain(_prefs->powersaving_enabled, 0, 1);
|
||||
_prefs->reboot_interval = constrain(_prefs->reboot_interval, 0, 255);
|
||||
|
||||
_prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1);
|
||||
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2);
|
||||
@@ -620,6 +628,16 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
// sanitise settings
|
||||
_prefs->rx_boosted_gain = constrain(_prefs->rx_boosted_gain, 0, 1); // boolean
|
||||
_prefs->radio_fem_rxgain = constrain(_prefs->radio_fem_rxgain, 0, 1); // boolean
|
||||
if (flood_max_unscoped_read != sizeof(_prefs->flood_max_unscoped)) {
|
||||
_prefs->flood_max_unscoped = 64;
|
||||
} else {
|
||||
_prefs->flood_max_unscoped = constrain(_prefs->flood_max_unscoped, 0, 64);
|
||||
}
|
||||
if (flood_max_advert_read != sizeof(_prefs->flood_max_advert)) {
|
||||
_prefs->flood_max_advert = 8;
|
||||
} else {
|
||||
_prefs->flood_max_advert = constrain(_prefs->flood_max_advert, 0, 64);
|
||||
}
|
||||
_prefs->retry_preset = retryPresetOrDefault(_prefs->retry_preset);
|
||||
if (retry_step_read != sizeof(_prefs->direct_retry_step_ms)) {
|
||||
_prefs->direct_retry_step_ms = retryPresetStepDefault(_prefs->retry_preset);
|
||||
@@ -733,7 +751,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.write((uint8_t *)&_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled)); // 152
|
||||
file.write(pad, 3); // 153
|
||||
file.write((uint8_t *)&_prefs->reboot_interval, sizeof(_prefs->reboot_interval)); // 153
|
||||
file.write(pad, 2); // 154
|
||||
file.write((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.write((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
file.write((uint8_t *)&_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161
|
||||
@@ -764,7 +783,9 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *)&_prefs->battery_alert_enabled, sizeof(_prefs->battery_alert_enabled)); // 664
|
||||
file.write((uint8_t *)&_prefs->battery_alert_low_percent, sizeof(_prefs->battery_alert_low_percent)); // 665
|
||||
file.write((uint8_t *)&_prefs->battery_alert_critical_percent, sizeof(_prefs->battery_alert_critical_percent)); // 666
|
||||
// next: 667
|
||||
file.write((uint8_t *)&_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 667
|
||||
file.write((uint8_t *)&_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 668
|
||||
// next: 669
|
||||
|
||||
file.close();
|
||||
}
|
||||
@@ -1825,6 +1846,24 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
} else {
|
||||
strcpy(reply, "Error, cannot be negative");
|
||||
}
|
||||
} else if (memcmp(config, "flood.max.unscoped ", 19) == 0) {
|
||||
uint8_t m = atoi(&config[19]);
|
||||
if (m <= 64) {
|
||||
_prefs->flood_max_unscoped = m;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Error, max 64");
|
||||
}
|
||||
} else if (memcmp(config, "flood.max.advert ", 17) == 0) {
|
||||
uint8_t m = atoi(&config[17]);
|
||||
if (m <= 64) {
|
||||
_prefs->flood_max_advert = m;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Error, max 64");
|
||||
}
|
||||
} else if (memcmp(config, "flood.max ", 10) == 0) {
|
||||
uint8_t m = atoi(&config[10]);
|
||||
if (m <= 64) {
|
||||
@@ -2091,6 +2130,19 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
_prefs->adc_multiplier = 0.0f;
|
||||
strcpy(reply, "Error: unsupported");
|
||||
};
|
||||
} else if (memcmp(config, "reboot.interval ", 16) == 0) {
|
||||
int hours = _atoi(&config[16]);
|
||||
if (hours == 0) {
|
||||
_prefs->reboot_interval = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "reboot.interval disabled");
|
||||
} else if (hours < 1 || 255 < hours) {
|
||||
strcpy(reply, "Error: interval range is 1-255 hours");
|
||||
} else {
|
||||
_prefs->reboot_interval = hours;
|
||||
savePrefs();
|
||||
sprintf(reply, "OK - reboot.interval set to %d", _prefs->reboot_interval);
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "unknown config: ");
|
||||
}
|
||||
@@ -2151,6 +2203,10 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->rx_delay_base));
|
||||
} else if (memcmp(config, "txdelay", 7) == 0) {
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->tx_delay_factor));
|
||||
} else if (memcmp(config, "flood.max.advert", 16) == 0) {
|
||||
sprintf(reply, "> %d", (uint32_t)_prefs->flood_max_advert);
|
||||
} else if (memcmp(config, "flood.max.unscoped", 18) == 0) {
|
||||
sprintf(reply, "> %d", (uint32_t)_prefs->flood_max_unscoped);
|
||||
} else if (memcmp(config, "flood.max", 9) == 0) {
|
||||
sprintf(reply, "> %d", (uint32_t)_prefs->flood_max);
|
||||
} else if (memcmp(config, "retry.preset", 12) == 0) {
|
||||
@@ -2296,6 +2352,12 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
#else
|
||||
strcpy(reply, "ERROR: Power management not supported");
|
||||
#endif
|
||||
} else if (memcmp(config, "reboot.interval", 15) == 0) {
|
||||
if (_prefs->reboot_interval == 0) {
|
||||
strcpy(reply, "disabled");
|
||||
} else {
|
||||
sprintf(reply, "> %d", (uint8_t)_prefs->reboot_interval);
|
||||
}
|
||||
} else {
|
||||
sprintf(reply, "??: %s", config);
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ struct NodePrefs { // persisted to file
|
||||
uint8_t multi_acks;
|
||||
float bw;
|
||||
uint8_t flood_max;
|
||||
uint8_t flood_max_unscoped;
|
||||
uint8_t flood_max_advert;
|
||||
uint8_t interference_threshold;
|
||||
uint8_t agc_reset_interval; // secs / 4
|
||||
// Bridge settings
|
||||
@@ -104,6 +106,7 @@ struct NodePrefs { // persisted to file
|
||||
char bridge_secret[16]; // for XOR encryption of bridge packets (ESP-NOW only)
|
||||
// Power setting
|
||||
uint8_t powersaving_enabled; // boolean
|
||||
uint8_t reboot_interval; // hours, 0-255 (default 0=disable)
|
||||
// Gps settings
|
||||
uint8_t gps_enabled;
|
||||
uint32_t gps_interval; // in seconds
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <Wire.h>
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_system.h"
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class ESP32Board : public mesh::MainBoard {
|
||||
protected:
|
||||
@@ -62,7 +63,32 @@ public:
|
||||
return raw / 4;
|
||||
}
|
||||
|
||||
uint32_t getIRQGpio() {
|
||||
void powerOff() override {
|
||||
enterDeepSleep(0); // Do not wakeup
|
||||
}
|
||||
|
||||
void enterDeepSleep(uint32_t secs) {
|
||||
// Clear stale wakeup sources to avoid ghost wakeup
|
||||
// This is required when Power Management and automatic lightsleep are enabled
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000ULL);
|
||||
}
|
||||
|
||||
// Keep LoRa inactive during deepsleep
|
||||
digitalWrite(P_LORA_NSS, HIGH);
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
#else
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
#endif
|
||||
|
||||
// Finally set ESP32 into deepsleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
uint32_t getIRQGpio() override {
|
||||
return P_LORA_DIO_1; // default for SX1262
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
#include "ESP32Board.h"
|
||||
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class MeshadventurerBoard : public ESP32Board {
|
||||
|
||||
public:
|
||||
@@ -35,34 +33,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are held on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void powerOff() override {
|
||||
// TODO: re-enable this when there is a definite wake-up source pin:
|
||||
// enterDeepSleep(0);
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
analogReadResolution(12);
|
||||
|
||||
|
||||
@@ -182,6 +182,10 @@ size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) {
|
||||
|
||||
#define BLE_WRITE_MIN_INTERVAL 60
|
||||
|
||||
bool SerialBLEInterface::isReadBusy() const {
|
||||
return (recv_queue_len > 0);
|
||||
}
|
||||
|
||||
bool SerialBLEInterface::isWriteBusy() const {
|
||||
return millis() < _last_write + BLE_WRITE_MIN_INTERVAL; // still too soon to start another write?
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ public:
|
||||
|
||||
bool isConnected() const override;
|
||||
|
||||
bool isReadBusy() const override;
|
||||
bool isWriteBusy() const override;
|
||||
size_t writeFrame(const uint8_t src[], size_t len) override;
|
||||
size_t checkRecvFrame(uint8_t dest[]) override;
|
||||
|
||||
@@ -39,6 +39,10 @@ size_t SerialWifiInterface::writeFrame(const uint8_t src[], size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SerialWifiInterface::isReadBusy() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SerialWifiInterface::isWriteBusy() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
bool isEnabled() const override { return _isEnabled; }
|
||||
|
||||
bool isConnected() const override;
|
||||
bool isReadBusy() const override;
|
||||
bool isWriteBusy() const override;
|
||||
|
||||
size_t writeFrame(const uint8_t src[], size_t len) override;
|
||||
|
||||
@@ -86,7 +86,6 @@
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
#include "helpers/ESP32Board.h"
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class TBeamBoard : public ESP32Board {
|
||||
XPowersLibInterface *PMU = NULL;
|
||||
@@ -131,29 +130,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts(){
|
||||
return PMU->getBattVoltage();
|
||||
}
|
||||
|
||||
@@ -401,6 +401,10 @@ bool SerialBLEInterface::isConnected() const {
|
||||
return _isDeviceConnected && Bluefruit.connected() > 0;
|
||||
}
|
||||
|
||||
bool SerialBLEInterface::isReadBusy() const {
|
||||
return (recv_queue_len > 0);
|
||||
}
|
||||
|
||||
bool SerialBLEInterface::isWriteBusy() const {
|
||||
return send_queue_len >= (FRAME_QUEUE_SIZE * 2 / 3);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
void disable() override;
|
||||
bool isEnabled() const override { return _isEnabled; }
|
||||
bool isConnected() const override;
|
||||
bool isReadBusy() const override;
|
||||
bool isWriteBusy() const override;
|
||||
size_t writeFrame(const uint8_t src[], size_t len) override;
|
||||
size_t checkRecvFrame(uint8_t dest[]) override;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
#ifndef TELEM_BME680_ADDRESS
|
||||
#define TELEM_BME680_ADDRESS 0x76
|
||||
#define TELEM_BME680_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BME680_SEALEVELPRESSURE_HPA (1013.25)
|
||||
#include <bsec.h>
|
||||
@@ -40,6 +41,7 @@ static uint32_t bsec_last_save_ms = 0;
|
||||
#ifdef ENV_INCLUDE_BME680
|
||||
#ifndef TELEM_BME680_ADDRESS
|
||||
#define TELEM_BME680_ADDRESS 0x76
|
||||
#define TELEM_BME680_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BME680_SEALEVELPRESSURE_HPA (1013.25)
|
||||
#include <Adafruit_BME680.h>
|
||||
@@ -63,6 +65,7 @@ static Adafruit_AHTX0 AHTX0;
|
||||
#if ENV_INCLUDE_BME280
|
||||
#ifndef TELEM_BME280_ADDRESS
|
||||
#define TELEM_BME280_ADDRESS 0x76 // BME280 environmental sensor I2C address
|
||||
#define TELEM_BME280_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BME280_SEALEVELPRESSURE_HPA (1013.25) // Atmospheric pressure at sea level
|
||||
#include <Adafruit_BME280.h>
|
||||
@@ -72,6 +75,7 @@ static Adafruit_BME280 BME280;
|
||||
#if ENV_INCLUDE_BMP280
|
||||
#ifndef TELEM_BMP280_ADDRESS
|
||||
#define TELEM_BMP280_ADDRESS 0x76 // BMP280 environmental sensor I2C address
|
||||
#define TELEM_BMP280_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BMP280_SEALEVELPRESSURE_HPA (1013.25) // Atmospheric pressure at sea level
|
||||
#include <Adafruit_BMP280.h>
|
||||
@@ -557,15 +561,27 @@ static const SensorDef SENSOR_TABLE[] = {
|
||||
#endif
|
||||
#ifdef ENV_INCLUDE_BME680
|
||||
{ TELEM_BME680_ADDRESS, "BME680", init_bme680, query_bme680 },
|
||||
#ifdef TELEM_BME680_ADDRESS_2
|
||||
{ TELEM_BME680_ADDRESS_2, "BME680", init_bme680, query_bme680 },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
{ TELEM_BME680_ADDRESS, "BME680+BSEC", init_bme680_bsec, query_bme680_bsec },
|
||||
#ifdef TELEM_BME680_ADDRESS_2
|
||||
{ TELEM_BME680_ADDRESS_2, "BME680+BSEC", init_bme680_bsec, query_bme680_bsec },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME280
|
||||
{ TELEM_BME280_ADDRESS, "BME280", init_bme280, query_bme280 },
|
||||
#ifdef TELEM_BME280_ADDRESS_2
|
||||
{ TELEM_BME280_ADDRESS_2, "BME280", init_bme280, query_bme280 },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_BMP280
|
||||
{ TELEM_BMP280_ADDRESS, "BMP280", init_bmp280, query_bmp280 },
|
||||
#ifdef TELEM_BMP280_ADDRESS_2
|
||||
{ TELEM_BMP280_ADDRESS_2, "BMP280", init_bmp280, query_bmp280 },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_SHTC3
|
||||
{ 0x70, "SHTC3", init_shtc3, query_shtc3 },
|
||||
|
||||
@@ -63,6 +63,15 @@ void ST7735Display::turnOff() {
|
||||
#else
|
||||
digitalWrite(PIN_TFT_LEDA_CTL, LOW);
|
||||
#endif
|
||||
|
||||
// Prevent back-powering to save 2.8 mA
|
||||
pinMode(PIN_TFT_CS, INPUT);
|
||||
pinMode(PIN_TFT_DC, INPUT);
|
||||
pinMode(PIN_TFT_SDA, INPUT);
|
||||
pinMode(PIN_TFT_SCL, INPUT);
|
||||
pinMode(PIN_TFT_RST, INPUT);
|
||||
pinMode(PIN_TFT_LEDA_CTL, INPUT);
|
||||
|
||||
_isOn = false;
|
||||
|
||||
if (_peripher_power) _peripher_power->release();
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
extends = nrf52_base
|
||||
board = rak4631
|
||||
board_check = true
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
${sensor_base.build_flags}
|
||||
-I variants/gat562_30s_mesh_kit
|
||||
-D RAK_4631
|
||||
-D RAK_BOARD
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D PIN_BOARD_SCL=14
|
||||
-D PIN_BOARD_SDA=13
|
||||
-D PIN_OLED_RESET=-1
|
||||
|
||||
@@ -5,7 +5,7 @@ board_check = true
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
${sensor_base.build_flags}
|
||||
-I variants/gat562_mesh_evb_pro
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D PIN_BOARD_SCL=14
|
||||
-D PIN_BOARD_SDA=13
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
extends = nrf52_base
|
||||
board = rak4631
|
||||
board_check = true
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
${sensor_base.build_flags}
|
||||
-I variants/gat562_mesh_tracker_pro
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D PIN_BOARD_SCL=14
|
||||
-D PIN_BOARD_SDA=13
|
||||
-D PIN_OLED_RESET=-1
|
||||
|
||||
@@ -8,7 +8,7 @@ build_flags = ${nrf52_base.build_flags}
|
||||
-I variants/gat562_mesh_watch13
|
||||
-D RAK_4631
|
||||
-D RAK_BOARD
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D PIN_BOARD_SCL=14
|
||||
-D PIN_BOARD_SDA=13
|
||||
-D PIN_OLED_RESET=-1
|
||||
|
||||
@@ -130,6 +130,10 @@ lib_deps =
|
||||
${esp32_ota.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_ct62_companion_radio_ble_ps]
|
||||
extends = env:Heltec_ct62_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:Heltec_ct62_sensor]
|
||||
extends = Heltec_ct62
|
||||
build_flags =
|
||||
|
||||
@@ -20,33 +20,6 @@ void HeltecE213Board::begin() {
|
||||
}
|
||||
}
|
||||
|
||||
void HeltecE213Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void HeltecE213Board::powerOff() {
|
||||
enterDeepSleep(0);
|
||||
}
|
||||
|
||||
uint16_t HeltecE213Board::getBattMilliVolts() {
|
||||
analogReadResolution(10);
|
||||
digitalWrite(PIN_ADC_CTRL, HIGH);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <helpers/RefCountedDigitalPin.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class HeltecE213Board : public ESP32Board {
|
||||
|
||||
@@ -13,8 +12,6 @@ public:
|
||||
HeltecE213Board() : periph_power(PIN_VEXT_EN,PIN_VEXT_EN_ACTIVE) { }
|
||||
|
||||
void begin();
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);
|
||||
void powerOff() override;
|
||||
uint16_t getBattMilliVolts() override;
|
||||
const char* getManufacturerName() const override ;
|
||||
};
|
||||
|
||||
@@ -20,33 +20,6 @@ void HeltecE290Board::begin() {
|
||||
}
|
||||
}
|
||||
|
||||
void HeltecE290Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void HeltecE290Board::powerOff() {
|
||||
enterDeepSleep(0);
|
||||
}
|
||||
|
||||
uint16_t HeltecE290Board::getBattMilliVolts() {
|
||||
analogReadResolution(10);
|
||||
digitalWrite(PIN_ADC_CTRL, HIGH);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <helpers/RefCountedDigitalPin.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class HeltecE290Board : public ESP32Board {
|
||||
|
||||
@@ -13,8 +12,6 @@ public:
|
||||
HeltecE290Board() : periph_power(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE) { }
|
||||
|
||||
void begin();
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);
|
||||
void powerOff() override;
|
||||
uint16_t getBattMilliVolts() override;
|
||||
const char* getManufacturerName() const override ;
|
||||
|
||||
|
||||
@@ -12,10 +12,11 @@ class LoRaFEMControl
|
||||
void setRxModeEnable(void);
|
||||
void setRxModeEnableWhenMCUSleep(void);
|
||||
void setLNAEnable(bool enabled);
|
||||
bool isLnaCanControl(void) { return lna_can_control; }
|
||||
bool isLnaCanControl(void) const { return lna_can_control; }
|
||||
void setLnaCanControl(bool can_control) { lna_can_control = can_control; }
|
||||
bool isLNAEnabled(void) const { return lna_enabled; }
|
||||
|
||||
private:
|
||||
bool lna_enabled = false;
|
||||
bool lna_enabled = true;
|
||||
bool lna_can_control = false;
|
||||
};
|
||||
|
||||
@@ -123,4 +123,26 @@ void T096Board::powerOff() {
|
||||
|
||||
const char* T096Board::getManufacturerName() const {
|
||||
return "Heltec T096";
|
||||
}
|
||||
}
|
||||
|
||||
bool T096Board::setLoRaFemLnaEnabled(bool enable) {
|
||||
#if defined(RADIO_FEM_RXGAIN) && (RADIO_FEM_RXGAIN == 0)
|
||||
enable = false;
|
||||
#endif
|
||||
|
||||
if (!loRaFEMControl.isLnaCanControl()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
loRaFEMControl.setLNAEnable(enable);
|
||||
loRaFEMControl.setRxModeEnable();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool T096Board::canControlLoRaFemLna() const {
|
||||
return loRaFEMControl.isLnaCanControl();
|
||||
}
|
||||
|
||||
bool T096Board::isLoRaFemLnaEnabled() const {
|
||||
return loRaFEMControl.isLNAEnabled();
|
||||
}
|
||||
|
||||
@@ -25,4 +25,7 @@ public:
|
||||
uint16_t getBattMilliVolts() override;
|
||||
const char* getManufacturerName() const override ;
|
||||
void powerOff() override;
|
||||
bool setLoRaFemLnaEnabled(bool enable) override;
|
||||
bool canControlLoRaFemLna() const override;
|
||||
bool isLoRaFemLnaEnabled() const override;
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ build_flags = ${nrf52_base.build_flags}
|
||||
-I variants/heltec_t096
|
||||
-I src/helpers/ui
|
||||
-D HELTEC_T096
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D P_LORA_DIO_1=21
|
||||
-D P_LORA_NSS=5
|
||||
-D P_LORA_RESET=16
|
||||
@@ -120,7 +120,7 @@ build_src_filter = ${Heltec_t096.build_src_filter}
|
||||
lib_deps =
|
||||
${Heltec_t096.lib_deps}
|
||||
|
||||
[env:Heltec_t096_companion_radio_ble]
|
||||
[env:Heltec_t096_companion_radio_ble_femon]
|
||||
extends = Heltec_t096
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
@@ -143,6 +143,12 @@ lib_deps =
|
||||
${Heltec_t096.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_t096_companion_radio_ble_femoff]
|
||||
extends = env:Heltec_t096_companion_radio_ble_femon
|
||||
build_flags =
|
||||
${env:Heltec_t096_companion_radio_ble_femon.build_flags}
|
||||
-D RADIO_FEM_RXGAIN=0 ; undefined (default on), 1=on, 0=off
|
||||
|
||||
[env:Heltec_t096_companion_radio_usb]
|
||||
extends = Heltec_t096
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
|
||||
@@ -12,7 +12,7 @@ build_flags = ${nrf52_base.build_flags}
|
||||
-I variants/heltec_t114
|
||||
-I src/helpers/ui
|
||||
-D HELTEC_T114
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D P_LORA_DIO_1=20
|
||||
-D P_LORA_NSS=24
|
||||
-D P_LORA_RESET=25
|
||||
|
||||
@@ -20,33 +20,6 @@ void HeltecT190Board::begin() {
|
||||
}
|
||||
}
|
||||
|
||||
void HeltecT190Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void HeltecT190Board::powerOff() {
|
||||
enterDeepSleep(0);
|
||||
}
|
||||
|
||||
uint16_t HeltecT190Board::getBattMilliVolts() {
|
||||
analogReadResolution(10);
|
||||
digitalWrite(PIN_ADC_CTRL, HIGH);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <helpers/RefCountedDigitalPin.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class HeltecT190Board : public ESP32Board {
|
||||
|
||||
@@ -13,8 +12,6 @@ public:
|
||||
HeltecT190Board() : periph_power(PIN_VEXT_EN,PIN_VEXT_EN_ACTIVE) { }
|
||||
|
||||
void begin();
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);
|
||||
void powerOff() override;
|
||||
uint16_t getBattMilliVolts() override;
|
||||
const char* getManufacturerName() const override ;
|
||||
|
||||
|
||||
@@ -99,6 +99,10 @@ lib_deps =
|
||||
${Heltec_tracker_base.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_Wireless_Tracker_companion_radio_ble_ps]
|
||||
extends = env:Heltec_Wireless_Tracker_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:Heltec_Wireless_Tracker_repeater]
|
||||
extends = Heltec_tracker_base
|
||||
build_flags =
|
||||
|
||||
@@ -35,33 +35,12 @@ void HeltecTrackerV2Board::begin() {
|
||||
loRaFEMControl.setRxModeEnable();
|
||||
}
|
||||
|
||||
void HeltecTrackerV2Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
void HeltecTrackerV2Board::powerOff() {
|
||||
// Turn off PA
|
||||
digitalWrite(P_LORA_PA_POWER, LOW);
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
loRaFEMControl.setRxModeEnableWhenMCUSleep();//It also needs to be enabled in receive mode
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void HeltecTrackerV2Board::powerOff() {
|
||||
enterDeepSleep(0);
|
||||
ESP32Board::powerOff();
|
||||
}
|
||||
|
||||
uint16_t HeltecTrackerV2Board::getBattMilliVolts() {
|
||||
@@ -82,3 +61,21 @@ void HeltecTrackerV2Board::begin() {
|
||||
const char* HeltecTrackerV2Board::getManufacturerName() const {
|
||||
return "Heltec Tracker V2";
|
||||
}
|
||||
|
||||
bool HeltecTrackerV2Board::setLoRaFemLnaEnabled(bool enable) {
|
||||
if (!loRaFEMControl.isLnaCanControl()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
loRaFEMControl.setLNAEnable(enable);
|
||||
loRaFEMControl.setRxModeEnable();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HeltecTrackerV2Board::canControlLoRaFemLna() const {
|
||||
return loRaFEMControl.isLnaCanControl();
|
||||
}
|
||||
|
||||
bool HeltecTrackerV2Board::isLoRaFemLnaEnabled() const {
|
||||
return loRaFEMControl.isLNAEnabled();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <helpers/RefCountedDigitalPin.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <driver/rtc_io.h>
|
||||
#include "LoRaFEMControl.h"
|
||||
|
||||
class HeltecTrackerV2Board : public ESP32Board {
|
||||
@@ -17,9 +16,11 @@ public:
|
||||
void begin();
|
||||
void onBeforeTransmit(void) override;
|
||||
void onAfterTransmit(void) override;
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);
|
||||
void powerOff() override;
|
||||
uint16_t getBattMilliVolts() override;
|
||||
const char* getManufacturerName() const override ;
|
||||
bool setLoRaFemLnaEnabled(bool enable) override;
|
||||
bool canControlLoRaFemLna() const override;
|
||||
bool isLoRaFemLnaEnabled() const override;
|
||||
|
||||
};
|
||||
|
||||
@@ -12,10 +12,11 @@ class LoRaFEMControl
|
||||
void setRxModeEnable(void);
|
||||
void setRxModeEnableWhenMCUSleep(void);
|
||||
void setLNAEnable(bool enabled);
|
||||
bool isLnaCanControl(void) { return lna_can_control; }
|
||||
bool isLnaCanControl(void) const { return lna_can_control; }
|
||||
void setLnaCanControl(bool can_control) { lna_can_control = can_control; }
|
||||
bool isLNAEnabled(void) const { return lna_enabled; }
|
||||
|
||||
private:
|
||||
bool lna_enabled = false;
|
||||
bool lna_enabled = true;
|
||||
bool lna_can_control = false;
|
||||
};
|
||||
|
||||
@@ -176,6 +176,10 @@ lib_deps =
|
||||
${Heltec_tracker_v2.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:heltec_tracker_v2_companion_radio_ble_ps]
|
||||
extends = env:heltec_tracker_v2_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:heltec_tracker_v2_companion_radio_wifi]
|
||||
extends = Heltec_tracker_v2
|
||||
build_flags =
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#define PIN_VBAT_READ 37
|
||||
#define PIN_LED_BUILTIN 25
|
||||
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class HeltecV2Board : public ESP32Board {
|
||||
public:
|
||||
void begin() {
|
||||
@@ -26,29 +24,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_0, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_0);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_0), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_0) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
analogReadResolution(10);
|
||||
|
||||
|
||||
@@ -172,6 +172,10 @@ lib_deps =
|
||||
${Heltec_lora32_v2.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_v2_companion_radio_ble_ps]
|
||||
extends = env:Heltec_v2_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:Heltec_v2_companion_radio_wifi]
|
||||
extends = Heltec_lora32_v2
|
||||
build_flags =
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#define PIN_ADC_CTRL_ACTIVE LOW
|
||||
#define PIN_ADC_CTRL_INACTIVE HIGH
|
||||
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class HeltecV3Board : public ESP32Board {
|
||||
private:
|
||||
bool adc_active_state;
|
||||
@@ -52,33 +50,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void powerOff() override {
|
||||
enterDeepSleep(0);
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
analogReadResolution(10);
|
||||
digitalWrite(PIN_ADC_CTRL, adc_active_state);
|
||||
|
||||
@@ -179,6 +179,10 @@ lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_v3_companion_radio_ble_ps]
|
||||
extends = env:Heltec_v3_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:Heltec_v3_companion_radio_wifi]
|
||||
extends = Heltec_lora32_v3
|
||||
build_flags =
|
||||
@@ -320,6 +324,10 @@ lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_WSL3_companion_radio_ble_ps]
|
||||
extends = env:Heltec_WSL3_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:Heltec_WSL3_companion_radio_usb]
|
||||
extends = Heltec_lora32_v3
|
||||
build_flags =
|
||||
|
||||
@@ -32,33 +32,12 @@ void HeltecV4Board::begin() {
|
||||
loRaFEMControl.setRxModeEnable();
|
||||
}
|
||||
|
||||
void HeltecV4Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
void HeltecV4Board::powerOff() {
|
||||
// Turn off PA
|
||||
digitalWrite(P_LORA_PA_POWER, LOW);
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
loRaFEMControl.setRxModeEnableWhenMCUSleep();//It also needs to be enabled in receive mode
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void HeltecV4Board::powerOff() {
|
||||
enterDeepSleep(0);
|
||||
ESP32Board::powerOff();
|
||||
}
|
||||
|
||||
uint16_t HeltecV4Board::getBattMilliVolts() {
|
||||
@@ -83,3 +62,25 @@ void HeltecV4Board::begin() {
|
||||
return loRaFEMControl.getFEMType() == KCT8103L_PA ? "Heltec V4.3 OLED" : "Heltec V4 OLED";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool HeltecV4Board::setLoRaFemLnaEnabled(bool enable) {
|
||||
#if defined(RADIO_FEM_RXGAIN) && (RADIO_FEM_RXGAIN == 0)
|
||||
enable = false;
|
||||
#endif
|
||||
|
||||
if (!loRaFEMControl.isLnaCanControl()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
loRaFEMControl.setLNAEnable(enable);
|
||||
loRaFEMControl.setRxModeEnable();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HeltecV4Board::canControlLoRaFemLna() const {
|
||||
return loRaFEMControl.isLnaCanControl();
|
||||
}
|
||||
|
||||
bool HeltecV4Board::isLoRaFemLnaEnabled() const {
|
||||
return loRaFEMControl.isLNAEnabled();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <helpers/RefCountedDigitalPin.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <driver/rtc_io.h>
|
||||
#include "LoRaFEMControl.h"
|
||||
|
||||
#ifndef ADC_MULTIPLIER
|
||||
@@ -23,8 +22,10 @@ public:
|
||||
void begin();
|
||||
void onBeforeTransmit(void) override;
|
||||
void onAfterTransmit(void) override;
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);
|
||||
void powerOff() override;
|
||||
bool setLoRaFemLnaEnabled(bool enable) override;
|
||||
bool canControlLoRaFemLna() const override;
|
||||
bool isLoRaFemLnaEnabled() const override;
|
||||
uint16_t getBattMilliVolts() override;
|
||||
bool setAdcMultiplier(float multiplier) override {
|
||||
if (multiplier == 0.0f) {
|
||||
|
||||
@@ -18,12 +18,13 @@ class LoRaFEMControl
|
||||
void setRxModeEnable(void);
|
||||
void setRxModeEnableWhenMCUSleep(void);
|
||||
void setLNAEnable(bool enabled);
|
||||
bool isLnaCanControl(void) { return lna_can_control; }
|
||||
bool isLnaCanControl(void) const { return lna_can_control; }
|
||||
void setLnaCanControl(bool can_control) { lna_can_control = can_control; }
|
||||
bool isLNAEnabled(void) const { return lna_enabled; }
|
||||
LoRaFEMType getFEMType(void) const { return fem_type; }
|
||||
private:
|
||||
LoRaFEMType fem_type=OTHER_FEM_TYPES;
|
||||
bool lna_enabled=false;
|
||||
bool lna_enabled=true;
|
||||
bool lna_can_control=false;
|
||||
};
|
||||
|
||||
|
||||
@@ -222,6 +222,16 @@ lib_deps =
|
||||
${heltec_v4_oled.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:heltec_v4_companion_radio_ble_ps_femon]
|
||||
extends = env:heltec_v4_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:heltec_v4_3_companion_radio_ble_ps_femoff]
|
||||
extends = env:heltec_v4_companion_radio_ble_ps_femon
|
||||
build_flags =
|
||||
${env:heltec_v4_companion_radio_ble_ps_femon.build_flags}
|
||||
-D RADIO_FEM_RXGAIN=0 ; undefined (default on), 1=on, 0=off
|
||||
|
||||
[env:heltec_v4_companion_radio_wifi]
|
||||
extends = heltec_v4_oled
|
||||
build_flags =
|
||||
@@ -386,6 +396,14 @@ lib_deps =
|
||||
${heltec_v4_tft.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:heltec_v4_expansionkit_tft_companion_radio_ble_ps]
|
||||
extends = env:heltec_v4_tft_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
build_flags =
|
||||
${env:heltec_v4_tft_companion_radio_ble.build_flags}
|
||||
-D ENV_PIN_SDA=4
|
||||
-D ENV_PIN_SCL=3
|
||||
|
||||
[env:heltec_v4_tft_companion_radio_wifi]
|
||||
extends = heltec_v4_tft
|
||||
build_flags =
|
||||
|
||||
@@ -64,6 +64,10 @@ lib_deps =
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
bakercp/CRC32 @ ^2.0.0
|
||||
|
||||
[env:Heltec_Wireless_Paper_companion_radio_ble_ps]
|
||||
extends = env:Heltec_Wireless_Paper_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:Heltec_Wireless_Paper_companion_radio_usb]
|
||||
extends = Heltec_Wireless_Paper_base
|
||||
build_flags =
|
||||
|
||||
@@ -174,6 +174,10 @@ lib_deps =
|
||||
${LilyGo_T3S3_sx1262.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:LilyGo_T3S3_sx1262_companion_radio_ble_ps]
|
||||
extends = env:LilyGo_T3S3_sx1262_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:LilyGo_T3S3_sx1262_kiss_modem]
|
||||
extends = LilyGo_T3S3_sx1262
|
||||
build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}
|
||||
|
||||
@@ -146,6 +146,11 @@ lib_deps =
|
||||
${LilyGo_TBeam_1W.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
; === LILYGO T-Beam 1W Companion Radio PS (BLE PS) ===
|
||||
[env:LilyGo_TBeam_1W_companion_radio_ble_ps]
|
||||
extends = env:LilyGo_TBeam_1W_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
; === LILYGO T-Beam 1W Companion Radio (WiFi) ===
|
||||
[env:LilyGo_TBeam_1W_companion_radio_wifi]
|
||||
extends = LilyGo_TBeam_1W
|
||||
|
||||
@@ -65,6 +65,13 @@ lib_deps =
|
||||
${LilyGo_TBeam_SX1262.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Tbeam_SX1262_companion_radio_ble_ps]
|
||||
extends = env:Tbeam_SX1262_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
build_flags =
|
||||
${env:Tbeam_SX1262_companion_radio_ble.build_flags}
|
||||
-D MAX_CONTACTS=150
|
||||
|
||||
[env:Tbeam_SX1262_repeater]
|
||||
extends = LilyGo_TBeam_SX1262
|
||||
build_flags =
|
||||
|
||||
@@ -61,6 +61,10 @@ lib_deps =
|
||||
${LilyGo_TBeam_SX1276.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Tbeam_SX1276_companion_radio_ble_ps]
|
||||
extends = env:Tbeam_SX1276_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:Tbeam_SX1276_repeater]
|
||||
extends = LilyGo_TBeam_SX1276
|
||||
build_flags =
|
||||
|
||||
@@ -142,6 +142,10 @@ lib_deps =
|
||||
${T_Beam_S3_Supreme_SX1262.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:T_Beam_S3_Supreme_SX1262_companion_radio_ble_ps]
|
||||
extends = env:T_Beam_S3_Supreme_SX1262_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:T_Beam_S3_Supreme_SX1262_companion_radio_wifi]
|
||||
extends = T_Beam_S3_Supreme_SX1262
|
||||
build_flags =
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "helpers/ESP32Board.h"
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
#define PIN_VBAT_READ 4
|
||||
#define BATTERY_SAMPLES 8
|
||||
@@ -23,29 +22,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts() {
|
||||
#if defined(PIN_VBAT_READ) && defined(ADC_MULTIPLIER)
|
||||
analogReadResolution(12);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <helpers/ESP32Board.h>
|
||||
|
||||
class TETHEliteBoard : public ESP32Board {
|
||||
public:
|
||||
const char* getManufacturerName() const override {
|
||||
return "LilyGO T-ETH Elite";
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
[LilyGo_TETH_Elite_sx1262]
|
||||
extends = esp32_base
|
||||
board = esp32s3box
|
||||
board_build.partitions = default_16MB.csv
|
||||
board_upload.flash_size = 16MB
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/lilygo_teth_elite
|
||||
-D BOARD_HAS_PSRAM
|
||||
-D LILYGO_TETH_ELITE
|
||||
-D LILYGO_T_ETH_ELITE_ESP32S3
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-D P_LORA_DIO_1=8
|
||||
-D P_LORA_NSS=40
|
||||
-D P_LORA_RESET=46
|
||||
-D P_LORA_BUSY=16
|
||||
-D P_LORA_SCLK=10
|
||||
-D P_LORA_MISO=9
|
||||
-D P_LORA_MOSI=11
|
||||
-D P_LORA_TX_LED=38
|
||||
-D SX126X_DIO2_AS_RF_SWITCH=true
|
||||
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
|
||||
-D SX126X_CURRENT_LIMIT=140
|
||||
-D USE_SX1262
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
-D LORA_TX_POWER=8
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/lilygo_teth_elite>
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
|
||||
[env:LilyGo_TETH_Elite_sx1262_repeater]
|
||||
extends = LilyGo_TETH_Elite_sx1262
|
||||
build_flags =
|
||||
${LilyGo_TETH_Elite_sx1262.build_flags}
|
||||
-D ADVERT_NAME='"T-ETH Elite Repeater"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=50
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${LilyGo_TETH_Elite_sx1262.build_src_filter}
|
||||
+<../examples/simple_repeater>
|
||||
lib_deps =
|
||||
${LilyGo_TETH_Elite_sx1262.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_TETH_Elite_sx1262_room_server]
|
||||
extends = LilyGo_TETH_Elite_sx1262
|
||||
build_flags =
|
||||
${LilyGo_TETH_Elite_sx1262.build_flags}
|
||||
-D ADVERT_NAME='"T-ETH Elite Room"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${LilyGo_TETH_Elite_sx1262.build_src_filter}
|
||||
+<../examples/simple_room_server>
|
||||
lib_deps =
|
||||
${LilyGo_TETH_Elite_sx1262.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_TETH_Elite_sx1262_companion_radio_usb]
|
||||
extends = LilyGo_TETH_Elite_sx1262
|
||||
build_flags =
|
||||
${LilyGo_TETH_Elite_sx1262.build_flags}
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${LilyGo_TETH_Elite_sx1262.build_src_filter}
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps =
|
||||
${LilyGo_TETH_Elite_sx1262.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:LilyGo_TETH_Elite_sx1262_companion_radio_ble]
|
||||
extends = LilyGo_TETH_Elite_sx1262
|
||||
build_flags =
|
||||
${LilyGo_TETH_Elite_sx1262.build_flags}
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D BLE_DEBUG_LOGGING=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${LilyGo_TETH_Elite_sx1262.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps =
|
||||
${LilyGo_TETH_Elite_sx1262.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
|
||||
TETHEliteBoard board;
|
||||
|
||||
static SPIClass spi(HSPI);
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
|
||||
WRAPPER_CLASS radio_driver(radio, board);
|
||||
|
||||
ESP32RTCClock fallback_clock;
|
||||
AutoDiscoverRTCClock rtc_clock(fallback_clock);
|
||||
SensorManager sensors;
|
||||
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
|
||||
bool radio_init() {
|
||||
fallback_clock.begin();
|
||||
rtc_clock.begin(Wire);
|
||||
|
||||
return radio.std_init(&spi);
|
||||
}
|
||||
|
||||
uint32_t radio_get_rng_seed() {
|
||||
return radio.random(0x7FFFFFFF);
|
||||
}
|
||||
|
||||
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
|
||||
radio.setFrequency(freq);
|
||||
radio.setSpreadingFactor(sf);
|
||||
radio.setBandwidth(bw);
|
||||
radio.setCodingRate(cr);
|
||||
}
|
||||
|
||||
void radio_set_tx_power(int8_t dbm) {
|
||||
radio.setOutputPower(dbm);
|
||||
}
|
||||
|
||||
mesh::LocalIdentity radio_new_identity() {
|
||||
RadioNoiseListener rng(radio);
|
||||
return mesh::LocalIdentity(&rng);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/radiolib/RadioLibWrappers.h>
|
||||
#include <helpers/radiolib/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
#include <helpers/SensorManager.h>
|
||||
#include "TETHEliteBoard.h"
|
||||
|
||||
extern TETHEliteBoard board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
extern SensorManager sensors;
|
||||
|
||||
bool radio_init();
|
||||
uint32_t radio_get_rng_seed();
|
||||
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
|
||||
void radio_set_tx_power(int8_t dbm);
|
||||
mesh::LocalIdentity radio_new_identity();
|
||||
@@ -92,7 +92,7 @@ extends = LilyGo_TLora_V2_1_1_6
|
||||
build_flags =
|
||||
${LilyGo_TLora_V2_1_1_6.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=160
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D OFFLINE_QUEUE_SIZE=128
|
||||
@@ -108,6 +108,10 @@ lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:LilyGo_TLora_V2_1_1_6_companion_radio_ble_ps]
|
||||
extends = env:LilyGo_TLora_V2_1_1_6_companion_radio_ble
|
||||
platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
|
||||
|
||||
[env:LilyGo_TLora_V2_1_1_6_room_server]
|
||||
extends = LilyGo_TLora_V2_1_1_6
|
||||
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[Promicro]
|
||||
extends = nrf52_base
|
||||
board = promicro_nrf52840
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
-I variants/promicro
|
||||
-D PROMICRO
|
||||
|
||||
@@ -91,6 +91,7 @@ build_src_filter = ${rak11310.build_src_filter}
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps = ${rak11310.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
lib_ignore = BLE
|
||||
|
||||
; [env:RAK_11310_companion_radio_ble]
|
||||
; extends = rak11310
|
||||
|
||||
@@ -12,6 +12,12 @@ VolatileRTCClock fallback_clock;
|
||||
AutoDiscoverRTCClock rtc_clock(fallback_clock);
|
||||
SensorManager sensors;
|
||||
|
||||
bool radio_init() {
|
||||
rtc_clock.begin(Wire);
|
||||
|
||||
return radio.std_init(&SPI1);
|
||||
}
|
||||
|
||||
void radio_set_tx_power(int8_t dbm) {
|
||||
radio.setOutputPower(dbm);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000)
|
||||
#define BATTERY_SAMPLES 8
|
||||
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class RAK3112Board : public ESP32Board {
|
||||
private:
|
||||
bool adc_active_state;
|
||||
@@ -51,33 +49,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void powerOff() override {
|
||||
enterDeepSleep(0);
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
analogReadResolution(12);
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
extends = nrf52_base
|
||||
board = rak3401
|
||||
board_check = true
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
${sensor_base.build_flags}
|
||||
-I variants/rak3401
|
||||
-D RAK_3401
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
-D LORA_TX_POWER=22
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
extends = nrf52_base
|
||||
board = rak4631
|
||||
board_check = true
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
extra_scripts = ${nrf52_base.extra_scripts}
|
||||
post:variants/rak4631/fix_bsec_lib.py
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
@@ -9,7 +10,7 @@ build_flags = ${nrf52_base.build_flags}
|
||||
-I variants/rak4631
|
||||
-D RAK_4631
|
||||
-D RAK_BOARD
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D PIN_BOARD_SCL=14
|
||||
-D PIN_BOARD_SDA=13
|
||||
-D PIN_GPS_TX=PIN_SERIAL1_RX
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
extends = nrf52_base
|
||||
board = rak4631
|
||||
board_check = true
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
${sensor_base.build_flags}
|
||||
-I variants/rak_wismesh_tag
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[rpi_picow]
|
||||
extends = rp2040_base
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
board = rpipicow
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
@@ -65,6 +64,7 @@ build_src_filter = ${rpi_picow.build_src_filter}
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps = ${rpi_picow.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
lib_ignore = BLE
|
||||
|
||||
; [env:PicoW_companion_radio_ble]
|
||||
; extends = rpi_picow
|
||||
|
||||
@@ -10,7 +10,7 @@ build_flags = ${nrf52_base.build_flags}
|
||||
-I src/helpers/nrf52
|
||||
-D NRF52_PLATFORM=1
|
||||
-D USE_SX1262
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
; -D NRF52_POWER_MANAGEMENT
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
-D P_LORA_TX_LED=12
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user