mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-10 03:47:39 +00:00
Compare commits
25 Commits
ch341-read
...
v2.7.17.90
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5e952b008 | ||
|
|
11b5f1a4fe | ||
|
|
f9c9350f45 | ||
|
|
a5b2d4a9d5 | ||
|
|
7fb95841e4 | ||
|
|
eaab8f04b5 | ||
|
|
9058ccecf9 | ||
|
|
1b83501ee2 | ||
|
|
ac571d5dd2 | ||
|
|
ef30fd850d | ||
|
|
b9a0015149 | ||
|
|
9673cfb0b2 | ||
|
|
757f7b68d6 | ||
|
|
5510dae8d3 | ||
|
|
52fd362720 | ||
|
|
33e1f58f6e | ||
|
|
9dc7ef612e | ||
|
|
b2c82bdc41 | ||
|
|
54a928f47f | ||
|
|
33f18659c8 | ||
|
|
3a7093a973 | ||
|
|
a4f6f4515a | ||
|
|
d609d05698 | ||
|
|
83c6161ac6 | ||
|
|
d93d68d31e |
2
.github/workflows/test_native.yml
vendored
2
.github/workflows/test_native.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
|||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Test Report
|
- name: Test Report
|
||||||
uses: dorny/test-reporter@v2.3.0
|
uses: dorny/test-reporter@v2.4.0
|
||||||
with:
|
with:
|
||||||
name: PlatformIO Tests
|
name: PlatformIO Tests
|
||||||
path: testreport.xml
|
path: testreport.xml
|
||||||
|
|||||||
2
.github/workflows/update_protobufs.yml
vendored
2
.github/workflows/update_protobufs.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Update submodule
|
- name: Update submodule
|
||||||
if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' }}
|
if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
run: |
|
run: |
|
||||||
git submodule update --remote protobufs
|
git submodule update --remote protobufs
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ plugins:
|
|||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.495
|
- checkov@3.2.497
|
||||||
- renovate@42.64.1
|
- renovate@42.69.2
|
||||||
- prettier@3.7.4
|
- prettier@3.7.4
|
||||||
- trufflehog@3.92.3
|
- trufflehog@3.92.4
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
- bandit@1.9.2
|
- bandit@1.9.2
|
||||||
- trivy@0.68.2
|
- trivy@0.68.2
|
||||||
@@ -21,7 +21,7 @@ lint:
|
|||||||
- markdownlint@0.47.0
|
- markdownlint@0.47.0
|
||||||
- oxipng@10.0.0
|
- oxipng@10.0.0
|
||||||
- svgo@4.0.0
|
- svgo@4.0.0
|
||||||
- actionlint@1.7.9
|
- actionlint@1.7.10
|
||||||
- flake8@7.3.0
|
- flake8@7.3.0
|
||||||
- hadolint@2.14.0
|
- hadolint@2.14.0
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ rm -f $BUILDDIR/firmware*
|
|||||||
export APP_VERSION=$VERSION
|
export APP_VERSION=$VERSION
|
||||||
|
|
||||||
basename=firmware-$1-$VERSION
|
basename=firmware-$1-$VERSION
|
||||||
|
ota_basename=${basename}-ota
|
||||||
|
|
||||||
pio run --environment $1 -t mtjson # -v
|
pio run --environment $1 -t mtjson # -v
|
||||||
|
|
||||||
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
||||||
|
|
||||||
echo "Copying NRF52 dfu (OTA) file"
|
echo "Copying NRF52 dfu (OTA) file"
|
||||||
cp $BUILDDIR/$basename.zip $OUTDIR/$basename.zip
|
cp $BUILDDIR/$basename.zip $OUTDIR/$ota_basename.zip
|
||||||
|
|
||||||
echo "Copying NRF52 UF2 file"
|
echo "Copying NRF52 UF2 file"
|
||||||
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
|
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
|
||||||
|
|||||||
@@ -87,9 +87,6 @@
|
|||||||
</screenshots>
|
</screenshots>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
<release version="2.7.18" date="2025-12-20">
|
|
||||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.18</url>
|
|
||||||
</release>
|
|
||||||
<release version="2.7.17" date="2025-11-28">
|
<release version="2.7.17" date="2025-11-28">
|
||||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.17</url>
|
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.17</url>
|
||||||
</release>
|
</release>
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ lfsbin = f"{progname.replace('firmware-', 'littlefs-')}.bin"
|
|||||||
|
|
||||||
def manifest_gather(source, target, env):
|
def manifest_gather(source, target, env):
|
||||||
out = []
|
out = []
|
||||||
|
board_platform = env.BoardConfig().get("platform")
|
||||||
|
needs_ota_suffix = board_platform == "nordicnrf52"
|
||||||
check_paths = [
|
check_paths = [
|
||||||
progname,
|
progname,
|
||||||
f"{progname}.elf",
|
f"{progname}.elf",
|
||||||
@@ -32,8 +34,11 @@ def manifest_gather(source, target, env):
|
|||||||
for p in check_paths:
|
for p in check_paths:
|
||||||
f = env.File(env.subst(f"$BUILD_DIR/{p}"))
|
f = env.File(env.subst(f"$BUILD_DIR/{p}"))
|
||||||
if f.exists():
|
if f.exists():
|
||||||
|
manifest_name = p
|
||||||
|
if needs_ota_suffix and p == f"{progname}.zip":
|
||||||
|
manifest_name = f"{progname}-ota.zip"
|
||||||
d = {
|
d = {
|
||||||
"name": p,
|
"name": manifest_name,
|
||||||
"md5": f.get_content_hash(), # Returns MD5 hash
|
"md5": f.get_content_hash(), # Returns MD5 hash
|
||||||
"bytes": f.get_size() # Returns file size in bytes
|
"bytes": f.get_size() # Returns file size in bytes
|
||||||
}
|
}
|
||||||
|
|||||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,9 +1,3 @@
|
|||||||
meshtasticd (2.7.18.0) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Version 2.7.18
|
|
||||||
|
|
||||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Sat, 20 Dec 2025 15:47:25 +0000
|
|
||||||
|
|
||||||
meshtasticd (2.7.17.0) unstable; urgency=medium
|
meshtasticd (2.7.17.0) unstable; urgency=medium
|
||||||
|
|
||||||
* Version 2.7.17
|
* Version 2.7.17
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ monitor_speed = 115200
|
|||||||
monitor_filters = direct
|
monitor_filters = direct
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master
|
||||||
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/2887bf4a19f64d92c984dcc8fd5ca7429e425e4a.zip
|
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/b34c6817c25d6faabb3a8a162b5d14fb75395433.zip
|
||||||
# renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master
|
||||||
https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip
|
https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip
|
||||||
# renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master
|
||||||
@@ -103,13 +103,17 @@ lib_deps =
|
|||||||
thingsboard/TBPubSubClient@2.12.1
|
thingsboard/TBPubSubClient@2.12.1
|
||||||
# renovate: datasource=custom.pio depName=NTPClient packageName=arduino-libraries/library/NTPClient
|
# renovate: datasource=custom.pio depName=NTPClient packageName=arduino-libraries/library/NTPClient
|
||||||
arduino-libraries/NTPClient@3.2.1
|
arduino-libraries/NTPClient@3.2.1
|
||||||
|
|
||||||
; Extra TCP/IP networking libs for supported devices
|
|
||||||
[networking_extra]
|
|
||||||
lib_deps =
|
|
||||||
# renovate: datasource=custom.pio depName=Syslog packageName=arcao/library/Syslog
|
# renovate: datasource=custom.pio depName=Syslog packageName=arcao/library/Syslog
|
||||||
arcao/Syslog@2.0.0
|
arcao/Syslog@2.0.0
|
||||||
|
|
||||||
|
; Minimal networking libs for nrf52 (excludes Syslog to save flash)
|
||||||
|
[nrf52_networking_base]
|
||||||
|
lib_deps =
|
||||||
|
# renovate: datasource=custom.pio depName=TBPubSubClient packageName=thingsboard/library/TBPubSubClient
|
||||||
|
thingsboard/TBPubSubClient@2.12.1
|
||||||
|
# renovate: datasource=custom.pio depName=NTPClient packageName=arduino-libraries/library/NTPClient
|
||||||
|
arduino-libraries/NTPClient@3.2.1
|
||||||
|
|
||||||
[radiolib_base]
|
[radiolib_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib
|
# renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib
|
||||||
@@ -119,7 +123,7 @@ lib_deps =
|
|||||||
[device-ui_base]
|
[device-ui_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||||
https://github.com/meshtastic/device-ui/archive/862ed040c4ab44f0dfbbe492691f144886102588.zip
|
https://github.com/meshtastic/device-ui/archive/a8e2f947f7abaf0c5ac8e6dd189a22156335beaa.zip
|
||||||
|
|
||||||
; Common libs for environmental measurements in telemetry module
|
; Common libs for environmental measurements in telemetry module
|
||||||
[environmental_base]
|
[environmental_base]
|
||||||
@@ -158,8 +162,8 @@ lib_deps =
|
|||||||
emotibit/EmotiBit MLX90632@1.0.8
|
emotibit/EmotiBit MLX90632@1.0.8
|
||||||
# renovate: datasource=custom.pio depName=Adafruit MLX90614 packageName=adafruit/library/Adafruit MLX90614 Library
|
# renovate: datasource=custom.pio depName=Adafruit MLX90614 packageName=adafruit/library/Adafruit MLX90614 Library
|
||||||
adafruit/Adafruit MLX90614 Library@2.1.5
|
adafruit/Adafruit MLX90614 Library@2.1.5
|
||||||
# renovate: datasource=git-refs depName=INA3221 packageName=https://github.com/sgtwilko/INA3221 gitBranch=FixOverflow
|
# renovate: datasource=github-tags depName=INA3221 packageName=sgtwilko/INA3221
|
||||||
https://github.com/sgtwilko/INA3221/archive/bb03d7e9bfcc74fc798838a54f4f99738f29fc6a.zip
|
https://github.com/sgtwilko/INA3221#bb03d7e9bfcc74fc798838a54f4f99738f29fc6a
|
||||||
# renovate: datasource=custom.pio depName=QMC5883L Compass packageName=mprograms/library/QMC5883LCompass
|
# renovate: datasource=custom.pio depName=QMC5883L Compass packageName=mprograms/library/QMC5883LCompass
|
||||||
mprograms/QMC5883LCompass@1.2.3
|
mprograms/QMC5883LCompass@1.2.3
|
||||||
# renovate: datasource=custom.pio depName=DFRobot_RTU packageName=dfrobot/library/DFRobot_RTU
|
# renovate: datasource=custom.pio depName=DFRobot_RTU packageName=dfrobot/library/DFRobot_RTU
|
||||||
|
|||||||
Submodule protobufs updated: c474fd3f49...9beb80f1d3
@@ -13,81 +13,41 @@ const Emote emotes[] = {
|
|||||||
{"\U0001F44E", thumbdown, thumbs_width, thumbs_height}, // 👎 Thumbs Down
|
{"\U0001F44E", thumbdown, thumbs_width, thumbs_height}, // 👎 Thumbs Down
|
||||||
|
|
||||||
// --- Smileys (Multiple Unicode Aliases) ---
|
// --- Smileys (Multiple Unicode Aliases) ---
|
||||||
{"\U0001F60A", smiling_eyes, smiling_eyes_width, smiling_eyes_height}, // 😊 Smiling Eyes
|
{"\U0001F60A", Smiling_Eyes, Smiling_Eyes_width, Smiling_Eyes_height}, // 😊 Smiling Eyes
|
||||||
{"\U0001F600", grinning, grinning_width, grinning_height}, // 😀 Grinning Face
|
{"\U0001F600", Grinning, Grinning_width, Grinning_height}, // 😀 Grinning Face
|
||||||
{"\U0001F642", slightly_smiling, slightly_smiling_width, slightly_smiling_height}, // 🙂 Slightly Smiling Face
|
{"\U0001F642", Slightly_Smiling, Slightly_Smiling_width, Slightly_Smiling_height}, // 🙂 Slightly Smiling Face
|
||||||
{"\U0001F609", winking_face, winking_face_width, winking_face_height}, // 😉 Winking Face
|
{"\U0001F609", Winking_Face, Winking_Face_width, Winking_Face_height}, // 😉 Winking Face
|
||||||
{"\U0001F601", grinning_smiling_eyes, grinning_smiling_eyes_width, grinning_smiling_eyes_height}, // 😁 Grinning Smiling Eyes
|
{"\U0001F601", Grinning_Smiling_Eyes, Grinning_Smiling_Eyes_width, Grinning_Smiling_Eyes_height}, // 😁 Grinning Smiling Eyes
|
||||||
{"\U0001F60D", heart_eyes, heart_eyes_width, heart_eyes_height}, // 😍 Heart Eyes
|
{"\U0001F60D", Heart_eyes, Heart_eyes_width, Heart_eyes_height}, // 😍 Heart Eyes
|
||||||
{"\U0001F970", heart_smile, heart_smile_width, heart_smile_height}, // 🥰 Smiling Face with Hearts
|
{"\U0001F970", heart_smile, heart_smile_width, heart_smile_height}, // 🥰 Smiling Face with Hearts
|
||||||
|
|
||||||
// --- Question/Alert ---
|
// --- Question/Alert ---
|
||||||
{"\u2753", question, question_width, question_height}, // ❓ Question Mark
|
{"\u2753", question, question_width, question_height}, // ❓ Question Mark
|
||||||
{"\u203C\uFE0F", bang, bang_width, bang_height}, // ‼️ Double Exclamation Mark
|
{"\u203C\uFE0F", bang, bang_width, bang_height}, // ‼️ Double Exclamation Mark
|
||||||
{"\u26A0\uFE0F", caution, caution_width, caution_height}, // ⚠️ Warning Sign
|
|
||||||
|
|
||||||
// --- Laughing Faces ---
|
// --- Laughing Faces ---
|
||||||
{"\U0001F602", haha, haha_width, haha_height}, // 😂 Face with Tears of Joy
|
{"\U0001F602", haha, haha_width, haha_height}, // 😂 Face with Tears of Joy
|
||||||
{"\U0001F923", rofl, rofl_width, rofl_height}, // 🤣 Rolling on the Floor Laughing
|
{"\U0001F923", ROFL, ROFL_width, ROFL_height}, // 🤣 Rolling on the Floor Laughing
|
||||||
{"\U0001F606", smiling_closed_eyes, smiling_closed_eyes_width, smiling_closed_eyes_height}, // 😆 Smiling Closed Eyes
|
{"\U0001F606", Smiling_Closed_Eyes, Smiling_Closed_Eyes_width, Smiling_Closed_Eyes_height}, // 😆 Smiling Closed Eyes
|
||||||
{"\U0001F605", haha, haha_width, haha_height}, // 😅 Smiling with Sweat
|
{"\U0001F605", haha, haha_width, haha_height}, // 😅 Smiling with Sweat
|
||||||
{"\U0001F604", grinning_smiling_eyes_2, grinning_smiling_eyes_2_width,
|
{"\U0001F604", Grinning_SmilingEyes2, Grinning_SmilingEyes2_width,
|
||||||
grinning_smiling_eyes_2_height}, // 😄 Grinning Face with Smiling Eyes
|
Grinning_SmilingEyes2_height}, // 😄 Grinning Face with Smiling Eyes
|
||||||
{"\U0001F62D", loudly_crying_face, loudly_crying_face_width, loudly_crying_face_height}, // 😭 Loudly Crying Face
|
{"\U0001F62D", Loudly_Crying_Face, Loudly_Crying_Face_width, Loudly_Crying_Face_height}, // 😭 Loudly Crying Face
|
||||||
{"\U0001F92E", vomiting, vomiting_width, vomiting_height}, // 🤮 Face Vomiting
|
|
||||||
{"\U0001F60E", cool, cool_width, cool_height}, // 😎 Smiling Face with Sunglasses
|
|
||||||
{"\U0001F440", eyes, eyes_width, eyes_height}, // 👀 Eyes
|
|
||||||
{"\U0001F441\uFE0F", eye, eye_width, eye_height}, // 👁️ Eye
|
|
||||||
|
|
||||||
// --- Gestures and People ---
|
// --- Gestures and People ---
|
||||||
{"\U0001F44B", wave_icon, wave_icon_width, wave_icon_height}, // 👋 Waving Hand
|
{"\U0001F44B", wave_icon, wave_icon_width, wave_icon_height}, // 👋 Waving Hand
|
||||||
{"\u270C\uFE0F", peace_sign, peace_sign_width, peace_sign_height}, // ✌️ Victory Hand
|
{"\u270C\uFE0F", peace_sign, peace_sign_width, peace_sign_height}, // ✌️ Victory Hand
|
||||||
{"\U0001F596", vulcan_salute, vulcan_salute_width, vulcan_salute_height}, // 🖖 Vulcan Salute
|
{"\U0001F596", vulcan_salute, vulcan_salute_width, vulcan_salute_height}, // 🖖 Vulcan Salute
|
||||||
{"\U0001F64F", praying, praying_width, praying_height}, // 🙏 Praying Hands
|
{"\U0001F64F", Praying, Praying_width, Praying_height}, // 🙏 Praying Hands
|
||||||
{"\U0001F4AA", strong, strong_width, strong_height}, // 💪 Flexed Biceps
|
|
||||||
{"\U0001F937", shrug, shrug_width, shrug_height}, // 🤷 Person Shrugging
|
|
||||||
{"\U0001F920", cowboy, cowboy_width, cowboy_height}, // 🤠 Cowboy Hat Face
|
{"\U0001F920", cowboy, cowboy_width, cowboy_height}, // 🤠 Cowboy Hat Face
|
||||||
{"\U0001F3A7", deadmau5, deadmau5_width, deadmau5_height}, // 🎧 Headphones
|
{"\U0001F3A7", deadmau5, deadmau5_width, deadmau5_height}, // 🎧 Headphones
|
||||||
|
|
||||||
// --- Symbols ---
|
|
||||||
{"\u2714\uFE0F", check_mark, check_mark_width, check_mark_height}, // ✔️ Check Mark
|
|
||||||
{"\u2705", check_mark, check_mark_width, check_mark_height}, // ✅ Check Mark Button
|
|
||||||
{"\u2611\uFE0F", check_mark, check_mark_width, check_mark_height}, // ☑️ Check Box with Check
|
|
||||||
{"\U0001F3E0", house, house_width, house_height}, // 🏠 House
|
|
||||||
|
|
||||||
// --- Weather ---
|
// --- Weather ---
|
||||||
{"\u2600", sun, sun_width, sun_height}, // ☀ Sun (without variation selector)
|
{"\u2600", sun, sun_width, sun_height}, // ☀ Sun (without variation selector)
|
||||||
{"\u2600\uFE0F", sun, sun_width, sun_height}, // ☀️ Sun (with variation selector)
|
{"\u2600\uFE0F", sun, sun_width, sun_height}, // ☀️ Sun (with variation selector)
|
||||||
{"\U0001F327\uFE0F", rain, rain_width, rain_height}, // 🌧️ Cloud with Rain
|
{"\U0001F327\uFE0F", rain, rain_width, rain_height}, // 🌧️ Cloud with Rain
|
||||||
{"\u2601\uFE0F", cloud, cloud_width, cloud_height}, // ☁️ Cloud
|
{"\u2601\uFE0F", cloud, cloud_width, cloud_height}, // ☁️ Cloud
|
||||||
{"\U0001F32B\uFE0F", fog, fog_width, fog_height}, // 🌫️ Fog
|
{"\U0001F32B\uFE0F", fog, fog_width, fog_height}, // 🌫️ Fog
|
||||||
{"\u2744\uFE0F", snowflake, snowflake_width, snowflake_height}, // ❄️ Snowflake
|
|
||||||
{"\U0001F4A7", drop, drop_width, drop_height}, // 💧 Droplet
|
|
||||||
{"\U0001F321\uFE0F", thermometer, thermometer_width, thermometer_height}, // 🌡️ Thermometer
|
|
||||||
{"\U0001F326\uFE0F", sun_behind_raincloud, sun_behind_raincloud_width,
|
|
||||||
sun_behind_raincloud_height}, // 🌦️ Sun Behind Rain Cloud
|
|
||||||
{"\u26C5", sun_behind_cloud, sun_behind_cloud_width, sun_behind_cloud_height}, // ⛅ Sun Behind Cloud
|
|
||||||
{"\u26C5\uFE0F", sun_behind_cloud, sun_behind_cloud_width, sun_behind_cloud_height}, // ⛅️ Sun Behind Cloud
|
|
||||||
{"\U0001F328\uFE0F", cloud_with_snow, cloud_with_snow_width, cloud_with_snow_height}, // 🌨️ Cloud with Snow
|
|
||||||
{"\U0001F329\uFE0F", cloud_with_lightning, cloud_with_lightning_width,
|
|
||||||
cloud_with_lightning_height}, // 🌩️ Cloud with Lightning
|
|
||||||
{"\u26C8", cloud_with_lightning_rain, cloud_with_lightning_rain_width,
|
|
||||||
cloud_with_lightning_rain_height}, // ⛈ Cloud with Lightning and Rain
|
|
||||||
{"\u26C8\uFE0F", cloud_with_lightning_rain, cloud_with_lightning_rain_width,
|
|
||||||
cloud_with_lightning_rain_height}, // ⛈️ Cloud with Lightning and Rain
|
|
||||||
{"\U0001F32C\uFE0F", wind_face, wind_face_width, wind_face_height}, // 🌬️ Wind Face
|
|
||||||
|
|
||||||
// --- Moon Phases ---
|
|
||||||
{"\U0001F311", new_moon, new_moon_width, new_moon_height}, // 🌑 New Moon
|
|
||||||
{"\U0001F312", waxing_crescent_moon, waxing_crescent_moon_width, waxing_crescent_moon_height}, // 🌒 Waxing Crescent Moon
|
|
||||||
{"\U0001F313", first_quarter_moon, first_quarter_moon_width, first_quarter_moon_height}, // 🌓 First Quarter Moon
|
|
||||||
{"\U0001F314", waxing_gibbous_moon, waxing_gibbous_moon_width, waxing_gibbous_moon_height}, // 🌔 Waxing Gibbous Moon
|
|
||||||
{"\U0001F315", full_moon, full_moon_width, full_moon_height}, // 🌕 Full Moon
|
|
||||||
{"\U0001F316", waning_gibbous_moon, waning_gibbous_moon_width, waning_gibbous_moon_height}, // 🌖 Waning Gibbous Moon
|
|
||||||
{"\U0001F317", last_quarter_moon, last_quarter_moon_width, last_quarter_moon_height}, // 🌗 Last Quarter Moon
|
|
||||||
{"\U0001F318", waning_crescent_moon, waning_crescent_moon_width, waning_crescent_moon_height}, // 🌘 Waning Crescent Moon
|
|
||||||
{"\U0001F31B", first_quarter_moon_face, first_quarter_moon_face_width,
|
|
||||||
first_quarter_moon_face_height}, // 🌛 First Quarter Moon Face
|
|
||||||
|
|
||||||
// --- Misc Faces ---
|
// --- Misc Faces ---
|
||||||
{"\U0001F608", devil, devil_width, devil_height}, // 😈 Smiling Face with Horns
|
{"\U0001F608", devil, devil_width, devil_height}, // 😈 Smiling Face with Horns
|
||||||
@@ -107,49 +67,13 @@ const Emote emotes[] = {
|
|||||||
{"\U0001F498", heart, heart_width, heart_height}, // 💘 Heart with Arrow
|
{"\U0001F498", heart, heart_width, heart_height}, // 💘 Heart with Arrow
|
||||||
|
|
||||||
// --- Objects ---
|
// --- Objects ---
|
||||||
{"\U0001F4A9", poo, poo_width, poo_height}, // 💩 Pile of Poo
|
{"\U0001F4A9", poo, poo_width, poo_height}, // 💩 Pile of Poo
|
||||||
{"\U0001F514", bell_icon, bell_icon_width, bell_icon_height}, // 🔔 Bell
|
{"\U0001F514", bell_icon, bell_icon_width, bell_icon_height}, // 🔔 Bell
|
||||||
{"\U0001F4CB", clipboard, clipboard_width, clipboard_height}, // 📋 Clipboard
|
{"\U0001F36A", cookie, cookie_width, cookie_height}, // 🍪 Cookie
|
||||||
{"\U0001F36A", cookie, cookie_width, cookie_height}, // 🍪 Cookie
|
{"\U0001F525", Fire, Fire_width, Fire_height}, // 🔥 Fire
|
||||||
{"\U0001F370", shortcake, shortcake_width, shortcake_height}, // 🍰 Shortcake
|
{"\u2728", Sparkles, Sparkles_width, Sparkles_height}, // ✨ Sparkles
|
||||||
{"\U0001F351", peach, peach_width, peach_height}, // 🍑 Peach
|
{"\U0001F573\uFE0F", hole, hole_width, hole_height}, // 🕳️ Hole
|
||||||
{"\U0001F983", turkey, turkey_width, turkey_height}, // 🦃 Turkey
|
{"\U0001F3B3", bowling, bowling_width, bowling_height} // 🎳 Bowling
|
||||||
{"\U0001F357", turkey_leg, turkey_leg_width, turkey_leg_height}, // 🍗 Poultry Leg
|
|
||||||
{"\U0001F525", fire, fire_width, fire_height}, // 🔥 Fire
|
|
||||||
{"\u2728", sparkles, sparkles_width, sparkles_height}, // ✨ Sparkles
|
|
||||||
{"\U0001F573\uFE0F", hole, hole_width, hole_height}, // 🕳️ Hole
|
|
||||||
{"\U0001F3B3", bowling, bowling_width, bowling_height}, // 🎳 Bowling
|
|
||||||
|
|
||||||
// --- Arrows ---
|
|
||||||
{"\u2193", downwards_arrow, downwards_arrow_width, downwards_arrow_height}, // ↓ Downwards Arrow
|
|
||||||
{"\u2193\uFE0E", downwards_arrow, downwards_arrow_width, downwards_arrow_height}, // ↓︎ Downwards Arrow (text)
|
|
||||||
{"\u2193\uFE0F", downwards_arrow, downwards_arrow_width, downwards_arrow_height}, // ↓️ Downwards Arrow (emoji)
|
|
||||||
{"\u2199", south_west_arrow, south_west_arrow_width, south_west_arrow_height}, // ↙ South West Arrow
|
|
||||||
{"\u2199\uFE0E", south_west_arrow, south_west_arrow_width, south_west_arrow_height}, // ↙︎ South West Arrow (text)
|
|
||||||
{"\u2199\uFE0F", south_west_arrow, south_west_arrow_width, south_west_arrow_height}, // ↙️ South West Arrow (emoji)
|
|
||||||
{"\u2190", leftwards_arrow, leftwards_arrow_width, leftwards_arrow_height}, // ← Leftwards Arrow
|
|
||||||
{"\u2190\uFE0E", leftwards_arrow, leftwards_arrow_width, leftwards_arrow_height}, // ←︎ Leftwards Arrow (text)
|
|
||||||
{"\u2190\uFE0F", leftwards_arrow, leftwards_arrow_width, leftwards_arrow_height}, // ←️ Leftwards Arrow (emoji)
|
|
||||||
{"\u2196", north_west_arrow, north_west_arrow_width, north_west_arrow_height}, // ↖ North West Arrow
|
|
||||||
{"\u2196\uFE0E", north_west_arrow, north_west_arrow_width, north_west_arrow_height}, // ↖︎ North West Arrow (text)
|
|
||||||
{"\u2196\uFE0F", north_west_arrow, north_west_arrow_width, north_west_arrow_height}, // ↖️ North West Arrow (emoji)
|
|
||||||
{"\u2191", upwards_arrow, upwards_arrow_width, upwards_arrow_height}, // ↑ Upwards Arrow
|
|
||||||
{"\u2191\uFE0E", upwards_arrow, upwards_arrow_width, upwards_arrow_height}, // ↑︎ Upwards Arrow (text)
|
|
||||||
{"\u2191\uFE0F", upwards_arrow, upwards_arrow_width, upwards_arrow_height}, // ↑️ Upwards Arrow (emoji)
|
|
||||||
{"\u2197", north_east_arrow, north_east_arrow_width, north_east_arrow_height}, // ↗ North East Arrow
|
|
||||||
{"\u2197\uFE0E", north_east_arrow, north_east_arrow_width, north_east_arrow_height}, // ↗︎ North East Arrow (text)
|
|
||||||
{"\u2197\uFE0F", north_east_arrow, north_east_arrow_width, north_east_arrow_height}, // ↗️ North East Arrow (emoji)
|
|
||||||
{"\u2192", rightwards_arrow, rightwards_arrow_width, rightwards_arrow_height}, // → Rightwards Arrow
|
|
||||||
{"\u2192\uFE0E", rightwards_arrow, rightwards_arrow_width, rightwards_arrow_height}, // →︎ Rightwards Arrow (text)
|
|
||||||
{"\u2192\uFE0F", rightwards_arrow, rightwards_arrow_width, rightwards_arrow_height}, // →️ Rightwards Arrow (emoji)
|
|
||||||
{"\u2198", south_east_arrow, south_east_arrow_width, south_east_arrow_height}, // ↘ South East Arrow
|
|
||||||
{"\u2198\uFE0E", south_east_arrow, south_east_arrow_width, south_east_arrow_height}, // ↘︎ South East Arrow (text)
|
|
||||||
{"\u2198\uFE0F", south_east_arrow, south_east_arrow_width, south_east_arrow_height}, // ↘️ South East Arrow (emoji)
|
|
||||||
|
|
||||||
// --- Halloween ---
|
|
||||||
{"\U0001F383", jack_o_lantern, jack_o_lantern_width, jack_o_lantern_height}, // 🎃 Jack-O-Lantern
|
|
||||||
{"\U0001F47B", ghost, ghost_width, ghost_height}, // 👻 Ghost
|
|
||||||
{"\U0001F480", skull, skull_width, skull_height} // 💀 Skull
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -164,23 +88,23 @@ const unsigned char thumbdown[] PROGMEM = {0xF0, 0x1F, 0x08, 0x20, 0x06, 0x30, 0
|
|||||||
0x40, 0x06, 0x70, 0x06, 0x40, 0x06, 0x3F, 0x18, 0x02, 0x20, 0x02,
|
0x40, 0x06, 0x70, 0x06, 0x40, 0x06, 0x3F, 0x18, 0x02, 0x20, 0x02,
|
||||||
0x40, 0x04, 0x80, 0x04, 0x80, 0x04, 0x00, 0x03, 0x00, 0x00};
|
0x40, 0x04, 0x80, 0x04, 0x80, 0x04, 0x00, 0x03, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char smiling_eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x52,
|
const unsigned char Smiling_Eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x52,
|
||||||
0x4A, 0x02, 0x40, 0x02, 0x40, 0x22, 0x44, 0x22, 0x44, 0xC2, 0x43,
|
0x4A, 0x02, 0x40, 0x02, 0x40, 0x22, 0x44, 0x22, 0x44, 0xC2, 0x43,
|
||||||
0x04, 0x20, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0x04, 0x20, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char grinning[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x44, 0x22, 0x42,
|
const unsigned char Grinning[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x44, 0x22, 0x42,
|
||||||
0x42, 0x02, 0x40, 0x02, 0x40, 0xF2, 0x4F, 0x12, 0x48, 0x22, 0x44,
|
0x42, 0x02, 0x40, 0x02, 0x40, 0xF2, 0x4F, 0x12, 0x48, 0x22, 0x44,
|
||||||
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char slightly_smiling[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x44, 0x22, 0x42,
|
const unsigned char Slightly_Smiling[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x44, 0x22, 0x42,
|
||||||
0x42, 0x02, 0x40, 0x02, 0x40, 0x12, 0x48, 0x12, 0x48, 0x22, 0x44,
|
0x42, 0x02, 0x40, 0x02, 0x40, 0x12, 0x48, 0x12, 0x48, 0x22, 0x44,
|
||||||
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char winking_face[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x44, 0x20, 0x42,
|
const unsigned char Winking_Face[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x44, 0x20, 0x42,
|
||||||
0x46, 0x02, 0x40, 0x02, 0x40, 0x12, 0x48, 0x12, 0x48, 0x22, 0x44,
|
0x46, 0x02, 0x40, 0x02, 0x40, 0x12, 0x48, 0x12, 0x48, 0x22, 0x44,
|
||||||
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char grinning_smiling_eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x52,
|
const unsigned char Grinning_Smiling_Eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x52,
|
||||||
0x4A, 0x02, 0x40, 0xFA, 0x5F, 0x0A, 0x50, 0x0A, 0x50, 0x12, 0x48,
|
0x4A, 0x02, 0x40, 0xFA, 0x5F, 0x0A, 0x50, 0x0A, 0x50, 0x12, 0x48,
|
||||||
0x24, 0x24, 0xC4, 0x23, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0x24, 0x24, 0xC4, 0x23, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
@@ -188,7 +112,7 @@ const unsigned char heart_smile[] PROGMEM = {0x00, 0x00, 0x6C, 0x07, 0x7C, 0x18,
|
|||||||
0x0A, 0x02, 0xD8, 0x02, 0xF8, 0x22, 0xFC, 0x20, 0x74, 0xDB, 0x23,
|
0x0A, 0x02, 0xD8, 0x02, 0xF8, 0x22, 0xFC, 0x20, 0x74, 0xDB, 0x23,
|
||||||
0x1F, 0x00, 0x1F, 0x20, 0x0E, 0x18, 0xE4, 0x07, 0x00, 0x00};
|
0x1F, 0x00, 0x1F, 0x20, 0x0E, 0x18, 0xE4, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char heart_eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x54, 0x2A, 0xFA,
|
const unsigned char Heart_eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x54, 0x2A, 0xFA,
|
||||||
0x5F, 0x72, 0x4E, 0x22, 0x44, 0x02, 0x40, 0x12, 0x48, 0x12, 0x48,
|
0x5F, 0x72, 0x4E, 0x22, 0x44, 0x02, 0x40, 0x12, 0x48, 0x12, 0x48,
|
||||||
0x24, 0x24, 0xC4, 0x23, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0x24, 0x24, 0xC4, 0x23, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
@@ -204,19 +128,19 @@ const unsigned char haha[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04,
|
|||||||
0x4A, 0x0A, 0x50, 0x0E, 0x70, 0xF2, 0x4F, 0x12, 0x48, 0x32, 0x44,
|
0x4A, 0x0A, 0x50, 0x0E, 0x70, 0xF2, 0x4F, 0x12, 0x48, 0x32, 0x44,
|
||||||
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char rofl[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x84, 0x21, 0x84, 0x20, 0x02,
|
const unsigned char ROFL[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x84, 0x21, 0x84, 0x20, 0x02,
|
||||||
0x4C, 0x02, 0x4A, 0x1A, 0x49, 0x8A, 0x48, 0x42, 0x48, 0x22, 0x44,
|
0x4C, 0x02, 0x4A, 0x1A, 0x49, 0x8A, 0x48, 0x42, 0x48, 0x22, 0x44,
|
||||||
0xE4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0xE4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char smiling_closed_eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x42,
|
const unsigned char Smiling_Closed_Eyes[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x42,
|
||||||
0x42, 0x22, 0x44, 0x02, 0x40, 0xF2, 0x4F, 0x12, 0x48, 0x22, 0x44,
|
0x42, 0x22, 0x44, 0x02, 0x40, 0xF2, 0x4F, 0x12, 0x48, 0x22, 0x44,
|
||||||
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char grinning_smiling_eyes_2[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x52,
|
const unsigned char Grinning_SmilingEyes2[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x24, 0x24, 0x52,
|
||||||
0x4A, 0x02, 0x40, 0x02, 0x40, 0xF2, 0x4F, 0x12, 0x48, 0x22, 0x44,
|
0x4A, 0x02, 0x40, 0x02, 0x40, 0xF2, 0x4F, 0x12, 0x48, 0x22, 0x44,
|
||||||
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char loudly_crying_face[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x34, 0x2C, 0x4A,
|
const unsigned char Loudly_Crying_Face[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x34, 0x2C, 0x4A,
|
||||||
0x52, 0x12, 0x48, 0x12, 0x48, 0x92, 0x49, 0x52, 0x4A, 0x52, 0x4A,
|
0x52, 0x12, 0x48, 0x12, 0x48, 0x92, 0x49, 0x52, 0x4A, 0x52, 0x4A,
|
||||||
0x54, 0x2A, 0x94, 0x29, 0x18, 0x18, 0xF0, 0x0F, 0x00, 0x00};
|
0x54, 0x2A, 0x94, 0x29, 0x18, 0x18, 0xF0, 0x0F, 0x00, 0x00};
|
||||||
|
|
||||||
@@ -268,7 +192,7 @@ const unsigned char cookie[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04
|
|||||||
0x40, 0x02, 0x58, 0x82, 0x5B, 0x92, 0x43, 0x82, 0x43, 0x02, 0x40,
|
0x40, 0x02, 0x58, 0x82, 0x5B, 0x92, 0x43, 0x82, 0x43, 0x02, 0x40,
|
||||||
0x64, 0x28, 0x64, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
0x64, 0x28, 0x64, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char fire[] PROGMEM = {0x30, 0x00, 0xF0, 0x00, 0xF8, 0x03, 0xF8, 0x07, 0xFC, 0x1F, 0xFC,
|
const unsigned char Fire[] PROGMEM = {0x30, 0x00, 0xF0, 0x00, 0xF8, 0x03, 0xF8, 0x07, 0xFC, 0x1F, 0xFC,
|
||||||
0x1F, 0xFE, 0x3E, 0x7E, 0x3E, 0x3E, 0x7C, 0x1E, 0x78, 0x1E, 0x70,
|
0x1F, 0xFE, 0x3E, 0x7E, 0x3E, 0x3E, 0x7C, 0x1E, 0x78, 0x1E, 0x70,
|
||||||
0x1C, 0x70, 0x1C, 0x70, 0x38, 0x38, 0x30, 0x38, 0x60, 0x0C};
|
0x1C, 0x70, 0x1C, 0x70, 0x38, 0x38, 0x30, 0x38, 0x60, 0x0C};
|
||||||
|
|
||||||
@@ -276,11 +200,11 @@ const unsigned char peace_sign[] PROGMEM = {0xC0, 0x30, 0x40, 0x29, 0x40, 0x25,
|
|||||||
0x0A, 0x54, 0x68, 0x54, 0x58, 0x54, 0x44, 0x3C, 0x22, 0x04, 0x22,
|
0x0A, 0x54, 0x68, 0x54, 0x58, 0x54, 0x44, 0x3C, 0x22, 0x04, 0x22,
|
||||||
0x04, 0x12, 0x08, 0x10, 0x10, 0x08, 0xE0, 0x07, 0x00, 0x00};
|
0x04, 0x12, 0x08, 0x10, 0x10, 0x08, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char praying[] PROGMEM = {0x00, 0x00, 0x40, 0x02, 0xA0, 0x05, 0x90, 0x09, 0x90, 0x09, 0x90,
|
const unsigned char Praying[] PROGMEM = {0x00, 0x00, 0x40, 0x02, 0xA0, 0x05, 0x90, 0x09, 0x90, 0x09, 0x90,
|
||||||
0x09, 0x98, 0x19, 0x94, 0x29, 0xA4, 0x25, 0xA4, 0x25, 0x84, 0x21,
|
0x09, 0x98, 0x19, 0x94, 0x29, 0xA4, 0x25, 0xA4, 0x25, 0x84, 0x21,
|
||||||
0x84, 0x21, 0x86, 0x61, 0x4E, 0x72, 0x7F, 0x7E, 0x3F, 0xFC};
|
0x84, 0x21, 0x86, 0x61, 0x4E, 0x72, 0x7F, 0x7E, 0x3F, 0xFC};
|
||||||
|
|
||||||
const unsigned char sparkles[] PROGMEM = {0x00, 0x00, 0x10, 0x00, 0x38, 0x04, 0x10, 0x04, 0x00, 0x0E, 0x00,
|
const unsigned char Sparkles[] PROGMEM = {0x00, 0x00, 0x10, 0x00, 0x38, 0x04, 0x10, 0x04, 0x00, 0x0E, 0x00,
|
||||||
0x1F, 0x80, 0x3F, 0xE0, 0xFF, 0x80, 0x3F, 0x10, 0x1F, 0x10, 0x0E,
|
0x1F, 0x80, 0x3F, 0xE0, 0xFF, 0x80, 0x3F, 0x10, 0x1F, 0x10, 0x0E,
|
||||||
0x38, 0x04, 0xFE, 0x04, 0x38, 0x00, 0x10, 0x00, 0x10, 0x00};
|
0x38, 0x04, 0xFE, 0x04, 0x38, 0x00, 0x10, 0x00, 0x10, 0x00};
|
||||||
|
|
||||||
@@ -303,179 +227,7 @@ const unsigned char bowling[] PROGMEM = {0x00, 0x38, 0x00, 0x44, 0x00, 0x44, 0x0
|
|||||||
const unsigned char vulcan_salute[] PROGMEM = {0x08, 0x02, 0x16, 0x0D, 0x15, 0x15, 0x15, 0x15, 0xA9, 0x12, 0x4A,
|
const unsigned char vulcan_salute[] PROGMEM = {0x08, 0x02, 0x16, 0x0D, 0x15, 0x15, 0x15, 0x15, 0xA9, 0x12, 0x4A,
|
||||||
0x0A, 0x02, 0x38, 0x04, 0x48, 0x04, 0x44, 0x04, 0x22, 0x04, 0x22,
|
0x0A, 0x02, 0x38, 0x04, 0x48, 0x04, 0x44, 0x04, 0x22, 0x04, 0x22,
|
||||||
0x04, 0x12, 0x08, 0x10, 0x10, 0x08, 0xE0, 0x07, 0x00, 0x00};
|
0x04, 0x12, 0x08, 0x10, 0x10, 0x08, 0xE0, 0x07, 0x00, 0x00};
|
||||||
|
|
||||||
const unsigned char jack_o_lantern[] PROGMEM = {0xC0, 0x00, 0x80, 0x01, 0xB8, 0x1D, 0xC4, 0x23, 0x22, 0x44, 0x05,
|
|
||||||
0xA0, 0x31, 0x8C, 0x51, 0x8A, 0x61, 0x86, 0x09, 0x90, 0xB9, 0x9D,
|
|
||||||
0x49, 0x92, 0xB2, 0x4D, 0x42, 0x42, 0x04, 0x20, 0xF8, 0x1F};
|
|
||||||
|
|
||||||
const unsigned char ghost[] PROGMEM = {0xC0, 0x03, 0xF0, 0x0F, 0xF8, 0x1F, 0xDC, 0x3B, 0xBC, 0x3D, 0xDF,
|
|
||||||
0xFB, 0xFF, 0xFF, 0x1F, 0xF8, 0x1E, 0x78, 0x1C, 0x38, 0x3C, 0x3C,
|
|
||||||
0xFC, 0x3F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0x8C, 0x31};
|
|
||||||
|
|
||||||
const unsigned char skull[] PROGMEM = {0xE0, 0x07, 0xF8, 0x1F, 0xFC, 0x3F, 0xFE, 0x7F, 0xFE, 0x7F, 0xC7,
|
|
||||||
0xE3, 0x87, 0xE1, 0x87, 0xE1, 0x8F, 0xF1, 0xFE, 0x7F, 0x7C, 0x3E,
|
|
||||||
0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xF8, 0x1F, 0xB0, 0x0D};
|
|
||||||
|
|
||||||
const unsigned char vomiting[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x04, 0x20, 0x22,
|
|
||||||
0x44, 0x42, 0x42, 0x22, 0x44, 0x02, 0x40, 0x02, 0x40, 0xC2, 0x43,
|
|
||||||
0x64, 0x26, 0x64, 0x26, 0x68, 0x16, 0x50, 0x0A, 0xF8, 0x1F};
|
|
||||||
|
|
||||||
const unsigned char cool[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0xFC, 0x3F, 0xFA,
|
|
||||||
0x5F, 0x72, 0x4E, 0x02, 0x40, 0x12, 0x48, 0x12, 0x48, 0x22, 0x44,
|
|
||||||
0xC4, 0x23, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char shortcake[] PROGMEM = {0x00, 0x00, 0x00, 0x0F, 0x80, 0x3F, 0xE0, 0xFC, 0xE0, 0xE1, 0xF0,
|
|
||||||
0xB8, 0x10, 0x87, 0xC8, 0x80, 0x3C, 0xE0, 0x06, 0x98, 0x02, 0xC7,
|
|
||||||
0xE2, 0x30, 0x1A, 0x0E, 0xC6, 0x01, 0x32, 0x00, 0x0E, 0x00};
|
|
||||||
|
|
||||||
const unsigned char caution[] PROGMEM = {0x00, 0x00, 0x80, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0x60, 0x06, 0x60,
|
|
||||||
0x06, 0x70, 0x0E, 0x70, 0x0E, 0x78, 0x1E, 0x78, 0x1E, 0x7C, 0x3E,
|
|
||||||
0xFC, 0x3F, 0x7E, 0x7E, 0x7E, 0x7E, 0xFC, 0x3F, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char clipboard[] PROGMEM = {0xC0, 0x03, 0x7E, 0x7E, 0xC2, 0x43, 0xFA, 0x5F, 0x0A, 0x5B, 0xFA,
|
|
||||||
0x5F, 0x8A, 0x54, 0xFA, 0x5F, 0x4A, 0x58, 0xFA, 0x5F, 0x2A, 0x51,
|
|
||||||
0xFA, 0x5F, 0x0A, 0x59, 0xFA, 0x5F, 0x02, 0x40, 0xFE, 0x7F};
|
|
||||||
|
|
||||||
const unsigned char snowflake[] PROGMEM = {0x00, 0x00, 0x40, 0x01, 0x88, 0x08, 0x8C, 0x18, 0xD0, 0x05, 0x60,
|
|
||||||
0x03, 0x32, 0x26, 0x1C, 0x1C, 0x32, 0x26, 0x60, 0x03, 0xD0, 0x05,
|
|
||||||
0x8C, 0x18, 0x88, 0x08, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char drop[] PROGMEM = {0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x0F, 0xE0,
|
|
||||||
0x0F, 0xF0, 0x1F, 0xF0, 0x1F, 0xF8, 0x3F, 0xF8, 0x3F, 0xF8, 0x3F,
|
|
||||||
0xF8, 0x3F, 0xF0, 0x1F, 0xE0, 0x0F, 0x80, 0x03, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char thermometer[] PROGMEM = {0x00, 0x00, 0x0C, 0x00, 0x16, 0x00, 0x2E, 0x00, 0x5C, 0x00, 0xB8,
|
|
||||||
0x00, 0x70, 0x01, 0xE0, 0x02, 0xC0, 0x05, 0x80, 0x3B, 0x00, 0x47,
|
|
||||||
0x00, 0xBE, 0x00, 0x9E, 0x00, 0xBE, 0x00, 0x7C, 0x00, 0x38};
|
|
||||||
|
|
||||||
const unsigned char sun_behind_raincloud[] PROGMEM = {0xC0, 0x03, 0x20, 0x04, 0x10, 0x0E, 0x38, 0x1F, 0xFC, 0x37, 0xEE,
|
|
||||||
0x77, 0xDE, 0x7B, 0x3E, 0x7C, 0xFC, 0x3F, 0x00, 0x00, 0x48, 0x12,
|
|
||||||
0x48, 0x12, 0x24, 0x09, 0x24, 0x09, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char sun_behind_cloud[] PROGMEM = {0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x04, 0x0E, 0x3C, 0x1B, 0xFC,
|
|
||||||
0x3B, 0xFE, 0x7B, 0xFA, 0x7B, 0xF6, 0x7D, 0x0C, 0x3E, 0xF8, 0x1F,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char cloud_with_snow[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x38, 0x1F, 0xFC, 0x3F, 0xFE,
|
|
||||||
0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFC, 0x3F, 0x00, 0x00, 0x08, 0x02,
|
|
||||||
0x40, 0x10, 0x00, 0x00, 0x24, 0x09, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char cloud_with_lightning[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x38, 0x1F, 0xFC, 0x3F, 0xFE,
|
|
||||||
0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFC, 0x3F, 0x00, 0x01, 0x80, 0x01,
|
|
||||||
0x80, 0x01, 0xC0, 0x07, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01};
|
|
||||||
|
|
||||||
const unsigned char cloud_with_lightning_rain[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x38, 0x1F, 0xFC, 0x3F, 0xFE,
|
|
||||||
0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFC, 0x3F, 0x00, 0x01, 0x90, 0x21,
|
|
||||||
0x90, 0x21, 0xC8, 0x17, 0x08, 0x13, 0x00, 0x03, 0x00, 0x01};
|
|
||||||
|
|
||||||
const unsigned char wind_face[] PROGMEM = {0xFF, 0x00, 0x01, 0x01, 0x01, 0x01, 0xF9, 0x00, 0xF9, 0x01, 0xD9,
|
|
||||||
0x01, 0x99, 0x01, 0xF9, 0x01, 0xF9, 0x33, 0xFD, 0x4B, 0xFD, 0x85,
|
|
||||||
0xFD, 0x9A, 0xFD, 0x75, 0xFD, 0x09, 0xFD, 0x01, 0xFF, 0x00};
|
|
||||||
|
|
||||||
const unsigned char new_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x04, 0x20, 0x02,
|
|
||||||
0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,
|
|
||||||
0x04, 0x20, 0x04, 0x20, 0x18, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char waxing_crescent_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x1F, 0x04, 0x3E, 0x04, 0x3C, 0x02,
|
|
||||||
0x78, 0x02, 0x78, 0x02, 0x78, 0x02, 0x78, 0x02, 0x78, 0x02, 0x78,
|
|
||||||
0x04, 0x3C, 0x04, 0x3E, 0x18, 0x1F, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char first_quarter_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x1F, 0x04, 0x3F, 0x04, 0x3F, 0x02,
|
|
||||||
0x7F, 0x02, 0x7F, 0x02, 0x7F, 0x02, 0x7F, 0x02, 0x7F, 0x02, 0x7F,
|
|
||||||
0x04, 0x3F, 0x04, 0x3F, 0x18, 0x1F, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char waxing_gibbous_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0x18, 0x1F, 0x84, 0x3F, 0xC4, 0x3F, 0xC2,
|
|
||||||
0x7F, 0xC2, 0x7F, 0xC2, 0x7F, 0xC2, 0x7F, 0xC2, 0x7F, 0xC2, 0x7F,
|
|
||||||
0xC4, 0x3F, 0x84, 0x3F, 0x18, 0x1F, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char full_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0xF8, 0x1F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFE,
|
|
||||||
0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F,
|
|
||||||
0xFC, 0x3F, 0xFC, 0x3F, 0xF8, 0x1F, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char waning_gibbous_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0xF8, 0x18, 0xFC, 0x21, 0xFC, 0x23, 0xFE,
|
|
||||||
0x43, 0xFE, 0x43, 0xFE, 0x43, 0xFE, 0x43, 0xFE, 0x43, 0xFE, 0x43,
|
|
||||||
0xFC, 0x23, 0xFC, 0x21, 0xF8, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char last_quarter_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0xF8, 0x18, 0xFC, 0x20, 0xFC, 0x20, 0xFE,
|
|
||||||
0x40, 0xFE, 0x40, 0xFE, 0x40, 0xFE, 0x40, 0xFE, 0x40, 0xFE, 0x40,
|
|
||||||
0xFC, 0x20, 0xFC, 0x20, 0xF8, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char waning_crescent_moon[] PROGMEM = {0x00, 0x00, 0xE0, 0x07, 0xF8, 0x18, 0x7C, 0x20, 0x3C, 0x20, 0x1E,
|
|
||||||
0x40, 0x1E, 0x40, 0x1E, 0x40, 0x1E, 0x40, 0x1E, 0x40, 0x1E, 0x40,
|
|
||||||
0x3C, 0x20, 0x7C, 0x20, 0xF8, 0x18, 0xE0, 0x07, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char first_quarter_moon_face[] PROGMEM = {0x00, 0x0F, 0x00, 0x12, 0x00, 0x24, 0x00, 0x44, 0x00, 0x48, 0x00,
|
|
||||||
0x88, 0x00, 0x84, 0x80, 0x93, 0x80, 0x80, 0x03, 0x81, 0x8D, 0x80,
|
|
||||||
0x71, 0x40, 0x82, 0x41, 0x02, 0x20, 0x0C, 0x18, 0xF0, 0x07};
|
|
||||||
|
|
||||||
const unsigned char peach[] PROGMEM = {0x70, 0x0F, 0x88, 0x10, 0x78, 0x1F, 0x88, 0x11, 0x04, 0x22, 0x02,
|
|
||||||
0x44, 0x02, 0x44, 0x02, 0x44, 0x02, 0x44, 0x02, 0x42, 0x02, 0x40,
|
|
||||||
0x04, 0x20, 0x04, 0x20, 0x08, 0x10, 0x30, 0x0C, 0xC0, 0x03};
|
|
||||||
|
|
||||||
const unsigned char turkey[] PROGMEM = {0x00, 0x00, 0x38, 0x00, 0x44, 0x38, 0x56, 0x54, 0x45, 0x52, 0xE2,
|
|
||||||
0x21, 0x2C, 0x56, 0x14, 0x58, 0x0A, 0x37, 0x86, 0x68, 0x82, 0x50,
|
|
||||||
0x82, 0x20, 0x04, 0x41, 0xF8, 0x7F, 0x40, 0x02, 0xF0, 0x07};
|
|
||||||
|
|
||||||
const unsigned char turkey_leg[] PROGMEM = {0x0C, 0x00, 0x1E, 0x00, 0x1F, 0x00, 0x2F, 0x00, 0x46, 0x00, 0x88,
|
|
||||||
0x01, 0x10, 0x0E, 0x20, 0x30, 0x20, 0x40, 0x40, 0x40, 0x40, 0x80,
|
|
||||||
0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x43, 0x00, 0x3C};
|
|
||||||
|
|
||||||
const unsigned char south_west_arrow[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1C, 0x00, 0x3E, 0x00,
|
|
||||||
0x1F, 0x80, 0x0F, 0xC2, 0x07, 0xE6, 0x03, 0xFE, 0x01, 0xFE, 0x00,
|
|
||||||
0x7E, 0x00, 0x7E, 0x00, 0xFE, 0x00, 0xFE, 0x01, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char south_east_arrow[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x38, 0x00, 0x7C, 0x00, 0xF8,
|
|
||||||
0x00, 0xF0, 0x01, 0xE0, 0x43, 0xC0, 0x67, 0x80, 0x7F, 0x00, 0x7F,
|
|
||||||
0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7F, 0x80, 0x7F, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char north_west_arrow[] PROGMEM = {0x00, 0x00, 0xFE, 0x01, 0xFE, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0xFE,
|
|
||||||
0x00, 0xFE, 0x01, 0xE6, 0x03, 0xC2, 0x07, 0x80, 0x0F, 0x00, 0x1F,
|
|
||||||
0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char north_east_arrow[] PROGMEM = {0x00, 0x00, 0x80, 0x7F, 0x00, 0x7F, 0x00, 0x7E, 0x00, 0x7E, 0x00,
|
|
||||||
0x7F, 0x80, 0x7F, 0xC0, 0x67, 0xE0, 0x43, 0xF0, 0x01, 0xF8, 0x00,
|
|
||||||
0x7C, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char downwards_arrow[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
|
|
||||||
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xFC, 0x3F,
|
|
||||||
0xF8, 0x1F, 0xF0, 0x0F, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x01};
|
|
||||||
|
|
||||||
const unsigned char leftwards_arrow[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x38, 0x00, 0x3C,
|
|
||||||
0x00, 0xFE, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xFE, 0x3F, 0x3C, 0x00,
|
|
||||||
0x38, 0x00, 0x30, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char upwards_arrow[] PROGMEM = {0x80, 0x01, 0xC0, 0x03, 0xE0, 0x07, 0xF0, 0x0F, 0xF8, 0x1F, 0xFC,
|
|
||||||
0x3F, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03,
|
|
||||||
0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char rightwards_arrow[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x1C, 0x00,
|
|
||||||
0x3C, 0xFC, 0x7F, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0x7F, 0x00, 0x3C,
|
|
||||||
0x00, 0x1C, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char strong[] PROGMEM = {0x38, 0x00, 0x44, 0x00, 0x62, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3A,
|
|
||||||
0x00, 0x11, 0x3C, 0x11, 0x42, 0xD1, 0x81, 0x31, 0x82, 0x11, 0x82,
|
|
||||||
0x21, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0xFC, 0x3F};
|
|
||||||
|
|
||||||
const unsigned char check_mark[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x70, 0x00, 0x3C, 0x00,
|
|
||||||
0x1E, 0x00, 0x0F, 0x80, 0x07, 0xC3, 0x03, 0xEE, 0x03, 0xFC, 0x01,
|
|
||||||
0xF8, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x60, 0x00, 0x20, 0x00};
|
|
||||||
|
|
||||||
const unsigned char house[] PROGMEM = {0x80, 0x01, 0x5C, 0x02, 0x34, 0x04, 0x14, 0x08, 0x0C, 0x10, 0x04,
|
|
||||||
0x20, 0x02, 0x40, 0xFF, 0xFF, 0x02, 0x40, 0x7A, 0x5F, 0x4A, 0x55,
|
|
||||||
0x4A, 0x5F, 0x6A, 0x55, 0x4A, 0x5F, 0x4A, 0x40, 0xFE, 0x7F};
|
|
||||||
|
|
||||||
const unsigned char shrug[] PROGMEM = {0xC0, 0x03, 0x20, 0x04, 0x10, 0x08, 0x50, 0x0A, 0x10, 0x08, 0x90,
|
|
||||||
0x09, 0x27, 0xE4, 0x49, 0x92, 0xAA, 0x55, 0x16, 0x68, 0x12, 0x48,
|
|
||||||
0x02, 0x40, 0x02, 0x40, 0x0C, 0x30, 0x08, 0x10, 0xF8, 0x1F};
|
|
||||||
|
|
||||||
const unsigned char eyes[] PROGMEM = {0x00, 0x00, 0x3C, 0x3C, 0x42, 0x42, 0x81, 0x81, 0x85, 0x85, 0x8F,
|
|
||||||
0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
|
|
||||||
0x85, 0x85, 0x81, 0x81, 0x42, 0x42, 0x3C, 0x3C, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char eye[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0xF8, 0x1F, 0xF4,
|
|
||||||
0x2F, 0x7A, 0x5E, 0x39, 0x9C, 0x39, 0x9C, 0x7A, 0x5E, 0xF4, 0x2F,
|
|
||||||
0xF8, 0x1F, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#endif
|
#endif
|
||||||
@@ -22,33 +22,33 @@ extern const int numEmotes;
|
|||||||
extern const unsigned char thumbup[] PROGMEM;
|
extern const unsigned char thumbup[] PROGMEM;
|
||||||
extern const unsigned char thumbdown[] PROGMEM;
|
extern const unsigned char thumbdown[] PROGMEM;
|
||||||
|
|
||||||
#define smiling_eyes_height 16
|
#define Smiling_Eyes_height 16
|
||||||
#define smiling_eyes_width 16
|
#define Smiling_Eyes_width 16
|
||||||
extern const unsigned char smiling_eyes[] PROGMEM;
|
extern const unsigned char Smiling_Eyes[] PROGMEM;
|
||||||
|
|
||||||
#define grinning_height 16
|
#define Grinning_height 16
|
||||||
#define grinning_width 16
|
#define Grinning_width 16
|
||||||
extern const unsigned char grinning[] PROGMEM;
|
extern const unsigned char Grinning[] PROGMEM;
|
||||||
|
|
||||||
#define slightly_smiling_height 16
|
#define Slightly_Smiling_height 16
|
||||||
#define slightly_smiling_width 16
|
#define Slightly_Smiling_width 16
|
||||||
extern const unsigned char slightly_smiling[] PROGMEM;
|
extern const unsigned char Slightly_Smiling[] PROGMEM;
|
||||||
|
|
||||||
#define winking_face_height 16
|
#define Winking_Face_height 16
|
||||||
#define winking_face_width 16
|
#define Winking_Face_width 16
|
||||||
extern const unsigned char winking_face[] PROGMEM;
|
extern const unsigned char Winking_Face[] PROGMEM;
|
||||||
|
|
||||||
#define grinning_smiling_eyes_height 16
|
#define Grinning_Smiling_Eyes_height 16
|
||||||
#define grinning_smiling_eyes_width 16
|
#define Grinning_Smiling_Eyes_width 16
|
||||||
extern const unsigned char grinning_smiling_eyes[] PROGMEM;
|
extern const unsigned char Grinning_Smiling_Eyes[] PROGMEM;
|
||||||
|
|
||||||
#define heart_smile_height 16
|
#define heart_smile_height 16
|
||||||
#define heart_smile_width 16
|
#define heart_smile_width 16
|
||||||
extern const unsigned char heart_smile[] PROGMEM;
|
extern const unsigned char heart_smile[] PROGMEM;
|
||||||
|
|
||||||
#define heart_eyes_height 16
|
#define Heart_eyes_height 16
|
||||||
#define heart_eyes_width 16
|
#define Heart_eyes_width 16
|
||||||
extern const unsigned char heart_eyes[] PROGMEM;
|
extern const unsigned char Heart_eyes[] PROGMEM;
|
||||||
|
|
||||||
#define question_height 16
|
#define question_height 16
|
||||||
#define question_width 16
|
#define question_width 16
|
||||||
@@ -62,21 +62,21 @@ extern const unsigned char bang[] PROGMEM;
|
|||||||
#define haha_width 16
|
#define haha_width 16
|
||||||
extern const unsigned char haha[] PROGMEM;
|
extern const unsigned char haha[] PROGMEM;
|
||||||
|
|
||||||
#define rofl_height 16
|
#define ROFL_height 16
|
||||||
#define rofl_width 16
|
#define ROFL_width 16
|
||||||
extern const unsigned char rofl[] PROGMEM;
|
extern const unsigned char ROFL[] PROGMEM;
|
||||||
|
|
||||||
#define smiling_closed_eyes_height 16
|
#define Smiling_Closed_Eyes_height 16
|
||||||
#define smiling_closed_eyes_width 16
|
#define Smiling_Closed_Eyes_width 16
|
||||||
extern const unsigned char smiling_closed_eyes[] PROGMEM;
|
extern const unsigned char Smiling_Closed_Eyes[] PROGMEM;
|
||||||
|
|
||||||
#define grinning_smiling_eyes_2_height 16
|
#define Grinning_SmilingEyes2_height 16
|
||||||
#define grinning_smiling_eyes_2_width 16
|
#define Grinning_SmilingEyes2_width 16
|
||||||
extern const unsigned char grinning_smiling_eyes_2[] PROGMEM;
|
extern const unsigned char Grinning_SmilingEyes2[] PROGMEM;
|
||||||
|
|
||||||
#define loudly_crying_face_height 16
|
#define Loudly_Crying_Face_height 16
|
||||||
#define loudly_crying_face_width 16
|
#define Loudly_Crying_Face_width 16
|
||||||
extern const unsigned char loudly_crying_face[] PROGMEM;
|
extern const unsigned char Loudly_Crying_Face[] PROGMEM;
|
||||||
|
|
||||||
#define wave_icon_height 16
|
#define wave_icon_height 16
|
||||||
#define wave_icon_width 16
|
#define wave_icon_width 16
|
||||||
@@ -126,21 +126,21 @@ extern const unsigned char bell_icon[] PROGMEM;
|
|||||||
#define cookie_height 16
|
#define cookie_height 16
|
||||||
extern const unsigned char cookie[] PROGMEM;
|
extern const unsigned char cookie[] PROGMEM;
|
||||||
|
|
||||||
#define fire_width 16
|
#define Fire_width 16
|
||||||
#define fire_height 16
|
#define Fire_height 16
|
||||||
extern const unsigned char fire[] PROGMEM;
|
extern const unsigned char Fire[] PROGMEM;
|
||||||
|
|
||||||
#define peace_sign_width 16
|
#define peace_sign_width 16
|
||||||
#define peace_sign_height 16
|
#define peace_sign_height 16
|
||||||
extern const unsigned char peace_sign[] PROGMEM;
|
extern const unsigned char peace_sign[] PROGMEM;
|
||||||
|
|
||||||
#define praying_width 16
|
#define Praying_width 16
|
||||||
#define praying_height 16
|
#define Praying_height 16
|
||||||
extern const unsigned char praying[] PROGMEM;
|
extern const unsigned char Praying[] PROGMEM;
|
||||||
|
|
||||||
#define sparkles_width 16
|
#define Sparkles_width 16
|
||||||
#define sparkles_height 16
|
#define Sparkles_height 16
|
||||||
extern const unsigned char sparkles[] PROGMEM;
|
extern const unsigned char Sparkles[] PROGMEM;
|
||||||
|
|
||||||
#define clown_width 16
|
#define clown_width 16
|
||||||
#define clown_height 16
|
#define clown_height 16
|
||||||
@@ -161,178 +161,6 @@ extern const unsigned char bowling[] PROGMEM;
|
|||||||
#define vulcan_salute_width 16
|
#define vulcan_salute_width 16
|
||||||
#define vulcan_salute_height 16
|
#define vulcan_salute_height 16
|
||||||
extern const unsigned char vulcan_salute[] PROGMEM;
|
extern const unsigned char vulcan_salute[] PROGMEM;
|
||||||
|
|
||||||
#define jack_o_lantern_width 16
|
|
||||||
#define jack_o_lantern_height 16
|
|
||||||
extern const unsigned char jack_o_lantern[] PROGMEM;
|
|
||||||
|
|
||||||
#define ghost_width 16
|
|
||||||
#define ghost_height 16
|
|
||||||
extern const unsigned char ghost[] PROGMEM;
|
|
||||||
|
|
||||||
#define skull_width 16
|
|
||||||
#define skull_height 16
|
|
||||||
extern const unsigned char skull[] PROGMEM;
|
|
||||||
|
|
||||||
#define vomiting_width 16
|
|
||||||
#define vomiting_height 16
|
|
||||||
extern const unsigned char vomiting[] PROGMEM;
|
|
||||||
|
|
||||||
#define cool_width 16
|
|
||||||
#define cool_height 16
|
|
||||||
extern const unsigned char cool[] PROGMEM;
|
|
||||||
|
|
||||||
#define shortcake_width 16
|
|
||||||
#define shortcake_height 16
|
|
||||||
extern const unsigned char shortcake[] PROGMEM;
|
|
||||||
|
|
||||||
#define caution_width 16
|
|
||||||
#define caution_height 16
|
|
||||||
extern const unsigned char caution[] PROGMEM;
|
|
||||||
|
|
||||||
#define clipboard_width 16
|
|
||||||
#define clipboard_height 16
|
|
||||||
extern const unsigned char clipboard[] PROGMEM;
|
|
||||||
|
|
||||||
#define snowflake_width 16
|
|
||||||
#define snowflake_height 16
|
|
||||||
extern const unsigned char snowflake[] PROGMEM;
|
|
||||||
|
|
||||||
#define drop_width 16
|
|
||||||
#define drop_height 16
|
|
||||||
extern const unsigned char drop[] PROGMEM;
|
|
||||||
|
|
||||||
#define thermometer_width 16
|
|
||||||
#define thermometer_height 16
|
|
||||||
extern const unsigned char thermometer[] PROGMEM;
|
|
||||||
|
|
||||||
#define sun_behind_raincloud_width 16
|
|
||||||
#define sun_behind_raincloud_height 16
|
|
||||||
extern const unsigned char sun_behind_raincloud[] PROGMEM;
|
|
||||||
|
|
||||||
#define sun_behind_cloud_width 16
|
|
||||||
#define sun_behind_cloud_height 16
|
|
||||||
extern const unsigned char sun_behind_cloud[] PROGMEM;
|
|
||||||
|
|
||||||
#define cloud_with_snow_width 16
|
|
||||||
#define cloud_with_snow_height 16
|
|
||||||
extern const unsigned char cloud_with_snow[] PROGMEM;
|
|
||||||
|
|
||||||
#define cloud_with_lightning_width 16
|
|
||||||
#define cloud_with_lightning_height 16
|
|
||||||
extern const unsigned char cloud_with_lightning[] PROGMEM;
|
|
||||||
|
|
||||||
#define cloud_with_lightning_rain_width 16
|
|
||||||
#define cloud_with_lightning_rain_height 16
|
|
||||||
extern const unsigned char cloud_with_lightning_rain[] PROGMEM;
|
|
||||||
|
|
||||||
#define wind_face_width 16
|
|
||||||
#define wind_face_height 16
|
|
||||||
extern const unsigned char wind_face[] PROGMEM;
|
|
||||||
|
|
||||||
#define new_moon_width 16
|
|
||||||
#define new_moon_height 16
|
|
||||||
extern const unsigned char new_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define waxing_crescent_moon_width 16
|
|
||||||
#define waxing_crescent_moon_height 16
|
|
||||||
extern const unsigned char waxing_crescent_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define first_quarter_moon_width 16
|
|
||||||
#define first_quarter_moon_height 16
|
|
||||||
extern const unsigned char first_quarter_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define waxing_gibbous_moon_width 16
|
|
||||||
#define waxing_gibbous_moon_height 16
|
|
||||||
extern const unsigned char waxing_gibbous_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define full_moon_width 16
|
|
||||||
#define full_moon_height 16
|
|
||||||
extern const unsigned char full_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define waning_gibbous_moon_width 16
|
|
||||||
#define waning_gibbous_moon_height 16
|
|
||||||
extern const unsigned char waning_gibbous_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define last_quarter_moon_width 16
|
|
||||||
#define last_quarter_moon_height 16
|
|
||||||
extern const unsigned char last_quarter_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define waning_crescent_moon_width 16
|
|
||||||
#define waning_crescent_moon_height 16
|
|
||||||
extern const unsigned char waning_crescent_moon[] PROGMEM;
|
|
||||||
|
|
||||||
#define first_quarter_moon_face_width 16
|
|
||||||
#define first_quarter_moon_face_height 16
|
|
||||||
extern const unsigned char first_quarter_moon_face[] PROGMEM;
|
|
||||||
|
|
||||||
#define peach_width 16
|
|
||||||
#define peach_height 16
|
|
||||||
extern const unsigned char peach[] PROGMEM;
|
|
||||||
|
|
||||||
#define turkey_width 16
|
|
||||||
#define turkey_height 16
|
|
||||||
extern const unsigned char turkey[] PROGMEM;
|
|
||||||
|
|
||||||
#define turkey_leg_width 16
|
|
||||||
#define turkey_leg_height 16
|
|
||||||
extern const unsigned char turkey_leg[] PROGMEM;
|
|
||||||
|
|
||||||
#define south_west_arrow_width 16
|
|
||||||
#define south_west_arrow_height 16
|
|
||||||
extern const unsigned char south_west_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define south_east_arrow_width 16
|
|
||||||
#define south_east_arrow_height 16
|
|
||||||
extern const unsigned char south_east_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define north_west_arrow_width 16
|
|
||||||
#define north_west_arrow_height 16
|
|
||||||
extern const unsigned char north_west_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define north_east_arrow_width 16
|
|
||||||
#define north_east_arrow_height 16
|
|
||||||
extern const unsigned char north_east_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define downwards_arrow_width 16
|
|
||||||
#define downwards_arrow_height 16
|
|
||||||
extern const unsigned char downwards_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define leftwards_arrow_width 16
|
|
||||||
#define leftwards_arrow_height 16
|
|
||||||
extern const unsigned char leftwards_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define upwards_arrow_width 16
|
|
||||||
#define upwards_arrow_height 16
|
|
||||||
extern const unsigned char upwards_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define rightwards_arrow_width 16
|
|
||||||
#define rightwards_arrow_height 16
|
|
||||||
extern const unsigned char rightwards_arrow[] PROGMEM;
|
|
||||||
|
|
||||||
#define strong_width 16
|
|
||||||
#define strong_height 16
|
|
||||||
extern const unsigned char strong[] PROGMEM;
|
|
||||||
|
|
||||||
#define check_mark_width 16
|
|
||||||
#define check_mark_height 16
|
|
||||||
extern const unsigned char check_mark[] PROGMEM;
|
|
||||||
|
|
||||||
#define house_width 16
|
|
||||||
#define house_height 16
|
|
||||||
extern const unsigned char house[] PROGMEM;
|
|
||||||
|
|
||||||
#define shrug_width 16
|
|
||||||
#define shrug_height 16
|
|
||||||
extern const unsigned char shrug[] PROGMEM;
|
|
||||||
|
|
||||||
#define eyes_width 16
|
|
||||||
#define eyes_height 16
|
|
||||||
extern const unsigned char eyes[] PROGMEM;
|
|
||||||
|
|
||||||
#define eye_width 16
|
|
||||||
#define eye_height 16
|
|
||||||
extern const unsigned char eye[] PROGMEM;
|
|
||||||
#endif // EXCLUDE_EMOJI
|
#endif // EXCLUDE_EMOJI
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
@@ -88,14 +88,8 @@ class Applet : public GFX
|
|||||||
virtual void onForeground() {}
|
virtual void onForeground() {}
|
||||||
virtual void onBackground() {}
|
virtual void onBackground() {}
|
||||||
virtual void onShutdown() {}
|
virtual void onShutdown() {}
|
||||||
virtual void onButtonShortPress() {}
|
virtual void onButtonShortPress() {} // (System Applets only)
|
||||||
virtual void onButtonLongPress() {}
|
virtual void onButtonLongPress() {} // (System Applets only)
|
||||||
virtual void onExitShort() {}
|
|
||||||
virtual void onExitLong() {}
|
|
||||||
virtual void onNavUp() {}
|
|
||||||
virtual void onNavDown() {}
|
|
||||||
virtual void onNavLeft() {}
|
|
||||||
virtual void onNavRight() {}
|
|
||||||
|
|
||||||
virtual bool approveNotification(Notification &n); // Allow an applet to veto a notification
|
virtual bool approveNotification(Notification &n); // Allow an applet to veto a notification
|
||||||
|
|
||||||
|
|||||||
@@ -1,205 +0,0 @@
|
|||||||
#ifdef MESHTASTIC_INCLUDE_INKHUD
|
|
||||||
|
|
||||||
#include "./AlignStickApplet.h"
|
|
||||||
|
|
||||||
using namespace NicheGraphics;
|
|
||||||
|
|
||||||
InkHUD::AlignStickApplet::AlignStickApplet()
|
|
||||||
{
|
|
||||||
if (!settings->joystick.aligned)
|
|
||||||
bringToForeground();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onRender()
|
|
||||||
{
|
|
||||||
setFont(fontMedium);
|
|
||||||
printAt(0, 0, "Align Joystick:");
|
|
||||||
setFont(fontSmall);
|
|
||||||
std::string instructions = "Move joystick in the direction indicated";
|
|
||||||
printWrapped(0, fontMedium.lineHeight() * 1.5, width(), instructions);
|
|
||||||
|
|
||||||
// Size of the region in which the joystick graphic should fit
|
|
||||||
uint16_t joyXLimit = X(0.8);
|
|
||||||
uint16_t contentH = fontMedium.lineHeight() * 1.5 + fontSmall.lineHeight() * 1;
|
|
||||||
if (getTextWidth(instructions) > width())
|
|
||||||
contentH += fontSmall.lineHeight();
|
|
||||||
uint16_t freeY = height() - contentH - fontSmall.lineHeight() * 1.2;
|
|
||||||
uint16_t joyYLimit = freeY * 0.8;
|
|
||||||
|
|
||||||
// Use the shorter of the two
|
|
||||||
uint16_t joyWidth = joyXLimit < joyYLimit ? joyXLimit : joyYLimit;
|
|
||||||
|
|
||||||
// Center the joystick graphic
|
|
||||||
uint16_t centerX = X(0.5);
|
|
||||||
uint16_t centerY = contentH + freeY * 0.5;
|
|
||||||
|
|
||||||
// Draw joystick graphic
|
|
||||||
drawStick(centerX, centerY, joyWidth);
|
|
||||||
|
|
||||||
setFont(fontSmall);
|
|
||||||
printAt(X(0.5), Y(1.0) - fontSmall.lineHeight() * 0.2, "Long press to skip", CENTER, BOTTOM);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a scalable joystick graphic
|
|
||||||
void InkHUD::AlignStickApplet::drawStick(uint16_t centerX, uint16_t centerY, uint16_t width)
|
|
||||||
{
|
|
||||||
if (width < 9) // too small to draw
|
|
||||||
return;
|
|
||||||
|
|
||||||
else if (width < 40) { // only draw up arrow
|
|
||||||
uint16_t chamfer = width < 20 ? 1 : 2;
|
|
||||||
|
|
||||||
// Draw filled up arrow
|
|
||||||
drawDirection(centerX, centerY - width / 4, Direction::UP, width, chamfer, BLACK);
|
|
||||||
|
|
||||||
} else { // large enough to draw the full thing
|
|
||||||
uint16_t chamfer = width < 80 ? 1 : 2;
|
|
||||||
uint16_t stroke = 3; // pixels
|
|
||||||
uint16_t arrowW = width * 0.22;
|
|
||||||
uint16_t hollowW = arrowW - stroke * 2;
|
|
||||||
|
|
||||||
// Draw center circle
|
|
||||||
fillCircle((int16_t)centerX, (int16_t)centerY, (int16_t)(width * 0.2), BLACK);
|
|
||||||
fillCircle((int16_t)centerX, (int16_t)centerY, (int16_t)(width * 0.2) - stroke, WHITE);
|
|
||||||
|
|
||||||
// Draw filled up arrow
|
|
||||||
drawDirection(centerX, centerY - width / 2, Direction::UP, arrowW, chamfer, BLACK);
|
|
||||||
|
|
||||||
// Draw down arrow
|
|
||||||
drawDirection(centerX, centerY + width / 2, Direction::DOWN, arrowW, chamfer, BLACK);
|
|
||||||
drawDirection(centerX, centerY + width / 2 - stroke, Direction::DOWN, hollowW, 0, WHITE);
|
|
||||||
|
|
||||||
// Draw left arrow
|
|
||||||
drawDirection(centerX - width / 2, centerY, Direction::LEFT, arrowW, chamfer, BLACK);
|
|
||||||
drawDirection(centerX - width / 2 + stroke, centerY, Direction::LEFT, hollowW, 0, WHITE);
|
|
||||||
|
|
||||||
// Draw right arrow
|
|
||||||
drawDirection(centerX + width / 2, centerY, Direction::RIGHT, arrowW, chamfer, BLACK);
|
|
||||||
drawDirection(centerX + width / 2 - stroke, centerY, Direction::RIGHT, hollowW, 0, WHITE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a scalable joystick direction arrow
|
|
||||||
// a right-triangle with blunted tips
|
|
||||||
/*
|
|
||||||
_ <--point
|
|
||||||
^ / \
|
|
||||||
| / \
|
|
||||||
size / \
|
|
||||||
| / \
|
|
||||||
v |_________|
|
|
||||||
|
|
||||||
*/
|
|
||||||
void InkHUD::AlignStickApplet::drawDirection(uint16_t pointX, uint16_t pointY, Direction direction, uint16_t size,
|
|
||||||
uint16_t chamfer, Color color)
|
|
||||||
{
|
|
||||||
uint16_t chamferW = chamfer * 2 + 1;
|
|
||||||
uint16_t triangleW = size - chamferW;
|
|
||||||
|
|
||||||
// Draw arrow
|
|
||||||
switch (direction) {
|
|
||||||
case Direction::UP:
|
|
||||||
fillRect(pointX - chamfer, pointY, chamferW, triangleW, color);
|
|
||||||
fillRect(pointX - chamfer - triangleW, pointY + triangleW, chamferW + triangleW * 2, chamferW, color);
|
|
||||||
fillTriangle(pointX - chamfer, pointY, pointX - chamfer - triangleW, pointY + triangleW, pointX - chamfer,
|
|
||||||
pointY + triangleW, color);
|
|
||||||
fillTriangle(pointX + chamfer, pointY, pointX + chamfer + triangleW, pointY + triangleW, pointX + chamfer,
|
|
||||||
pointY + triangleW, color);
|
|
||||||
break;
|
|
||||||
case Direction::DOWN:
|
|
||||||
fillRect(pointX - chamfer, pointY - triangleW + 1, chamferW, triangleW, color);
|
|
||||||
fillRect(pointX - chamfer - triangleW, pointY - size + 1, chamferW + triangleW * 2, chamferW, color);
|
|
||||||
fillTriangle(pointX - chamfer, pointY, pointX - chamfer - triangleW, pointY - triangleW, pointX - chamfer,
|
|
||||||
pointY - triangleW, color);
|
|
||||||
fillTriangle(pointX + chamfer, pointY, pointX + chamfer + triangleW, pointY - triangleW, pointX + chamfer,
|
|
||||||
pointY - triangleW, color);
|
|
||||||
break;
|
|
||||||
case Direction::LEFT:
|
|
||||||
fillRect(pointX, pointY - chamfer, triangleW, chamferW, color);
|
|
||||||
fillRect(pointX + triangleW, pointY - chamfer - triangleW, chamferW, chamferW + triangleW * 2, color);
|
|
||||||
fillTriangle(pointX, pointY - chamfer, pointX + triangleW, pointY - chamfer - triangleW, pointX + triangleW,
|
|
||||||
pointY - chamfer, color);
|
|
||||||
fillTriangle(pointX, pointY + chamfer, pointX + triangleW, pointY + chamfer + triangleW, pointX + triangleW,
|
|
||||||
pointY + chamfer, color);
|
|
||||||
break;
|
|
||||||
case Direction::RIGHT:
|
|
||||||
fillRect(pointX - triangleW + 1, pointY - chamfer, triangleW, chamferW, color);
|
|
||||||
fillRect(pointX - size + 1, pointY - chamfer - triangleW, chamferW, chamferW + triangleW * 2, color);
|
|
||||||
fillTriangle(pointX, pointY - chamfer, pointX - triangleW, pointY - chamfer - triangleW, pointX - triangleW,
|
|
||||||
pointY - chamfer, color);
|
|
||||||
fillTriangle(pointX, pointY + chamfer, pointX - triangleW, pointY + chamfer + triangleW, pointX - triangleW,
|
|
||||||
pointY + chamfer, color);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onForeground()
|
|
||||||
{
|
|
||||||
// Prevent most other applets from requesting update, and skip their rendering entirely
|
|
||||||
// Another system applet with a higher precedence can potentially ignore this
|
|
||||||
SystemApplet::lockRendering = true;
|
|
||||||
SystemApplet::lockRequests = true;
|
|
||||||
|
|
||||||
handleInput = true; // Intercept the button input for our applet
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onBackground()
|
|
||||||
{
|
|
||||||
// Allow normal update behavior to resume
|
|
||||||
SystemApplet::lockRendering = false;
|
|
||||||
SystemApplet::lockRequests = false;
|
|
||||||
SystemApplet::handleInput = false;
|
|
||||||
|
|
||||||
// Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
|
|
||||||
// Usually, onBackground is followed by another applet's onForeground (which requests update), but not in this case
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onButtonLongPress()
|
|
||||||
{
|
|
||||||
sendToBackground();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onExitLong()
|
|
||||||
{
|
|
||||||
sendToBackground();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onNavUp()
|
|
||||||
{
|
|
||||||
settings->joystick.aligned = true;
|
|
||||||
|
|
||||||
sendToBackground();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onNavDown()
|
|
||||||
{
|
|
||||||
inkhud->rotateJoystick(2); // 180 deg
|
|
||||||
settings->joystick.aligned = true;
|
|
||||||
|
|
||||||
sendToBackground();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onNavLeft()
|
|
||||||
{
|
|
||||||
inkhud->rotateJoystick(3); // 270 deg
|
|
||||||
settings->joystick.aligned = true;
|
|
||||||
|
|
||||||
sendToBackground();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::AlignStickApplet::onNavRight()
|
|
||||||
{
|
|
||||||
inkhud->rotateJoystick(1); // 90 deg
|
|
||||||
settings->joystick.aligned = true;
|
|
||||||
|
|
||||||
sendToBackground();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#ifdef MESHTASTIC_INCLUDE_INKHUD
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
System Applet for manually aligning the joystick with the screen
|
|
||||||
|
|
||||||
should be run at startup if the joystick is enabled
|
|
||||||
and not aligned to the screen
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
#include "graphics/niche/InkHUD/SystemApplet.h"
|
|
||||||
|
|
||||||
namespace NicheGraphics::InkHUD
|
|
||||||
{
|
|
||||||
|
|
||||||
class AlignStickApplet : public SystemApplet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AlignStickApplet();
|
|
||||||
|
|
||||||
void onRender() override;
|
|
||||||
void onForeground() override;
|
|
||||||
void onBackground() override;
|
|
||||||
void onButtonLongPress() override;
|
|
||||||
void onExitLong() override;
|
|
||||||
void onNavUp() override;
|
|
||||||
void onNavDown() override;
|
|
||||||
void onNavLeft() override;
|
|
||||||
void onNavRight() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
enum Direction {
|
|
||||||
UP,
|
|
||||||
DOWN,
|
|
||||||
LEFT,
|
|
||||||
RIGHT,
|
|
||||||
};
|
|
||||||
|
|
||||||
void drawStick(uint16_t centerX, uint16_t centerY, uint16_t width);
|
|
||||||
void drawDirection(uint16_t pointX, uint16_t pointY, Direction direction, uint16_t size, uint16_t chamfer, Color color);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NicheGraphics::InkHUD
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -30,7 +30,6 @@ enum MenuAction {
|
|||||||
TOGGLE_AUTOSHOW_APPLET,
|
TOGGLE_AUTOSHOW_APPLET,
|
||||||
SET_RECENTS,
|
SET_RECENTS,
|
||||||
ROTATE,
|
ROTATE,
|
||||||
ALIGN_JOYSTICK,
|
|
||||||
LAYOUT,
|
LAYOUT,
|
||||||
TOGGLE_BATTERY_ICON,
|
TOGGLE_BATTERY_ICON,
|
||||||
TOGGLE_NOTIFICATIONS,
|
TOGGLE_NOTIFICATIONS,
|
||||||
|
|||||||
@@ -178,10 +178,6 @@ void InkHUD::MenuApplet::execute(MenuItem item)
|
|||||||
inkhud->rotate();
|
inkhud->rotate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALIGN_JOYSTICK:
|
|
||||||
inkhud->openAlignStick();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LAYOUT:
|
case LAYOUT:
|
||||||
// Todo: smarter incrementing of tile count
|
// Todo: smarter incrementing of tile count
|
||||||
settings->userTiles.count++;
|
settings->userTiles.count++;
|
||||||
@@ -291,17 +287,14 @@ void InkHUD::MenuApplet::showPage(MenuPage page)
|
|||||||
// items.push_back(MenuItem("Display Off", MenuPage::EXIT)); // TODO
|
// items.push_back(MenuItem("Display Off", MenuPage::EXIT)); // TODO
|
||||||
items.push_back(MenuItem("Save & Shut Down", MenuAction::SHUTDOWN));
|
items.push_back(MenuItem("Save & Shut Down", MenuAction::SHUTDOWN));
|
||||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||||
previousPage = MenuPage::EXIT;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEND:
|
case SEND:
|
||||||
populateSendPage();
|
populateSendPage();
|
||||||
previousPage = MenuPage::ROOT;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CANNEDMESSAGE_RECIPIENT:
|
case CANNEDMESSAGE_RECIPIENT:
|
||||||
populateRecipientPage();
|
populateRecipientPage();
|
||||||
previousPage = MenuPage::OPTIONS;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPTIONS:
|
case OPTIONS:
|
||||||
@@ -328,8 +321,6 @@ void InkHUD::MenuApplet::showPage(MenuPage page)
|
|||||||
if (settings->userTiles.maxCount > 1)
|
if (settings->userTiles.maxCount > 1)
|
||||||
items.push_back(MenuItem("Layout", MenuAction::LAYOUT, MenuPage::OPTIONS));
|
items.push_back(MenuItem("Layout", MenuAction::LAYOUT, MenuPage::OPTIONS));
|
||||||
items.push_back(MenuItem("Rotate", MenuAction::ROTATE, MenuPage::OPTIONS));
|
items.push_back(MenuItem("Rotate", MenuAction::ROTATE, MenuPage::OPTIONS));
|
||||||
if (settings->joystick.enabled)
|
|
||||||
items.push_back(MenuItem("Align Joystick", MenuAction::ALIGN_JOYSTICK, MenuPage::EXIT));
|
|
||||||
items.push_back(MenuItem("Notifications", MenuAction::TOGGLE_NOTIFICATIONS, MenuPage::OPTIONS,
|
items.push_back(MenuItem("Notifications", MenuAction::TOGGLE_NOTIFICATIONS, MenuPage::OPTIONS,
|
||||||
&settings->optionalFeatures.notifications));
|
&settings->optionalFeatures.notifications));
|
||||||
items.push_back(MenuItem("Battery Icon", MenuAction::TOGGLE_BATTERY_ICON, MenuPage::OPTIONS,
|
items.push_back(MenuItem("Battery Icon", MenuAction::TOGGLE_BATTERY_ICON, MenuPage::OPTIONS,
|
||||||
@@ -341,24 +332,20 @@ void InkHUD::MenuApplet::showPage(MenuPage page)
|
|||||||
items.push_back(
|
items.push_back(
|
||||||
MenuItem("12-Hour Clock", MenuAction::TOGGLE_12H_CLOCK, MenuPage::OPTIONS, &config.display.use_12h_clock));
|
MenuItem("12-Hour Clock", MenuAction::TOGGLE_12H_CLOCK, MenuPage::OPTIONS, &config.display.use_12h_clock));
|
||||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||||
previousPage = MenuPage::ROOT;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case APPLETS:
|
case APPLETS:
|
||||||
populateAppletPage();
|
populateAppletPage();
|
||||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||||
previousPage = MenuPage::OPTIONS;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUTOSHOW:
|
case AUTOSHOW:
|
||||||
populateAutoshowPage();
|
populateAutoshowPage();
|
||||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||||
previousPage = MenuPage::OPTIONS;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RECENTS:
|
case RECENTS:
|
||||||
populateRecentsPage();
|
populateRecentsPage();
|
||||||
previousPage = MenuPage::OPTIONS;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXIT:
|
case EXIT:
|
||||||
@@ -492,21 +479,12 @@ void InkHUD::MenuApplet::onButtonShortPress()
|
|||||||
// Push the auto-close timer back
|
// Push the auto-close timer back
|
||||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
||||||
|
|
||||||
if (!settings->joystick.enabled) {
|
// Move menu cursor to next entry, then update
|
||||||
// Move menu cursor to next entry, then update
|
if (cursorShown)
|
||||||
if (cursorShown)
|
cursor = (cursor + 1) % items.size();
|
||||||
cursor = (cursor + 1) % items.size();
|
else
|
||||||
else
|
cursorShown = true;
|
||||||
cursorShown = true;
|
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
|
||||||
} else {
|
|
||||||
if (cursorShown)
|
|
||||||
execute(items.at(cursor));
|
|
||||||
else
|
|
||||||
showPage(MenuPage::EXIT);
|
|
||||||
if (!wantsToRender())
|
|
||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InkHUD::MenuApplet::onButtonLongPress()
|
void InkHUD::MenuApplet::onButtonLongPress()
|
||||||
@@ -526,62 +504,6 @@ void InkHUD::MenuApplet::onButtonLongPress()
|
|||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InkHUD::MenuApplet::onExitShort()
|
|
||||||
{
|
|
||||||
// Exit the menu
|
|
||||||
showPage(MenuPage::EXIT);
|
|
||||||
|
|
||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::MenuApplet::onNavUp()
|
|
||||||
{
|
|
||||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
|
||||||
|
|
||||||
// Move menu cursor to previous entry, then update
|
|
||||||
if (cursor == 0)
|
|
||||||
cursor = items.size() - 1;
|
|
||||||
else
|
|
||||||
cursor--;
|
|
||||||
|
|
||||||
if (!cursorShown)
|
|
||||||
cursorShown = true;
|
|
||||||
|
|
||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::MenuApplet::onNavDown()
|
|
||||||
{
|
|
||||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
|
||||||
|
|
||||||
// Move menu cursor to next entry, then update
|
|
||||||
if (cursorShown)
|
|
||||||
cursor = (cursor + 1) % items.size();
|
|
||||||
else
|
|
||||||
cursorShown = true;
|
|
||||||
|
|
||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::MenuApplet::onNavLeft()
|
|
||||||
{
|
|
||||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
|
||||||
|
|
||||||
// Go to the previous menu page
|
|
||||||
showPage(previousPage);
|
|
||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::MenuApplet::onNavRight()
|
|
||||||
{
|
|
||||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
|
||||||
|
|
||||||
if (cursorShown)
|
|
||||||
execute(items.at(cursor));
|
|
||||||
if (!wantsToRender())
|
|
||||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamically create MenuItem entries for activating / deactivating Applets, for the "Applet Selection" submenu
|
// Dynamically create MenuItem entries for activating / deactivating Applets, for the "Applet Selection" submenu
|
||||||
void InkHUD::MenuApplet::populateAppletPage()
|
void InkHUD::MenuApplet::populateAppletPage()
|
||||||
{
|
{
|
||||||
@@ -874,4 +796,4 @@ void InkHUD::MenuApplet::freeCannedMessageResources()
|
|||||||
cm.recipientItems.clear();
|
cm.recipientItems.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -27,11 +27,6 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
|
|||||||
void onBackground() override;
|
void onBackground() override;
|
||||||
void onButtonShortPress() override;
|
void onButtonShortPress() override;
|
||||||
void onButtonLongPress() override;
|
void onButtonLongPress() override;
|
||||||
void onExitShort() override;
|
|
||||||
void onNavUp() override;
|
|
||||||
void onNavDown() override;
|
|
||||||
void onNavLeft() override;
|
|
||||||
void onNavRight() override;
|
|
||||||
void onRender() override;
|
void onRender() override;
|
||||||
|
|
||||||
void show(Tile *t); // Open the menu, onto a user tile
|
void show(Tile *t); // Open the menu, onto a user tile
|
||||||
@@ -57,7 +52,6 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
|
|||||||
void freeCannedMessageResources(); // Clear MenuApplet's canned message processing data
|
void freeCannedMessageResources(); // Clear MenuApplet's canned message processing data
|
||||||
|
|
||||||
MenuPage currentPage = MenuPage::ROOT;
|
MenuPage currentPage = MenuPage::ROOT;
|
||||||
MenuPage previousPage = MenuPage::EXIT;
|
|
||||||
uint8_t cursor = 0; // Which menu item is currently highlighted
|
uint8_t cursor = 0; // Which menu item is currently highlighted
|
||||||
bool cursorShown = false; // Is *any* item highlighted? (Root menu: no initial selection)
|
bool cursorShown = false; // Is *any* item highlighted? (Root menu: no initial selection)
|
||||||
|
|
||||||
@@ -103,4 +97,4 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
|
|||||||
|
|
||||||
} // namespace NicheGraphics::InkHUD
|
} // namespace NicheGraphics::InkHUD
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -153,42 +153,6 @@ void InkHUD::NotificationApplet::onButtonLongPress()
|
|||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InkHUD::NotificationApplet::onExitShort()
|
|
||||||
{
|
|
||||||
dismiss();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::NotificationApplet::onExitLong()
|
|
||||||
{
|
|
||||||
dismiss();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::NotificationApplet::onNavUp()
|
|
||||||
{
|
|
||||||
dismiss();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::NotificationApplet::onNavDown()
|
|
||||||
{
|
|
||||||
dismiss();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::NotificationApplet::onNavLeft()
|
|
||||||
{
|
|
||||||
dismiss();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::NotificationApplet::onNavRight()
|
|
||||||
{
|
|
||||||
dismiss();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask the WindowManager to check whether any displayed applets are already displaying the info from this notification
|
// Ask the WindowManager to check whether any displayed applets are already displaying the info from this notification
|
||||||
// Called internally when we first get a "notifiable event", and then again before render,
|
// Called internally when we first get a "notifiable event", and then again before render,
|
||||||
// in case autoshow swapped which applet was displayed
|
// in case autoshow swapped which applet was displayed
|
||||||
|
|||||||
@@ -31,12 +31,6 @@ class NotificationApplet : public SystemApplet
|
|||||||
void onBackground() override;
|
void onBackground() override;
|
||||||
void onButtonShortPress() override;
|
void onButtonShortPress() override;
|
||||||
void onButtonLongPress() override;
|
void onButtonLongPress() override;
|
||||||
void onExitShort() override;
|
|
||||||
void onExitLong() override;
|
|
||||||
void onNavUp() override;
|
|
||||||
void onNavDown() override;
|
|
||||||
void onNavLeft() override;
|
|
||||||
void onNavRight() override;
|
|
||||||
|
|
||||||
int onReceiveTextMessage(const meshtastic_MeshPacket *p);
|
int onReceiveTextMessage(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
|
|||||||
@@ -112,21 +112,12 @@ void InkHUD::TipsApplet::onRender()
|
|||||||
setFont(fontSmall);
|
setFont(fontSmall);
|
||||||
int16_t cursorY = fontMedium.lineHeight() * 1.5;
|
int16_t cursorY = fontMedium.lineHeight() * 1.5;
|
||||||
|
|
||||||
if (!settings->joystick.enabled) {
|
printAt(0, cursorY, "User Button");
|
||||||
printAt(0, cursorY, "User Button");
|
cursorY += fontSmall.lineHeight() * 1.2;
|
||||||
cursorY += fontSmall.lineHeight() * 1.2;
|
printAt(0, cursorY, "- short press: next");
|
||||||
printAt(0, cursorY, "- short press: next");
|
cursorY += fontSmall.lineHeight() * 1.2;
|
||||||
cursorY += fontSmall.lineHeight() * 1.2;
|
printAt(0, cursorY, "- long press: select / open menu");
|
||||||
printAt(0, cursorY, "- long press: select / open menu");
|
cursorY += fontSmall.lineHeight() * 1.5;
|
||||||
} else {
|
|
||||||
printAt(0, cursorY, "Joystick");
|
|
||||||
cursorY += fontSmall.lineHeight() * 1.2;
|
|
||||||
printAt(0, cursorY, "- open menu / select");
|
|
||||||
cursorY += fontSmall.lineHeight() * 1.5;
|
|
||||||
printAt(0, cursorY, "Exit Button");
|
|
||||||
cursorY += fontSmall.lineHeight() * 1.2;
|
|
||||||
printAt(0, cursorY, "- switch tile / close menu");
|
|
||||||
}
|
|
||||||
|
|
||||||
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
|
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
|
||||||
} break;
|
} break;
|
||||||
@@ -136,13 +127,8 @@ void InkHUD::TipsApplet::onRender()
|
|||||||
printAt(0, 0, "Tip: Rotation");
|
printAt(0, 0, "Tip: Rotation");
|
||||||
|
|
||||||
setFont(fontSmall);
|
setFont(fontSmall);
|
||||||
if (!settings->joystick.enabled) {
|
printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
|
||||||
printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
|
"To rotate the display, use the InkHUD menu. Long-press the user button > Options > Rotate.");
|
||||||
"To rotate the display, use the InkHUD menu. Long-press the user button > Options > Rotate.");
|
|
||||||
} else {
|
|
||||||
printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
|
|
||||||
"To rotate the display, use the InkHUD menu. Press the user button > Options > Rotate.");
|
|
||||||
}
|
|
||||||
|
|
||||||
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
|
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
|
||||||
|
|
||||||
@@ -246,10 +232,4 @@ void InkHUD::TipsApplet::onButtonShortPress()
|
|||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions the same as the user button in this instance
|
|
||||||
void InkHUD::TipsApplet::onExitShort()
|
|
||||||
{
|
|
||||||
onButtonShortPress();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -36,7 +36,6 @@ class TipsApplet : public SystemApplet
|
|||||||
void onForeground() override;
|
void onForeground() override;
|
||||||
void onBackground() override;
|
void onBackground() override;
|
||||||
void onButtonShortPress() override;
|
void onButtonShortPress() override;
|
||||||
void onExitShort() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderWelcome(); // Very first screen of tutorial
|
void renderWelcome(); // Very first screen of tutorial
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifdef MESHTASTIC_INCLUDE_INKHUD
|
#ifdef MESHTASTIC_INCLUDE_INKHUD
|
||||||
|
|
||||||
#include "./PositionsApplet.h"
|
#include "./PositionsApplet.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
|
||||||
using namespace NicheGraphics;
|
using namespace NicheGraphics;
|
||||||
|
|
||||||
@@ -49,8 +50,8 @@ ProcessMessage InkHUD::PositionsApplet::handleReceived(const meshtastic_MeshPack
|
|||||||
if (!hasPosition)
|
if (!hasPosition)
|
||||||
return ProcessMessage::CONTINUE;
|
return ProcessMessage::CONTINUE;
|
||||||
|
|
||||||
bool hasHopsAway = (mp.hop_start != 0 && mp.hop_limit <= mp.hop_start); // From NodeDB::updateFrom
|
const int8_t hopsAway = getHopsAway(mp);
|
||||||
uint8_t hopsAway = mp.hop_start - mp.hop_limit;
|
const bool hasHopsAway = hopsAway >= 0;
|
||||||
|
|
||||||
// Determine if the position packet would change anything on-screen
|
// Determine if the position packet would change anything on-screen
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|||||||
@@ -55,15 +55,10 @@ void InkHUD::Events::onButtonShort()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If no system applet is handling input, default behavior instead is to cycle applets
|
// If no system applet is handling input, default behavior instead is to cycle applets
|
||||||
// or open menu if joystick is enabled
|
if (consumer)
|
||||||
if (consumer) {
|
|
||||||
consumer->onButtonShortPress();
|
consumer->onButtonShortPress();
|
||||||
} else if (!dismissedExt) { // Don't change applet if this button press silenced the external notification module
|
else if (!dismissedExt) // Don't change applet if this button press silenced the external notification module
|
||||||
if (!settings->joystick.enabled)
|
inkhud->nextApplet();
|
||||||
inkhud->nextApplet();
|
|
||||||
else
|
|
||||||
inkhud->openMenu();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InkHUD::Events::onButtonLong()
|
void InkHUD::Events::onButtonLong()
|
||||||
@@ -88,156 +83,6 @@ void InkHUD::Events::onButtonLong()
|
|||||||
inkhud->openMenu();
|
inkhud->openMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InkHUD::Events::onExitShort()
|
|
||||||
{
|
|
||||||
if (settings->joystick.enabled) {
|
|
||||||
// Audio feedback (via buzzer)
|
|
||||||
// Short tone
|
|
||||||
playChirp();
|
|
||||||
// Cancel any beeping, buzzing, blinking
|
|
||||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
|
||||||
bool dismissedExt = dismissExternalNotification();
|
|
||||||
|
|
||||||
// Check which system applet wants to handle the button press (if any)
|
|
||||||
SystemApplet *consumer = nullptr;
|
|
||||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
|
||||||
if (sa->handleInput) {
|
|
||||||
consumer = sa;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no system applet is handling input, default behavior instead is change tiles
|
|
||||||
if (consumer)
|
|
||||||
consumer->onExitShort();
|
|
||||||
else if (!dismissedExt) // Don't change tile if this button press silenced the external notification module
|
|
||||||
inkhud->nextTile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::Events::onExitLong()
|
|
||||||
{
|
|
||||||
if (settings->joystick.enabled) {
|
|
||||||
// Audio feedback (via buzzer)
|
|
||||||
// Slightly longer than playChirp
|
|
||||||
playBoop();
|
|
||||||
|
|
||||||
// Check which system applet wants to handle the button press (if any)
|
|
||||||
SystemApplet *consumer = nullptr;
|
|
||||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
|
||||||
if (sa->handleInput) {
|
|
||||||
consumer = sa;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumer)
|
|
||||||
consumer->onExitLong();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::Events::onNavUp()
|
|
||||||
{
|
|
||||||
if (settings->joystick.enabled) {
|
|
||||||
// Audio feedback (via buzzer)
|
|
||||||
// Short tone
|
|
||||||
playChirp();
|
|
||||||
// Cancel any beeping, buzzing, blinking
|
|
||||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
|
||||||
bool dismissedExt = dismissExternalNotification();
|
|
||||||
|
|
||||||
// Check which system applet wants to handle the button press (if any)
|
|
||||||
SystemApplet *consumer = nullptr;
|
|
||||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
|
||||||
if (sa->handleInput) {
|
|
||||||
consumer = sa;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumer)
|
|
||||||
consumer->onNavUp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::Events::onNavDown()
|
|
||||||
{
|
|
||||||
if (settings->joystick.enabled) {
|
|
||||||
// Audio feedback (via buzzer)
|
|
||||||
// Short tone
|
|
||||||
playChirp();
|
|
||||||
// Cancel any beeping, buzzing, blinking
|
|
||||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
|
||||||
bool dismissedExt = dismissExternalNotification();
|
|
||||||
|
|
||||||
// Check which system applet wants to handle the button press (if any)
|
|
||||||
SystemApplet *consumer = nullptr;
|
|
||||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
|
||||||
if (sa->handleInput) {
|
|
||||||
consumer = sa;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumer)
|
|
||||||
consumer->onNavDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::Events::onNavLeft()
|
|
||||||
{
|
|
||||||
if (settings->joystick.enabled) {
|
|
||||||
// Audio feedback (via buzzer)
|
|
||||||
// Short tone
|
|
||||||
playChirp();
|
|
||||||
// Cancel any beeping, buzzing, blinking
|
|
||||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
|
||||||
bool dismissedExt = dismissExternalNotification();
|
|
||||||
|
|
||||||
// Check which system applet wants to handle the button press (if any)
|
|
||||||
SystemApplet *consumer = nullptr;
|
|
||||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
|
||||||
if (sa->handleInput) {
|
|
||||||
consumer = sa;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no system applet is handling input, default behavior instead is to cycle applets
|
|
||||||
if (consumer)
|
|
||||||
consumer->onNavLeft();
|
|
||||||
else if (!dismissedExt) // Don't change applet if this button press silenced the external notification module
|
|
||||||
inkhud->prevApplet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::Events::onNavRight()
|
|
||||||
{
|
|
||||||
if (settings->joystick.enabled) {
|
|
||||||
// Audio feedback (via buzzer)
|
|
||||||
// Short tone
|
|
||||||
playChirp();
|
|
||||||
// Cancel any beeping, buzzing, blinking
|
|
||||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
|
||||||
bool dismissedExt = dismissExternalNotification();
|
|
||||||
|
|
||||||
// Check which system applet wants to handle the button press (if any)
|
|
||||||
SystemApplet *consumer = nullptr;
|
|
||||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
|
||||||
if (sa->handleInput) {
|
|
||||||
consumer = sa;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no system applet is handling input, default behavior instead is to cycle applets
|
|
||||||
if (consumer)
|
|
||||||
consumer->onNavRight();
|
|
||||||
else if (!dismissedExt) // Don't change applet if this button press silenced the external notification module
|
|
||||||
inkhud->nextApplet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback for deepSleepObserver
|
// Callback for deepSleepObserver
|
||||||
// Returns 0 to signal that we agree to sleep now
|
// Returns 0 to signal that we agree to sleep now
|
||||||
int InkHUD::Events::beforeDeepSleep(void *unused)
|
int InkHUD::Events::beforeDeepSleep(void *unused)
|
||||||
|
|||||||
@@ -29,12 +29,6 @@ class Events
|
|||||||
|
|
||||||
void onButtonShort(); // User button: short press
|
void onButtonShort(); // User button: short press
|
||||||
void onButtonLong(); // User button: long press
|
void onButtonLong(); // User button: long press
|
||||||
void onExitShort(); // Exit button: short press
|
|
||||||
void onExitLong(); // Exit button: long press
|
|
||||||
void onNavUp(); // Navigate up
|
|
||||||
void onNavDown(); // Navigate down
|
|
||||||
void onNavLeft(); // Navigate left
|
|
||||||
void onNavRight(); // Navigate right
|
|
||||||
|
|
||||||
int beforeDeepSleep(void *unused); // Prepare for shutdown
|
int beforeDeepSleep(void *unused); // Prepare for shutdown
|
||||||
int beforeReboot(void *unused); // Prepare for reboot
|
int beforeReboot(void *unused); // Prepare for reboot
|
||||||
|
|||||||
@@ -80,94 +80,6 @@ void InkHUD::InkHUD::longpress()
|
|||||||
events->onButtonLong();
|
events->onButtonLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this when your exit button gets a short press
|
|
||||||
void InkHUD::InkHUD::exitShort()
|
|
||||||
{
|
|
||||||
events->onExitShort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this when your exit button gets a long press
|
|
||||||
void InkHUD::InkHUD::exitLong()
|
|
||||||
{
|
|
||||||
events->onExitLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this when your joystick gets an up input
|
|
||||||
void InkHUD::InkHUD::navUp()
|
|
||||||
{
|
|
||||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
|
||||||
case 1: // 90 deg
|
|
||||||
events->onNavLeft();
|
|
||||||
break;
|
|
||||||
case 2: // 180 deg
|
|
||||||
events->onNavDown();
|
|
||||||
break;
|
|
||||||
case 3: // 270 deg
|
|
||||||
events->onNavRight();
|
|
||||||
break;
|
|
||||||
default: // 0 deg
|
|
||||||
events->onNavUp();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this when your joystick gets a down input
|
|
||||||
void InkHUD::InkHUD::navDown()
|
|
||||||
{
|
|
||||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
|
||||||
case 1: // 90 deg
|
|
||||||
events->onNavRight();
|
|
||||||
break;
|
|
||||||
case 2: // 180 deg
|
|
||||||
events->onNavUp();
|
|
||||||
break;
|
|
||||||
case 3: // 270 deg
|
|
||||||
events->onNavLeft();
|
|
||||||
break;
|
|
||||||
default: // 0 deg
|
|
||||||
events->onNavDown();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this when your joystick gets a left input
|
|
||||||
void InkHUD::InkHUD::navLeft()
|
|
||||||
{
|
|
||||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
|
||||||
case 1: // 90 deg
|
|
||||||
events->onNavDown();
|
|
||||||
break;
|
|
||||||
case 2: // 180 deg
|
|
||||||
events->onNavRight();
|
|
||||||
break;
|
|
||||||
case 3: // 270 deg
|
|
||||||
events->onNavUp();
|
|
||||||
break;
|
|
||||||
default: // 0 deg
|
|
||||||
events->onNavLeft();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this when your joystick gets a right input
|
|
||||||
void InkHUD::InkHUD::navRight()
|
|
||||||
{
|
|
||||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
|
||||||
case 1: // 90 deg
|
|
||||||
events->onNavUp();
|
|
||||||
break;
|
|
||||||
case 2: // 180 deg
|
|
||||||
events->onNavLeft();
|
|
||||||
break;
|
|
||||||
case 3: // 270 deg
|
|
||||||
events->onNavDown();
|
|
||||||
break;
|
|
||||||
default: // 0 deg
|
|
||||||
events->onNavRight();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cycle the next user applet to the foreground
|
// Cycle the next user applet to the foreground
|
||||||
// Only activated applets are cycled
|
// Only activated applets are cycled
|
||||||
// If user has a multi-applet layout, the applets will cycle on the "focused tile"
|
// If user has a multi-applet layout, the applets will cycle on the "focused tile"
|
||||||
@@ -176,14 +88,6 @@ void InkHUD::InkHUD::nextApplet()
|
|||||||
windowManager->nextApplet();
|
windowManager->nextApplet();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cycle the previous user applet to the foreground
|
|
||||||
// Only activated applets are cycled
|
|
||||||
// If user has a multi-applet layout, the applets will cycle on the "focused tile"
|
|
||||||
void InkHUD::InkHUD::prevApplet()
|
|
||||||
{
|
|
||||||
windowManager->prevApplet();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the menu (on the the focused tile)
|
// Show the menu (on the the focused tile)
|
||||||
// The applet previously displayed there will be restored once the menu closes
|
// The applet previously displayed there will be restored once the menu closes
|
||||||
void InkHUD::InkHUD::openMenu()
|
void InkHUD::InkHUD::openMenu()
|
||||||
@@ -191,12 +95,6 @@ void InkHUD::InkHUD::openMenu()
|
|||||||
windowManager->openMenu();
|
windowManager->openMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bring AlignStick applet to the foreground
|
|
||||||
void InkHUD::InkHUD::openAlignStick()
|
|
||||||
{
|
|
||||||
windowManager->openAlignStick();
|
|
||||||
}
|
|
||||||
|
|
||||||
// In layouts where multiple applets are shown at once, change which tile is focused
|
// In layouts where multiple applets are shown at once, change which tile is focused
|
||||||
// The focused tile in the one which cycles applets on button short press, and displays menu on long press
|
// The focused tile in the one which cycles applets on button short press, and displays menu on long press
|
||||||
void InkHUD::InkHUD::nextTile()
|
void InkHUD::InkHUD::nextTile()
|
||||||
@@ -204,26 +102,12 @@ void InkHUD::InkHUD::nextTile()
|
|||||||
windowManager->nextTile();
|
windowManager->nextTile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// In layouts where multiple applets are shown at once, change which tile is focused
|
|
||||||
// The focused tile in the one which cycles applets on button short press, and displays menu on long press
|
|
||||||
void InkHUD::InkHUD::prevTile()
|
|
||||||
{
|
|
||||||
windowManager->prevTile();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotate the display image by 90 degrees
|
// Rotate the display image by 90 degrees
|
||||||
void InkHUD::InkHUD::rotate()
|
void InkHUD::InkHUD::rotate()
|
||||||
{
|
{
|
||||||
windowManager->rotate();
|
windowManager->rotate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// rotate the joystick in 90 degree increments
|
|
||||||
void InkHUD::InkHUD::rotateJoystick(uint8_t angle)
|
|
||||||
{
|
|
||||||
persistence->settings.joystick.alignment += angle;
|
|
||||||
persistence->settings.joystick.alignment %= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show / hide the battery indicator in top-right
|
// Show / hide the battery indicator in top-right
|
||||||
void InkHUD::InkHUD::toggleBatteryIcon()
|
void InkHUD::InkHUD::toggleBatteryIcon()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,25 +55,15 @@ class InkHUD
|
|||||||
|
|
||||||
void shortpress();
|
void shortpress();
|
||||||
void longpress();
|
void longpress();
|
||||||
void exitShort();
|
|
||||||
void exitLong();
|
|
||||||
void navUp();
|
|
||||||
void navDown();
|
|
||||||
void navLeft();
|
|
||||||
void navRight();
|
|
||||||
|
|
||||||
// Trigger UI changes
|
// Trigger UI changes
|
||||||
// - called by various InkHUD components
|
// - called by various InkHUD components
|
||||||
// - suitable(?) for use by aux button, connected in variant nicheGraphics.h
|
// - suitable(?) for use by aux button, connected in variant nicheGraphics.h
|
||||||
|
|
||||||
void nextApplet();
|
void nextApplet();
|
||||||
void prevApplet();
|
|
||||||
void openMenu();
|
void openMenu();
|
||||||
void openAlignStick();
|
|
||||||
void nextTile();
|
void nextTile();
|
||||||
void prevTile();
|
|
||||||
void rotate();
|
void rotate();
|
||||||
void rotateJoystick(uint8_t angle = 1); // rotate 90 deg by default
|
|
||||||
void toggleBatteryIcon();
|
void toggleBatteryIcon();
|
||||||
|
|
||||||
// Updating the display
|
// Updating the display
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class Persistence
|
|||||||
|
|
||||||
// Used to invalidate old settings, if needed
|
// Used to invalidate old settings, if needed
|
||||||
// Version 0 is reserved for testing, and will always load defaults
|
// Version 0 is reserved for testing, and will always load defaults
|
||||||
static constexpr uint32_t SETTINGS_VERSION = 3;
|
static constexpr uint32_t SETTINGS_VERSION = 2;
|
||||||
|
|
||||||
struct Settings {
|
struct Settings {
|
||||||
struct Meta {
|
struct Meta {
|
||||||
@@ -96,19 +96,6 @@ class Persistence
|
|||||||
bool safeShutdownSeen = false;
|
bool safeShutdownSeen = false;
|
||||||
} tips;
|
} tips;
|
||||||
|
|
||||||
// Joystick settings for enabling and aligning to the screen
|
|
||||||
struct Joystick {
|
|
||||||
// Modifies the UI for joystick use
|
|
||||||
bool enabled = false;
|
|
||||||
|
|
||||||
// gets set to true when AlignStick applet is completed
|
|
||||||
bool aligned = false;
|
|
||||||
|
|
||||||
// Rotation of the joystick
|
|
||||||
// Multiples of 90 degrees clockwise
|
|
||||||
uint8_t alignment = 0;
|
|
||||||
} joystick;
|
|
||||||
|
|
||||||
// Rotation of the display
|
// Rotation of the display
|
||||||
// Multiples of 90 degrees clockwise
|
// Multiples of 90 degrees clockwise
|
||||||
// Most commonly: rotation is 0 when flex connector is oriented below display
|
// Most commonly: rotation is 0 when flex connector is oriented below display
|
||||||
|
|||||||
@@ -8,5 +8,4 @@ build_flags =
|
|||||||
-D MESHTASTIC_EXCLUDE_INPUTBROKER ; Suppress default input handling
|
-D MESHTASTIC_EXCLUDE_INPUTBROKER ; Suppress default input handling
|
||||||
-D HAS_BUTTON=0 ; Suppress default ButtonThread
|
-D HAS_BUTTON=0 ; Suppress default ButtonThread
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# TODO renovate
|
https://github.com/ZinggJM/GFX_Root#2.0.0 ; Used by InkHUD as a "slimmer" version of AdafruitGFX
|
||||||
https://github.com/ZinggJM/GFX_Root#2.0.0 ; Used by InkHUD as a "slimmer" version of AdafruitGFX
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "./WindowManager.h"
|
#include "./WindowManager.h"
|
||||||
|
|
||||||
#include "./Applets/System/AlignStick/AlignStickApplet.h"
|
|
||||||
#include "./Applets/System/BatteryIcon/BatteryIconApplet.h"
|
#include "./Applets/System/BatteryIcon/BatteryIconApplet.h"
|
||||||
#include "./Applets/System/Logo/LogoApplet.h"
|
#include "./Applets/System/Logo/LogoApplet.h"
|
||||||
#include "./Applets/System/Menu/MenuApplet.h"
|
#include "./Applets/System/Menu/MenuApplet.h"
|
||||||
@@ -99,38 +98,6 @@ void InkHUD::WindowManager::nextTile()
|
|||||||
userTiles.at(settings->userTiles.focused)->requestHighlight();
|
userTiles.at(settings->userTiles.focused)->requestHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focus on a different tile but decrement index
|
|
||||||
void InkHUD::WindowManager::prevTile()
|
|
||||||
{
|
|
||||||
// Close the menu applet if open
|
|
||||||
// We don't *really* want to do this, but it simplifies handling *a lot*
|
|
||||||
MenuApplet *menu = (MenuApplet *)inkhud->getSystemApplet("Menu");
|
|
||||||
bool menuWasOpen = false;
|
|
||||||
if (menu->isForeground()) {
|
|
||||||
menu->sendToBackground();
|
|
||||||
menuWasOpen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap to next tile
|
|
||||||
if (settings->userTiles.focused == 0)
|
|
||||||
settings->userTiles.focused = settings->userTiles.count - 1;
|
|
||||||
else
|
|
||||||
settings->userTiles.focused--;
|
|
||||||
|
|
||||||
// Make sure that we don't get stuck on the placeholder tile
|
|
||||||
refocusTile();
|
|
||||||
|
|
||||||
if (menuWasOpen)
|
|
||||||
menu->show(userTiles.at(settings->userTiles.focused));
|
|
||||||
|
|
||||||
// Ask the tile to draw an indicator showing which tile is now focused
|
|
||||||
// Requests a render
|
|
||||||
// We only draw this indicator if the device uses an aux button to switch tiles.
|
|
||||||
// Assume aux button is used to switch tiles if the "next tile" menu item is hidden
|
|
||||||
if (!settings->optionalMenuItems.nextTile)
|
|
||||||
userTiles.at(settings->userTiles.focused)->requestHighlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the menu (on the the focused tile)
|
// Show the menu (on the the focused tile)
|
||||||
// The applet previously displayed there will be restored once the menu closes
|
// The applet previously displayed there will be restored once the menu closes
|
||||||
void InkHUD::WindowManager::openMenu()
|
void InkHUD::WindowManager::openMenu()
|
||||||
@@ -139,15 +106,6 @@ void InkHUD::WindowManager::openMenu()
|
|||||||
menu->show(userTiles.at(settings->userTiles.focused));
|
menu->show(userTiles.at(settings->userTiles.focused));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bring the AlignStick applet to the foreground
|
|
||||||
void InkHUD::WindowManager::openAlignStick()
|
|
||||||
{
|
|
||||||
if (settings->joystick.enabled) {
|
|
||||||
AlignStickApplet *alignStick = (AlignStickApplet *)inkhud->getSystemApplet("AlignStick");
|
|
||||||
alignStick->bringToForeground();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// On the currently focussed tile: cycle to the next available user applet
|
// On the currently focussed tile: cycle to the next available user applet
|
||||||
// Applets available for this must be activated, and not already displayed on another tile
|
// Applets available for this must be activated, and not already displayed on another tile
|
||||||
void InkHUD::WindowManager::nextApplet()
|
void InkHUD::WindowManager::nextApplet()
|
||||||
@@ -197,59 +155,6 @@ void InkHUD::WindowManager::nextApplet()
|
|||||||
inkhud->forceUpdate(EInk::UpdateTypes::FAST); // bringToForeground already requested, but we're manually forcing FAST
|
inkhud->forceUpdate(EInk::UpdateTypes::FAST); // bringToForeground already requested, but we're manually forcing FAST
|
||||||
}
|
}
|
||||||
|
|
||||||
// On the currently focussed tile: cycle to the previous available user applet
|
|
||||||
// Applets available for this must be activated, and not already displayed on another tile
|
|
||||||
void InkHUD::WindowManager::prevApplet()
|
|
||||||
{
|
|
||||||
Tile *t = userTiles.at(settings->userTiles.focused);
|
|
||||||
|
|
||||||
// Abort if zero applets available
|
|
||||||
// nullptr means WindowManager::refocusTile determined that there were no available applets
|
|
||||||
if (!t->getAssignedApplet())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Find the index of the applet currently shown on the tile
|
|
||||||
uint8_t appletIndex = -1;
|
|
||||||
for (uint8_t i = 0; i < inkhud->userApplets.size(); i++) {
|
|
||||||
if (inkhud->userApplets.at(i) == t->getAssignedApplet()) {
|
|
||||||
appletIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm that we did find the applet
|
|
||||||
assert(appletIndex != (uint8_t)-1);
|
|
||||||
|
|
||||||
// Iterate forward through the WindowManager::applets, looking for the previous valid applet
|
|
||||||
Applet *prevValidApplet = nullptr;
|
|
||||||
for (uint8_t i = 1; i < inkhud->userApplets.size(); i++) {
|
|
||||||
uint8_t newAppletIndex = 0;
|
|
||||||
if (i > appletIndex)
|
|
||||||
newAppletIndex = inkhud->userApplets.size() + appletIndex - i;
|
|
||||||
else
|
|
||||||
newAppletIndex = (appletIndex - i);
|
|
||||||
Applet *a = inkhud->userApplets.at(newAppletIndex);
|
|
||||||
|
|
||||||
// Looking for an applet which is active (enabled by user), but currently in background
|
|
||||||
if (a->isActive() && !a->isForeground()) {
|
|
||||||
prevValidApplet = a;
|
|
||||||
settings->userTiles.displayedUserApplet[settings->userTiles.focused] =
|
|
||||||
newAppletIndex; // Remember this setting between boots!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm that we found another applet
|
|
||||||
if (!prevValidApplet)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Hide old applet, show new applet
|
|
||||||
t->getAssignedApplet()->sendToBackground();
|
|
||||||
t->assignApplet(prevValidApplet);
|
|
||||||
prevValidApplet->bringToForeground();
|
|
||||||
inkhud->forceUpdate(EInk::UpdateTypes::FAST); // bringToForeground already requested, but we're manually forcing FAST
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotate the display image by 90 degrees
|
// Rotate the display image by 90 degrees
|
||||||
void InkHUD::WindowManager::rotate()
|
void InkHUD::WindowManager::rotate()
|
||||||
{
|
{
|
||||||
@@ -433,8 +338,6 @@ void InkHUD::WindowManager::createSystemApplets()
|
|||||||
addSystemApplet("Logo", new LogoApplet, new Tile);
|
addSystemApplet("Logo", new LogoApplet, new Tile);
|
||||||
addSystemApplet("Pairing", new PairingApplet, new Tile);
|
addSystemApplet("Pairing", new PairingApplet, new Tile);
|
||||||
addSystemApplet("Tips", new TipsApplet, new Tile);
|
addSystemApplet("Tips", new TipsApplet, new Tile);
|
||||||
if (settings->joystick.enabled)
|
|
||||||
addSystemApplet("AlignStick", new AlignStickApplet, new Tile);
|
|
||||||
|
|
||||||
addSystemApplet("Menu", new MenuApplet, nullptr);
|
addSystemApplet("Menu", new MenuApplet, nullptr);
|
||||||
|
|
||||||
@@ -457,8 +360,6 @@ void InkHUD::WindowManager::placeSystemTiles()
|
|||||||
inkhud->getSystemApplet("Logo")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
inkhud->getSystemApplet("Logo")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
||||||
inkhud->getSystemApplet("Pairing")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
inkhud->getSystemApplet("Pairing")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
||||||
inkhud->getSystemApplet("Tips")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
inkhud->getSystemApplet("Tips")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
||||||
if (settings->joystick.enabled)
|
|
||||||
inkhud->getSystemApplet("AlignStick")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
|
||||||
|
|
||||||
inkhud->getSystemApplet("Notification")->getTile()->setRegion(0, 0, inkhud->width(), 20);
|
inkhud->getSystemApplet("Notification")->getTile()->setRegion(0, 0, inkhud->width(), 20);
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,8 @@ class WindowManager
|
|||||||
// - call these to make stuff change
|
// - call these to make stuff change
|
||||||
|
|
||||||
void nextTile();
|
void nextTile();
|
||||||
void prevTile();
|
|
||||||
void openMenu();
|
void openMenu();
|
||||||
void openAlignStick();
|
|
||||||
void nextApplet();
|
void nextApplet();
|
||||||
void prevApplet();
|
|
||||||
void rotate();
|
void rotate();
|
||||||
void toggleBatteryIcon();
|
void toggleBatteryIcon();
|
||||||
|
|
||||||
|
|||||||
@@ -1,523 +0,0 @@
|
|||||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
|
||||||
|
|
||||||
#include "./TwoButtonExtended.h"
|
|
||||||
|
|
||||||
#include "NodeDB.h" // For the helper function TwoButtonExtended::getUserButtonPin
|
|
||||||
#include "PowerFSM.h"
|
|
||||||
#include "sleep.h"
|
|
||||||
|
|
||||||
using namespace NicheGraphics::Inputs;
|
|
||||||
|
|
||||||
TwoButtonExtended::TwoButtonExtended() : concurrency::OSThread("TwoButtonExtended")
|
|
||||||
{
|
|
||||||
// Don't start polling buttons for release immediately
|
|
||||||
// Assume they are in a "released" state at boot
|
|
||||||
OSThread::disable();
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
// Register callbacks for before and after lightsleep
|
|
||||||
lsObserver.observe(¬ifyLightSleep);
|
|
||||||
lsEndObserver.observe(¬ifyLightSleepEnd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Explicitly initialize these, just to keep cppcheck quiet..
|
|
||||||
buttons[0] = Button();
|
|
||||||
buttons[1] = Button();
|
|
||||||
joystick[Direction::UP] = SimpleButton();
|
|
||||||
joystick[Direction::DOWN] = SimpleButton();
|
|
||||||
joystick[Direction::LEFT] = SimpleButton();
|
|
||||||
joystick[Direction::RIGHT] = SimpleButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get access to (or create) the singleton instance of this class
|
|
||||||
// Accessible inside the ISRs, even though we maybe shouldn't
|
|
||||||
TwoButtonExtended *TwoButtonExtended::getInstance()
|
|
||||||
{
|
|
||||||
// Instantiate the class the first time this method is called
|
|
||||||
static TwoButtonExtended *const singletonInstance = new TwoButtonExtended;
|
|
||||||
|
|
||||||
return singletonInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Begin receiving button input
|
|
||||||
// We probably need to do this after sleep, as well as at boot
|
|
||||||
void TwoButtonExtended::start()
|
|
||||||
{
|
|
||||||
if (buttons[0].pin != 0xFF)
|
|
||||||
attachInterrupt(buttons[0].pin, TwoButtonExtended::isrPrimary, buttons[0].activeLogic == LOW ? FALLING : RISING);
|
|
||||||
|
|
||||||
if (buttons[1].pin != 0xFF)
|
|
||||||
attachInterrupt(buttons[1].pin, TwoButtonExtended::isrSecondary, buttons[1].activeLogic == LOW ? FALLING : RISING);
|
|
||||||
|
|
||||||
if (joystick[Direction::UP].pin != 0xFF)
|
|
||||||
attachInterrupt(joystick[Direction::UP].pin, TwoButtonExtended::isrJoystickUp,
|
|
||||||
joystickActiveLogic == LOW ? FALLING : RISING);
|
|
||||||
|
|
||||||
if (joystick[Direction::DOWN].pin != 0xFF)
|
|
||||||
attachInterrupt(joystick[Direction::DOWN].pin, TwoButtonExtended::isrJoystickDown,
|
|
||||||
joystickActiveLogic == LOW ? FALLING : RISING);
|
|
||||||
|
|
||||||
if (joystick[Direction::LEFT].pin != 0xFF)
|
|
||||||
attachInterrupt(joystick[Direction::LEFT].pin, TwoButtonExtended::isrJoystickLeft,
|
|
||||||
joystickActiveLogic == LOW ? FALLING : RISING);
|
|
||||||
|
|
||||||
if (joystick[Direction::RIGHT].pin != 0xFF)
|
|
||||||
attachInterrupt(joystick[Direction::RIGHT].pin, TwoButtonExtended::isrJoystickRight,
|
|
||||||
joystickActiveLogic == LOW ? FALLING : RISING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop receiving button input, and run custom sleep code
|
|
||||||
// Called before device sleeps. This might be power-off, or just ESP32 light sleep
|
|
||||||
// Some devices will want to attach interrupts here, for the user button to wake from sleep
|
|
||||||
void TwoButtonExtended::stop()
|
|
||||||
{
|
|
||||||
if (buttons[0].pin != 0xFF)
|
|
||||||
detachInterrupt(buttons[0].pin);
|
|
||||||
|
|
||||||
if (buttons[1].pin != 0xFF)
|
|
||||||
detachInterrupt(buttons[1].pin);
|
|
||||||
|
|
||||||
if (joystick[Direction::UP].pin != 0xFF)
|
|
||||||
detachInterrupt(joystick[Direction::UP].pin);
|
|
||||||
|
|
||||||
if (joystick[Direction::DOWN].pin != 0xFF)
|
|
||||||
detachInterrupt(joystick[Direction::DOWN].pin);
|
|
||||||
|
|
||||||
if (joystick[Direction::LEFT].pin != 0xFF)
|
|
||||||
detachInterrupt(joystick[Direction::LEFT].pin);
|
|
||||||
|
|
||||||
if (joystick[Direction::RIGHT].pin != 0xFF)
|
|
||||||
detachInterrupt(joystick[Direction::RIGHT].pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to resolve a GPIO pin for the user button, honoring userPrefs.jsonc and device settings
|
|
||||||
// This helper method isn't used by the TwoButtonExtended class itself, it could be moved elsewhere.
|
|
||||||
// Intention is to pass this value to TwoButtonExtended::setWiring in the setupNicheGraphics method.
|
|
||||||
uint8_t TwoButtonExtended::getUserButtonPin()
|
|
||||||
{
|
|
||||||
uint8_t pin = 0xFF; // Unset
|
|
||||||
|
|
||||||
// Use default pin for variant, if no better source
|
|
||||||
#ifdef BUTTON_PIN
|
|
||||||
pin = BUTTON_PIN;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// From userPrefs.jsonc, if set
|
|
||||||
#ifdef USERPREFS_BUTTON_PIN
|
|
||||||
pin = USERPREFS_BUTTON_PIN;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// From user's override in device settings, if set
|
|
||||||
if (config.device.button_gpio)
|
|
||||||
pin = config.device.button_gpio;
|
|
||||||
|
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configures the wiring and logic of either button
|
|
||||||
// Called when outlining your NicheGraphics implementation, in variant/nicheGraphics.cpp
|
|
||||||
void TwoButtonExtended::setWiring(uint8_t whichButton, uint8_t pin, bool internalPullup)
|
|
||||||
{
|
|
||||||
// Prevent the same GPIO being assigned to multiple buttons
|
|
||||||
// Allows an edge case when the user remaps hardware buttons using device settings, due to a broken user button
|
|
||||||
for (uint8_t i = 0; i < whichButton; i++) {
|
|
||||||
if (buttons[i].pin == pin) {
|
|
||||||
LOG_WARN("Attempted reuse of GPIO %d. Ignoring assignment whichButton=%d", pin, whichButton);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].pin = pin;
|
|
||||||
buttons[whichButton].activeLogic = LOW;
|
|
||||||
|
|
||||||
pinMode(buttons[whichButton].pin, internalPullup ? INPUT_PULLUP : INPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configures the wiring and logic of the joystick buttons
|
|
||||||
// Called when outlining your NicheGraphics implementation, in variant/nicheGraphics.cpp
|
|
||||||
void TwoButtonExtended::setJoystickWiring(uint8_t uPin, uint8_t dPin, uint8_t lPin, uint8_t rPin, bool internalPullup)
|
|
||||||
{
|
|
||||||
if (joystick[Direction::UP].pin == uPin || joystick[Direction::DOWN].pin == dPin || joystick[Direction::LEFT].pin == lPin ||
|
|
||||||
joystick[Direction::RIGHT].pin == rPin) {
|
|
||||||
LOG_WARN("Attempted reuse of Joystick GPIO. Ignoring assignment");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
joystick[Direction::UP].pin = uPin;
|
|
||||||
joystick[Direction::DOWN].pin = dPin;
|
|
||||||
joystick[Direction::LEFT].pin = lPin;
|
|
||||||
joystick[Direction::RIGHT].pin = rPin;
|
|
||||||
joystickActiveLogic = LOW;
|
|
||||||
|
|
||||||
pinMode(joystick[Direction::UP].pin, internalPullup ? INPUT_PULLUP : INPUT);
|
|
||||||
pinMode(joystick[Direction::DOWN].pin, internalPullup ? INPUT_PULLUP : INPUT);
|
|
||||||
pinMode(joystick[Direction::LEFT].pin, internalPullup ? INPUT_PULLUP : INPUT);
|
|
||||||
pinMode(joystick[Direction::RIGHT].pin, internalPullup ? INPUT_PULLUP : INPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoButtonExtended::setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs)
|
|
||||||
{
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].debounceLength = debounceMs;
|
|
||||||
buttons[whichButton].longpressLength = longpressMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoButtonExtended::setJoystickDebounce(uint32_t debounceMs)
|
|
||||||
{
|
|
||||||
joystickDebounceLength = debounceMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a button becomes pressed
|
|
||||||
// Use this to implement a "while held" behavior
|
|
||||||
void TwoButtonExtended::setHandlerDown(uint8_t whichButton, Callback onDown)
|
|
||||||
{
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].onDown = onDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a button becomes unpressed
|
|
||||||
// Use this to implement a "While held" behavior
|
|
||||||
void TwoButtonExtended::setHandlerUp(uint8_t whichButton, Callback onUp)
|
|
||||||
{
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].onUp = onUp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a "short press" event has occurred
|
|
||||||
void TwoButtonExtended::setHandlerShortPress(uint8_t whichButton, Callback onPress)
|
|
||||||
{
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].onPress = onPress;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a "long press" event has fired
|
|
||||||
// Note: this will occur while the button is still held
|
|
||||||
void TwoButtonExtended::setHandlerLongPress(uint8_t whichButton, Callback onLongPress)
|
|
||||||
{
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].onLongPress = onLongPress;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a joystick button becomes pressed
|
|
||||||
// Use this to implement a "while held" behavior
|
|
||||||
void TwoButtonExtended::setJoystickDownHandlers(Callback uDown, Callback dDown, Callback lDown, Callback rDown)
|
|
||||||
{
|
|
||||||
joystick[Direction::UP].onDown = uDown;
|
|
||||||
joystick[Direction::DOWN].onDown = dDown;
|
|
||||||
joystick[Direction::LEFT].onDown = lDown;
|
|
||||||
joystick[Direction::RIGHT].onDown = rDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a joystick button becomes unpressed
|
|
||||||
// Use this to implement a "while held" behavior
|
|
||||||
void TwoButtonExtended::setJoystickUpHandlers(Callback uUp, Callback dUp, Callback lUp, Callback rUp)
|
|
||||||
{
|
|
||||||
joystick[Direction::UP].onUp = uUp;
|
|
||||||
joystick[Direction::DOWN].onUp = dUp;
|
|
||||||
joystick[Direction::LEFT].onUp = lUp;
|
|
||||||
joystick[Direction::RIGHT].onUp = rUp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a "press" event has fired
|
|
||||||
// Note: this will occur while the joystick button is still held
|
|
||||||
void TwoButtonExtended::setJoystickPressHandlers(Callback uPress, Callback dPress, Callback lPress, Callback rPress)
|
|
||||||
{
|
|
||||||
joystick[Direction::UP].onPress = uPress;
|
|
||||||
joystick[Direction::DOWN].onPress = dPress;
|
|
||||||
joystick[Direction::LEFT].onPress = lPress;
|
|
||||||
joystick[Direction::RIGHT].onPress = rPress;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the start of a press to the primary button
|
|
||||||
// Wakes our button thread
|
|
||||||
void TwoButtonExtended::isrPrimary()
|
|
||||||
{
|
|
||||||
static volatile bool isrRunning = false;
|
|
||||||
|
|
||||||
if (!isrRunning) {
|
|
||||||
isrRunning = true;
|
|
||||||
TwoButtonExtended *b = TwoButtonExtended::getInstance();
|
|
||||||
if (b->buttons[0].state == State::REST) {
|
|
||||||
b->buttons[0].state = State::IRQ;
|
|
||||||
b->buttons[0].irqAtMillis = millis();
|
|
||||||
b->startThread();
|
|
||||||
}
|
|
||||||
isrRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the start of a press to the secondary button
|
|
||||||
// Wakes our button thread
|
|
||||||
void TwoButtonExtended::isrSecondary()
|
|
||||||
{
|
|
||||||
static volatile bool isrRunning = false;
|
|
||||||
|
|
||||||
if (!isrRunning) {
|
|
||||||
isrRunning = true;
|
|
||||||
TwoButtonExtended *b = TwoButtonExtended::getInstance();
|
|
||||||
if (b->buttons[1].state == State::REST) {
|
|
||||||
b->buttons[1].state = State::IRQ;
|
|
||||||
b->buttons[1].irqAtMillis = millis();
|
|
||||||
b->startThread();
|
|
||||||
}
|
|
||||||
isrRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the start of a press to the joystick buttons
|
|
||||||
// Also wakes our button thread
|
|
||||||
void TwoButtonExtended::isrJoystickUp()
|
|
||||||
{
|
|
||||||
static volatile bool isrRunning = false;
|
|
||||||
|
|
||||||
if (!isrRunning) {
|
|
||||||
isrRunning = true;
|
|
||||||
TwoButtonExtended *b = TwoButtonExtended::getInstance();
|
|
||||||
if (b->joystick[Direction::UP].state == State::REST) {
|
|
||||||
b->joystick[Direction::UP].state = State::IRQ;
|
|
||||||
b->joystick[Direction::UP].irqAtMillis = millis();
|
|
||||||
b->startThread();
|
|
||||||
}
|
|
||||||
isrRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoButtonExtended::isrJoystickDown()
|
|
||||||
{
|
|
||||||
static volatile bool isrRunning = false;
|
|
||||||
|
|
||||||
if (!isrRunning) {
|
|
||||||
isrRunning = true;
|
|
||||||
TwoButtonExtended *b = TwoButtonExtended::getInstance();
|
|
||||||
if (b->joystick[Direction::DOWN].state == State::REST) {
|
|
||||||
b->joystick[Direction::DOWN].state = State::IRQ;
|
|
||||||
b->joystick[Direction::DOWN].irqAtMillis = millis();
|
|
||||||
b->startThread();
|
|
||||||
}
|
|
||||||
isrRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoButtonExtended::isrJoystickLeft()
|
|
||||||
{
|
|
||||||
static volatile bool isrRunning = false;
|
|
||||||
|
|
||||||
if (!isrRunning) {
|
|
||||||
isrRunning = true;
|
|
||||||
TwoButtonExtended *b = TwoButtonExtended::getInstance();
|
|
||||||
if (b->joystick[Direction::LEFT].state == State::REST) {
|
|
||||||
b->joystick[Direction::LEFT].state = State::IRQ;
|
|
||||||
b->joystick[Direction::LEFT].irqAtMillis = millis();
|
|
||||||
b->startThread();
|
|
||||||
}
|
|
||||||
isrRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwoButtonExtended::isrJoystickRight()
|
|
||||||
{
|
|
||||||
static volatile bool isrRunning = false;
|
|
||||||
|
|
||||||
if (!isrRunning) {
|
|
||||||
isrRunning = true;
|
|
||||||
TwoButtonExtended *b = TwoButtonExtended::getInstance();
|
|
||||||
if (b->joystick[Direction::RIGHT].state == State::REST) {
|
|
||||||
b->joystick[Direction::RIGHT].state = State::IRQ;
|
|
||||||
b->joystick[Direction::RIGHT].irqAtMillis = millis();
|
|
||||||
b->startThread();
|
|
||||||
}
|
|
||||||
isrRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Concise method to start our button thread
|
|
||||||
// Follows an ISR, listening for button release
|
|
||||||
void TwoButtonExtended::startThread()
|
|
||||||
{
|
|
||||||
if (!OSThread::enabled) {
|
|
||||||
OSThread::setInterval(10);
|
|
||||||
OSThread::enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Concise method to stop our button thread
|
|
||||||
// Called when we no longer need to poll for button release
|
|
||||||
void TwoButtonExtended::stopThread()
|
|
||||||
{
|
|
||||||
if (OSThread::enabled) {
|
|
||||||
OSThread::disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset both buttons manually
|
|
||||||
// Just in case an IRQ fires during the process of resetting the system
|
|
||||||
// Can occur with super rapid presses?
|
|
||||||
buttons[0].state = REST;
|
|
||||||
buttons[1].state = REST;
|
|
||||||
joystick[Direction::UP].state = REST;
|
|
||||||
joystick[Direction::DOWN].state = REST;
|
|
||||||
joystick[Direction::LEFT].state = REST;
|
|
||||||
joystick[Direction::RIGHT].state = REST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Our button thread
|
|
||||||
// Started by an IRQ, on either button
|
|
||||||
// Polls for button releases
|
|
||||||
// Stops when both buttons released
|
|
||||||
int32_t TwoButtonExtended::runOnce()
|
|
||||||
{
|
|
||||||
constexpr uint8_t BUTTON_COUNT = sizeof(buttons) / sizeof(Button);
|
|
||||||
constexpr uint8_t JOYSTICK_COUNT = sizeof(joystick) / sizeof(SimpleButton);
|
|
||||||
|
|
||||||
// Allow either button to request that our thread should continue polling
|
|
||||||
bool awaitingRelease = false;
|
|
||||||
|
|
||||||
// Check both primary and secondary buttons
|
|
||||||
for (uint8_t i = 0; i < BUTTON_COUNT; i++) {
|
|
||||||
switch (buttons[i].state) {
|
|
||||||
// No action: button has not been pressed
|
|
||||||
case REST:
|
|
||||||
break;
|
|
||||||
|
|
||||||
// New press detected by interrupt
|
|
||||||
case IRQ:
|
|
||||||
powerFSM.trigger(EVENT_PRESS); // Tell PowerFSM that press occurred (resets sleep timer)
|
|
||||||
buttons[i].onDown(); // Run callback: press has begun (possible hold behavior)
|
|
||||||
buttons[i].state = State::POLLING_UNFIRED; // Mark that button-down has been handled
|
|
||||||
awaitingRelease = true; // Mark that polling-for-release should continue
|
|
||||||
break;
|
|
||||||
|
|
||||||
// An existing press continues
|
|
||||||
// Not held long enough to register as longpress
|
|
||||||
case POLLING_UNFIRED: {
|
|
||||||
uint32_t length = millis() - buttons[i].irqAtMillis;
|
|
||||||
|
|
||||||
// If button released since last thread tick,
|
|
||||||
if (digitalRead(buttons[i].pin) != buttons[i].activeLogic) {
|
|
||||||
buttons[i].onUp(); // Run callback: press has ended (possible release of a hold)
|
|
||||||
buttons[i].state = State::REST; // Mark that the button has reset
|
|
||||||
if (length > buttons[i].debounceLength && length < buttons[i].longpressLength) // If too short for longpress,
|
|
||||||
buttons[i].onPress(); // Run callback: press
|
|
||||||
}
|
|
||||||
// If button not yet released
|
|
||||||
else {
|
|
||||||
awaitingRelease = true; // Mark that polling-for-release should continue
|
|
||||||
if (length >= buttons[i].longpressLength) {
|
|
||||||
// Run callback: long press (once)
|
|
||||||
// Then continue waiting for release, to rearm
|
|
||||||
buttons[i].state = State::POLLING_FIRED;
|
|
||||||
buttons[i].onLongPress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Button still held, but duration long enough that longpress event already fired
|
|
||||||
// Just waiting for release
|
|
||||||
case POLLING_FIRED:
|
|
||||||
// Release detected
|
|
||||||
if (digitalRead(buttons[i].pin) != buttons[i].activeLogic) {
|
|
||||||
buttons[i].state = State::REST;
|
|
||||||
buttons[i].onUp(); // Callback: release of hold (in this case: *after* longpress has fired)
|
|
||||||
}
|
|
||||||
// Not yet released, keep polling
|
|
||||||
else
|
|
||||||
awaitingRelease = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check all the joystick directions
|
|
||||||
for (uint8_t i = 0; i < JOYSTICK_COUNT; i++) {
|
|
||||||
switch (joystick[i].state) {
|
|
||||||
// No action: button has not been pressed
|
|
||||||
case REST:
|
|
||||||
break;
|
|
||||||
|
|
||||||
// New press detected by interrupt
|
|
||||||
case IRQ:
|
|
||||||
powerFSM.trigger(EVENT_PRESS); // Tell PowerFSM that press occurred (resets sleep timer)
|
|
||||||
joystick[i].onDown(); // Run callback: press has begun (possible hold behavior)
|
|
||||||
joystick[i].state = State::POLLING_UNFIRED; // Mark that button-down has been handled
|
|
||||||
awaitingRelease = true; // Mark that polling-for-release should continue
|
|
||||||
break;
|
|
||||||
|
|
||||||
// An existing press continues
|
|
||||||
// Not held long enough to register as press
|
|
||||||
case POLLING_UNFIRED: {
|
|
||||||
uint32_t length = millis() - joystick[i].irqAtMillis;
|
|
||||||
|
|
||||||
// If button released since last thread tick,
|
|
||||||
if (digitalRead(joystick[i].pin) != joystickActiveLogic) {
|
|
||||||
joystick[i].onUp(); // Run callback: press has ended (possible release of a hold)
|
|
||||||
joystick[i].state = State::REST; // Mark that the button has reset
|
|
||||||
}
|
|
||||||
// If button not yet released
|
|
||||||
else {
|
|
||||||
awaitingRelease = true; // Mark that polling-for-release should continue
|
|
||||||
if (length >= joystickDebounceLength) {
|
|
||||||
// Run callback: long press (once)
|
|
||||||
// Then continue waiting for release, to rearm
|
|
||||||
joystick[i].state = State::POLLING_FIRED;
|
|
||||||
joystick[i].onPress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Button still held after press
|
|
||||||
// Just waiting for release
|
|
||||||
case POLLING_FIRED:
|
|
||||||
// Release detected
|
|
||||||
if (digitalRead(joystick[i].pin) != joystickActiveLogic) {
|
|
||||||
joystick[i].state = State::REST;
|
|
||||||
joystick[i].onUp(); // Callback: release of hold
|
|
||||||
}
|
|
||||||
// Not yet released, keep polling
|
|
||||||
else
|
|
||||||
awaitingRelease = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all buttons are now released
|
|
||||||
// we don't need to waste cpu resources polling
|
|
||||||
// IRQ will restart this thread when we next need it
|
|
||||||
if (!awaitingRelease)
|
|
||||||
stopThread();
|
|
||||||
|
|
||||||
// Run this method again, or don't..
|
|
||||||
// Use whatever behavior was previously set by stopThread() or startThread()
|
|
||||||
return OSThread::interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
|
|
||||||
// Detach our class' interrupts before lightsleep
|
|
||||||
// Allows sleep.cpp to configure its own interrupts, which wake the device on user-button press
|
|
||||||
int TwoButtonExtended::beforeLightSleep(void *unused)
|
|
||||||
{
|
|
||||||
stop();
|
|
||||||
return 0; // Indicates success
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reconfigure our interrupts
|
|
||||||
// Our class' interrupts were disconnected during sleep, to allow the user button to wake the device from sleep
|
|
||||||
int TwoButtonExtended::afterLightSleep(esp_sleep_wakeup_cause_t cause)
|
|
||||||
{
|
|
||||||
start();
|
|
||||||
|
|
||||||
// Manually trigger the button-down ISR
|
|
||||||
// - during light sleep, our ISR is disabled
|
|
||||||
// - if light sleep ends by button press, pretend our own ISR caught it
|
|
||||||
// - need to manually confirm by reading pin ourselves, to avoid occasional false positives
|
|
||||||
// (false positive only when using internal pullup resistors?)
|
|
||||||
if (cause == ESP_SLEEP_WAKEUP_GPIO && digitalRead(buttons[0].pin) == buttons[0].activeLogic)
|
|
||||||
isrPrimary();
|
|
||||||
|
|
||||||
return 0; // Indicates success
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Re-usable NicheGraphics input source
|
|
||||||
|
|
||||||
Short and Long press for up to two buttons
|
|
||||||
Interrupt driven
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This expansion adds support for four more buttons
|
|
||||||
These buttons are single-action only, no long press
|
|
||||||
Interrupt driven
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
#include "assert.h"
|
|
||||||
#include "functional"
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
#include "esp_sleep.h" // For light-sleep handling
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Observer.h"
|
|
||||||
|
|
||||||
namespace NicheGraphics::Inputs
|
|
||||||
{
|
|
||||||
|
|
||||||
class TwoButtonExtended : protected concurrency::OSThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::function<void()> Callback;
|
|
||||||
|
|
||||||
static uint8_t getUserButtonPin(); // Resolve the GPIO, considering the various possible source of definition
|
|
||||||
|
|
||||||
static TwoButtonExtended *getInstance(); // Create or get the singleton instance
|
|
||||||
void start(); // Start handling button input
|
|
||||||
void stop(); // Stop handling button input (disconnect ISRs for sleep)
|
|
||||||
void setWiring(uint8_t whichButton, uint8_t pin, bool internalPullup = false);
|
|
||||||
void setJoystickWiring(uint8_t uPin, uint8_t dPin, uint8_t lPin, uint8_t rPin, bool internalPullup = false);
|
|
||||||
void setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs);
|
|
||||||
void setJoystickDebounce(uint32_t debounceMs);
|
|
||||||
void setHandlerDown(uint8_t whichButton, Callback onDown);
|
|
||||||
void setHandlerUp(uint8_t whichButton, Callback onUp);
|
|
||||||
void setHandlerShortPress(uint8_t whichButton, Callback onShortPress);
|
|
||||||
void setHandlerLongPress(uint8_t whichButton, Callback onLongPress);
|
|
||||||
void setJoystickDownHandlers(Callback uDown, Callback dDown, Callback ldown, Callback rDown);
|
|
||||||
void setJoystickUpHandlers(Callback uUp, Callback dUp, Callback lUp, Callback rUp);
|
|
||||||
void setJoystickPressHandlers(Callback uPress, Callback dPress, Callback lPress, Callback rPress);
|
|
||||||
|
|
||||||
// Disconnect and reconnect interrupts for light sleep
|
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
int beforeLightSleep(void *unused);
|
|
||||||
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Internal state of a specific button
|
|
||||||
enum State {
|
|
||||||
REST, // Up, no activity
|
|
||||||
IRQ, // Down detected, not yet handled
|
|
||||||
POLLING_UNFIRED, // Down handled, polling for release
|
|
||||||
POLLING_FIRED, // Longpress fired, button still held
|
|
||||||
};
|
|
||||||
|
|
||||||
// Joystick Directions
|
|
||||||
enum Direction { UP = 0, DOWN, LEFT, RIGHT };
|
|
||||||
|
|
||||||
// Data used for direction (single-action) buttons
|
|
||||||
class SimpleButton
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Per-button config
|
|
||||||
uint8_t pin = 0xFF; // 0xFF: unset
|
|
||||||
volatile State state = State::REST; // Internal state
|
|
||||||
volatile uint32_t irqAtMillis; // millis() when button went down
|
|
||||||
|
|
||||||
// Per-button event callbacks
|
|
||||||
static void noop(){};
|
|
||||||
std::function<void()> onDown = noop;
|
|
||||||
std::function<void()> onUp = noop;
|
|
||||||
std::function<void()> onPress = noop;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Data used for double-action buttons
|
|
||||||
class Button : public SimpleButton
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Per-button extended config
|
|
||||||
bool activeLogic = LOW; // Active LOW by default.
|
|
||||||
uint32_t debounceLength = 50; // Minimum length for shortpress in ms
|
|
||||||
uint32_t longpressLength = 500; // Time until longpress in ms
|
|
||||||
|
|
||||||
// Per-button event callbacks
|
|
||||||
std::function<void()> onLongPress = noop;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
// Get notified when lightsleep begins and ends
|
|
||||||
CallbackObserver<TwoButtonExtended, void *> lsObserver =
|
|
||||||
CallbackObserver<TwoButtonExtended, void *>(this, &TwoButtonExtended::beforeLightSleep);
|
|
||||||
CallbackObserver<TwoButtonExtended, esp_sleep_wakeup_cause_t> lsEndObserver =
|
|
||||||
CallbackObserver<TwoButtonExtended, esp_sleep_wakeup_cause_t>(this, &TwoButtonExtended::afterLightSleep);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t runOnce() override; // Timer method. Polls for button release
|
|
||||||
|
|
||||||
void startThread(); // Start polling for release
|
|
||||||
void stopThread(); // Stop polling for release
|
|
||||||
|
|
||||||
static void isrPrimary(); // User Button ISR
|
|
||||||
static void isrSecondary(); // optional aux button or joystick center
|
|
||||||
static void isrJoystickUp();
|
|
||||||
static void isrJoystickDown();
|
|
||||||
static void isrJoystickLeft();
|
|
||||||
static void isrJoystickRight();
|
|
||||||
|
|
||||||
TwoButtonExtended(); // Constructor made private: force use of Button::instance()
|
|
||||||
|
|
||||||
// Info about both buttons
|
|
||||||
Button buttons[2];
|
|
||||||
bool joystickActiveLogic = LOW; // Active LOW by default
|
|
||||||
uint32_t joystickDebounceLength = 50; // time until press in ms
|
|
||||||
SimpleButton joystick[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
}; // namespace NicheGraphics::Inputs
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -27,7 +27,9 @@ bool RotaryEncoderInterruptImpl1::init()
|
|||||||
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
||||||
RotaryEncoderInterruptImpl1::handleIntPressed);
|
RotaryEncoderInterruptImpl1::handleIntPressed);
|
||||||
inputBroker->registerSource(this);
|
inputBroker->registerSource(this);
|
||||||
|
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||||
osk_found = true;
|
osk_found = true;
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLef
|
|||||||
|
|
||||||
LOG_DEBUG("Trackball GPIO initialized - UP:%d DOWN:%d LEFT:%d RIGHT:%d PRESS:%d", this->_pinUp, this->_pinDown,
|
LOG_DEBUG("Trackball GPIO initialized - UP:%d DOWN:%d LEFT:%d RIGHT:%d PRESS:%d", this->_pinUp, this->_pinDown,
|
||||||
this->_pinLeft, this->_pinRight, pinPress);
|
this->_pinLeft, this->_pinRight, pinPress);
|
||||||
|
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||||
osk_found = true;
|
osk_found = true;
|
||||||
|
#endif
|
||||||
this->setInterval(100);
|
this->setInterval(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ bool UpDownInterruptImpl1::init()
|
|||||||
eventDownLong, UpDownInterruptImpl1::handleIntDown, UpDownInterruptImpl1::handleIntUp,
|
eventDownLong, UpDownInterruptImpl1::handleIntDown, UpDownInterruptImpl1::handleIntUp,
|
||||||
UpDownInterruptImpl1::handleIntPressed);
|
UpDownInterruptImpl1::handleIntPressed);
|
||||||
inputBroker->registerSource(this);
|
inputBroker->registerSource(this);
|
||||||
|
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||||
osk_found = true;
|
osk_found = true;
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
src/main.cpp
11
src/main.cpp
@@ -428,17 +428,10 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
RTCQuality ourQuality = RTCQualityDevice;
|
|
||||||
|
|
||||||
std::string timeCommandResult = exec("timedatectl status | grep synchronized | grep yes -c");
|
|
||||||
if (timeCommandResult[0] == '1') {
|
|
||||||
ourQuality = RTCQualityNTP;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = time(NULL);
|
tv.tv_sec = time(NULL);
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
perhapsSetRTC(ourQuality, &tv);
|
perhapsSetRTC(RTCQualityDevice, &tv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
powerMonInit();
|
powerMonInit();
|
||||||
@@ -1465,8 +1458,10 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAS_TRACKBALL) || (defined(INPUTDRIVER_ENCODER_TYPE) && INPUTDRIVER_ENCODER_TYPE == 2)
|
#if defined(HAS_TRACKBALL) || (defined(INPUTDRIVER_ENCODER_TYPE) && INPUTDRIVER_ENCODER_TYPE == 2)
|
||||||
|
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||||
osk_found = true;
|
osk_found = true;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WEBSERVER
|
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WEBSERVER
|
||||||
// Start web server thread.
|
// Start web server thread.
|
||||||
|
|||||||
@@ -96,8 +96,6 @@ class Channels
|
|||||||
|
|
||||||
bool setDefaultPresetCryptoForHash(ChannelHash channelHash);
|
bool setDefaultPresetCryptoForHash(ChannelHash channelHash);
|
||||||
|
|
||||||
int16_t getHash(ChannelIndex i) { return hashes[i]; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Given a channel index, change to use the crypto key specified by that index
|
/** Given a channel index, change to use the crypto key specified by that index
|
||||||
*
|
*
|
||||||
@@ -115,6 +113,8 @@ class Channels
|
|||||||
*/
|
*/
|
||||||
int16_t generateHash(ChannelIndex channelNum);
|
int16_t generateHash(ChannelIndex channelNum);
|
||||||
|
|
||||||
|
int16_t getHash(ChannelIndex i) { return hashes[i]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate a channel, fixing any errors as needed
|
* Validate a channel, fixing any errors as needed
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
|||||||
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
|
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
|
||||||
// bad.
|
// bad.
|
||||||
routingModule->sendAckNak(meshtastic_Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel,
|
routingModule->sendAckNak(meshtastic_Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel,
|
||||||
routingModule->getHopLimitForResponse(mp.hop_start, mp.hop_limit));
|
routingModule->getHopLimitForResponse(mp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to)
|
|||||||
assert(p->which_payload_variant == meshtastic_MeshPacket_decoded_tag); // Should already be set by now
|
assert(p->which_payload_variant == meshtastic_MeshPacket_decoded_tag); // Should already be set by now
|
||||||
p->to = getFrom(&to); // Make sure that if we are sending to the local node, we use our local node addr, not 0
|
p->to = getFrom(&to); // Make sure that if we are sending to the local node, we use our local node addr, not 0
|
||||||
p->channel = to.channel; // Use the same channel that the request came in on
|
p->channel = to.channel; // Use the same channel that the request came in on
|
||||||
p->hop_limit = routingModule->getHopLimitForResponse(to.hop_start, to.hop_limit);
|
p->hop_limit = routingModule->getHopLimitForResponse(to);
|
||||||
|
|
||||||
// No need for an ack if we are just delivering locally (it just generates an ignored ack)
|
// No need for an ack if we are just delivering locally (it just generates an ignored ack)
|
||||||
p->want_ack = (to.from != 0) ? to.want_ack : false;
|
p->want_ack = (to.from != 0) ? to.want_ack : false;
|
||||||
|
|||||||
@@ -93,11 +93,8 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
|
|||||||
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
|
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
|
||||||
nodeInfoModule && !isPreferredRebroadcaster && !nodeDB->isFull()) {
|
nodeInfoModule && !isPreferredRebroadcaster && !nodeDB->isFull()) {
|
||||||
if (airTime->isTxAllowedChannelUtil(true)) {
|
if (airTime->isTxAllowedChannelUtil(true)) {
|
||||||
// Hops used by the request. If somebody in between running modified firmware modified it, ignore it
|
const int8_t hopsUsed = getHopsAway(*mp, config.lora.hop_limit);
|
||||||
auto hopStart = mp->hop_start;
|
if (hopsUsed > (int32_t)(config.lora.hop_limit + 2)) {
|
||||||
auto hopLimit = mp->hop_limit;
|
|
||||||
uint8_t hopsUsed = hopStart < hopLimit ? config.lora.hop_limit : hopStart - hopLimit;
|
|
||||||
if (hopsUsed > config.lora.hop_limit + 2) {
|
|
||||||
LOG_DEBUG("Skip send NodeInfo: %d hops away is too far away", hopsUsed);
|
LOG_DEBUG("Skip send NodeInfo: %d hops away is too far away", hopsUsed);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Heard new node on ch. %d, send NodeInfo and ask for response", mp->channel);
|
LOG_INFO("Heard new node on ch. %d, send NodeInfo and ask for response", mp->channel);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ bool NextHopRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
perhapsRebroadcast(p);
|
perhapsRebroadcast(p);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool isRepeated = p->hop_start > 0 && p->hop_start == p->hop_limit;
|
bool isRepeated = getHopsAway(*p) == 0;
|
||||||
// If repeated and not in Tx queue anymore, try relaying again, or if we are the destination, send the ACK again
|
// If repeated and not in Tx queue anymore, try relaying again, or if we are the destination, send the ACK again
|
||||||
if (isRepeated) {
|
if (isRepeated) {
|
||||||
if (!findInTxQueue(p->from, p->id)) {
|
if (!findInTxQueue(p->from, p->id)) {
|
||||||
@@ -101,8 +101,7 @@ void NextHopRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtast
|
|||||||
bool wasAlreadyRelayer = wasRelayer(p->relay_node, p->decoded.request_id, p->to);
|
bool wasAlreadyRelayer = wasRelayer(p->relay_node, p->decoded.request_id, p->to);
|
||||||
bool weWereSoleRelayer = false;
|
bool weWereSoleRelayer = false;
|
||||||
bool weWereRelayer = wasRelayer(ourRelayID, p->decoded.request_id, p->to, &weWereSoleRelayer);
|
bool weWereRelayer = wasRelayer(ourRelayID, p->decoded.request_id, p->to, &weWereSoleRelayer);
|
||||||
if ((weWereRelayer && wasAlreadyRelayer) ||
|
if ((weWereRelayer && wasAlreadyRelayer) || (getHopsAway(*p) == 0 && weWereSoleRelayer)) {
|
||||||
(p->hop_start != 0 && p->hop_start == p->hop_limit && weWereSoleRelayer)) {
|
|
||||||
if (origTx->next_hop != p->relay_node) { // Not already set
|
if (origTx->next_hop != p->relay_node) { // Not already set
|
||||||
LOG_INFO("Update next hop of 0x%x to 0x%x based on ACK/reply (was relayer %d we were sole %d)", p->from,
|
LOG_INFO("Update next hop of 0x%x to 0x%x based on ACK/reply (was relayer %d we were sole %d)", p->from,
|
||||||
p->relay_node, wasAlreadyRelayer, weWereSoleRelayer);
|
p->relay_node, wasAlreadyRelayer, weWereSoleRelayer);
|
||||||
|
|||||||
@@ -805,7 +805,8 @@ void NodeDB::installDefaultModuleConfig()
|
|||||||
moduleConfig.external_notification.output_ms = 500;
|
moduleConfig.external_notification.output_ms = 500;
|
||||||
moduleConfig.external_notification.nag_timeout = 2;
|
moduleConfig.external_notification.nag_timeout = 2;
|
||||||
#endif
|
#endif
|
||||||
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE) || defined(ELECROW_ThinkNode_M3)
|
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE) || defined(ELECROW_ThinkNode_M3) || \
|
||||||
|
defined(ELECROW_ThinkNode_M6)
|
||||||
// Default to PIN_LED2 for external notification output (LED color depends on device variant)
|
// Default to PIN_LED2 for external notification output (LED color depends on device variant)
|
||||||
moduleConfig.external_notification.enabled = true;
|
moduleConfig.external_notification.enabled = true;
|
||||||
moduleConfig.external_notification.output = PIN_LED2;
|
moduleConfig.external_notification.output = PIN_LED2;
|
||||||
@@ -1548,6 +1549,23 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
|
|||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t getHopsAway(const meshtastic_MeshPacket &p, int8_t defaultIfUnknown)
|
||||||
|
{
|
||||||
|
// Firmware prior to 2.3.0 (585805c) lacked a hop_start field. Firmware version 2.5.0 (bf34329) introduced a
|
||||||
|
// bitfield that is always present. Use the presence of the bitfield to determine if the origin's firmware
|
||||||
|
// version is guaranteed to have hop_start populated. Note that this can only be done for decoded packets as
|
||||||
|
// the bitfield is encrypted under the channel encryption key. For encrypted packets, this returns
|
||||||
|
// defaultIfUnknown when hop_start is 0.
|
||||||
|
if (p.hop_start == 0 && !(p.which_payload_variant == meshtastic_MeshPacket_decoded_tag && p.decoded.has_bitfield))
|
||||||
|
return defaultIfUnknown; // Cannot reliably determine the number of hops.
|
||||||
|
|
||||||
|
// Guard against invalid values.
|
||||||
|
if (p.hop_start < p.hop_limit)
|
||||||
|
return defaultIfUnknown;
|
||||||
|
|
||||||
|
return p.hop_start - p.hop_limit;
|
||||||
|
}
|
||||||
|
|
||||||
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
|
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
|
||||||
|
|
||||||
size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
|
size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
|
||||||
@@ -1800,9 +1818,10 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
|||||||
info->via_mqtt = mp.via_mqtt; // Store if we received this packet via MQTT
|
info->via_mqtt = mp.via_mqtt; // Store if we received this packet via MQTT
|
||||||
|
|
||||||
// If hopStart was set and there wasn't someone messing with the limit in the middle, add hopsAway
|
// If hopStart was set and there wasn't someone messing with the limit in the middle, add hopsAway
|
||||||
if (mp.hop_start != 0 && mp.hop_limit <= mp.hop_start) {
|
const int8_t hopsAway = getHopsAway(mp);
|
||||||
|
if (hopsAway >= 0) {
|
||||||
info->has_hops_away = true;
|
info->has_hops_away = true;
|
||||||
info->hops_away = mp.hop_start - mp.hop_limit;
|
info->hops_away = hopsAway;
|
||||||
}
|
}
|
||||||
sortMeshDB();
|
sortMeshDB();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,10 @@ uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n);
|
|||||||
/// Given a packet, return how many seconds in the past (vs now) it was received
|
/// Given a packet, return how many seconds in the past (vs now) it was received
|
||||||
uint32_t sinceReceived(const meshtastic_MeshPacket *p);
|
uint32_t sinceReceived(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
|
/// Given a packet, return the number of hops used to reach this node.
|
||||||
|
/// Returns defaultIfUnknown if the number of hops couldn't be determined.
|
||||||
|
int8_t getHopsAway(const meshtastic_MeshPacket &p, int8_t defaultIfUnknown = -1);
|
||||||
|
|
||||||
enum LoadFileResult {
|
enum LoadFileResult {
|
||||||
// Successfully opened the file
|
// Successfully opened the file
|
||||||
LOAD_SUCCESS = 1,
|
LOAD_SUCCESS = 1,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "ReliableRouter.h"
|
#include "ReliableRouter.h"
|
||||||
#include "Default.h"
|
#include "Default.h"
|
||||||
#include "MeshTypes.h"
|
#include "MeshTypes.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "memGet.h"
|
#include "memGet.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
@@ -108,12 +109,12 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
|
|||||||
// If this packet should always be ACKed reliably with want_ack back to the original sender, make sure we
|
// If this packet should always be ACKed reliably with want_ack back to the original sender, make sure we
|
||||||
// do that unconditionally.
|
// do that unconditionally.
|
||||||
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel,
|
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel,
|
||||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit), true);
|
routingModule->getHopLimitForResponse(*p), true);
|
||||||
} else if (!p->decoded.request_id && !p->decoded.reply_id) {
|
} else if (!p->decoded.request_id && !p->decoded.reply_id) {
|
||||||
// If it's not an ACK or a reply, send an ACK.
|
// If it's not an ACK or a reply, send an ACK.
|
||||||
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel,
|
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel,
|
||||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit));
|
routingModule->getHopLimitForResponse(*p));
|
||||||
} else if ((p->hop_start > 0 && p->hop_start == p->hop_limit) || p->next_hop != NO_NEXT_HOP_PREFERENCE) {
|
} else if ((getHopsAway(*p) == 0) || p->next_hop != NO_NEXT_HOP_PREFERENCE) {
|
||||||
// If we received the packet directly from the original sender, send a 0-hop ACK since the original sender
|
// If we received the packet directly from the original sender, send a 0-hop ACK since the original sender
|
||||||
// won't overhear any implicit ACKs. If we received the packet via NextHopRouter, also send a 0-hop ACK to
|
// won't overhear any implicit ACKs. If we received the packet via NextHopRouter, also send a 0-hop ACK to
|
||||||
// stop the immediate relayer's retransmissions.
|
// stop the immediate relayer's retransmissions.
|
||||||
@@ -123,11 +124,11 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
|
|||||||
(nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) {
|
(nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) {
|
||||||
LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY");
|
LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY");
|
||||||
sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(),
|
sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(),
|
||||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit));
|
routingModule->getHopLimitForResponse(*p));
|
||||||
} else {
|
} else {
|
||||||
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
|
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
|
||||||
sendAckNak(meshtastic_Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex(),
|
sendAckNak(meshtastic_Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex(),
|
||||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit));
|
routingModule->getHopLimitForResponse(*p));
|
||||||
}
|
}
|
||||||
} else if (p->next_hop == nodeDB->getLastByteOfNodeNum(getNodeNum()) && p->hop_limit > 0) {
|
} else if (p->next_hop == nodeDB->getLastByteOfNodeNum(getNodeNum()) && p->hop_limit > 0) {
|
||||||
// No wantAck, but we need to ACK with hop limit of 0 if we were the next hop to stop their retransmissions
|
// No wantAck, but we need to ACK with hop limit of 0 if we were the next hop to stop their retransmissions
|
||||||
|
|||||||
@@ -81,8 +81,7 @@ Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRA
|
|||||||
bool Router::shouldDecrementHopLimit(const meshtastic_MeshPacket *p)
|
bool Router::shouldDecrementHopLimit(const meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
// First hop MUST always decrement to prevent retry issues
|
// First hop MUST always decrement to prevent retry issues
|
||||||
bool isFirstHop = (p->hop_start != 0 && p->hop_start == p->hop_limit);
|
if (getHopsAway(*p) == 0) {
|
||||||
if (isFirstHop) {
|
|
||||||
return true; // Always decrement on first hop
|
return true; // Always decrement on first hop
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,7 +691,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
|
|
||||||
// Store a copy of encrypted packet for MQTT
|
// Store a copy of encrypted packet for MQTT
|
||||||
DEBUG_HEAP_BEFORE;
|
DEBUG_HEAP_BEFORE;
|
||||||
p_encrypted = packetPool.allocCopy(*p);
|
meshtastic_MeshPacket *p_encrypted = packetPool.allocCopy(*p);
|
||||||
DEBUG_HEAP_AFTER("Router::handleReceived", p_encrypted);
|
DEBUG_HEAP_AFTER("Router::handleReceived", p_encrypted);
|
||||||
|
|
||||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
||||||
@@ -745,20 +744,23 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
MeshModule::callModules(*p, src);
|
MeshModule::callModules(*p, src);
|
||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||||
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not to
|
if (p_encrypted == nullptr) {
|
||||||
// us (because we would be able to decrypt it)
|
LOG_WARN("p_encrypted is null, skipping MQTT publish");
|
||||||
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
|
} else {
|
||||||
!isBroadcast(p->to) && !isToUs(p))
|
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not
|
||||||
p_encrypted->pki_encrypted = true;
|
// to us (because we would be able to decrypt it)
|
||||||
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
|
||||||
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
|
!isBroadcast(p->to) && !isToUs(p))
|
||||||
!isFromUs(p) && mqtt)
|
p_encrypted->pki_encrypted = true;
|
||||||
mqtt->onSend(*p_encrypted, *p, p->channel);
|
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
||||||
|
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
|
||||||
|
!isFromUs(p) && mqtt)
|
||||||
|
mqtt->onSend(*p_encrypted, *p, p->channel);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
packetPool.release(p_encrypted); // Release the encrypted packet
|
packetPool.release(p_encrypted); // Release the encrypted packet
|
||||||
p_encrypted = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
|
void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
|
||||||
|
|||||||
@@ -91,9 +91,6 @@ class Router : protected concurrency::OSThread, protected PacketHistory
|
|||||||
before us */
|
before us */
|
||||||
uint32_t rxDupe = 0, txRelayCanceled = 0;
|
uint32_t rxDupe = 0, txRelayCanceled = 0;
|
||||||
|
|
||||||
// pointer to the encrypted packet
|
|
||||||
meshtastic_MeshPacket *p_encrypted = nullptr;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RoutingModule;
|
friend class RoutingModule;
|
||||||
|
|
||||||
|
|||||||
@@ -33,5 +33,3 @@ PB_BIND(meshtastic_KeyVerificationAdmin, meshtastic_KeyVerificationAdmin, AUTO)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,16 +16,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enum definitions */
|
/* Enum definitions */
|
||||||
/* Firmware update mode for OTA updates */
|
|
||||||
typedef enum _meshtastic_OTAMode {
|
|
||||||
/* Do not reboot into OTA mode */
|
|
||||||
meshtastic_OTAMode_NO_REBOOT_OTA = 0,
|
|
||||||
/* Reboot into OTA mode for BLE firmware update */
|
|
||||||
meshtastic_OTAMode_OTA_BLE = 1,
|
|
||||||
/* Reboot into OTA mode for WiFi firmware update */
|
|
||||||
meshtastic_OTAMode_OTA_WIFI = 2
|
|
||||||
} meshtastic_OTAMode;
|
|
||||||
|
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
typedef enum _meshtastic_AdminMessage_ConfigType {
|
typedef enum _meshtastic_AdminMessage_ConfigType {
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
@@ -268,13 +258,10 @@ typedef struct _meshtastic_AdminMessage {
|
|||||||
meshtastic_SharedContact add_contact;
|
meshtastic_SharedContact add_contact;
|
||||||
/* Initiate or respond to a key verification request */
|
/* Initiate or respond to a key verification request */
|
||||||
meshtastic_KeyVerificationAdmin key_verification;
|
meshtastic_KeyVerificationAdmin key_verification;
|
||||||
/* Tell the node to reboot into OTA mode for firmware update via BLE or WiFi (ESP32 only for now) */
|
|
||||||
meshtastic_OTAMode reboot_ota_mode;
|
|
||||||
/* Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. */
|
/* Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. */
|
||||||
int32_t factory_reset_device;
|
int32_t factory_reset_device;
|
||||||
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
||||||
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
|
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */
|
||||||
Deprecated in favor of reboot_ota_mode in 2.7.17 */
|
|
||||||
int32_t reboot_ota_seconds;
|
int32_t reboot_ota_seconds;
|
||||||
/* This message is only supported for the simulator Portduino build.
|
/* This message is only supported for the simulator Portduino build.
|
||||||
If received the simulator will exit successfully. */
|
If received the simulator will exit successfully. */
|
||||||
@@ -301,10 +288,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _meshtastic_OTAMode_MIN meshtastic_OTAMode_NO_REBOOT_OTA
|
|
||||||
#define _meshtastic_OTAMode_MAX meshtastic_OTAMode_OTA_WIFI
|
|
||||||
#define _meshtastic_OTAMode_ARRAYSIZE ((meshtastic_OTAMode)(meshtastic_OTAMode_OTA_WIFI+1))
|
|
||||||
|
|
||||||
#define _meshtastic_AdminMessage_ConfigType_MIN meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG
|
#define _meshtastic_AdminMessage_ConfigType_MIN meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG
|
||||||
#define _meshtastic_AdminMessage_ConfigType_MAX meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG
|
#define _meshtastic_AdminMessage_ConfigType_MAX meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG
|
||||||
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG+1))
|
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG+1))
|
||||||
@@ -326,7 +309,6 @@ extern "C" {
|
|||||||
#define meshtastic_AdminMessage_payload_variant_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
#define meshtastic_AdminMessage_payload_variant_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
||||||
#define meshtastic_AdminMessage_payload_variant_restore_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
#define meshtastic_AdminMessage_payload_variant_restore_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
||||||
#define meshtastic_AdminMessage_payload_variant_remove_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
#define meshtastic_AdminMessage_payload_variant_remove_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
||||||
#define meshtastic_AdminMessage_payload_variant_reboot_ota_mode_ENUMTYPE meshtastic_OTAMode
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -414,7 +396,6 @@ extern "C" {
|
|||||||
#define meshtastic_AdminMessage_commit_edit_settings_tag 65
|
#define meshtastic_AdminMessage_commit_edit_settings_tag 65
|
||||||
#define meshtastic_AdminMessage_add_contact_tag 66
|
#define meshtastic_AdminMessage_add_contact_tag 66
|
||||||
#define meshtastic_AdminMessage_key_verification_tag 67
|
#define meshtastic_AdminMessage_key_verification_tag 67
|
||||||
#define meshtastic_AdminMessage_reboot_ota_mode_tag 68
|
|
||||||
#define meshtastic_AdminMessage_factory_reset_device_tag 94
|
#define meshtastic_AdminMessage_factory_reset_device_tag 94
|
||||||
#define meshtastic_AdminMessage_reboot_ota_seconds_tag 95
|
#define meshtastic_AdminMessage_reboot_ota_seconds_tag 95
|
||||||
#define meshtastic_AdminMessage_exit_simulator_tag 96
|
#define meshtastic_AdminMessage_exit_simulator_tag 96
|
||||||
@@ -473,7 +454,6 @@ X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_ed
|
|||||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \
|
X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,add_contact,add_contact), 66) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,add_contact,add_contact), 66) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification,key_verification), 67) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification,key_verification), 67) \
|
||||||
X(a, STATIC, ONEOF, UENUM, (payload_variant,reboot_ota_mode,reboot_ota_mode), 68) \
|
|
||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \
|
||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \
|
X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ PB_BIND(meshtastic_Data, meshtastic_Data, 2)
|
|||||||
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_StoreForwardPlusPlus, meshtastic_StoreForwardPlusPlus, 2)
|
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
||||||
|
|
||||||
|
|
||||||
@@ -124,8 +121,6 @@ PB_BIND(meshtastic_ChunkedPayloadResponse, meshtastic_ChunkedPayloadResponse, AU
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -478,22 +478,6 @@ typedef enum _meshtastic_Routing_Error {
|
|||||||
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
|
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
|
||||||
} meshtastic_Routing_Error;
|
} meshtastic_Routing_Error;
|
||||||
|
|
||||||
/* Enum of message types */
|
|
||||||
typedef enum _meshtastic_StoreForwardPlusPlus_SFPP_message_type {
|
|
||||||
/* Send an announcement of the canonical tip of a chain */
|
|
||||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE = 0,
|
|
||||||
/* Query whether a specific link is on the chain */
|
|
||||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CHAIN_QUERY = 1,
|
|
||||||
/* Request the next link in the chain */
|
|
||||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_REQUEST = 3,
|
|
||||||
/* Provide a link to add to the chain */
|
|
||||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE = 4,
|
|
||||||
/* If we must fragment, send the first half */
|
|
||||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_FIRSTHALF = 5,
|
|
||||||
/* If we must fragment, send the second half */
|
|
||||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF = 6
|
|
||||||
} meshtastic_StoreForwardPlusPlus_SFPP_message_type;
|
|
||||||
|
|
||||||
/* The priority of this message for sending.
|
/* The priority of this message for sending.
|
||||||
Higher priorities are sent first (when managing the transmit queue).
|
Higher priorities are sent first (when managing the transmit queue).
|
||||||
This field is never sent over the air, it is only used internally inside of a local device node.
|
This field is never sent over the air, it is only used internally inside of a local device node.
|
||||||
@@ -798,32 +782,6 @@ typedef struct _meshtastic_KeyVerification {
|
|||||||
meshtastic_KeyVerification_hash2_t hash2;
|
meshtastic_KeyVerification_hash2_t hash2;
|
||||||
} meshtastic_KeyVerification;
|
} meshtastic_KeyVerification;
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_message_hash_t;
|
|
||||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_commit_hash_t;
|
|
||||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_root_hash_t;
|
|
||||||
typedef PB_BYTES_ARRAY_T(240) meshtastic_StoreForwardPlusPlus_message_t;
|
|
||||||
/* The actual over-the-mesh message doing store and forward++ */
|
|
||||||
typedef struct _meshtastic_StoreForwardPlusPlus {
|
|
||||||
/* Which message type is this */
|
|
||||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type sfpp_message_type;
|
|
||||||
/* The hash of the specific message */
|
|
||||||
meshtastic_StoreForwardPlusPlus_message_hash_t message_hash;
|
|
||||||
/* The hash of a link on a chain */
|
|
||||||
meshtastic_StoreForwardPlusPlus_commit_hash_t commit_hash;
|
|
||||||
/* the root hash of a chain */
|
|
||||||
meshtastic_StoreForwardPlusPlus_root_hash_t root_hash;
|
|
||||||
/* The encrypted bytes from a message */
|
|
||||||
meshtastic_StoreForwardPlusPlus_message_t message;
|
|
||||||
/* Message ID of the contained message */
|
|
||||||
uint32_t encapsulated_id;
|
|
||||||
/* Destination of the contained message */
|
|
||||||
uint32_t encapsulated_to;
|
|
||||||
/* Sender of the contained message */
|
|
||||||
uint32_t encapsulated_from;
|
|
||||||
/* The receive time of the message in question */
|
|
||||||
uint32_t encapsulated_rxtime;
|
|
||||||
} meshtastic_StoreForwardPlusPlus;
|
|
||||||
|
|
||||||
/* Waypoint message, used to share arbitrary locations across the mesh */
|
/* Waypoint message, used to share arbitrary locations across the mesh */
|
||||||
typedef struct _meshtastic_Waypoint {
|
typedef struct _meshtastic_Waypoint {
|
||||||
/* Id of the waypoint */
|
/* Id of the waypoint */
|
||||||
@@ -1352,10 +1310,6 @@ extern "C" {
|
|||||||
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
|
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
|
||||||
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
|
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
|
||||||
|
|
||||||
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE
|
|
||||||
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MAX meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF
|
|
||||||
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_ARRAYSIZE ((meshtastic_StoreForwardPlusPlus_SFPP_message_type)(meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF+1))
|
|
||||||
|
|
||||||
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
||||||
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
||||||
#define _meshtastic_MeshPacket_Priority_ARRAYSIZE ((meshtastic_MeshPacket_Priority)(meshtastic_MeshPacket_Priority_MAX+1))
|
#define _meshtastic_MeshPacket_Priority_ARRAYSIZE ((meshtastic_MeshPacket_Priority)(meshtastic_MeshPacket_Priority_MAX+1))
|
||||||
@@ -1384,8 +1338,6 @@ extern "C" {
|
|||||||
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_ENUMTYPE meshtastic_StoreForwardPlusPlus_SFPP_message_type
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
||||||
@@ -1428,7 +1380,6 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
||||||
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||||
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
||||||
#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
|
|
||||||
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||||
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||||
@@ -1460,7 +1411,6 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
||||||
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||||
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
||||||
#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
|
|
||||||
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||||
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||||
@@ -1539,15 +1489,6 @@ extern "C" {
|
|||||||
#define meshtastic_KeyVerification_nonce_tag 1
|
#define meshtastic_KeyVerification_nonce_tag 1
|
||||||
#define meshtastic_KeyVerification_hash1_tag 2
|
#define meshtastic_KeyVerification_hash1_tag 2
|
||||||
#define meshtastic_KeyVerification_hash2_tag 3
|
#define meshtastic_KeyVerification_hash2_tag 3
|
||||||
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_tag 1
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_message_hash_tag 2
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_commit_hash_tag 3
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_root_hash_tag 4
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_message_tag 5
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_id_tag 6
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_to_tag 7
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_from_tag 8
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_rxtime_tag 9
|
|
||||||
#define meshtastic_Waypoint_id_tag 1
|
#define meshtastic_Waypoint_id_tag 1
|
||||||
#define meshtastic_Waypoint_latitude_i_tag 2
|
#define meshtastic_Waypoint_latitude_i_tag 2
|
||||||
#define meshtastic_Waypoint_longitude_i_tag 3
|
#define meshtastic_Waypoint_longitude_i_tag 3
|
||||||
@@ -1764,19 +1705,6 @@ X(a, STATIC, SINGULAR, BYTES, hash2, 3)
|
|||||||
#define meshtastic_KeyVerification_CALLBACK NULL
|
#define meshtastic_KeyVerification_CALLBACK NULL
|
||||||
#define meshtastic_KeyVerification_DEFAULT NULL
|
#define meshtastic_KeyVerification_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UENUM, sfpp_message_type, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, BYTES, message_hash, 2) \
|
|
||||||
X(a, STATIC, SINGULAR, BYTES, commit_hash, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, BYTES, root_hash, 4) \
|
|
||||||
X(a, STATIC, SINGULAR, BYTES, message, 5) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_id, 6) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_to, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_from, 8) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_rxtime, 9)
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_CALLBACK NULL
|
|
||||||
#define meshtastic_StoreForwardPlusPlus_DEFAULT NULL
|
|
||||||
|
|
||||||
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
||||||
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
||||||
@@ -2052,7 +1980,6 @@ extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg;
|
|||||||
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Data_msg;
|
extern const pb_msgdesc_t meshtastic_Data_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_StoreForwardPlusPlus_msg;
|
|
||||||
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
||||||
@@ -2086,7 +2013,6 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
|||||||
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
||||||
#define meshtastic_Data_fields &meshtastic_Data_msg
|
#define meshtastic_Data_fields &meshtastic_Data_msg
|
||||||
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
||||||
#define meshtastic_StoreForwardPlusPlus_fields &meshtastic_StoreForwardPlusPlus_msg
|
|
||||||
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
||||||
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
||||||
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
||||||
@@ -2143,7 +2069,6 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
|||||||
#define meshtastic_QueueStatus_size 23
|
#define meshtastic_QueueStatus_size 23
|
||||||
#define meshtastic_RouteDiscovery_size 256
|
#define meshtastic_RouteDiscovery_size 256
|
||||||
#define meshtastic_Routing_size 259
|
#define meshtastic_Routing_size 259
|
||||||
#define meshtastic_StoreForwardPlusPlus_size 371
|
|
||||||
#define meshtastic_ToRadio_size 504
|
#define meshtastic_ToRadio_size 504
|
||||||
#define meshtastic_User_size 115
|
#define meshtastic_User_size 115
|
||||||
#define meshtastic_Waypoint_size 165
|
#define meshtastic_Waypoint_size 165
|
||||||
|
|||||||
@@ -86,11 +86,6 @@ typedef enum _meshtastic_PortNum {
|
|||||||
/* Paxcounter lib included in the firmware
|
/* Paxcounter lib included in the firmware
|
||||||
ENCODING: protobuf */
|
ENCODING: protobuf */
|
||||||
meshtastic_PortNum_PAXCOUNTER_APP = 34,
|
meshtastic_PortNum_PAXCOUNTER_APP = 34,
|
||||||
/* Store and Forward++ module included in the firmware
|
|
||||||
ENCODING: protobuf
|
|
||||||
This module is specifically for Native Linux nodes, and provides a Git-style
|
|
||||||
chain of messages. */
|
|
||||||
meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP = 35,
|
|
||||||
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
|
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
|
||||||
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
||||||
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
|
|||||||
} else {
|
} else {
|
||||||
LOG_DEBUG(" Ignoring dummy neighbor info packet (single neighbor with nodeId 0, snr 0)");
|
LOG_DEBUG(" Ignoring dummy neighbor info packet (single neighbor with nodeId 0, snr 0)");
|
||||||
}
|
}
|
||||||
} else if (mp.hop_start != 0 && mp.hop_start == mp.hop_limit) {
|
} else if (getHopsAway(mp) == 0) {
|
||||||
LOG_DEBUG("Get or create neighbor: %u with snr %f", mp.from, mp.rx_snr);
|
LOG_DEBUG("Get or create neighbor: %u with snr %f", mp.from, mp.rx_snr);
|
||||||
// If the hopLimit is the same as hopStart, then it is a neighbor
|
// If the hopLimit is the same as hopStart, then it is a neighbor
|
||||||
getOrCreateNeighbor(mp.from, mp.from, 0,
|
getOrCreateNeighbor(mp.from, mp.from, 0,
|
||||||
|
|||||||
@@ -429,7 +429,9 @@ int32_t PositionModule::runOnce()
|
|||||||
|
|
||||||
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
||||||
if (waitingForFreshPosition) {
|
if (waitingForFreshPosition) {
|
||||||
|
#ifdef GPS_DEBUG
|
||||||
LOG_DEBUG("Skip initial position send; no fresh position since boot");
|
LOG_DEBUG("Skip initial position send; no fresh position since boot");
|
||||||
|
#endif
|
||||||
} else if (nodeDB->hasValidPosition(node)) {
|
} else if (nodeDB->hasValidPosition(node)) {
|
||||||
lastGpsSend = now;
|
lastGpsSend = now;
|
||||||
|
|
||||||
|
|||||||
@@ -58,12 +58,11 @@ void RoutingModule::sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketI
|
|||||||
router->sendLocal(p); // we sometimes send directly to the local node
|
router->sendLocal(p); // we sometimes send directly to the local node
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t RoutingModule::getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit)
|
uint8_t RoutingModule::getHopLimitForResponse(const meshtastic_MeshPacket &mp)
|
||||||
{
|
{
|
||||||
if (hopStart != 0) {
|
const int8_t hopsUsed = getHopsAway(mp);
|
||||||
// Hops used by the request. If somebody in between running modified firmware modified it, ignore it
|
if (hopsUsed >= 0) {
|
||||||
uint8_t hopsUsed = hopStart < hopLimit ? config.lora.hop_limit : hopStart - hopLimit;
|
if (hopsUsed > (int32_t)(config.lora.hop_limit)) {
|
||||||
if (hopsUsed > config.lora.hop_limit) {
|
|
||||||
// In event mode, we never want to send packets with more than our default 3 hops.
|
// In event mode, we never want to send packets with more than our default 3 hops.
|
||||||
#if !(EVENTMODE) // This falls through to the default.
|
#if !(EVENTMODE) // This falls through to the default.
|
||||||
return hopsUsed; // If the request used more hops than the limit, use the same amount of hops
|
return hopsUsed; // If the request used more hops than the limit, use the same amount of hops
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class RoutingModule : public ProtobufModule<meshtastic_Routing>
|
|||||||
uint8_t hopLimit = 0);
|
uint8_t hopLimit = 0);
|
||||||
|
|
||||||
// Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response
|
// Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response
|
||||||
uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit);
|
uint8_t getHopLimitForResponse(const meshtastic_MeshPacket &mp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Router;
|
friend class Router;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ int StatusLEDModule::handleStatusUpdate(const meshtastic::Status *arg)
|
|||||||
switch (arg->getStatusType()) {
|
switch (arg->getStatusType()) {
|
||||||
case STATUS_TYPE_POWER: {
|
case STATUS_TYPE_POWER: {
|
||||||
meshtastic::PowerStatus *powerStatus = (meshtastic::PowerStatus *)arg;
|
meshtastic::PowerStatus *powerStatus = (meshtastic::PowerStatus *)arg;
|
||||||
if (powerStatus->getHasUSB()) {
|
if (powerStatus->getHasUSB() || powerStatus->getIsCharging()) {
|
||||||
power_state = charging;
|
power_state = charging;
|
||||||
if (powerStatus->getBatteryChargePercent() >= 100) {
|
if (powerStatus->getBatteryChargePercent() >= 100) {
|
||||||
power_state = charged;
|
power_state = charged;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "TraceRouteModule.h"
|
#include "TraceRouteModule.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
#include "graphics/ScreenFonts.h"
|
#include "graphics/ScreenFonts.h"
|
||||||
#include "graphics/SharedUIDisplay.h"
|
#include "graphics/SharedUIDisplay.h"
|
||||||
@@ -359,10 +360,10 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only insert unknown hops if hop_start is valid
|
// Only insert unknown hops if hop_start is valid
|
||||||
if (p.hop_start != 0 && p.hop_limit <= p.hop_start) {
|
const int8_t hopsTaken = getHopsAway(p);
|
||||||
uint8_t hopsTaken = p.hop_start - p.hop_limit;
|
if (hopsTaken >= 0) {
|
||||||
int8_t diff = hopsTaken - *route_count;
|
int8_t diff = hopsTaken - *route_count;
|
||||||
for (uint8_t i = 0; i < diff; i++) {
|
for (int8_t i = 0; i < diff; i++) {
|
||||||
if (*route_count < ROUTE_SIZE) {
|
if (*route_count < ROUTE_SIZE) {
|
||||||
route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop
|
route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop
|
||||||
*route_count += 1;
|
*route_count += 1;
|
||||||
@@ -370,7 +371,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
|
|||||||
}
|
}
|
||||||
// Add unknown SNR values if necessary
|
// Add unknown SNR values if necessary
|
||||||
diff = *route_count - *snr_count;
|
diff = *route_count - *snr_count;
|
||||||
for (uint8_t i = 0; i < diff; i++) {
|
for (int8_t i = 0; i < diff; i++) {
|
||||||
if (*snr_count < ROUTE_SIZE) {
|
if (*snr_count < ROUTE_SIZE) {
|
||||||
snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR
|
snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR
|
||||||
*snr_count += 1;
|
*snr_count += 1;
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
#include "NimBLEAdvertising.h"
|
#include "NimBLEAdvertising.h"
|
||||||
#ifdef CONFIG_BT_NIMBLE_EXT_ADV
|
|
||||||
#include "NimBLEExtAdvertising.h"
|
#include "NimBLEExtAdvertising.h"
|
||||||
#endif
|
|
||||||
#include "PowerStatus.h"
|
#include "PowerStatus.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
#include "host/ble_gap.h"
|
#include "host/ble_gap.h"
|
||||||
@@ -26,12 +26,15 @@
|
|||||||
#include "nimble/nimble/host/include/host/ble_gap.h"
|
#include "nimble/nimble/host/include/host/ble_gap.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr uint16_t kPreferredBleMtu = 517;
|
constexpr uint16_t kPreferredBleMtu = 517;
|
||||||
constexpr uint16_t kPreferredBleTxOctets = 251;
|
constexpr uint16_t kPreferredBleTxOctets = 251;
|
||||||
constexpr uint16_t kPreferredBleTxTimeUs = (kPreferredBleTxOctets + 14) * 8;
|
constexpr uint16_t kPreferredBleTxTimeUs = (kPreferredBleTxOctets + 14) * 8;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
// Debugging options: careful, they slow things down quite a bit!
|
// Debugging options: careful, they slow things down quite a bit!
|
||||||
// #define DEBUG_NIMBLE_ON_READ_TIMING // uncomment to time onRead duration
|
// #define DEBUG_NIMBLE_ON_READ_TIMING // uncomment to time onRead duration
|
||||||
@@ -310,9 +313,11 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
|
|||||||
{
|
{
|
||||||
PhoneAPI::onNowHasData(fromRadioNum);
|
PhoneAPI::onNowHasData(fromRadioNum);
|
||||||
|
|
||||||
#ifdef DEBUG_NIMBLE_NOTIFY
|
|
||||||
int currentNotifyCount = notifyCount.fetch_add(1);
|
int currentNotifyCount = notifyCount.fetch_add(1);
|
||||||
|
|
||||||
uint8_t cc = bleServer->getConnectedCount();
|
uint8_t cc = bleServer->getConnectedCount();
|
||||||
|
|
||||||
|
#ifdef DEBUG_NIMBLE_NOTIFY
|
||||||
// This logging slows things down when there are lots of packets going to the phone, like initial connection:
|
// This logging slows things down when there are lots of packets going to the phone, like initial connection:
|
||||||
LOG_DEBUG("BLE notify(%d) fromNum: %d connections: %d", currentNotifyCount, fromRadioNum, cc);
|
LOG_DEBUG("BLE notify(%d) fromNum: %d connections: %d", currentNotifyCount, fromRadioNum, cc);
|
||||||
#endif
|
#endif
|
||||||
@@ -321,7 +326,13 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
|
|||||||
put_le32(val, fromRadioNum);
|
put_le32(val, fromRadioNum);
|
||||||
|
|
||||||
fromNumCharacteristic->setValue(val, sizeof(val));
|
fromNumCharacteristic->setValue(val, sizeof(val));
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
|
// NOTE: I don't have any NIMBLE_TWO devices, but this line makes me suspicious, and I suspect it needs to just be
|
||||||
|
// notify().
|
||||||
fromNumCharacteristic->notify(val, sizeof(val), BLE_HS_CONN_HANDLE_NONE);
|
fromNumCharacteristic->notify(val, sizeof(val), BLE_HS_CONN_HANDLE_NONE);
|
||||||
|
#else
|
||||||
|
fromNumCharacteristic->notify();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check the current underlying physical link to see if the client is currently connected
|
/// Check the current underlying physical link to see if the client is currently connected
|
||||||
@@ -386,7 +397,12 @@ static uint8_t lastToRadio[MAX_TO_FROM_RADIO_SIZE];
|
|||||||
|
|
||||||
class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
||||||
{
|
{
|
||||||
void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &) override
|
#ifdef NIMBLE_TWO
|
||||||
|
virtual void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
|
||||||
|
#else
|
||||||
|
virtual void onWrite(NimBLECharacteristic *pCharacteristic)
|
||||||
|
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
||||||
// Assumption: onWrite is serialized by NimBLE, so we don't need to lock here against multiple concurrent onWrite calls.
|
// Assumption: onWrite is serialized by NimBLE, so we don't need to lock here against multiple concurrent onWrite calls.
|
||||||
@@ -433,7 +449,11 @@ class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
|||||||
|
|
||||||
class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks
|
class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks
|
||||||
{
|
{
|
||||||
void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &) override
|
#ifdef NIMBLE_TWO
|
||||||
|
virtual void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
|
||||||
|
#else
|
||||||
|
virtual void onRead(NimBLECharacteristic *pCharacteristic)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
||||||
|
|
||||||
@@ -541,27 +561,32 @@ class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks
|
|||||||
|
|
||||||
class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||||
{
|
{
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
public:
|
public:
|
||||||
explicit NimbleBluetoothServerCallback(NimbleBluetooth *ble) : ble(ble) {}
|
NimbleBluetoothServerCallback(NimbleBluetooth *ble) { this->ble = ble; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NimbleBluetooth *ble;
|
NimbleBluetooth *ble;
|
||||||
|
|
||||||
uint32_t onPassKeyDisplay() override
|
virtual uint32_t onPassKeyDisplay()
|
||||||
|
#else
|
||||||
|
virtual uint32_t onPassKeyRequest()
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
uint32_t passkey = config.bluetooth.fixed_pin;
|
uint32_t passkey = config.bluetooth.fixed_pin;
|
||||||
|
|
||||||
if (config.bluetooth.mode == meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
|
if (config.bluetooth.mode == meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
|
||||||
LOG_INFO("Use random passkey");
|
LOG_INFO("Use random passkey");
|
||||||
|
// This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
|
||||||
passkey = random(100000, 999999);
|
passkey = random(100000, 999999);
|
||||||
}
|
}
|
||||||
LOG_INFO("*** Enter passkey %06u on the peer side ***", passkey);
|
LOG_INFO("*** Enter passkey %d on the peer side ***", passkey);
|
||||||
|
|
||||||
powerFSM.trigger(EVENT_BLUETOOTH_PAIR);
|
powerFSM.trigger(EVENT_BLUETOOTH_PAIR);
|
||||||
meshtastic::BluetoothStatus newStatus(std::to_string(passkey));
|
meshtastic::BluetoothStatus newStatus(std::to_string(passkey));
|
||||||
bluetoothStatus->updateStatus(&newStatus);
|
bluetoothStatus->updateStatus(&newStatus);
|
||||||
|
|
||||||
#if HAS_SCREEN
|
#if HAS_SCREEN // Todo: migrate this display code back into Screen class, and observe bluetoothStatus
|
||||||
if (screen) {
|
if (screen) {
|
||||||
screen->startAlert([passkey](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
screen->startAlert([passkey](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||||
char btPIN[16] = "888888";
|
char btPIN[16] = "888888";
|
||||||
@@ -590,29 +615,39 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
passkeyShowing = true;
|
passkeyShowing = true;
|
||||||
|
|
||||||
return passkey;
|
return passkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAuthenticationComplete(NimBLEConnInfo &connInfo) override
|
#ifdef NIMBLE_TWO
|
||||||
|
virtual void onAuthenticationComplete(NimBLEConnInfo &connInfo)
|
||||||
|
#else
|
||||||
|
virtual void onAuthenticationComplete(ble_gap_conn_desc *desc)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
LOG_INFO("BLE authentication complete");
|
LOG_INFO("BLE authentication complete");
|
||||||
|
|
||||||
meshtastic::BluetoothStatus newStatus(meshtastic::BluetoothStatus::ConnectionState::CONNECTED);
|
meshtastic::BluetoothStatus newStatus(meshtastic::BluetoothStatus::ConnectionState::CONNECTED);
|
||||||
bluetoothStatus->updateStatus(&newStatus);
|
bluetoothStatus->updateStatus(&newStatus);
|
||||||
|
|
||||||
|
// Todo: migrate this display code back into Screen class, and observe bluetoothStatus
|
||||||
if (passkeyShowing) {
|
if (passkeyShowing) {
|
||||||
passkeyShowing = false;
|
passkeyShowing = false;
|
||||||
if (screen) {
|
if (screen)
|
||||||
screen->endAlert();
|
screen->endAlert();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store the connection handle for future use
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
nimbleBluetoothConnHandle = connInfo.getConnHandle();
|
nimbleBluetoothConnHandle = connInfo.getConnHandle();
|
||||||
|
#else
|
||||||
|
nimbleBluetoothConnHandle = desc->conn_handle;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo) override
|
#ifdef NIMBLE_TWO
|
||||||
|
virtual void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo)
|
||||||
{
|
{
|
||||||
LOG_INFO("BLE incoming connection %s", connInfo.getAddress().toString().c_str());
|
LOG_INFO("BLE incoming connection %s", connInfo.getAddress().toString().c_str());
|
||||||
|
|
||||||
@@ -637,12 +672,21 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
|||||||
LOG_INFO("BLE conn %u initial MTU %u (target %u)", connHandle, connInfo.getMTU(), kPreferredBleMtu);
|
LOG_INFO("BLE conn %u initial MTU %u (target %u)", connHandle, connInfo.getMTU(), kPreferredBleMtu);
|
||||||
pServer->updateConnParams(connHandle, 6, 12, 0, 200);
|
pServer->updateConnParams(connHandle, 6, 12, 0, 200);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason) override
|
#ifdef NIMBLE_TWO
|
||||||
|
virtual void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason)
|
||||||
{
|
{
|
||||||
LOG_INFO("BLE disconnect reason: %d", reason);
|
LOG_INFO("BLE disconnect reason: %d", reason);
|
||||||
|
#else
|
||||||
|
virtual void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc)
|
||||||
|
{
|
||||||
|
LOG_INFO("BLE disconnect");
|
||||||
|
#endif
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
if (ble->isDeInit)
|
if (ble->isDeInit)
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
meshtastic::BluetoothStatus newStatus(meshtastic::BluetoothStatus::ConnectionState::DISCONNECTED);
|
meshtastic::BluetoothStatus newStatus(meshtastic::BluetoothStatus::ConnectionState::DISCONNECTED);
|
||||||
bluetoothStatus->updateStatus(&newStatus);
|
bluetoothStatus->updateStatus(&newStatus);
|
||||||
@@ -666,69 +710,35 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
|||||||
bluetoothPhoneAPI->writeCount = 0;
|
bluetoothPhoneAPI->writeCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear the last ToRadio packet buffer to avoid rejecting first packet from new connection
|
||||||
memset(lastToRadio, 0, sizeof(lastToRadio));
|
memset(lastToRadio, 0, sizeof(lastToRadio));
|
||||||
|
|
||||||
nimbleBluetoothConnHandle = BLE_HS_CONN_HANDLE_NONE;
|
nimbleBluetoothConnHandle = BLE_HS_CONN_HANDLE_NONE; // BLE_HS_CONN_HANDLE_NONE means "no connection"
|
||||||
|
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
|
// Restart Advertising
|
||||||
ble->startAdvertising();
|
ble->startAdvertising();
|
||||||
|
#else
|
||||||
|
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||||
|
if (!pAdvertising->start(0)) {
|
||||||
|
if (pAdvertising->isAdvertising()) {
|
||||||
|
LOG_DEBUG("BLE advertising already running");
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("BLE failed to restart advertising");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static NimbleBluetoothToRadioCallback *toRadioCallbacks;
|
static NimbleBluetoothToRadioCallback *toRadioCallbacks;
|
||||||
static NimbleBluetoothFromRadioCallback *fromRadioCallbacks;
|
static NimbleBluetoothFromRadioCallback *fromRadioCallbacks;
|
||||||
|
|
||||||
void NimbleBluetooth::startAdvertising()
|
|
||||||
{
|
|
||||||
#if defined(CONFIG_BT_NIMBLE_EXT_ADV)
|
|
||||||
NimBLEExtAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
|
||||||
NimBLEExtAdvertisement legacyAdvertising;
|
|
||||||
|
|
||||||
legacyAdvertising.setLegacyAdvertising(true);
|
|
||||||
legacyAdvertising.setScannable(true);
|
|
||||||
legacyAdvertising.setConnectable(true);
|
|
||||||
legacyAdvertising.setFlags(BLE_HS_ADV_F_DISC_GEN);
|
|
||||||
if (powerStatus->getHasBattery() == 1) {
|
|
||||||
legacyAdvertising.setCompleteServices(NimBLEUUID((uint16_t)0x180f));
|
|
||||||
}
|
|
||||||
legacyAdvertising.setCompleteServices(NimBLEUUID(MESH_SERVICE_UUID));
|
|
||||||
legacyAdvertising.setMinInterval(500);
|
|
||||||
legacyAdvertising.setMaxInterval(1000);
|
|
||||||
|
|
||||||
NimBLEExtAdvertisement legacyScanResponse;
|
|
||||||
legacyScanResponse.setLegacyAdvertising(true);
|
|
||||||
legacyScanResponse.setConnectable(true);
|
|
||||||
legacyScanResponse.setName(getDeviceName());
|
|
||||||
|
|
||||||
if (!pAdvertising->setInstanceData(0, legacyAdvertising)) {
|
|
||||||
LOG_ERROR("BLE failed to set legacyAdvertising");
|
|
||||||
} else if (!pAdvertising->setScanResponseData(0, legacyScanResponse)) {
|
|
||||||
LOG_ERROR("BLE failed to set legacyScanResponse");
|
|
||||||
} else if (!pAdvertising->start(0, 0, 0)) {
|
|
||||||
LOG_ERROR("BLE failed to start legacyAdvertising");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
|
||||||
pAdvertising->reset();
|
|
||||||
pAdvertising->addServiceUUID(MESH_SERVICE_UUID);
|
|
||||||
if (powerStatus->getHasBattery() == 1) {
|
|
||||||
pAdvertising->addServiceUUID(NimBLEUUID((uint16_t)0x180f));
|
|
||||||
}
|
|
||||||
|
|
||||||
NimBLEAdvertisementData scan;
|
|
||||||
scan.setName(getDeviceName());
|
|
||||||
pAdvertising->setScanResponseData(scan);
|
|
||||||
pAdvertising->enableScanResponse(true);
|
|
||||||
|
|
||||||
if (!pAdvertising->start(0)) {
|
|
||||||
LOG_ERROR("BLE failed to start advertising");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
LOG_DEBUG("BLE Advertising started");
|
|
||||||
}
|
|
||||||
|
|
||||||
void NimbleBluetooth::shutdown()
|
void NimbleBluetooth::shutdown()
|
||||||
{
|
{
|
||||||
|
// No measurable power saving for ESP32 during light-sleep(?)
|
||||||
#ifndef ARCH_ESP32
|
#ifndef ARCH_ESP32
|
||||||
|
// Shutdown bluetooth for minimum power draw
|
||||||
LOG_INFO("Disable bluetooth");
|
LOG_INFO("Disable bluetooth");
|
||||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||||
pAdvertising->reset();
|
pAdvertising->reset();
|
||||||
@@ -736,6 +746,7 @@ void NimbleBluetooth::shutdown()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Proper shutdown for ESP32. Needs reboot to reverse.
|
||||||
void NimbleBluetooth::deinit()
|
void NimbleBluetooth::deinit()
|
||||||
{
|
{
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
@@ -749,17 +760,21 @@ void NimbleBluetooth::deinit()
|
|||||||
digitalWrite(BLE_LED, LOW);
|
digitalWrite(BLE_LED, LOW);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NIMBLE_TWO
|
||||||
|
NimBLEDevice::deinit();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has initial setup been completed
|
||||||
bool NimbleBluetooth::isActive()
|
bool NimbleBluetooth::isActive()
|
||||||
{
|
{
|
||||||
return bleServer != nullptr;
|
return bleServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NimbleBluetooth::isConnected()
|
bool NimbleBluetooth::isConnected()
|
||||||
{
|
{
|
||||||
return bleServer && bleServer->getConnectedCount() > 0;
|
return bleServer->getConnectedCount() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NimbleBluetooth::getRssi()
|
int NimbleBluetooth::getRssi()
|
||||||
@@ -803,7 +818,7 @@ void NimbleBluetooth::setup()
|
|||||||
LOG_INFO("Init the NimBLE bluetooth module");
|
LOG_INFO("Init the NimBLE bluetooth module");
|
||||||
|
|
||||||
NimBLEDevice::init(getDeviceName());
|
NimBLEDevice::init(getDeviceName());
|
||||||
NimBLEDevice::setPower(9);
|
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
|
||||||
|
|
||||||
#if NIMBLE_ENABLE_2M_PHY && (defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6))
|
#if NIMBLE_ENABLE_2M_PHY && (defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6))
|
||||||
int mtuResult = NimBLEDevice::setMTU(kPreferredBleMtu);
|
int mtuResult = NimBLEDevice::setMTU(kPreferredBleMtu);
|
||||||
@@ -836,7 +851,11 @@ void NimbleBluetooth::setup()
|
|||||||
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
||||||
}
|
}
|
||||||
bleServer = NimBLEDevice::createServer();
|
bleServer = NimBLEDevice::createServer();
|
||||||
auto *serverCallbacks = new NimbleBluetoothServerCallback(this);
|
#ifdef NIMBLE_TWO
|
||||||
|
NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback(this);
|
||||||
|
#else
|
||||||
|
NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback();
|
||||||
|
#endif
|
||||||
bleServer->setCallbacks(serverCallbacks, true);
|
bleServer->setCallbacks(serverCallbacks, true);
|
||||||
setupService();
|
setupService();
|
||||||
startAdvertising();
|
startAdvertising();
|
||||||
@@ -881,7 +900,11 @@ void NimbleBluetooth::setupService()
|
|||||||
NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
||||||
BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic)
|
BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic)
|
||||||
(uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY, 1);
|
(uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY, 1);
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
NimBLE2904 *batteryLevelDescriptor = BatteryCharacteristic->create2904();
|
NimBLE2904 *batteryLevelDescriptor = BatteryCharacteristic->create2904();
|
||||||
|
#else
|
||||||
|
NimBLE2904 *batteryLevelDescriptor = (NimBLE2904 *)BatteryCharacteristic->createDescriptor((uint16_t)0x2904);
|
||||||
|
#endif
|
||||||
batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
|
batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
|
||||||
batteryLevelDescriptor->setNamespace(1);
|
batteryLevelDescriptor->setNamespace(1);
|
||||||
batteryLevelDescriptor->setUnit(0x27ad);
|
batteryLevelDescriptor->setUnit(0x27ad);
|
||||||
@@ -889,12 +912,54 @@ void NimbleBluetooth::setupService()
|
|||||||
batteryService->start();
|
batteryService->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NimbleBluetooth::startAdvertising()
|
||||||
|
{
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
|
NimBLEExtAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||||
|
NimBLEExtAdvertisement legacyAdvertising;
|
||||||
|
|
||||||
|
legacyAdvertising.setLegacyAdvertising(true);
|
||||||
|
legacyAdvertising.setScannable(true);
|
||||||
|
legacyAdvertising.setConnectable(true);
|
||||||
|
legacyAdvertising.setFlags(BLE_HS_ADV_F_DISC_GEN);
|
||||||
|
if (powerStatus->getHasBattery() == 1) {
|
||||||
|
legacyAdvertising.setCompleteServices(NimBLEUUID((uint16_t)0x180f));
|
||||||
|
}
|
||||||
|
legacyAdvertising.setCompleteServices(NimBLEUUID(MESH_SERVICE_UUID));
|
||||||
|
legacyAdvertising.setMinInterval(500);
|
||||||
|
legacyAdvertising.setMaxInterval(1000);
|
||||||
|
|
||||||
|
NimBLEExtAdvertisement legacyScanResponse;
|
||||||
|
legacyScanResponse.setLegacyAdvertising(true);
|
||||||
|
legacyScanResponse.setConnectable(true);
|
||||||
|
legacyScanResponse.setName(getDeviceName());
|
||||||
|
|
||||||
|
if (!pAdvertising->setInstanceData(0, legacyAdvertising)) {
|
||||||
|
LOG_ERROR("BLE failed to set legacyAdvertising");
|
||||||
|
} else if (!pAdvertising->setScanResponseData(0, legacyScanResponse)) {
|
||||||
|
LOG_ERROR("BLE failed to set legacyScanResponse");
|
||||||
|
} else if (!pAdvertising->start(0, 0, 0)) {
|
||||||
|
LOG_ERROR("BLE failed to start legacyAdvertising");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||||
|
pAdvertising->reset();
|
||||||
|
pAdvertising->addServiceUUID(MESH_SERVICE_UUID);
|
||||||
|
pAdvertising->addServiceUUID(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
||||||
|
pAdvertising->start(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a level between 0-100, update the BLE attribute
|
/// Given a level between 0-100, update the BLE attribute
|
||||||
void updateBatteryLevel(uint8_t level)
|
void updateBatteryLevel(uint8_t level)
|
||||||
{
|
{
|
||||||
if ((config.bluetooth.enabled == true) && bleServer && nimbleBluetooth->isConnected()) {
|
if ((config.bluetooth.enabled == true) && bleServer && nimbleBluetooth->isConnected()) {
|
||||||
BatteryCharacteristic->setValue(&level, 1);
|
BatteryCharacteristic->setValue(&level, 1);
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
BatteryCharacteristic->notify(&level, 1, BLE_HS_CONN_HANDLE_NONE);
|
BatteryCharacteristic->notify(&level, 1, BLE_HS_CONN_HANDLE_NONE);
|
||||||
|
#else
|
||||||
|
BatteryCharacteristic->notify();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -909,7 +974,11 @@ void NimbleBluetooth::sendLog(const uint8_t *logMessage, size_t length)
|
|||||||
if (!bleServer || !isConnected() || length > 512) {
|
if (!bleServer || !isConnected() || length > 512) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef NIMBLE_TWO
|
||||||
logRadioCharacteristic->notify(logMessage, length, BLE_HS_CONN_HANDLE_NONE);
|
logRadioCharacteristic->notify(logMessage, length, BLE_HS_CONN_HANDLE_NONE);
|
||||||
|
#else
|
||||||
|
logRadioCharacteristic->notify(logMessage, length, true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearNVS()
|
void clearNVS()
|
||||||
|
|||||||
@@ -12,11 +12,16 @@ class NimbleBluetooth : BluetoothApi
|
|||||||
bool isConnected();
|
bool isConnected();
|
||||||
int getRssi();
|
int getRssi();
|
||||||
void sendLog(const uint8_t *logMessage, size_t length);
|
void sendLog(const uint8_t *logMessage, size_t length);
|
||||||
|
#if defined(NIMBLE_TWO)
|
||||||
void startAdvertising();
|
void startAdvertising();
|
||||||
|
#endif
|
||||||
bool isDeInit = false;
|
bool isDeInit = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupService();
|
void setupService();
|
||||||
|
#if !defined(NIMBLE_TWO)
|
||||||
|
void startAdvertising();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void setBluetoothEnable(bool enable);
|
void setBluetoothEnable(bool enable);
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ void portduinoSetup()
|
|||||||
// RAK6421-13300-S1:aabbcc123456:5ba85807d92138b7519cfb60460573af:3061e8d8
|
// RAK6421-13300-S1:aabbcc123456:5ba85807d92138b7519cfb60460573af:3061e8d8
|
||||||
// <model string>:mac address :<16 random unique bytes in hexidecimal> : crc32
|
// <model string>:mac address :<16 random unique bytes in hexidecimal> : crc32
|
||||||
// crc32 is calculated on the eeprom string up to but not including the final colon
|
// crc32 is calculated on the eeprom string up to but not including the final colon
|
||||||
if (strlen(autoconf_product) < 6) {
|
if (strlen(autoconf_product) < 6 && portduino_config.i2cdev != "") {
|
||||||
try {
|
try {
|
||||||
char *mac_start = nullptr;
|
char *mac_start = nullptr;
|
||||||
char *devID_start = nullptr;
|
char *devID_start = nullptr;
|
||||||
@@ -867,4 +867,4 @@ void readGPIOFromYaml(YAML::Node sourceNode, pinMapping &destPin, int pinDefault
|
|||||||
destPin.line = destPin.pin;
|
destPin.line = destPin.pin;
|
||||||
destPin.gpiochip = portduino_config.lora_default_gpiochip;
|
destPin.gpiochip = portduino_config.lora_default_gpiochip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <libpinedio-usb.h>
|
#include <libpinedio-usb.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
extern "C" {
|
|
||||||
#include "platform/portduino/ch341a_i2c.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
// include the library for Raspberry GPIO pins
|
// include the library for Raspberry GPIO pins
|
||||||
|
|
||||||
@@ -50,9 +47,6 @@ class Ch341Hal : public RadioLibHal
|
|||||||
std::string s = "Could not open SPI: ";
|
std::string s = "Could not open SPI: ";
|
||||||
throw(s + std::to_string(ret));
|
throw(s + std::to_string(ret));
|
||||||
}
|
}
|
||||||
// How to read the eeprom
|
|
||||||
// uint8_t buffer[1024] = {0};
|
|
||||||
// ch341readEEPROM_param(buffer, 0, 128, 128, 8, 1, 0x50, pinedio.handle);
|
|
||||||
|
|
||||||
pinedio_set_option(&pinedio, PINEDIO_OPTION_AUTO_CS, 0);
|
pinedio_set_option(&pinedio, PINEDIO_OPTION_AUTO_CS, 0);
|
||||||
pinedio_set_pin_mode(&pinedio, 3, true);
|
pinedio_set_pin_mode(&pinedio, 3, true);
|
||||||
|
|||||||
@@ -1,204 +0,0 @@
|
|||||||
//
|
|
||||||
// ch341eeprom programmer version 0.1 (Beta)
|
|
||||||
//
|
|
||||||
// Programming tool for the 24Cxx serial EEPROMs using the Winchiphead CH341A IC
|
|
||||||
//
|
|
||||||
// (c) December 2011 asbokid <ballymunboy@gmail.com>
|
|
||||||
// (c) August 2023 Mikhail Medvedev <e-ink-reader@yandex.ru>
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "ch341a_i2c.h"
|
|
||||||
|
|
||||||
// extern struct libusb_device_handle *handle;
|
|
||||||
unsigned char *readbuf;
|
|
||||||
uint32_t getnextpkt; // set by the callback function
|
|
||||||
uint32_t syncackpkt; // synch / ack flag used by BULK OUT cb function
|
|
||||||
uint32_t byteoffset;
|
|
||||||
|
|
||||||
// callback functions for async USB transfers
|
|
||||||
static void cbBulkIn(struct libusb_transfer *transfer);
|
|
||||||
static void cbBulkOut(struct libusb_transfer *transfer);
|
|
||||||
|
|
||||||
void ch341ReadCmdMarshall(uint8_t *buffer, uint32_t addr, struct EEPROM *eeprom_info, uint32_t i2c_address)
|
|
||||||
{
|
|
||||||
uint8_t *ptr = buffer;
|
|
||||||
uint8_t msb_addr;
|
|
||||||
uint32_t size_kb;
|
|
||||||
|
|
||||||
*ptr++ = CH341_CMD_I2C_STREAM; // 0
|
|
||||||
*ptr++ = CH341_CMD_I2C_STM_STA; // 1
|
|
||||||
// Write address
|
|
||||||
*ptr++ = CH341_CMD_I2C_STM_OUT | ((*eeprom_info).addr_size + 1); // 2: I2C bus adddress + EEPROM address
|
|
||||||
if ((*eeprom_info).addr_size >= 2) {
|
|
||||||
// 24C32 and more
|
|
||||||
msb_addr = addr >> 16 & (*eeprom_info).i2c_addr_mask;
|
|
||||||
*ptr++ = (i2c_address | msb_addr) << 1; // 3
|
|
||||||
*ptr++ = (addr >> 8 & 0xFF); // 4
|
|
||||||
*ptr++ = (addr >> 0 & 0xFF); // 5
|
|
||||||
} else {
|
|
||||||
// 24C16 and less
|
|
||||||
msb_addr = addr >> 8 & (*eeprom_info).i2c_addr_mask;
|
|
||||||
*ptr++ = (i2c_address | msb_addr) << 1; // 3
|
|
||||||
*ptr++ = (addr >> 0 & 0xFF); // 4
|
|
||||||
}
|
|
||||||
// Read
|
|
||||||
*ptr++ = CH341_CMD_I2C_STM_STA; // 6/5
|
|
||||||
*ptr++ = CH341_CMD_I2C_STM_OUT | 1; // 7/6
|
|
||||||
*ptr++ = ((i2c_address | msb_addr) << 1) | 1; // 8/7: Read command
|
|
||||||
|
|
||||||
// Configuration?
|
|
||||||
*ptr++ = 0xE0; // 9/8
|
|
||||||
*ptr++ = 0x00; // 10/9
|
|
||||||
if ((*eeprom_info).addr_size < 2)
|
|
||||||
*ptr++ = 0x10; // x/10
|
|
||||||
memcpy(ptr, "\x00\x06\x04\x00\x00\x00\x00\x00\x00", 9);
|
|
||||||
ptr += 9; // 10
|
|
||||||
size_kb = (*eeprom_info).size / 1024;
|
|
||||||
*ptr++ = size_kb & 0xFF; // 19
|
|
||||||
*ptr++ = (size_kb >> 8) & 0xFF; // 20
|
|
||||||
memcpy(ptr, "\x00\x00\x11\x4d\x40\x77\xcd\xab\xba\xdc", 10);
|
|
||||||
ptr += 10;
|
|
||||||
|
|
||||||
// Frame 2
|
|
||||||
*ptr++ = CH341_CMD_I2C_STREAM;
|
|
||||||
memcpy(ptr,
|
|
||||||
"\xe0\x00\x00\xc4\xf1\x12\x00\x11\x4d\x40\x77\xf0\xf1\x12\x00"
|
|
||||||
"\xd9\x8b\x41\x7e\x00\xe0\xfd\x7f\xf0\xf1\x12\x00\x5a\x88\x41\x7e",
|
|
||||||
31);
|
|
||||||
ptr += 31;
|
|
||||||
|
|
||||||
// Frame 3
|
|
||||||
*ptr++ = CH341_CMD_I2C_STREAM;
|
|
||||||
memcpy(ptr,
|
|
||||||
"\xe0\x00\x00\x2a\x88\x41\x7e\x06\x04\x00\x00\x11\x4d\x40\x77"
|
|
||||||
"\xe8\xf3\x12\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00",
|
|
||||||
31);
|
|
||||||
ptr += 31;
|
|
||||||
|
|
||||||
// Finalize
|
|
||||||
*ptr++ = CH341_CMD_I2C_STREAM; // 0xAA
|
|
||||||
*ptr++ = 0xDF; // ???
|
|
||||||
*ptr++ = CH341_CMD_I2C_STM_IN; // 0xC0
|
|
||||||
*ptr++ = CH341_CMD_I2C_STM_STO; // 0x75
|
|
||||||
*ptr++ = CH341_CMD_I2C_STM_END; // 0x00
|
|
||||||
|
|
||||||
assert(ptr - buffer == CH341_EEPROM_READ_CMD_SZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ch341readEEPROM()
|
|
||||||
// read n bytes from device (in packets of 32 bytes)
|
|
||||||
int32_t ch341readEEPROM_param(uint8_t *buffer, uint32_t offset, uint32_t bytestoread, uint32_t ic_size, uint32_t block_size,
|
|
||||||
uint8_t algorithm, uint32_t i2c_address, struct libusb_device_handle *handle)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t ch341outBuffer[EEPROM_READ_BULKOUT_BUF_SZ];
|
|
||||||
uint8_t ch341inBuffer[IN_BUF_SZ]; // 0x100 bytes
|
|
||||||
int32_t ret = 0, readpktcount = 0;
|
|
||||||
struct libusb_transfer *xferBulkIn, *xferBulkOut;
|
|
||||||
struct timeval tv = {0, 100}; // our async polling interval
|
|
||||||
struct EEPROM eeprom_info;
|
|
||||||
eeprom_info.name = "24c01";
|
|
||||||
eeprom_info.size = ic_size;
|
|
||||||
eeprom_info.page_size = (uint16_t)block_size;
|
|
||||||
eeprom_info.addr_size = 0x0f & algorithm;
|
|
||||||
eeprom_info.i2c_addr_mask = (0xf0 & algorithm) / 16;
|
|
||||||
|
|
||||||
xferBulkIn = libusb_alloc_transfer(0);
|
|
||||||
xferBulkOut = libusb_alloc_transfer(0);
|
|
||||||
|
|
||||||
if (!xferBulkIn || !xferBulkOut) {
|
|
||||||
printf("Couldn't allocate USB transfer structures\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
byteoffset = 0;
|
|
||||||
|
|
||||||
memset(ch341inBuffer, 0, EEPROM_READ_BULKIN_BUF_SZ);
|
|
||||||
ch341ReadCmdMarshall(ch341outBuffer, offset, &eeprom_info, i2c_address); // Fill output buffer
|
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(xferBulkIn, handle, BULK_READ_ENDPOINT, ch341inBuffer, EEPROM_READ_BULKIN_BUF_SZ, cbBulkIn, NULL,
|
|
||||||
DEFAULT_TIMEOUT);
|
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(xferBulkOut, handle, BULK_WRITE_ENDPOINT, ch341outBuffer, EEPROM_READ_BULKOUT_BUF_SZ, cbBulkOut,
|
|
||||||
NULL, DEFAULT_TIMEOUT);
|
|
||||||
|
|
||||||
libusb_submit_transfer(xferBulkIn);
|
|
||||||
libusb_submit_transfer(xferBulkOut);
|
|
||||||
|
|
||||||
readbuf = buffer;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
ret = libusb_handle_events_timeout(NULL, &tv);
|
|
||||||
|
|
||||||
if (ret < 0 || getnextpkt == -1) { // indicates an error
|
|
||||||
printf("ret from libusb_handle_timeout = %d\n", ret);
|
|
||||||
printf("getnextpkt = %u\n", getnextpkt);
|
|
||||||
if (ret < 0)
|
|
||||||
printf("USB read error : %s\n", strerror(-ret));
|
|
||||||
libusb_free_transfer(xferBulkIn);
|
|
||||||
libusb_free_transfer(xferBulkOut);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (getnextpkt == 1) { // callback function reports a new BULK IN packet received
|
|
||||||
getnextpkt = 0; // reset the flag
|
|
||||||
readpktcount++; // increment the read packet counter
|
|
||||||
byteoffset += EEPROM_READ_BULKIN_BUF_SZ;
|
|
||||||
if (byteoffset == bytestoread)
|
|
||||||
break;
|
|
||||||
|
|
||||||
libusb_submit_transfer(xferBulkIn); // re-submit request for next BULK IN packet of EEPROM data
|
|
||||||
if (syncackpkt)
|
|
||||||
syncackpkt = 0;
|
|
||||||
// if 4th packet received, we are at end of 0x80 byte data block,
|
|
||||||
// if it is not the last block, then resubmit request for data
|
|
||||||
if (readpktcount == 4) {
|
|
||||||
readpktcount = 0;
|
|
||||||
|
|
||||||
ch341ReadCmdMarshall(ch341outBuffer, byteoffset, &eeprom_info, i2c_address); // Fill output buffer
|
|
||||||
libusb_fill_bulk_transfer(xferBulkOut, handle, BULK_WRITE_ENDPOINT, ch341outBuffer, EEPROM_READ_BULKOUT_BUF_SZ,
|
|
||||||
cbBulkOut, NULL, DEFAULT_TIMEOUT);
|
|
||||||
|
|
||||||
libusb_submit_transfer(xferBulkOut); // update transfer struct (with new EEPROM page offset)
|
|
||||||
// and re-submit next transfer request to BULK OUT endpoint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
libusb_free_transfer(xferBulkIn);
|
|
||||||
libusb_free_transfer(xferBulkOut);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback function for async bulk in comms
|
|
||||||
void cbBulkIn(struct libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
switch (transfer->status) {
|
|
||||||
case LIBUSB_TRANSFER_COMPLETED:
|
|
||||||
// copy read data to our EEPROM buffer
|
|
||||||
memcpy(readbuf + byteoffset, transfer->buffer, transfer->actual_length);
|
|
||||||
getnextpkt = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("\ncbBulkIn: error : %d\n", transfer->status);
|
|
||||||
getnextpkt = -1;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback function for async bulk out comms
|
|
||||||
void cbBulkOut(struct libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
syncackpkt = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// libUSB driver for the ch341a in i2c mode
|
|
||||||
//
|
|
||||||
// Copyright 2011 asbokid <ballymunboy@gmail.com>
|
|
||||||
#ifndef __CH341A_I2C_H__
|
|
||||||
#define __CH341A_I2C_H__
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <libusb-1.0/libusb.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BULK_WRITE_ENDPOINT 0x02 /* bEndpointAddress 0x02 EP 2 OUT (Bulk)*/
|
|
||||||
#define BULK_READ_ENDPOINT 0x82 /* bEndpointAddress 0x82 EP 2 IN (Bulk)*/
|
|
||||||
|
|
||||||
#define DEFAULT_TIMEOUT 300 // 300mS for USB timeouts
|
|
||||||
|
|
||||||
#define IN_BUF_SZ 0x100
|
|
||||||
#define EEPROM_READ_BULKIN_BUF_SZ 0x20
|
|
||||||
#define EEPROM_READ_BULKOUT_BUF_SZ 0x65
|
|
||||||
|
|
||||||
#define CH341_CMD_I2C_STREAM 0xAA
|
|
||||||
#define CH341_CMD_I2C_STM_STA 0x74
|
|
||||||
#define CH341_CMD_I2C_STM_STO 0x75
|
|
||||||
#define CH341_CMD_I2C_STM_OUT 0x80
|
|
||||||
#define CH341_CMD_I2C_STM_IN 0xC0
|
|
||||||
#define CH341_CMD_I2C_STM_END 0x00
|
|
||||||
|
|
||||||
#define CH341_EEPROM_READ_CMD_SZ 0x65 /* Same size for all 24cXX read setup and next packets*/
|
|
||||||
|
|
||||||
struct EEPROM {
|
|
||||||
char *name;
|
|
||||||
uint32_t size;
|
|
||||||
uint16_t page_size;
|
|
||||||
uint8_t addr_size; // Length of address in bytes
|
|
||||||
uint8_t i2c_addr_mask;
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t ch341readEEPROM_param(uint8_t *buffer, uint32_t offset, uint32_t bytestoread, uint32_t ic_size, uint32_t block_size,
|
|
||||||
uint8_t algorithm, uint32_t i2c_address, struct libusb_device_handle *handle);
|
|
||||||
#endif /* __CH341A_I2C_H__ */
|
|
||||||
@@ -418,8 +418,9 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
|
|||||||
jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
|
jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
|
||||||
if (mp->rx_snr != 0)
|
if (mp->rx_snr != 0)
|
||||||
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
|
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
|
||||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
const int8_t hopsAway = getHopsAway(*mp);
|
||||||
jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit));
|
if (hopsAway >= 0) {
|
||||||
|
jsonObj["hops_away"] = new JSONValue((unsigned int)(hopsAway));
|
||||||
jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start));
|
jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,8 +451,9 @@ std::string MeshPacketSerializer::JsonSerializeEncrypted(const meshtastic_MeshPa
|
|||||||
jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
|
jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
|
||||||
if (mp->rx_snr != 0)
|
if (mp->rx_snr != 0)
|
||||||
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
|
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
|
||||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
const int8_t hopsAway = getHopsAway(*mp);
|
||||||
jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit));
|
if (hopsAway >= 0) {
|
||||||
|
jsonObj["hops_away"] = new JSONValue((unsigned int)(hopsAway));
|
||||||
jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start));
|
jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start));
|
||||||
}
|
}
|
||||||
jsonObj["size"] = new JSONValue((unsigned int)mp->encrypted.size);
|
jsonObj["size"] = new JSONValue((unsigned int)mp->encrypted.size);
|
||||||
|
|||||||
@@ -358,8 +358,9 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
|
|||||||
jsonObj["rssi"] = (int)mp->rx_rssi;
|
jsonObj["rssi"] = (int)mp->rx_rssi;
|
||||||
if (mp->rx_snr != 0)
|
if (mp->rx_snr != 0)
|
||||||
jsonObj["snr"] = (float)mp->rx_snr;
|
jsonObj["snr"] = (float)mp->rx_snr;
|
||||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
const int8_t hopsAway = getHopsAway(*mp);
|
||||||
jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit);
|
if (hopsAway >= 0) {
|
||||||
|
jsonObj["hops_away"] = (unsigned int)(hopsAway);
|
||||||
jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
|
jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,8 +394,9 @@ std::string MeshPacketSerializer::JsonSerializeEncrypted(const meshtastic_MeshPa
|
|||||||
jsonObj["rssi"] = (int)mp->rx_rssi;
|
jsonObj["rssi"] = (int)mp->rx_rssi;
|
||||||
if (mp->rx_snr != 0)
|
if (mp->rx_snr != 0)
|
||||||
jsonObj["snr"] = (float)mp->rx_snr;
|
jsonObj["snr"] = (float)mp->rx_snr;
|
||||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
const int8_t hopsAway = getHopsAway(*mp);
|
||||||
jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit);
|
if (hopsAway >= 0) {
|
||||||
|
jsonObj["hops_away"] = (unsigned int)(hopsAway);
|
||||||
jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
|
jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
|
||||||
}
|
}
|
||||||
jsonObj["size"] = (unsigned int)mp->encrypted.size;
|
jsonObj["size"] = (unsigned int)mp->encrypted.size;
|
||||||
|
|||||||
@@ -15,5 +15,4 @@ upload_protocol = esptool
|
|||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=NeoPixel packageName=adafruit/library/Adafruit NeoPixel
|
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||||
adafruit/Adafruit NeoPixel@1.15.2
|
|
||||||
|
|||||||
@@ -13,3 +13,5 @@ board_build.f_cpu = 240000000L
|
|||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_port = /dev/ttyUSB0
|
;upload_port = /dev/ttyUSB0
|
||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
|
lib_deps =
|
||||||
|
${esp32_base.lib_deps}
|
||||||
|
|||||||
@@ -9,5 +9,4 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
lovyan03/LovyanGFX@^1.2.0
|
||||||
lovyan03/LovyanGFX@1.2.7
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ build_flags =
|
|||||||
-DAXP_DEBUG_PORT=Serial
|
-DAXP_DEBUG_PORT=Serial
|
||||||
-DCONFIG_BT_NIMBLE_ENABLED
|
-DCONFIG_BT_NIMBLE_ENABLED
|
||||||
-DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3
|
-DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3
|
||||||
-DCONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED
|
|
||||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||||
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
|
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
|
||||||
@@ -54,18 +53,17 @@ build_flags =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${networking_extra.lib_deps}
|
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
${environmental_extra.lib_deps}
|
${environmental_extra.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
|
||||||
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
|
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
|
||||||
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
||||||
h2zero/NimBLE-Arduino@^2.3.7
|
h2zero/NimBLE-Arduino@^1.4.3
|
||||||
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
||||||
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
||||||
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
|
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib
|
||||||
lewisxhe/XPowersLib@0.3.2
|
https://github.com/lewisxhe/XPowersLib/archive/v0.3.2.zip
|
||||||
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
|
||||||
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||||
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||||
|
|||||||
@@ -25,5 +25,4 @@ lib_ignore =
|
|||||||
m5stack-core
|
m5stack-core
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
lovyan03/LovyanGFX@^1.2.0
|
||||||
lovyan03/LovyanGFX@1.2.7
|
|
||||||
|
|||||||
@@ -18,10 +18,8 @@ build_flags =
|
|||||||
-DM5STACK
|
-DM5STACK
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
|
zinggjm/GxEPD2@^1.6.2
|
||||||
zinggjm/GxEPD2@1.6.5
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
# renovate: datasource=custom.pio depName=PCF8563 packageName=lewisxhe/library/PCF8563_Library
|
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
m5stack-coreink
|
m5stack-coreink
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
[env:nano-g1-explorer]
|
[env:nano-g1-explorer]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
|
lib_deps =
|
||||||
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D NANO_G1_EXPLORER
|
-D NANO_G1_EXPLORER
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
[env:nano-g1]
|
[env:nano-g1]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
|
lib_deps =
|
||||||
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D NANO_G1
|
-D NANO_G1
|
||||||
|
|||||||
@@ -13,5 +13,4 @@ board_build.f_cpu = 240000000L
|
|||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=github-tags depName=STK8xxx-Accelerometer packageName=gjelsoe/STK8xxx-Accelerometer
|
|
||||||
https://github.com/gjelsoe/STK8xxx-Accelerometer/archive/v0.1.1.zip
|
https://github.com/gjelsoe/STK8xxx-Accelerometer/archive/v0.1.1.zip
|
||||||
|
|||||||
@@ -15,3 +15,5 @@ build_flags =
|
|||||||
-I variants/esp32/radiomaster_900_bandit_nano
|
-I variants/esp32/radiomaster_900_bandit_nano
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
|
lib_deps =
|
||||||
|
${esp32_base.lib_deps}
|
||||||
|
|||||||
@@ -10,3 +10,5 @@ build_flags =
|
|||||||
-I variants/esp32/radiomaster_900_bandit_nano
|
-I variants/esp32/radiomaster_900_bandit_nano
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
|
lib_deps =
|
||||||
|
${esp32_base.lib_deps}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
[env:station-g1]
|
[env:station-g1]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
|
lib_deps =
|
||||||
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D STATION_G1
|
-D STATION_G1
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
[env:tbeam]
|
[env:tbeam]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
board_level = extra
|
|
||||||
board_check = true
|
board_check = true
|
||||||
|
lib_deps = ${esp32_base.lib_deps}
|
||||||
build_flags = ${esp32_base.build_flags}
|
build_flags = ${esp32_base.build_flags}
|
||||||
-D TBEAM_V10
|
-D TBEAM_V10
|
||||||
-I variants/esp32/tbeam
|
-I variants/esp32/tbeam
|
||||||
@@ -13,14 +14,12 @@ upload_speed = 921600
|
|||||||
|
|
||||||
[env:tbeam-displayshield]
|
[env:tbeam-displayshield]
|
||||||
extends = env:tbeam
|
extends = env:tbeam
|
||||||
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${env:tbeam.build_flags}
|
${env:tbeam.build_flags}
|
||||||
-D USE_ST7796
|
-D USE_ST7796
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env:tbeam.lib_deps}
|
${env:tbeam.lib_deps}
|
||||||
# renovate: datasource=github-tags depName=meshtastic-st7796 packageName=meshtastic/st7796
|
https://github.com/meshtastic/st7796/archive/refs/tags/1.0.5.zip ; display addon
|
||||||
https://github.com/meshtastic/st7796/archive/1.0.5.zip
|
lewisxhe/SensorLib@0.3.1 ; touchscreen addon
|
||||||
# renovate: datasource=custom.pio depName=lewisxhe-SensorLib packageName=lewisxhe/library/SensorLib
|
|
||||||
lewisxhe/SensorLib@0.3.1
|
|
||||||
@@ -10,9 +10,6 @@ build_flags =
|
|||||||
-I variants/esp32/wiphone
|
-I variants/esp32/wiphone
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
lovyan03/LovyanGFX@^1.2.0
|
||||||
lovyan03/LovyanGFX@1.2.7
|
sparkfun/SX1509 IO Expander@^3.0.5
|
||||||
# renovate: datasource=custom.pio depName=SX1509 IO Expander packageName=sparkfun/library/SX1509 IO Expander
|
pololu/APA102@^3.0.0
|
||||||
sparkfun/SX1509 IO Expander@3.0.6
|
|
||||||
# renovate: datasource=custom.pio depName=APA102 packageName=pololu/library/APA102
|
|
||||||
pololu/APA102@3.0.0
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
extends = esp32c3_base
|
extends = esp32c3_base
|
||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32c3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32c3/diy/esp32c3_super_mini
|
-I variants/esp32c3/diy/esp32c3_super_mini
|
||||||
-D ARDUINO_USB_MODE=1
|
-D ARDUINO_USB_MODE=1
|
||||||
|
|||||||
@@ -4,8 +4,3 @@ custom_esp32_kind = esp32c3
|
|||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_filters = esp32_c3_exception_decoder
|
monitor_filters = esp32_c3_exception_decoder
|
||||||
|
|
||||||
build_flags =
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
|
||||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends = esp32c3_base
|
|||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32c3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-D ARDUINO_USB_MODE=1
|
-D ARDUINO_USB_MODE=1
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends = esp32c3_base
|
|||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
board_level = pr
|
board_level = pr
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32c3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D HELTEC_HT62
|
-D HELTEC_HT62
|
||||||
-I variants/esp32c3/heltec_esp32c3
|
-I variants/esp32c3/heltec_esp32c3
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
extends = esp32c3_base
|
extends = esp32c3_base
|
||||||
board = adafruit_qtpy_esp32c3
|
board = adafruit_qtpy_esp32c3
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32c3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D HELTEC_HRU_3601
|
-D HELTEC_HRU_3601
|
||||||
-I variants/esp32c3/heltec_hru_3601
|
-I variants/esp32c3/heltec_hru_3601
|
||||||
lib_deps = ${esp32c3_base.lib_deps}
|
lib_deps = ${esp32c3_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=NeoPixel packageName=adafruit/library/Adafruit NeoPixel
|
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||||
adafruit/Adafruit NeoPixel@1.15.2
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends = esp32c3_base
|
|||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32c3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32c3/m5stack-stamp-c3
|
-I variants/esp32c3/m5stack-stamp-c3
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ build_unflags =
|
|||||||
-D HAS_WIFI
|
-D HAS_WIFI
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32c6_base.lib_deps}
|
${esp32c6_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=NeoPixel packageName=adafruit/library/Adafruit NeoPixel
|
adafruit/Adafruit NeoPixel@^1.12.3
|
||||||
adafruit/Adafruit NeoPixel@1.15.2
|
h2zero/NimBLE-Arduino@^2.3.6
|
||||||
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
|
||||||
h2zero/NimBLE-Arduino@2.3.7
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32c6_base.build_flags}
|
${esp32c6_base.build_flags}
|
||||||
-D M5STACK_UNITC6L
|
-D M5STACK_UNITC6L
|
||||||
@@ -26,6 +24,7 @@ build_flags =
|
|||||||
-D HAS_BLUETOOTH=1
|
-D HAS_BLUETOOTH=1
|
||||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||||
|
-D NIMBLE_TWO
|
||||||
monitor_speed=115200
|
monitor_speed=115200
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
NonBlockingRTTTL
|
NonBlockingRTTTL
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ build_flags =
|
|||||||
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
|
|
||||||
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
||||||
# renovate: datasource=custom.pio depName=PCF8563 packageName=lewisxhe/library/PCF8563_Library
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
maxpromer/PCA9557-arduino @ ^1.0.0
|
||||||
# renovate: datasource=custom.pio depName=PCA9557-arduino packageName=maxpromer/library/PCA9557-arduino
|
|
||||||
maxpromer/PCA9557-arduino@1.0.0
|
|
||||||
@@ -8,10 +8,9 @@ board_level = extra
|
|||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_port = /dev/ttyACM2
|
;upload_port = /dev/ttyACM2
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=caveman99-ESP32_Codec2 packageName=caveman99/library/ESP32 Codec2
|
caveman99/ESP32 Codec2@^1.0.1
|
||||||
caveman99/ESP32 Codec2@1.0.1
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32s3/bpi_picow_esp32_s3
|
-I variants/esp32s3/bpi_picow_esp32_s3
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ build_flags =
|
|||||||
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
|
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
|
|
||||||
https://github.com/meshtastic/GxEPD2/archive/33db3fa8ee6fc47d160bdb44f8f127c9a9203a10.zip
|
https://github.com/meshtastic/GxEPD2/archive/33db3fa8ee6fc47d160bdb44f8f127c9a9203a10.zip
|
||||||
|
|
||||||
[env:crowpanel-esp32s3-4-epaper]
|
[env:crowpanel-esp32s3-4-epaper]
|
||||||
@@ -55,7 +54,6 @@ build_flags =
|
|||||||
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
|
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
|
|
||||||
https://github.com/meshtastic/GxEPD2/archive/33db3fa8ee6fc47d160bdb44f8f127c9a9203a10.zip
|
https://github.com/meshtastic/GxEPD2/archive/33db3fa8ee6fc47d160bdb44f8f127c9a9203a10.zip
|
||||||
|
|
||||||
[env:crowpanel-esp32s3-2-epaper]
|
[env:crowpanel-esp32s3-2-epaper]
|
||||||
@@ -85,5 +83,4 @@ build_flags =
|
|||||||
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
|
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
|
|
||||||
https://github.com/meshtastic/GxEPD2/archive/33db3fa8ee6fc47d160bdb44f8f127c9a9203a10.zip
|
https://github.com/meshtastic/GxEPD2/archive/33db3fa8ee6fc47d160bdb44f8f127c9a9203a10.zip
|
||||||
|
|||||||
@@ -9,16 +9,14 @@ upload_protocol = esptool
|
|||||||
;upload_port = /dev/ttyACM1
|
;upload_port = /dev/ttyACM1
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
|
zinggjm/GxEPD2@^1.6.2
|
||||||
zinggjm/GxEPD2@1.6.5
|
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||||
# renovate: datasource=custom.pio depName=NeoPixel packageName=adafruit/library/Adafruit NeoPixel
|
|
||||||
adafruit/Adafruit NeoPixel@1.15.2
|
|
||||||
build_unflags =
|
build_unflags =
|
||||||
${esp32s3_base.build_unflags}
|
${esp32s3_base.build_unflags}
|
||||||
-DARDUINO_USB_MODE=1
|
-DARDUINO_USB_MODE=1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32s3/diy/my_esp32s3_diy_eink
|
-I variants/esp32s3/diy/my_esp32s3_diy_eink
|
||||||
-Dmy
|
-Dmy
|
||||||
|
|||||||
@@ -9,14 +9,13 @@ upload_protocol = esptool
|
|||||||
;upload_port = /dev/ttyACM0
|
;upload_port = /dev/ttyACM0
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=NeoPixel packageName=adafruit/library/Adafruit NeoPixel
|
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||||
adafruit/Adafruit NeoPixel@1.15.2
|
|
||||||
build_unflags =
|
build_unflags =
|
||||||
${esp32s3_base.build_unflags}
|
${esp32s3_base.build_unflags}
|
||||||
-DARDUINO_USB_MODE=1
|
-DARDUINO_USB_MODE=1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32s3/diy/my_esp32s3_diy_oled
|
-I variants/esp32s3/diy/my_esp32s3_diy_oled
|
||||||
-DBOARD_HAS_PSRAM
|
-DBOARD_HAS_PSRAM
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ build_flags =
|
|||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=ESP8266Audio packageName=earlephilhower/library/ESP8266Audio
|
earlephilhower/ESP8266Audio@^1.9.9
|
||||||
earlephilhower/ESP8266Audio@1.9.9
|
earlephilhower/ESP8266SAM@^1.0.1
|
||||||
# renovate: datasource=custom.pio depName=ESP8266SAM packageName=earlephilhower/library/ESP8266SAM
|
|
||||||
earlephilhower/ESP8266SAM@1.1.0
|
|
||||||
|
|
||||||
[env:dreamcatcher-2206]
|
[env:dreamcatcher-2206]
|
||||||
extends = esp32s3_base
|
extends = esp32s3_base
|
||||||
|
|||||||
@@ -41,13 +41,9 @@ build_flags = ${esp32s3_base.build_flags} -Os
|
|||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
${device-ui_base.lib_deps}
|
${device-ui_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=ESP8266Audio packageName=earlephilhower/library/ESP8266Audio
|
|
||||||
earlephilhower/ESP8266Audio@1.9.9
|
earlephilhower/ESP8266Audio@1.9.9
|
||||||
# renovate: datasource=custom.pio depName=ESP8266SAM packageName=earlephilhower/library/ESP8266SAM
|
|
||||||
earlephilhower/ESP8266SAM@1.0.1
|
earlephilhower/ESP8266SAM@1.0.1
|
||||||
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
|
||||||
lovyan03/LovyanGFX@1.2.0 ; note: v1.2.7 breaks the elecrow 7" display functionality
|
lovyan03/LovyanGFX@1.2.0 ; note: v1.2.7 breaks the elecrow 7" display functionality
|
||||||
# renovate: datasource=custom.pio depName=TCA9534 packageName=hideakitai/library/TCA9534
|
|
||||||
hideakitai/TCA9534@0.1.1
|
hideakitai/TCA9534@0.1.1
|
||||||
|
|
||||||
[crowpanel_small_esp32s3_base] ; 2.4, 2.8, 3.5 inch
|
[crowpanel_small_esp32s3_base] ; 2.4, 2.8, 3.5 inch
|
||||||
|
|||||||
@@ -22,7 +22,5 @@ build_flags = ${esp32s3_base.build_flags}
|
|||||||
-DEINK_HEIGHT=128
|
-DEINK_HEIGHT=128
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
|
zinggjm/GxEPD2@^1.6.2
|
||||||
zinggjm/GxEPD2@1.6.5
|
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||||
# renovate: datasource=custom.pio depName=NeoPixel packageName=adafruit/library/Adafruit NeoPixel
|
|
||||||
adafruit/Adafruit NeoPixel@1.15.2
|
|
||||||
|
|||||||
@@ -3,8 +3,3 @@ extends = esp32_base
|
|||||||
custom_esp32_kind = esp32s3
|
custom_esp32_kind = esp32s3
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
build_flags =
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
|
||||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
|
||||||
|
|||||||
@@ -12,5 +12,4 @@ build_flags = ${esp32s3_base.build_flags}
|
|||||||
-I variants/esp32s3/hackaday-communicator
|
-I variants/esp32s3/hackaday-communicator
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-Arduino_GFX packageName=https://github.com/meshtastic/Arduino_GFX gitBranch=master
|
https://github.com/meshtastic/Arduino_GFX/archive/054e81ffaf23784830a734e3c184346789349406.zip
|
||||||
https://github.com/meshtastic/Arduino_GFX/archive/054e81ffaf23784830a734e3c184346789349406.zip
|
|
||||||
@@ -9,5 +9,4 @@ build_flags =
|
|||||||
-D HELTEC_SENSOR_HUB
|
-D HELTEC_SENSOR_HUB
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=NeoPixel packageName=adafruit/library/Adafruit NeoPixel
|
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||||
adafruit/Adafruit NeoPixel@1.15.2
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ build_flags =
|
|||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D HELTEC_V4
|
-D HELTEC_V4
|
||||||
-I variants/esp32s3/heltec_v4
|
-I variants/esp32s3/heltec_v4
|
||||||
|
lib_deps =
|
||||||
|
${esp32s3_base.lib_deps}
|
||||||
|
|
||||||
|
|
||||||
[env:heltec-v4]
|
[env:heltec-v4]
|
||||||
@@ -21,6 +23,8 @@ build_flags =
|
|||||||
-D I2C_SCL=18
|
-D I2C_SCL=18
|
||||||
-D I2C_SDA1=4
|
-D I2C_SDA1=4
|
||||||
-D I2C_SCL1=3
|
-D I2C_SCL1=3
|
||||||
|
lib_deps =
|
||||||
|
${heltec_v4_base.lib_deps}
|
||||||
|
|
||||||
[env:heltec-v4-tft]
|
[env:heltec-v4-tft]
|
||||||
extends = heltec_v4_base
|
extends = heltec_v4_base
|
||||||
@@ -103,10 +107,6 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps = ${heltec_v4_base.lib_deps}
|
lib_deps = ${heltec_v4_base.lib_deps}
|
||||||
; ${device-ui_base.lib_deps}
|
; ${device-ui_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
|
||||||
lovyan03/LovyanGFX@1.2.0
|
lovyan03/LovyanGFX@1.2.0
|
||||||
# renovate: datasource=git-refs depName=Quency-D_chsc6x packageName=https://github.com/Quency-D/chsc6x gitBranch=master
|
|
||||||
https://github.com/Quency-D/chsc6x/archive/5cbead829d6b432a8d621ed1aafd4eb474fd4f27.zip
|
https://github.com/Quency-D/chsc6x/archive/5cbead829d6b432a8d621ed1aafd4eb474fd4f27.zip
|
||||||
; TODO revert to official device-ui (when merged)
|
|
||||||
# renovate: datasource=git-refs depName=Quency-D_device-ui packageName=https://github.com/Quency-D/device-ui gitBranch=heltec-v4-tft
|
|
||||||
https://github.com/Quency-D/device-ui/archive/7c9870b8016641190b059bdd90fe16c1012a39eb.zip
|
https://github.com/Quency-D/device-ui/archive/7c9870b8016641190b059bdd90fe16c1012a39eb.zip
|
||||||
|
|||||||
@@ -17,10 +17,8 @@ build_flags =
|
|||||||
-DEINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
|
-DEINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
|
|
||||||
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
||||||
# renovate: datasource=custom.pio depName=PCF8563 packageName=lewisxhe/library/PCF8563_Library
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
|
|
||||||
[env:heltec-vision-master-e213-inkhud]
|
[env:heltec-vision-master-e213-inkhud]
|
||||||
@@ -29,7 +27,7 @@ board = heltec_vision_master_e213
|
|||||||
board_level = pr
|
board_level = pr
|
||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32s3_base.build_src_filter}
|
${esp32_base.build_src_filter}
|
||||||
${inkhud.build_src_filter}
|
${inkhud.build_src_filter}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
|
|
||||||
https://github.com/meshtastic/GxEPD2/archive/448c8538129fde3d02a7cb5e6fc81971ad92547f.zip
|
https://github.com/meshtastic/GxEPD2/archive/448c8538129fde3d02a7cb5e6fc81971ad92547f.zip
|
||||||
# renovate: datasource=custom.pio depName=PCF8563 packageName=lewisxhe/library/PCF8563_Library
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
|
|
||||||
[env:heltec-vision-master-e290-inkhud]
|
[env:heltec-vision-master-e290-inkhud]
|
||||||
@@ -31,7 +29,7 @@ extends = esp32s3_base, inkhud
|
|||||||
board = heltec_vision_master_e290
|
board = heltec_vision_master_e290
|
||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32s3_base.build_src_filter}
|
${esp32_base.build_src_filter}
|
||||||
${inkhud.build_src_filter}
|
${inkhud.build_src_filter}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ build_flags =
|
|||||||
-D HELTEC_VISION_MASTER_T190
|
-D HELTEC_VISION_MASTER_T190
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
# renovate: datasource=custom.pio depName=PCF8563 packageName=lewisxhe/library/PCF8563_Library
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
|
||||||
# renovate: datasource=git-refs depName=meshtastic-st7789 packageName=https://github.com/meshtastic/st7789 gitBranch=main
|
|
||||||
https://github.com/meshtastic/st7789/archive/bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f.zip
|
https://github.com/meshtastic/st7789/archive/bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f.zip
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user