mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-10 11:57:25 +00:00
Merge branch 'master' into master
This commit is contained in:
5
.github/workflows/build_raspbian.yml
vendored
5
.github/workflows/build_raspbian.yml
vendored
@@ -10,6 +10,11 @@ jobs:
|
|||||||
build-raspbian:
|
build-raspbian:
|
||||||
runs-on: [self-hosted, linux, ARM64]
|
runs-on: [self-hosted, linux, ARM64]
|
||||||
steps:
|
steps:
|
||||||
|
- name: Install libbluetooth
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
51
.github/workflows/build_raspbian_armv7l.yml
vendored
Normal file
51
.github/workflows/build_raspbian_armv7l.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
name: Build Raspbian Arm
|
||||||
|
|
||||||
|
on: workflow_call
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-raspbian-armv7l:
|
||||||
|
runs-on: [self-hosted, linux, ARM]
|
||||||
|
steps:
|
||||||
|
- name: Install libbluetooth
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Upgrade python tools
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -U platformio adafruit-nrfutil
|
||||||
|
pip install -U meshtastic --pre
|
||||||
|
|
||||||
|
- name: Upgrade platformio
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
pio upgrade
|
||||||
|
|
||||||
|
- name: Build Raspbian
|
||||||
|
run: bin/build-native.sh
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Store binaries as an artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
||||||
|
overwrite: true
|
||||||
|
path: |
|
||||||
|
release/meshtasticd_linux_armv7l
|
||||||
|
bin/config-dist.yaml
|
||||||
32
.github/workflows/main_matrix.yml
vendored
32
.github/workflows/main_matrix.yml
vendored
@@ -103,15 +103,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
board: ${{ matrix.board }}
|
board: ${{ matrix.board }}
|
||||||
|
|
||||||
build-raspbian:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
max-parallel: 1
|
|
||||||
uses: ./.github/workflows/build_raspbian.yml
|
|
||||||
|
|
||||||
package-raspbian:
|
package-raspbian:
|
||||||
uses: ./.github/workflows/package_raspbian.yml
|
uses: ./.github/workflows/package_raspbian.yml
|
||||||
|
|
||||||
|
package-raspbian-armv7l:
|
||||||
|
uses: ./.github/workflows/package_raspbian_armv7l.yml
|
||||||
|
|
||||||
build-native:
|
build-native:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -195,10 +192,10 @@ jobs:
|
|||||||
build-esp32-s3,
|
build-esp32-s3,
|
||||||
build-esp32-c3,
|
build-esp32-c3,
|
||||||
build-nrf52,
|
build-nrf52,
|
||||||
build-raspbian,
|
|
||||||
build-native,
|
build-native,
|
||||||
build-rpi2040,
|
build-rpi2040,
|
||||||
package-raspbian,
|
package-raspbian,
|
||||||
|
package-raspbian-armv7l,
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
@@ -220,7 +217,7 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- name: Move files up
|
||||||
run: mv -b -t ./ ./release/meshtasticd_linux_aarch64 ./bin/config-dist.yaml
|
run: mv -b -t ./ ./release/meshtasticd_linux_aarch64 ./release/meshtasticd_linux_armv7l ./bin/config-dist.yaml
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
@@ -233,7 +230,7 @@ jobs:
|
|||||||
./firmware-*-ota.zip
|
./firmware-*-ota.zip
|
||||||
./device-*.sh
|
./device-*.sh
|
||||||
./device-*.bat
|
./device-*.bat
|
||||||
./meshtasticd_linux_*64
|
./meshtasticd_linux_*
|
||||||
./config-dist.yaml
|
./config-dist.yaml
|
||||||
./littlefs-*.bin
|
./littlefs-*.bin
|
||||||
./bleota*bin
|
./bleota*bin
|
||||||
@@ -303,8 +300,9 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
name: artifact-deb
|
path: ./output
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -R
|
run: ls -R
|
||||||
@@ -363,16 +361,26 @@ jobs:
|
|||||||
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||||
asset_content_type: application/zip
|
asset_content_type: application/zip
|
||||||
|
|
||||||
- name: Add raspbian .deb
|
- name: Add raspbian aarch64 .deb
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: ./meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
||||||
asset_name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
asset_name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
||||||
asset_content_type: application/vnd.debian.binary-package
|
asset_content_type: application/vnd.debian.binary-package
|
||||||
|
|
||||||
|
- name: Add raspbian armv7l .deb
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
||||||
|
asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
||||||
|
asset_content_type: application/vnd.debian.binary-package
|
||||||
|
|
||||||
- name: Bump version.properties
|
- name: Bump version.properties
|
||||||
run: >-
|
run: >-
|
||||||
bin/bump_version.py
|
bin/bump_version.py
|
||||||
|
|||||||
2
.github/workflows/package_raspbian.yml
vendored
2
.github/workflows/package_raspbian.yml
vendored
@@ -72,7 +72,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: artifact-deb
|
name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./*.deb
|
./*.deb
|
||||||
|
|||||||
78
.github/workflows/package_raspbian_armv7l.yml
vendored
Normal file
78
.github/workflows/package_raspbian_armv7l.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
name: Package Raspbian
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-raspbian_armv7l:
|
||||||
|
uses: ./.github/workflows/build_raspbian_armv7l.yml
|
||||||
|
|
||||||
|
package-raspbian_armv7l:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build-raspbian_armv7l
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Pull web ui
|
||||||
|
uses: dsaltares/fetch-gh-release-asset@master
|
||||||
|
with:
|
||||||
|
repo: meshtastic/web
|
||||||
|
file: build.tar
|
||||||
|
target: build.tar
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -R
|
||||||
|
|
||||||
|
- name: build .debpkg
|
||||||
|
run: |
|
||||||
|
mkdir -p .debpkg/DEBIAN
|
||||||
|
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
||||||
|
mkdir -p .debpkg/usr/sbin
|
||||||
|
mkdir -p .debpkg/etc/meshtasticd
|
||||||
|
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||||
|
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
|
||||||
|
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
|
||||||
|
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
|
||||||
|
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||||
|
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||||
|
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||||
|
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
||||||
|
chmod +x .debpkg/DEBIAN/conffiles
|
||||||
|
|
||||||
|
- uses: jiro4989/build-deb-action@v3
|
||||||
|
with:
|
||||||
|
package: meshtasticd
|
||||||
|
package_root: .debpkg
|
||||||
|
maintainer: Jonathan Bennett
|
||||||
|
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
||||||
|
arch: armhf
|
||||||
|
depends: libyaml-cpp0.7, openssl, libulfius2.7
|
||||||
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
||||||
|
overwrite: true
|
||||||
|
path: |
|
||||||
|
./*.deb
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = platformio/espressif32@6.3.2 # This is a temporary fix to the S3-based devices bluetooth issues until we can determine what within ESP-IDF changed and can develop a suitable patch.
|
platform = platformio/espressif32@6.7.0
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/> -<mesh/raspihttp>
|
||||||
@@ -15,8 +15,10 @@ board_build.filesystem = littlefs
|
|||||||
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
||||||
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
||||||
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
||||||
|
build_unflags = -fno-lto
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
|
-flto
|
||||||
-Wall
|
-Wall
|
||||||
-Wextra
|
-Wextra
|
||||||
-Isrc/platform/esp32
|
-Isrc/platform/esp32
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# trunk-ignore-all(ruff/F821)
|
||||||
|
# trunk-ignore-all(flake8/F821): For SConstruct imports
|
||||||
import sys
|
import sys
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
|
||||||
@@ -60,6 +62,7 @@ if platform.name == "espressif32":
|
|||||||
import esptool
|
import esptool
|
||||||
|
|
||||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin)
|
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin)
|
||||||
|
env.Append(LINKFLAGS=["--specs=nano.specs", "-u", "_printf_float"])
|
||||||
|
|
||||||
Import("projenv")
|
Import("projenv")
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"-DBOARD_HAS_PSRAM",
|
"-DBOARD_HAS_PSRAM",
|
||||||
"-DLILYGO_TBEAM_S3_CORE",
|
"-DLILYGO_TBEAM_S3_CORE",
|
||||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
"-DARDUINO_USB_MODE=1",
|
"-DARDUINO_USB_MODE=0",
|
||||||
"-DARDUINO_RUNNING_CORE=1",
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||||
],
|
],
|
||||||
|
|||||||
Submodule protobufs updated: 5cfadd1489...b5dc871a1b
@@ -50,7 +50,7 @@ RTC_NOINIT_ATTR uint64_t RTC_reg_b;
|
|||||||
|
|
||||||
esp_adc_cal_characteristics_t *adc_characs = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
|
esp_adc_cal_characteristics_t *adc_characs = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
|
||||||
#ifndef ADC_ATTENUATION
|
#ifndef ADC_ATTENUATION
|
||||||
static const adc_atten_t atten = ADC_ATTEN_DB_11;
|
static const adc_atten_t atten = ADC_ATTEN_DB_12;
|
||||||
#else
|
#else
|
||||||
static const adc_atten_t atten = ADC_ATTENUATION;
|
static const adc_atten_t atten = ADC_ATTENUATION;
|
||||||
#endif
|
#endif
|
||||||
@@ -555,14 +555,24 @@ void Power::readPowerStatus()
|
|||||||
#ifdef NRF_APM // Section of code detects USB power on the RAK4631 and updates the power states. Takes 20 seconds or so to detect
|
#ifdef NRF_APM // Section of code detects USB power on the RAK4631 and updates the power states. Takes 20 seconds or so to detect
|
||||||
// changes.
|
// changes.
|
||||||
|
|
||||||
|
static nrfx_power_usb_state_t prev_nrf_usb_state = (nrfx_power_usb_state_t)-1; // -1 so that state detected at boot
|
||||||
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
|
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
|
||||||
|
|
||||||
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED) {
|
// If state changed
|
||||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
if (nrf_usb_state != prev_nrf_usb_state) {
|
||||||
NRF_USB = OptFalse;
|
// If changed to DISCONNECTED
|
||||||
} else {
|
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED) {
|
||||||
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||||
NRF_USB = OptTrue;
|
NRF_USB = OptFalse;
|
||||||
|
}
|
||||||
|
// If changed to CONNECTED / READY
|
||||||
|
else {
|
||||||
|
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
||||||
|
NRF_USB = OptTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the current state
|
||||||
|
prev_nrf_usb_state = nrf_usb_state;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Notify any status instances that are observing us
|
// Notify any status instances that are observing us
|
||||||
|
|||||||
@@ -348,12 +348,18 @@ void PowerFSM_setup()
|
|||||||
|
|
||||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
|
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
|
||||||
|
|
||||||
powerFSM.add_timed_transition(&stateON, &stateDARK,
|
#ifdef USE_EINK
|
||||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
// Allow E-Ink devices to suppress the screensaver, if screen timeout set to 0
|
||||||
"Screen-on timeout");
|
if (config.display.screen_on_secs > 0)
|
||||||
powerFSM.add_timed_transition(&statePOWER, &stateDARK,
|
#endif
|
||||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
{
|
||||||
"Screen-on timeout");
|
powerFSM.add_timed_transition(&stateON, &stateDARK,
|
||||||
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs),
|
||||||
|
NULL, "Screen-on timeout");
|
||||||
|
powerFSM.add_timed_transition(&statePOWER, &stateDARK,
|
||||||
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs),
|
||||||
|
NULL, "Screen-on timeout");
|
||||||
|
}
|
||||||
|
|
||||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
|
|||||||
4
src/graphics/PointStruct.h
Normal file
4
src/graphics/PointStruct.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
struct PointStruct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
@@ -419,6 +419,536 @@ static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
|
|||||||
return packet->from != 0 && !moduleConfig.store_forward.enabled;
|
return packet->from != 0 && !moduleConfig.store_forward.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw power bars or a charging indicator on an image of a battery, determined by battery charge voltage or percentage.
|
||||||
|
static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *imgBuffer, const PowerStatus *powerStatus)
|
||||||
|
{
|
||||||
|
static const uint8_t powerBar[3] = {0x81, 0xBD, 0xBD};
|
||||||
|
static const uint8_t lightning[8] = {0xA1, 0xA1, 0xA5, 0xAD, 0xB5, 0xA5, 0x85, 0x85};
|
||||||
|
// Clear the bar area on the battery image
|
||||||
|
for (int i = 1; i < 14; i++) {
|
||||||
|
imgBuffer[i] = 0x81;
|
||||||
|
}
|
||||||
|
// If charging, draw a charging indicator
|
||||||
|
if (powerStatus->getIsCharging()) {
|
||||||
|
memcpy(imgBuffer + 3, lightning, 8);
|
||||||
|
// If not charging, Draw power bars
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (powerStatus->getBatteryChargePercent() >= 25 * i)
|
||||||
|
memcpy(imgBuffer + 1 + (i * 3), powerBar, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display->drawFastImage(x, y, 16, 8, imgBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
|
||||||
|
void Screen::drawWatchFaceToggleButton(OLEDDisplay *display, int16_t x, int16_t y, bool digitalMode, float scale)
|
||||||
|
{
|
||||||
|
uint16_t segmentWidth = SEGMENT_WIDTH * scale;
|
||||||
|
uint16_t segmentHeight = SEGMENT_HEIGHT * scale;
|
||||||
|
|
||||||
|
if (digitalMode) {
|
||||||
|
uint16_t radius = (segmentWidth + (segmentHeight * 2) + 4) / 2;
|
||||||
|
uint16_t centerX = (x + segmentHeight + 2) + (radius / 2);
|
||||||
|
uint16_t centerY = (y + segmentHeight + 2) + (radius / 2);
|
||||||
|
|
||||||
|
display->drawCircle(centerX, centerY, radius);
|
||||||
|
display->drawCircle(centerX, centerY, radius + 1);
|
||||||
|
display->drawLine(centerX, centerY, centerX, centerY - radius + 3);
|
||||||
|
display->drawLine(centerX, centerY, centerX + radius - 3, centerY);
|
||||||
|
} else {
|
||||||
|
uint16_t segmentOneX = x + segmentHeight + 2;
|
||||||
|
uint16_t segmentOneY = y;
|
||||||
|
|
||||||
|
uint16_t segmentTwoX = segmentOneX + segmentWidth + 2;
|
||||||
|
uint16_t segmentTwoY = segmentOneY + segmentHeight + 2;
|
||||||
|
|
||||||
|
uint16_t segmentThreeX = segmentOneX;
|
||||||
|
uint16_t segmentThreeY = segmentTwoY + segmentWidth + 2;
|
||||||
|
|
||||||
|
uint16_t segmentFourX = x;
|
||||||
|
uint16_t segmentFourY = y + segmentHeight + 2;
|
||||||
|
|
||||||
|
drawHorizontalSegment(display, segmentOneX, segmentOneY, segmentWidth, segmentHeight);
|
||||||
|
drawVerticalSegment(display, segmentTwoX, segmentTwoY, segmentWidth, segmentHeight);
|
||||||
|
drawHorizontalSegment(display, segmentThreeX, segmentThreeY, segmentWidth, segmentHeight);
|
||||||
|
drawVerticalSegment(display, segmentFourX, segmentFourY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a digital clock
|
||||||
|
void Screen::drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
|
||||||
|
drawBattery(display, x, y + 7, imgBattery, powerStatus);
|
||||||
|
|
||||||
|
if (powerStatus->getHasBattery()) {
|
||||||
|
String batteryPercent = String(powerStatus->getBatteryChargePercent()) + "%";
|
||||||
|
|
||||||
|
display->setFont(FONT_SMALL);
|
||||||
|
|
||||||
|
display->drawString(x + 20, y + 2, batteryPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nimbleBluetooth->isConnected()) {
|
||||||
|
drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawWatchFaceToggleButton(display, display->getWidth() - 36, display->getHeight() - 36, screen->digitalWatchFace, 1);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||||
|
|
||||||
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
|
||||||
|
if (rtc_sec > 0) {
|
||||||
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
|
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||||
|
|
||||||
|
int hour = hms / SEC_PER_HOUR;
|
||||||
|
int minute = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||||
|
int second = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||||
|
|
||||||
|
hour = hour > 12 ? hour - 12 : hour;
|
||||||
|
|
||||||
|
if (hour == 0) {
|
||||||
|
hour = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hours string
|
||||||
|
String hourString = String(hour);
|
||||||
|
|
||||||
|
// minutes string
|
||||||
|
String minuteString = minute < 10 ? "0" + String(minute) : String(minute);
|
||||||
|
|
||||||
|
String timeString = hourString + ":" + minuteString;
|
||||||
|
|
||||||
|
// seconds string
|
||||||
|
String secondString = second < 10 ? "0" + String(second) : String(second);
|
||||||
|
|
||||||
|
float scale = 1.5;
|
||||||
|
|
||||||
|
uint16_t segmentWidth = SEGMENT_WIDTH * scale;
|
||||||
|
uint16_t segmentHeight = SEGMENT_HEIGHT * scale;
|
||||||
|
|
||||||
|
// calculate hours:minutes string width
|
||||||
|
uint16_t timeStringWidth = timeString.length() * 5;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < timeString.length(); i++) {
|
||||||
|
String character = String(timeString[i]);
|
||||||
|
|
||||||
|
if (character == ":") {
|
||||||
|
timeStringWidth += segmentHeight;
|
||||||
|
} else {
|
||||||
|
timeStringWidth += segmentWidth + (segmentHeight * 2) + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate seconds string width
|
||||||
|
uint16_t secondStringWidth = (secondString.length() * 12) + 4;
|
||||||
|
|
||||||
|
// sum these to get total string width
|
||||||
|
uint16_t totalWidth = timeStringWidth + secondStringWidth;
|
||||||
|
|
||||||
|
uint16_t hourMinuteTextX = (display->getWidth() / 2) - (totalWidth / 2);
|
||||||
|
|
||||||
|
uint16_t startingHourMinuteTextX = hourMinuteTextX;
|
||||||
|
|
||||||
|
uint16_t hourMinuteTextY = (display->getHeight() / 2) - (((segmentWidth * 2) + (segmentHeight * 3) + 8) / 2);
|
||||||
|
|
||||||
|
// iterate over characters in hours:minutes string and draw segmented characters
|
||||||
|
for (uint8_t i = 0; i < timeString.length(); i++) {
|
||||||
|
String character = String(timeString[i]);
|
||||||
|
|
||||||
|
if (character == ":") {
|
||||||
|
drawSegmentedDisplayColon(display, hourMinuteTextX, hourMinuteTextY, scale);
|
||||||
|
|
||||||
|
hourMinuteTextX += segmentHeight + 6;
|
||||||
|
} else {
|
||||||
|
drawSegmentedDisplayCharacter(display, hourMinuteTextX, hourMinuteTextY, character.toInt(), scale);
|
||||||
|
|
||||||
|
hourMinuteTextX += segmentWidth + (segmentHeight * 2) + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
hourMinuteTextX += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw seconds string
|
||||||
|
display->setFont(FONT_MEDIUM);
|
||||||
|
display->drawString(startingHourMinuteTextX + timeStringWidth + 4,
|
||||||
|
(display->getHeight() - hourMinuteTextY) - FONT_HEIGHT_MEDIUM + 6, secondString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawSegmentedDisplayColon(OLEDDisplay *display, int x, int y, float scale)
|
||||||
|
{
|
||||||
|
uint16_t segmentWidth = SEGMENT_WIDTH * scale;
|
||||||
|
uint16_t segmentHeight = SEGMENT_HEIGHT * scale;
|
||||||
|
|
||||||
|
uint16_t cellHeight = (segmentWidth * 2) + (segmentHeight * 3) + 8;
|
||||||
|
|
||||||
|
uint16_t topAndBottomX = x + (4 * scale);
|
||||||
|
|
||||||
|
uint16_t quarterCellHeight = cellHeight / 4;
|
||||||
|
|
||||||
|
uint16_t topY = y + quarterCellHeight;
|
||||||
|
uint16_t bottomY = y + (quarterCellHeight * 3);
|
||||||
|
|
||||||
|
display->fillRect(topAndBottomX, topY, segmentHeight, segmentHeight);
|
||||||
|
display->fillRect(topAndBottomX, bottomY, segmentHeight, segmentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawSegmentedDisplayCharacter(OLEDDisplay *display, int x, int y, uint8_t number, float scale)
|
||||||
|
{
|
||||||
|
// the numbers 0-9, each expressed as an array of seven boolean (0|1) values encoding the on/off state of
|
||||||
|
// segment {innerIndex + 1}
|
||||||
|
// e.g., to display the numeral '0', segments 1-6 are on, and segment 7 is off.
|
||||||
|
uint8_t numbers[10][7] = {
|
||||||
|
{1, 1, 1, 1, 1, 1, 0}, // 0 Display segment key
|
||||||
|
{0, 1, 1, 0, 0, 0, 0}, // 1 1
|
||||||
|
{1, 1, 0, 1, 1, 0, 1}, // 2 ___
|
||||||
|
{1, 1, 1, 1, 0, 0, 1}, // 3 6 | | 2
|
||||||
|
{0, 1, 1, 0, 0, 1, 1}, // 4 |_7̲_|
|
||||||
|
{1, 0, 1, 1, 0, 1, 1}, // 5 5 | | 3
|
||||||
|
{1, 0, 1, 1, 1, 1, 1}, // 6 |___|
|
||||||
|
{1, 1, 1, 0, 0, 1, 0}, // 7
|
||||||
|
{1, 1, 1, 1, 1, 1, 1}, // 8 4
|
||||||
|
{1, 1, 1, 1, 0, 1, 1}, // 9
|
||||||
|
};
|
||||||
|
|
||||||
|
// the width and height of each segment's central rectangle:
|
||||||
|
// _____________________
|
||||||
|
// ⋰| (only this part, |⋱
|
||||||
|
// ⋰ | not including | ⋱
|
||||||
|
// ⋱ | the triangles | ⋰
|
||||||
|
// ⋱| on the ends) |⋰
|
||||||
|
// ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||||
|
|
||||||
|
uint16_t segmentWidth = SEGMENT_WIDTH * scale;
|
||||||
|
uint16_t segmentHeight = SEGMENT_HEIGHT * scale;
|
||||||
|
|
||||||
|
// segment x and y coordinates
|
||||||
|
uint16_t segmentOneX = x + segmentHeight + 2;
|
||||||
|
uint16_t segmentOneY = y;
|
||||||
|
|
||||||
|
uint16_t segmentTwoX = segmentOneX + segmentWidth + 2;
|
||||||
|
uint16_t segmentTwoY = segmentOneY + segmentHeight + 2;
|
||||||
|
|
||||||
|
uint16_t segmentThreeX = segmentTwoX;
|
||||||
|
uint16_t segmentThreeY = segmentTwoY + segmentWidth + 2 + segmentHeight + 2;
|
||||||
|
|
||||||
|
uint16_t segmentFourX = segmentOneX;
|
||||||
|
uint16_t segmentFourY = segmentThreeY + segmentWidth + 2;
|
||||||
|
|
||||||
|
uint16_t segmentFiveX = x;
|
||||||
|
uint16_t segmentFiveY = segmentThreeY;
|
||||||
|
|
||||||
|
uint16_t segmentSixX = x;
|
||||||
|
uint16_t segmentSixY = segmentTwoY;
|
||||||
|
|
||||||
|
uint16_t segmentSevenX = segmentOneX;
|
||||||
|
uint16_t segmentSevenY = segmentTwoY + segmentWidth + 2;
|
||||||
|
|
||||||
|
if (numbers[number][0]) {
|
||||||
|
drawHorizontalSegment(display, segmentOneX, segmentOneY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numbers[number][1]) {
|
||||||
|
drawVerticalSegment(display, segmentTwoX, segmentTwoY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numbers[number][2]) {
|
||||||
|
drawVerticalSegment(display, segmentThreeX, segmentThreeY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numbers[number][3]) {
|
||||||
|
drawHorizontalSegment(display, segmentFourX, segmentFourY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numbers[number][4]) {
|
||||||
|
drawVerticalSegment(display, segmentFiveX, segmentFiveY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numbers[number][5]) {
|
||||||
|
drawVerticalSegment(display, segmentSixX, segmentSixY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numbers[number][6]) {
|
||||||
|
drawHorizontalSegment(display, segmentSevenX, segmentSevenY, segmentWidth, segmentHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawHorizontalSegment(OLEDDisplay *display, int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
int halfHeight = height / 2;
|
||||||
|
|
||||||
|
// draw central rectangle
|
||||||
|
display->fillRect(x, y, width, height);
|
||||||
|
|
||||||
|
// draw end triangles
|
||||||
|
display->fillTriangle(x, y, x, y + height - 1, x - halfHeight, y + halfHeight);
|
||||||
|
|
||||||
|
display->fillTriangle(x + width, y, x + width + halfHeight, y + halfHeight, x + width, y + height - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawVerticalSegment(OLEDDisplay *display, int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
int halfHeight = height / 2;
|
||||||
|
|
||||||
|
// draw central rectangle
|
||||||
|
display->fillRect(x, y, height, width);
|
||||||
|
|
||||||
|
// draw end triangles
|
||||||
|
display->fillTriangle(x + halfHeight, y - halfHeight, x + height - 1, y, x, y);
|
||||||
|
|
||||||
|
display->fillTriangle(x, y + width, x + height - 1, y + width, x + halfHeight, y + width + halfHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawBluetoothConnectedIcon(OLEDDisplay *display, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
display->drawFastImage(x, y, 18, 14, bluetoothConnectedIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw an analog clock
|
||||||
|
void Screen::drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
|
||||||
|
drawBattery(display, x, y + 7, imgBattery, powerStatus);
|
||||||
|
|
||||||
|
if (powerStatus->getHasBattery()) {
|
||||||
|
String batteryPercent = String(powerStatus->getBatteryChargePercent()) + "%";
|
||||||
|
|
||||||
|
display->setFont(FONT_SMALL);
|
||||||
|
|
||||||
|
display->drawString(x + 20, y + 2, batteryPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nimbleBluetooth->isConnected()) {
|
||||||
|
drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawWatchFaceToggleButton(display, display->getWidth() - 36, display->getHeight() - 36, screen->digitalWatchFace, 1);
|
||||||
|
|
||||||
|
// clock face center coordinates
|
||||||
|
int16_t centerX = display->getWidth() / 2;
|
||||||
|
int16_t centerY = display->getHeight() / 2;
|
||||||
|
|
||||||
|
// clock face radius
|
||||||
|
int16_t radius = (display->getWidth() / 2) * 0.8;
|
||||||
|
|
||||||
|
// noon (0 deg) coordinates (outermost circle)
|
||||||
|
int16_t noonX = centerX;
|
||||||
|
int16_t noonY = centerY - radius;
|
||||||
|
|
||||||
|
// second hand radius and y coordinate (outermost circle)
|
||||||
|
int16_t secondHandNoonY = noonY + 1;
|
||||||
|
|
||||||
|
// tick mark outer y coordinate; (first nested circle)
|
||||||
|
int16_t tickMarkOuterNoonY = secondHandNoonY;
|
||||||
|
|
||||||
|
// seconds tick mark inner y coordinate; (second nested circle)
|
||||||
|
double secondsTickMarkInnerNoonY = (double)noonY + 8;
|
||||||
|
|
||||||
|
// hours tick mark inner y coordinate; (third nested circle)
|
||||||
|
double hoursTickMarkInnerNoonY = (double)noonY + 16;
|
||||||
|
|
||||||
|
// minute hand y coordinate
|
||||||
|
int16_t minuteHandNoonY = secondsTickMarkInnerNoonY + 4;
|
||||||
|
|
||||||
|
// hour string y coordinate
|
||||||
|
int16_t hourStringNoonY = minuteHandNoonY + 18;
|
||||||
|
|
||||||
|
// hour hand radius and y coordinate
|
||||||
|
int16_t hourHandRadius = radius * 0.55;
|
||||||
|
int16_t hourHandNoonY = centerY - hourHandRadius;
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||||
|
display->drawCircle(centerX, centerY, radius);
|
||||||
|
|
||||||
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
|
||||||
|
if (rtc_sec > 0) {
|
||||||
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
|
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||||
|
|
||||||
|
// Tear apart hms into h:m:s
|
||||||
|
int hour = hms / SEC_PER_HOUR;
|
||||||
|
int minute = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||||
|
int second = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||||
|
|
||||||
|
hour = hour > 12 ? hour - 12 : hour;
|
||||||
|
|
||||||
|
int16_t degreesPerHour = 30;
|
||||||
|
int16_t degreesPerMinuteOrSecond = 6;
|
||||||
|
|
||||||
|
double hourBaseAngle = hour * degreesPerHour;
|
||||||
|
double hourAngleOffset = ((double)minute / 60) * degreesPerHour;
|
||||||
|
double hourAngle = radians(hourBaseAngle + hourAngleOffset);
|
||||||
|
|
||||||
|
double minuteBaseAngle = minute * degreesPerMinuteOrSecond;
|
||||||
|
double minuteAngleOffset = ((double)second / 60) * degreesPerMinuteOrSecond;
|
||||||
|
double minuteAngle = radians(minuteBaseAngle + minuteAngleOffset);
|
||||||
|
|
||||||
|
double secondAngle = radians(second * degreesPerMinuteOrSecond);
|
||||||
|
|
||||||
|
double hourX = sin(-hourAngle) * (hourHandNoonY - centerY) + noonX;
|
||||||
|
double hourY = cos(-hourAngle) * (hourHandNoonY - centerY) + centerY;
|
||||||
|
|
||||||
|
double minuteX = sin(-minuteAngle) * (minuteHandNoonY - centerY) + noonX;
|
||||||
|
double minuteY = cos(-minuteAngle) * (minuteHandNoonY - centerY) + centerY;
|
||||||
|
|
||||||
|
double secondX = sin(-secondAngle) * (secondHandNoonY - centerY) + noonX;
|
||||||
|
double secondY = cos(-secondAngle) * (secondHandNoonY - centerY) + centerY;
|
||||||
|
|
||||||
|
display->setFont(FONT_MEDIUM);
|
||||||
|
|
||||||
|
// draw minute and hour tick marks and hour numbers
|
||||||
|
for (uint16_t angle = 0; angle < 360; angle += 6) {
|
||||||
|
double angleInRadians = radians(angle);
|
||||||
|
|
||||||
|
double sineAngleInRadians = sin(-angleInRadians);
|
||||||
|
double cosineAngleInRadians = cos(-angleInRadians);
|
||||||
|
|
||||||
|
double endX = sineAngleInRadians * (tickMarkOuterNoonY - centerY) + noonX;
|
||||||
|
double endY = cosineAngleInRadians * (tickMarkOuterNoonY - centerY) + centerY;
|
||||||
|
|
||||||
|
if (angle % degreesPerHour == 0) {
|
||||||
|
double startX = sineAngleInRadians * (hoursTickMarkInnerNoonY - centerY) + noonX;
|
||||||
|
double startY = cosineAngleInRadians * (hoursTickMarkInnerNoonY - centerY) + centerY;
|
||||||
|
|
||||||
|
// draw hour tick mark
|
||||||
|
display->drawLine(startX, startY, endX, endY);
|
||||||
|
|
||||||
|
static char buffer[2];
|
||||||
|
|
||||||
|
uint8_t hourInt = (angle / 30);
|
||||||
|
|
||||||
|
if (hourInt == 0) {
|
||||||
|
hourInt = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hour number x offset needs to be adjusted for some cases
|
||||||
|
int8_t hourStringXOffset;
|
||||||
|
int8_t hourStringYOffset = 13;
|
||||||
|
|
||||||
|
switch (hourInt) {
|
||||||
|
case 3:
|
||||||
|
hourStringXOffset = 5;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
hourStringXOffset = 7;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
hourStringXOffset = 8;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
hourStringXOffset = 13;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
hourStringXOffset = 6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
double hourStringX = (sineAngleInRadians * (hourStringNoonY - centerY) + noonX) - hourStringXOffset;
|
||||||
|
double hourStringY = (cosineAngleInRadians * (hourStringNoonY - centerY) + centerY) - hourStringYOffset;
|
||||||
|
|
||||||
|
// draw hour number
|
||||||
|
display->drawStringf(hourStringX, hourStringY, buffer, "%d", hourInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle % degreesPerMinuteOrSecond == 0) {
|
||||||
|
double startX = sineAngleInRadians * (secondsTickMarkInnerNoonY - centerY) + noonX;
|
||||||
|
double startY = cosineAngleInRadians * (secondsTickMarkInnerNoonY - centerY) + centerY;
|
||||||
|
|
||||||
|
// draw minute tick mark
|
||||||
|
display->drawLine(startX, startY, endX, endY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw hour hand
|
||||||
|
display->drawLine(centerX, centerY, hourX, hourY);
|
||||||
|
|
||||||
|
// draw minute hand
|
||||||
|
display->drawLine(centerX, centerY, minuteX, minuteY);
|
||||||
|
|
||||||
|
// draw second hand
|
||||||
|
display->drawLine(centerX, centerY, secondX, secondY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get an absolute time from "seconds ago" info. Returns false if no valid timestamp possible
|
||||||
|
bool deltaToTimestamp(uint32_t secondsAgo, uint8_t *hours, uint8_t *minutes, int32_t *daysAgo)
|
||||||
|
{
|
||||||
|
// Cache the result - avoid frequent recalculation
|
||||||
|
static uint8_t hoursCached = 0, minutesCached = 0;
|
||||||
|
static uint32_t daysAgoCached = 0;
|
||||||
|
static uint32_t secondsAgoCached = 0;
|
||||||
|
static bool validCached = false;
|
||||||
|
|
||||||
|
// Abort: if timezone not set
|
||||||
|
if (strlen(config.device.tzdef) == 0) {
|
||||||
|
validCached = false;
|
||||||
|
return validCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abort: if invalid pointers passed
|
||||||
|
if (hours == nullptr || minutes == nullptr || daysAgo == nullptr) {
|
||||||
|
validCached = false;
|
||||||
|
return validCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abort: if time seems invalid.. (> 6 months ago, probably seen before RTC set)
|
||||||
|
if (secondsAgo > SEC_PER_DAY * 30UL * 6) {
|
||||||
|
validCached = false;
|
||||||
|
return validCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If repeated request, don't bother recalculating
|
||||||
|
if (secondsAgo - secondsAgoCached < 60 && secondsAgoCached != 0) {
|
||||||
|
if (validCached) {
|
||||||
|
*hours = hoursCached;
|
||||||
|
*minutes = minutesCached;
|
||||||
|
*daysAgo = daysAgoCached;
|
||||||
|
}
|
||||||
|
return validCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get local time
|
||||||
|
uint32_t secondsRTC = getValidTime(RTCQuality::RTCQualityDevice, true); // Get local time
|
||||||
|
|
||||||
|
// Abort: if RTC not set
|
||||||
|
if (!secondsRTC) {
|
||||||
|
validCached = false;
|
||||||
|
return validCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get absolute time when last seen
|
||||||
|
uint32_t secondsSeenAt = secondsRTC - secondsAgo;
|
||||||
|
|
||||||
|
// Calculate daysAgo
|
||||||
|
*daysAgo = (secondsRTC / SEC_PER_DAY) - (secondsSeenAt / SEC_PER_DAY); // How many "midnights" have passed
|
||||||
|
|
||||||
|
// Get seconds since midnight
|
||||||
|
uint32_t hms = (secondsRTC - secondsAgo) % SEC_PER_DAY;
|
||||||
|
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||||
|
|
||||||
|
// Tear apart hms into hours and minutes
|
||||||
|
*hours = hms / SEC_PER_HOUR;
|
||||||
|
*minutes = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||||
|
|
||||||
|
// Cache the result
|
||||||
|
daysAgoCached = *daysAgo;
|
||||||
|
hoursCached = *hours;
|
||||||
|
minutesCached = *minutes;
|
||||||
|
secondsAgoCached = secondsAgo;
|
||||||
|
|
||||||
|
validCached = true;
|
||||||
|
return validCached;
|
||||||
|
}
|
||||||
|
|
||||||
/// Draw the last text message we received
|
/// Draw the last text message we received
|
||||||
static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
@@ -440,22 +970,98 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
|
|||||||
display->setColor(BLACK);
|
display->setColor(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For time delta
|
||||||
uint32_t seconds = sinceReceived(&mp);
|
uint32_t seconds = sinceReceived(&mp);
|
||||||
uint32_t minutes = seconds / 60;
|
uint32_t minutes = seconds / 60;
|
||||||
uint32_t hours = minutes / 60;
|
uint32_t hours = minutes / 60;
|
||||||
uint32_t days = hours / 24;
|
uint32_t days = hours / 24;
|
||||||
|
|
||||||
if (config.display.heading_bold) {
|
// For timestamp
|
||||||
display->drawStringf(1 + x, 0 + y, tempBuf, "%s ago from %s",
|
uint8_t timestampHours, timestampMinutes;
|
||||||
screen->drawTimeDelta(days, hours, minutes, seconds).c_str(),
|
int32_t daysAgo;
|
||||||
(node && node->has_user) ? node->user.short_name : "???");
|
bool useTimestamp = deltaToTimestamp(seconds, ×tampHours, ×tampMinutes, &daysAgo);
|
||||||
|
|
||||||
|
// If bold, draw twice, shifting right by one pixel
|
||||||
|
for (uint8_t xOff = 0; xOff <= (config.display.heading_bold ? 1 : 0); xOff++) {
|
||||||
|
// Show a timestamp if received today, but longer than 15 minutes ago
|
||||||
|
if (useTimestamp && minutes >= 15 && daysAgo == 0) {
|
||||||
|
display->drawStringf(xOff + x, 0 + y, tempBuf, "At %02hu:%02hu from %s", timestampHours, timestampMinutes,
|
||||||
|
(node && node->has_user) ? node->user.short_name : "???");
|
||||||
|
}
|
||||||
|
// Timestamp yesterday (if display is wide enough)
|
||||||
|
else if (useTimestamp && daysAgo == 1 && display->width() >= 200) {
|
||||||
|
display->drawStringf(xOff + x, 0 + y, tempBuf, "Yesterday %02hu:%02hu from %s", timestampHours, timestampMinutes,
|
||||||
|
(node && node->has_user) ? node->user.short_name : "???");
|
||||||
|
}
|
||||||
|
// Otherwise, show a time delta
|
||||||
|
else {
|
||||||
|
display->drawStringf(xOff + x, 0 + y, tempBuf, "%s ago from %s",
|
||||||
|
screen->drawTimeDelta(days, hours, minutes, seconds).c_str(),
|
||||||
|
(node && node->has_user) ? node->user.short_name : "???");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
display->drawStringf(0 + x, 0 + y, tempBuf, "%s ago from %s", screen->drawTimeDelta(days, hours, minutes, seconds).c_str(),
|
|
||||||
(node && node->has_user) ? node->user.short_name : "???");
|
|
||||||
|
|
||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
|
#ifndef EXCLUDE_EMOJI
|
||||||
|
if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\U0001F44D") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height,
|
||||||
|
thumbup);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\U0001F44E") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height,
|
||||||
|
thumbdown);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"❓") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height,
|
||||||
|
question);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"‼️") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5,
|
||||||
|
bang_width, bang_height, bang);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\U0001F4A9") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5,
|
||||||
|
poo_width, poo_height, poo);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\xf0\x9f\xa4\xa3") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5,
|
||||||
|
haha_width, haha_height, haha);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\U0001F44B") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width,
|
||||||
|
wave_icon_height, wave_icon);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\U0001F920") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height,
|
||||||
|
cowboy);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\U0001F42D") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height,
|
||||||
|
deadmau5);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\xE2\x98\x80\xEF\xB8\x8F") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5,
|
||||||
|
sun_width, sun_height, sun);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\u2614") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10,
|
||||||
|
rain_width, rain_height, rain);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"☁️") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"🌫️") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5,
|
||||||
|
fog_width, fog_height, fog);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"\xf0\x9f\x98\x88") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil);
|
||||||
|
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), u8"♥️") == 0) {
|
||||||
|
display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2,
|
||||||
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart);
|
||||||
|
} else {
|
||||||
|
snprintf(tempBuf, sizeof(tempBuf), "%s", mp.decoded.payload.bytes);
|
||||||
|
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf);
|
||||||
|
}
|
||||||
|
#else
|
||||||
snprintf(tempBuf, sizeof(tempBuf), "%s", mp.decoded.payload.bytes);
|
snprintf(tempBuf, sizeof(tempBuf), "%s", mp.decoded.payload.bytes);
|
||||||
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf);
|
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw the last waypoint we received
|
/// Draw the last waypoint we received
|
||||||
@@ -518,28 +1124,6 @@ static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw power bars or a charging indicator on an image of a battery, determined by battery charge voltage or percentage.
|
|
||||||
static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *imgBuffer, const PowerStatus *powerStatus)
|
|
||||||
{
|
|
||||||
static const uint8_t powerBar[3] = {0x81, 0xBD, 0xBD};
|
|
||||||
static const uint8_t lightning[8] = {0xA1, 0xA1, 0xA5, 0xAD, 0xB5, 0xA5, 0x85, 0x85};
|
|
||||||
// Clear the bar area on the battery image
|
|
||||||
for (int i = 1; i < 14; i++) {
|
|
||||||
imgBuffer[i] = 0x81;
|
|
||||||
}
|
|
||||||
// If charging, draw a charging indicator
|
|
||||||
if (powerStatus->getIsCharging()) {
|
|
||||||
memcpy(imgBuffer + 3, lightning, 8);
|
|
||||||
// If not charging, Draw power bars
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
if (powerStatus->getBatteryChargePercent() >= 25 * i)
|
|
||||||
memcpy(imgBuffer + 1 + (i * 3), powerBar, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
display->drawFastImage(x, y, 16, 8, imgBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw nodes status
|
// Draw nodes status
|
||||||
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStatus *nodeStatus)
|
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStatus *nodeStatus)
|
||||||
{
|
{
|
||||||
@@ -875,23 +1459,47 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
const char *username = node->has_user ? node->user.long_name : "Unknown Name";
|
const char *username = node->has_user ? node->user.long_name : "Unknown Name";
|
||||||
|
|
||||||
static char signalStr[20];
|
static char signalStr[20];
|
||||||
snprintf(signalStr, sizeof(signalStr), "Signal: %d%%", clamp((int)((node->snr + 10) * 5), 0, 100));
|
|
||||||
|
//section here to choose whether to display hops away rather than signal strength if more than 0 hops away.
|
||||||
|
if(node->hops_away>0)
|
||||||
|
{
|
||||||
|
snprintf(signalStr, sizeof(signalStr), "Hops Away: %d", node->hops_away);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(signalStr, sizeof(signalStr), "Signal: %d%%", clamp((int)((node->snr + 10) * 5), 0, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t agoSecs = sinceLastSeen(node);
|
uint32_t agoSecs = sinceLastSeen(node);
|
||||||
static char lastStr[20];
|
static char lastStr[20];
|
||||||
|
|
||||||
|
// Use an absolute timestamp in some cases.
|
||||||
|
// Particularly useful with E-Ink displays. Static UI, fewer refreshes.
|
||||||
|
uint8_t timestampHours, timestampMinutes;
|
||||||
|
int32_t daysAgo;
|
||||||
|
bool useTimestamp = deltaToTimestamp(agoSecs, ×tampHours, ×tampMinutes, &daysAgo);
|
||||||
|
|
||||||
if (agoSecs < 120) // last 2 mins?
|
if (agoSecs < 120) // last 2 mins?
|
||||||
snprintf(lastStr, sizeof(lastStr), "%u seconds ago", agoSecs);
|
snprintf(lastStr, sizeof(lastStr), "%u seconds ago", agoSecs);
|
||||||
|
// -- if suitable for timestamp --
|
||||||
|
else if (useTimestamp && agoSecs < 15 * SECONDS_IN_MINUTE) // Last 15 minutes
|
||||||
|
snprintf(lastStr, sizeof(lastStr), "%u minutes ago", agoSecs / SECONDS_IN_MINUTE);
|
||||||
|
else if (useTimestamp && daysAgo == 0) // Today
|
||||||
|
snprintf(lastStr, sizeof(lastStr), "Last seen: %02u:%02u", (unsigned int)timestampHours, (unsigned int)timestampMinutes);
|
||||||
|
else if (useTimestamp && daysAgo == 1) // Yesterday
|
||||||
|
snprintf(lastStr, sizeof(lastStr), "Seen yesterday");
|
||||||
|
else if (useTimestamp && daysAgo > 1) // Last six months (capped by deltaToTimestamp method)
|
||||||
|
snprintf(lastStr, sizeof(lastStr), "%li days ago", (long)daysAgo);
|
||||||
|
// -- if using time delta instead --
|
||||||
else if (agoSecs < 120 * 60) // last 2 hrs
|
else if (agoSecs < 120 * 60) // last 2 hrs
|
||||||
snprintf(lastStr, sizeof(lastStr), "%u minutes ago", agoSecs / 60);
|
snprintf(lastStr, sizeof(lastStr), "%u minutes ago", agoSecs / 60);
|
||||||
else {
|
// Only show hours ago if it's been less than 6 months. Otherwise, we may have bad data.
|
||||||
// Only show hours ago if it's been less than 6 months. Otherwise, we may have bad
|
else if ((agoSecs / 60 / 60) < (hours_in_month * 6))
|
||||||
// data.
|
snprintf(lastStr, sizeof(lastStr), "%u hours ago", agoSecs / 60 / 60);
|
||||||
if ((agoSecs / 60 / 60) < (hours_in_month * 6)) {
|
else
|
||||||
snprintf(lastStr, sizeof(lastStr), "%u hours ago", agoSecs / 60 / 60);
|
snprintf(lastStr, sizeof(lastStr), "unknown age");
|
||||||
} else {
|
|
||||||
snprintf(lastStr, sizeof(lastStr), "unknown age");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static char distStr[20];
|
static char distStr[20];
|
||||||
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
|
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
|
||||||
@@ -900,7 +1508,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
strncpy(distStr, "? km", sizeof(distStr));
|
strncpy(distStr, "? km", sizeof(distStr));
|
||||||
}
|
}
|
||||||
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||||
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
|
const char *fields[] = {username, lastStr, signalStr, distStr, NULL};
|
||||||
int16_t compassX = 0, compassY = 0;
|
int16_t compassX = 0, compassY = 0;
|
||||||
|
|
||||||
// coordinates for the center of the compass/circle
|
// coordinates for the center of the compass/circle
|
||||||
@@ -1218,6 +1826,10 @@ int32_t Screen::runOnce()
|
|||||||
return RUN_SAME;
|
return RUN_SAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (displayHeight == 0) {
|
||||||
|
displayHeight = dispdev->getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
// Show boot screen for first logo_timeout seconds, then switch to normal operation.
|
// Show boot screen for first logo_timeout seconds, then switch to normal operation.
|
||||||
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
|
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
|
||||||
static bool showingBootScreen = true;
|
static bool showingBootScreen = true;
|
||||||
@@ -1448,6 +2060,15 @@ void Screen::setFrames()
|
|||||||
LOG_DEBUG("showing standard frames\n");
|
LOG_DEBUG("showing standard frames\n");
|
||||||
showingNormalScreen = true;
|
showingNormalScreen = true;
|
||||||
|
|
||||||
|
#ifdef USE_EINK
|
||||||
|
// If user has disabled the screensaver, warn them after boot
|
||||||
|
static bool warnedScreensaverDisabled = false;
|
||||||
|
if (config.display.screen_on_secs == 0 && !warnedScreensaverDisabled) {
|
||||||
|
screen->print("Screensaver disabled\n");
|
||||||
|
warnedScreensaverDisabled = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
moduleFrames = MeshModule::GetMeshModulesWithUIFrames();
|
moduleFrames = MeshModule::GetMeshModulesWithUIFrames();
|
||||||
LOG_DEBUG("Showing %d module frames\n", moduleFrames.size());
|
LOG_DEBUG("Showing %d module frames\n", moduleFrames.size());
|
||||||
#ifdef DEBUG_PORT
|
#ifdef DEBUG_PORT
|
||||||
@@ -1487,6 +2108,10 @@ void Screen::setFrames()
|
|||||||
normalFrames[numframes++] = drawWaypointFrame;
|
normalFrames[numframes++] = drawWaypointFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
normalFrames[numframes++] = screen->digitalWatchFace ? &Screen::drawDigitalClockFrame : &Screen::drawAnalogClockFrame;
|
||||||
|
#endif
|
||||||
|
|
||||||
// then all the nodes
|
// then all the nodes
|
||||||
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens
|
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens
|
||||||
size_t numToShow = min(numMeshNodes, 4U);
|
size_t numToShow = min(numMeshNodes, 4U);
|
||||||
@@ -2058,6 +2683,19 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
|||||||
|
|
||||||
int Screen::handleInputEvent(const InputEvent *event)
|
int Screen::handleInputEvent(const InputEvent *event)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
// For the T-Watch, intercept touches to the 'toggle digital/analog watch face' button
|
||||||
|
if (this->ui->getUiState()->currentFrame == 0 && event->touchX >= 204 && event->touchX <= 240 && event->touchY >= 204 &&
|
||||||
|
event->touchY <= 240) {
|
||||||
|
screen->digitalWatchFace = !screen->digitalWatchFace;
|
||||||
|
|
||||||
|
setFrames();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (showingNormalScreen && moduleFrames.size() == 0) {
|
if (showingNormalScreen && moduleFrames.size() == 0) {
|
||||||
// LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
|
// LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
@@ -2073,4 +2711,4 @@ int Screen::handleInputEvent(const InputEvent *event)
|
|||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#else
|
#else
|
||||||
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
||||||
#endif // HAS_SCREEN
|
#endif // HAS_SCREEN
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class Screen
|
|||||||
|
|
||||||
#include "EInkDisplay2.h"
|
#include "EInkDisplay2.h"
|
||||||
#include "EInkDynamicDisplay.h"
|
#include "EInkDynamicDisplay.h"
|
||||||
|
#include "PointStruct.h"
|
||||||
#include "TFTDisplay.h"
|
#include "TFTDisplay.h"
|
||||||
#include "TypedQueue.h"
|
#include "TypedQueue.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
@@ -77,6 +78,10 @@ class Screen
|
|||||||
#define EINK_BLACK OLEDDISPLAY_COLOR::WHITE
|
#define EINK_BLACK OLEDDISPLAY_COLOR::WHITE
|
||||||
#define EINK_WHITE OLEDDISPLAY_COLOR::BLACK
|
#define EINK_WHITE OLEDDISPLAY_COLOR::BLACK
|
||||||
|
|
||||||
|
// Base segment dimensions for T-Watch segmented display
|
||||||
|
#define SEGMENT_WIDTH 16
|
||||||
|
#define SEGMENT_HEIGHT 4
|
||||||
|
|
||||||
namespace graphics
|
namespace graphics
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -389,6 +394,27 @@ class Screen : public concurrency::OSThread
|
|||||||
|
|
||||||
static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
static void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
|
static void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
|
static void drawSegmentedDisplayCharacter(OLEDDisplay *display, int x, int y, uint8_t number, float scale = 1);
|
||||||
|
|
||||||
|
static void drawHorizontalSegment(OLEDDisplay *display, int x, int y, int width, int height);
|
||||||
|
|
||||||
|
static void drawVerticalSegment(OLEDDisplay *display, int x, int y, int width, int height);
|
||||||
|
|
||||||
|
static void drawSegmentedDisplayColon(OLEDDisplay *display, int x, int y, float scale = 1);
|
||||||
|
|
||||||
|
static void drawWatchFaceToggleButton(OLEDDisplay *display, int16_t x, int16_t y, bool digitalMode = true, float scale = 1);
|
||||||
|
|
||||||
|
static void drawBluetoothConnectedIcon(OLEDDisplay *display, int16_t x, int16_t y);
|
||||||
|
|
||||||
|
// Whether we are showing the digital watch face or the analog one
|
||||||
|
bool digitalWatchFace = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Queue of commands to execute in doTask.
|
/// Queue of commands to execute in doTask.
|
||||||
TypedQueue<ScreenCmd> cmdQueue;
|
TypedQueue<ScreenCmd> cmdQueue;
|
||||||
/// Whether we are using a display
|
/// Whether we are using a display
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3
|
|||||||
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
||||||
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
|
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0xe3, 0x1f,
|
||||||
|
0xf3, 0x3f, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x03, 0x33, 0xff, 0x33,
|
||||||
|
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS) || \
|
||||||
ARCH_PORTDUINO) && \
|
ARCH_PORTDUINO) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
@@ -31,4 +37,171 @@ const uint8_t imgQuestion[] PROGMEM = {0xbf, 0x41, 0xc0, 0x8b, 0xdb, 0x70, 0xa1,
|
|||||||
const uint8_t imgSF[] PROGMEM = {0xd2, 0xb7, 0xad, 0xbb, 0x92, 0x01, 0xfd, 0xfd, 0x15, 0x85, 0xf5};
|
const uint8_t imgSF[] PROGMEM = {0xd2, 0xb7, 0xad, 0xbb, 0x92, 0x01, 0xfd, 0xfd, 0x15, 0x85, 0xf5};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXCLUDE_EMOJI
|
||||||
|
#define thumbs_height 25
|
||||||
|
#define thumbs_width 25
|
||||||
|
static unsigned char thumbup[] PROGMEM = {
|
||||||
|
0x00, 0x1C, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00,
|
||||||
|
0xC0, 0x08, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x18, 0x02, 0x00, 0x00,
|
||||||
|
0x0C, 0xCE, 0x7F, 0x00, 0x04, 0x20, 0x80, 0x00, 0x02, 0x20, 0x80, 0x00, 0x02, 0x60, 0xC0, 0x00, 0x01, 0xF8, 0xFF, 0x01,
|
||||||
|
0x01, 0x08, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01, 0x01, 0xF8, 0xFF, 0x00, 0x01, 0x10, 0x80, 0x00, 0x01, 0x18, 0x80, 0x00,
|
||||||
|
0x02, 0x30, 0xC0, 0x00, 0x06, 0xE0, 0x3F, 0x00, 0x0C, 0x20, 0x30, 0x00, 0x38, 0x20, 0x10, 0x00, 0xE0, 0xCF, 0x1F, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char thumbdown[] PROGMEM = {
|
||||||
|
0xE0, 0xCF, 0x1F, 0x00, 0x38, 0x20, 0x10, 0x00, 0x0C, 0x20, 0x30, 0x00, 0x06, 0xE0, 0x3F, 0x00, 0x02, 0x30, 0xC0, 0x00,
|
||||||
|
0x01, 0x18, 0x80, 0x00, 0x01, 0x10, 0x80, 0x00, 0x01, 0xF8, 0xFF, 0x00, 0x01, 0x08, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01,
|
||||||
|
0x01, 0xF8, 0xFF, 0x01, 0x02, 0x60, 0xC0, 0x00, 0x02, 0x20, 0x80, 0x00, 0x04, 0x20, 0x80, 0x00, 0x0C, 0xCE, 0x7F, 0x00,
|
||||||
|
0x18, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00,
|
||||||
|
0x80, 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define question_height 25
|
||||||
|
#define question_width 25
|
||||||
|
static unsigned char question[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0xE0, 0xFF, 0x07, 0x00,
|
||||||
|
0xE0, 0xC3, 0x0F, 0x00, 0xF0, 0x81, 0x0F, 0x00, 0xF0, 0x01, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x80, 0x0F, 0x00,
|
||||||
|
0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x7C, 0x00, 0x00,
|
||||||
|
0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x3E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define bang_height 30
|
||||||
|
#define bang_width 30
|
||||||
|
static unsigned char bang[] PROGMEM = {
|
||||||
|
0xFF, 0x0F, 0xFC, 0x3F, 0xFF, 0x0F, 0xFC, 0x3F, 0xFF, 0x0F, 0xFC, 0x3F, 0xFF, 0x07, 0xF8, 0x3F, 0xFF, 0x07, 0xF8, 0x3F,
|
||||||
|
0xFE, 0x07, 0xF8, 0x1F, 0xFE, 0x07, 0xF8, 0x1F, 0xFE, 0x07, 0xF8, 0x1F, 0xFE, 0x07, 0xF8, 0x1F, 0xFE, 0x07, 0xF8, 0x1F,
|
||||||
|
0xFE, 0x03, 0xF0, 0x1F, 0xFE, 0x03, 0xF0, 0x1F, 0xFC, 0x03, 0xF0, 0x0F, 0xFC, 0x03, 0xF0, 0x0F, 0xFC, 0x03, 0xF0, 0x0F,
|
||||||
|
0xFC, 0x03, 0xF0, 0x0F, 0xFC, 0x03, 0xF0, 0x0F, 0xFC, 0x03, 0xF0, 0x0F, 0xFC, 0x01, 0xE0, 0x0F, 0xFC, 0x01, 0xE0, 0x0F,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x03, 0xFC, 0x03, 0xF0, 0x0F, 0xFE, 0x03, 0xF0, 0x1F,
|
||||||
|
0xFE, 0x07, 0xF8, 0x1F, 0xFE, 0x07, 0xF8, 0x1F, 0xFE, 0x07, 0xF8, 0x1F, 0xFC, 0x03, 0xF0, 0x0F, 0xF8, 0x01, 0xE0, 0x07,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define haha_height 30
|
||||||
|
#define haha_width 30
|
||||||
|
static unsigned char haha[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00,
|
||||||
|
0x00, 0xFC, 0x0F, 0x00, 0x00, 0x1F, 0x3E, 0x00, 0x80, 0x03, 0x70, 0x00, 0xC0, 0x01, 0xE0, 0x00, 0xC0, 0x00, 0xC2, 0x00,
|
||||||
|
0x60, 0x00, 0x03, 0x00, 0x60, 0x00, 0xC1, 0x1F, 0x60, 0x80, 0x8F, 0x31, 0x30, 0x0E, 0x80, 0x31, 0x30, 0x10, 0x30, 0x1F,
|
||||||
|
0x30, 0x08, 0x58, 0x00, 0x30, 0x04, 0x6C, 0x03, 0x60, 0x00, 0xF3, 0x01, 0x60, 0xC0, 0xFC, 0x01, 0x80, 0x38, 0xBF, 0x01,
|
||||||
|
0xE0, 0xC5, 0xDF, 0x00, 0xB0, 0xF9, 0xEF, 0x00, 0x30, 0xF1, 0x73, 0x00, 0xB0, 0x1D, 0x3E, 0x00, 0xF0, 0xFD, 0x0F, 0x00,
|
||||||
|
0xE0, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define wave_icon_height 30
|
||||||
|
#define wave_icon_width 30
|
||||||
|
static unsigned char wave_icon[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x00,
|
||||||
|
0x00, 0x0C, 0x9C, 0x01, 0x80, 0x17, 0x20, 0x01, 0x80, 0x26, 0x46, 0x02, 0x80, 0x44, 0x88, 0x02, 0xC0, 0x89, 0x8A, 0x02,
|
||||||
|
0x40, 0x93, 0x8B, 0x02, 0x40, 0x26, 0x13, 0x00, 0x80, 0x44, 0x16, 0x00, 0xC0, 0x89, 0x24, 0x00, 0x40, 0x93, 0x60, 0x00,
|
||||||
|
0x40, 0x26, 0x40, 0x00, 0x80, 0x0C, 0x80, 0x00, 0x00, 0x09, 0x80, 0x00, 0x00, 0x02, 0x80, 0x00, 0x40, 0x06, 0x80, 0x00,
|
||||||
|
0x50, 0x0C, 0x80, 0x00, 0x50, 0x08, 0x40, 0x00, 0x90, 0x10, 0x20, 0x00, 0xB0, 0x21, 0x10, 0x00, 0x20, 0x47, 0x18, 0x00,
|
||||||
|
0x40, 0x80, 0x0F, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define cowboy_height 30
|
||||||
|
#define cowboy_width 30
|
||||||
|
static unsigned char cowboy[] PROGMEM = {
|
||||||
|
0x00, 0xF0, 0x03, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x3C, 0xFE, 0x1F, 0x0F,
|
||||||
|
0xFE, 0xFE, 0xDF, 0x1F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||||
|
0x3E, 0xC0, 0x00, 0x1F, 0x1E, 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x0E, 0x1C, 0x04, 0x00, 0x0E, 0x1C, 0x00,
|
||||||
|
0x04, 0x0E, 0x1C, 0x08, 0x04, 0x0E, 0x1C, 0x08, 0x04, 0x04, 0x08, 0x08, 0x04, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x08,
|
||||||
|
0x8C, 0x07, 0x70, 0x0C, 0x88, 0xFC, 0x4F, 0x04, 0x88, 0x01, 0x40, 0x04, 0x90, 0xFF, 0x7F, 0x02, 0x30, 0x03, 0x30, 0x03,
|
||||||
|
0x60, 0x0E, 0x9C, 0x01, 0xC0, 0xF8, 0xC7, 0x00, 0x80, 0x01, 0x60, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0xF8, 0x07, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define deadmau5_height 30
|
||||||
|
#define deadmau5_width 60
|
||||||
|
static unsigned char deadmau5[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00,
|
||||||
|
0x00, 0xFC, 0x03, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0x3F, 0x00,
|
||||||
|
0xE0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0x7F, 0x00, 0xF0, 0xFF, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xFF, 0x07,
|
||||||
|
0xFC, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x00,
|
||||||
|
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0x3F, 0xFC,
|
||||||
|
0x0F, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x1F, 0xF8, 0x0F, 0xFC, 0x3F, 0x00, 0x80, 0xFF, 0x0F, 0xF8, 0x1F, 0xFC, 0x1F, 0x00,
|
||||||
|
0x00, 0xFF, 0x0F, 0xFC, 0x3F, 0xFC, 0x0F, 0x00, 0x00, 0xF8, 0x1F, 0xFF, 0xFF, 0xFE, 0x01, 0x00, 0x00, 0x00, 0xFC, 0xFF,
|
||||||
|
0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
|
||||||
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x80, 0x07, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define sun_width 30
|
||||||
|
#define sun_height 30
|
||||||
|
static unsigned char sun[] PROGMEM = {
|
||||||
|
0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x30, 0xC0, 0x00, 0x03,
|
||||||
|
0x70, 0x00, 0x80, 0x03, 0xF0, 0x00, 0xC0, 0x03, 0xF0, 0xF8, 0xC7, 0x03, 0xE0, 0xFC, 0xCF, 0x01, 0x00, 0xFE, 0x1F, 0x00,
|
||||||
|
0x00, 0xFF, 0x3F, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0x8E, 0xFF, 0x7F, 0x1C, 0x9F, 0xFF, 0x7F, 0x3E,
|
||||||
|
0x9F, 0xFF, 0x7F, 0x3E, 0x8E, 0xFF, 0x7F, 0x1C, 0x80, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0x3F, 0x00,
|
||||||
|
0x00, 0xFE, 0x1F, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0xC0, 0xF9, 0xE7, 0x00, 0xE0, 0x01, 0xE0, 0x01, 0xF0, 0x01, 0xE0, 0x03,
|
||||||
|
0xF0, 0xC0, 0xC0, 0x03, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define rain_width 30
|
||||||
|
#define rain_height 30
|
||||||
|
static unsigned char rain[] PROGMEM = {
|
||||||
|
0xC0, 0x0F, 0xC0, 0x00, 0x40, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x03, 0x38, 0x00,
|
||||||
|
0x00, 0x0E, 0x0C, 0x00, 0x00, 0x18, 0x02, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x20,
|
||||||
|
0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x30, 0x02, 0x00,
|
||||||
|
0x00, 0x10, 0x06, 0x00, 0x00, 0x08, 0xFC, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x01, 0x80, 0x00, 0x01, 0x00,
|
||||||
|
0xC0, 0xC0, 0x81, 0x03, 0xA0, 0x60, 0xC1, 0x03, 0x90, 0x20, 0x41, 0x01, 0xF0, 0xE0, 0xC0, 0x01, 0x60, 0x4C,
|
||||||
|
0x98, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x0B, 0x12, 0x00, 0x00, 0x09, 0x1A, 0x00, 0x00, 0x06, 0x0E, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define cloud_height 30
|
||||||
|
#define cloud_width 30
|
||||||
|
static unsigned char cloud[] PROGMEM = {
|
||||||
|
0x00, 0x80, 0x07, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x70, 0x30, 0x00, 0x00, 0x10, 0x60, 0x00, 0x80, 0x1F, 0x40, 0x00,
|
||||||
|
0xC0, 0x0F, 0xC0, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x60, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x01,
|
||||||
|
0x20, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x18, 0x02, 0x00, 0x00, 0x10,
|
||||||
|
0x02, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20,
|
||||||
|
0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x10,
|
||||||
|
0x02, 0x00, 0x00, 0x10, 0x06, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x0C, 0xFC, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x03,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define fog_height 25
|
||||||
|
#define fog_width 25
|
||||||
|
static unsigned char fog[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3C, 0x00, 0xFE, 0x01, 0xFF, 0x00, 0x87, 0xC7, 0xC3, 0x01, 0x03, 0xFE, 0x80, 0x01,
|
||||||
|
0x00, 0x38, 0x00, 0x00, 0xFC, 0x00, 0x7E, 0x00, 0xFF, 0x83, 0xFF, 0x01, 0x03, 0xFF, 0x81, 0x01, 0x00, 0x7C, 0x00, 0x00,
|
||||||
|
0xF8, 0x00, 0x3E, 0x00, 0xFE, 0x01, 0xFF, 0x00, 0x87, 0xC7, 0xC3, 0x01, 0x03, 0xFE, 0x80, 0x01, 0x00, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define devil_height 30
|
||||||
|
#define devil_width 30
|
||||||
|
static unsigned char devil[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x10, 0x03, 0xC0, 0x01, 0x38, 0x07, 0x7C, 0x0F, 0x38, 0x1F, 0x03, 0x30, 0x1E,
|
||||||
|
0xFE, 0x01, 0xE0, 0x1F, 0x7E, 0x00, 0x80, 0x1F, 0x3C, 0x00, 0x00, 0x0F, 0x1C, 0x00, 0x00, 0x0E, 0x18, 0x00, 0x00, 0x06,
|
||||||
|
0x08, 0x00, 0x00, 0x04, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x0E, 0x1C, 0x0C,
|
||||||
|
0x0C, 0x18, 0x06, 0x0C, 0x0C, 0x1C, 0x06, 0x0C, 0x0C, 0x1C, 0x0E, 0x0C, 0x0C, 0x1C, 0x0E, 0x0C, 0x0C, 0x0C, 0x06, 0x0C,
|
||||||
|
0x08, 0x00, 0x00, 0x06, 0x18, 0x02, 0x10, 0x06, 0x10, 0x0C, 0x0C, 0x03, 0x30, 0xF8, 0x07, 0x03, 0x60, 0xE0, 0x80, 0x01,
|
||||||
|
0xC0, 0x00, 0xC0, 0x00, 0x80, 0x01, 0x70, 0x00, 0x00, 0x06, 0x1C, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define heart_height 30
|
||||||
|
#define heart_width 30
|
||||||
|
static unsigned char heart[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0xF0, 0x00, 0xF8, 0x0F, 0xFC, 0x07, 0xFC, 0x1F, 0x06, 0x0E, 0xFE, 0x3F, 0x03, 0x18,
|
||||||
|
0xFE, 0xFF, 0x7F, 0x10, 0xFF, 0xFF, 0xFF, 0x31, 0xFF, 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0xFF, 0x37, 0xFF, 0xFF, 0xFF, 0x37,
|
||||||
|
0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF, 0x1F, 0xFE, 0xFF, 0xFF, 0x1F,
|
||||||
|
0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0x03,
|
||||||
|
0xE0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x1F, 0x00,
|
||||||
|
0x00, 0xFC, 0x0F, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define poo_width 30
|
||||||
|
#define poo_height 30
|
||||||
|
static unsigned char poo[] PROGMEM = {
|
||||||
|
0x00, 0x1C, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xEC, 0x01, 0x00, 0x00, 0x8C, 0x07, 0x00, 0x00, 0x0C, 0x06, 0x00,
|
||||||
|
0x00, 0x24, 0x0C, 0x00, 0x00, 0x34, 0x08, 0x00, 0x00, 0x1F, 0x08, 0x00, 0xC0, 0x0F, 0x08, 0x00, 0xC0, 0x00, 0x3C, 0x00,
|
||||||
|
0x60, 0x00, 0x7C, 0x00, 0x60, 0x00, 0xC6, 0x00, 0x20, 0x00, 0xCB, 0x00, 0xA0, 0xC7, 0xFF, 0x00, 0xE0, 0x7F, 0xF7, 0x00,
|
||||||
|
0xF0, 0x18, 0xE3, 0x03, 0x78, 0x18, 0x41, 0x03, 0x6C, 0x9B, 0x5D, 0x06, 0x64, 0x9B, 0x5D, 0x04, 0x44, 0x1A, 0x41, 0x04,
|
||||||
|
0x4C, 0xD8, 0x63, 0x06, 0xF8, 0xFC, 0x36, 0x06, 0xFE, 0x0F, 0x9C, 0x1F, 0x07, 0x03, 0xC0, 0x30, 0x03, 0x00, 0x78, 0x20,
|
||||||
|
0x01, 0x00, 0x1F, 0x20, 0x03, 0xE0, 0x03, 0x20, 0x07, 0x7E, 0x04, 0x30, 0xFE, 0x0F, 0xFC, 0x1F, 0xF0, 0x00, 0xF0, 0x0F,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "img/icon.xbm"
|
#include "img/icon.xbm"
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ typedef struct _InputEvent {
|
|||||||
const char *source;
|
const char *source;
|
||||||
char inputEvent;
|
char inputEvent;
|
||||||
char kbchar;
|
char kbchar;
|
||||||
|
uint16_t touchX;
|
||||||
|
uint16_t touchY;
|
||||||
} InputEvent;
|
} InputEvent;
|
||||||
class InputBroker : public Observable<const InputEvent *>
|
class InputBroker : public Observable<const InputEvent *>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -155,6 +155,9 @@ int32_t LinuxInput::runOnce()
|
|||||||
case KEY_ENTER: // Enter
|
case KEY_ENTER: // Enter
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||||
break;
|
break;
|
||||||
|
case KEY_POWER:
|
||||||
|
system("poweroff");
|
||||||
|
break;
|
||||||
default: // all other keys
|
default: // all other keys
|
||||||
if (keymap[code]) {
|
if (keymap[code]) {
|
||||||
e.inputEvent = ANYKEY;
|
e.inputEvent = ANYKEY;
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ void TouchScreenImpl1::onEvent(const TouchEvent &event)
|
|||||||
{
|
{
|
||||||
InputEvent e;
|
InputEvent e;
|
||||||
e.source = event.source;
|
e.source = event.source;
|
||||||
|
|
||||||
|
e.touchX = event.x;
|
||||||
|
e.touchY = event.y;
|
||||||
|
|
||||||
switch (event.touchEvent) {
|
switch (event.touchEvent) {
|
||||||
case TOUCH_ACTION_LEFT: {
|
case TOUCH_ACTION_LEFT: {
|
||||||
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT);
|
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ typedef struct _meshtastic_HamParameters {
|
|||||||
Ensure your radio is capable of operating of the selected frequency before setting this. */
|
Ensure your radio is capable of operating of the selected frequency before setting this. */
|
||||||
float frequency;
|
float frequency;
|
||||||
/* Optional short name of user */
|
/* Optional short name of user */
|
||||||
char short_name[6];
|
char short_name[5];
|
||||||
} meshtastic_HamParameters;
|
} meshtastic_HamParameters;
|
||||||
|
|
||||||
/* Response envelope for node_remote_hardware_pins */
|
/* Response envelope for node_remote_hardware_pins */
|
||||||
@@ -342,7 +342,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg;
|
|||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size
|
#define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size
|
||||||
#define meshtastic_AdminMessage_size 500
|
#define meshtastic_AdminMessage_size 500
|
||||||
#define meshtastic_HamParameters_size 32
|
#define meshtastic_HamParameters_size 31
|
||||||
#define meshtastic_NodeRemoteHardwarePinsResponse_size 496
|
#define meshtastic_NodeRemoteHardwarePinsResponse_size 496
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ CannedMessageModule::CannedMessageModule()
|
|||||||
disable();
|
disable();
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("CannedMessageModule is enabled\n");
|
LOG_INFO("CannedMessageModule is enabled\n");
|
||||||
|
|
||||||
|
// T-Watch interface currently has no way to select destination type, so default to 'node'
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
||||||
|
#endif
|
||||||
|
|
||||||
this->inputObserver.observe(inputBroker);
|
this->inputObserver.observe(inputBroker);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -67,8 +73,16 @@ int CannedMessageModule::splitConfiguredMessages()
|
|||||||
int messageIndex = 0;
|
int messageIndex = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
String messages = cannedMessageModuleConfig.messages;
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
String separator = messages.length() ? "|" : "";
|
||||||
|
|
||||||
|
messages = "[---- Free Text ----]" + separator + messages;
|
||||||
|
#endif
|
||||||
|
|
||||||
// collect all the message parts
|
// collect all the message parts
|
||||||
strncpy(this->messageStore, cannedMessageModuleConfig.messages, sizeof(this->messageStore));
|
strncpy(this->messageStore, messages.c_str(), sizeof(this->messageStore));
|
||||||
|
|
||||||
// The first message points to the beginning of the store.
|
// The first message points to the beginning of the store.
|
||||||
this->messages[messageIndex++] = this->messageStore;
|
this->messages[messageIndex++] = this->messageStore;
|
||||||
@@ -78,7 +92,6 @@ int CannedMessageModule::splitConfiguredMessages()
|
|||||||
if (this->messageStore[i] == '|') {
|
if (this->messageStore[i] == '|') {
|
||||||
// Message ending found, replace it with string-end character.
|
// Message ending found, replace it with string-end character.
|
||||||
this->messageStore[i] = '\0';
|
this->messageStore[i] = '\0';
|
||||||
LOG_DEBUG("CannedMessage %d is: '%s'\n", messageIndex - 1, this->messages[messageIndex - 1]);
|
|
||||||
|
|
||||||
// hit our max messages, bail
|
// hit our max messages, bail
|
||||||
if (messageIndex >= CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT) {
|
if (messageIndex >= CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT) {
|
||||||
@@ -119,20 +132,30 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
bool validEvent = false;
|
bool validEvent = false;
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP)) {
|
||||||
if (this->messagesCount > 0) {
|
if (this->messagesCount > 0) {
|
||||||
// LOG_DEBUG("Canned message event UP\n");
|
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN)) {
|
||||||
if (this->messagesCount > 0) {
|
if (this->messagesCount > 0) {
|
||||||
// LOG_DEBUG("Canned message event DOWN\n");
|
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) {
|
||||||
LOG_DEBUG("Canned message event Select\n");
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
if (this->currentMessageIndex == 0) {
|
||||||
|
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
||||||
|
|
||||||
|
UIFrameEvent e = {false, true};
|
||||||
|
e.frameChanged = true;
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// when inactive, call the onebutton shortpress instead. Activate Module only on up/down
|
// when inactive, call the onebutton shortpress instead. Activate Module only on up/down
|
||||||
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
@@ -143,38 +166,47 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL)) {
|
||||||
LOG_DEBUG("Canned message event Cancel\n");
|
|
||||||
UIFrameEvent e = {false, true};
|
UIFrameEvent e = {false, true};
|
||||||
e.frameChanged = true;
|
e.frameChanged = true;
|
||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
|
|
||||||
|
#ifndef T_WATCH_S3
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
if ((event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
|
if ((event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
|
||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
||||||
// LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
|
this->payload = 0xb4;
|
||||||
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
||||||
|
this->payload = 0xb7;
|
||||||
|
}
|
||||||
|
#else
|
||||||
// tweak for left/right events generated via trackball/touch with empty kbchar
|
// tweak for left/right events generated via trackball/touch with empty kbchar
|
||||||
if (!event->kbchar) {
|
if (!event->kbchar) {
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
this->payload = 0xb4;
|
this->payload = 0xb4;
|
||||||
// this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
|
||||||
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
||||||
this->payload = 0xb7;
|
this->payload = 0xb7;
|
||||||
// this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// pass the pressed key
|
// pass the pressed key
|
||||||
this->payload = event->kbchar;
|
this->payload = event->kbchar;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
this->lastTouchMillis = millis();
|
this->lastTouchMillis = millis();
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
}
|
}
|
||||||
if (event->inputEvent == static_cast<char>(ANYKEY)) {
|
if (event->inputEvent == static_cast<char>(ANYKEY)) {
|
||||||
LOG_DEBUG("Canned message event any key pressed\n");
|
|
||||||
// when inactive, this will switch to the freetext mode
|
// when inactive, this will switch to the freetext mode
|
||||||
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) ||
|
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) ||
|
||||||
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
||||||
@@ -250,8 +282,68 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal
|
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||||
|
String keyTapped = keyForCoordinates(event->touchX, event->touchY);
|
||||||
|
|
||||||
|
if (keyTapped == "⇧") {
|
||||||
|
this->highlight = -1;
|
||||||
|
|
||||||
|
this->payload = 0x00;
|
||||||
|
|
||||||
|
validEvent = true;
|
||||||
|
|
||||||
|
this->shift = !this->shift;
|
||||||
|
} else if (keyTapped == "⌫") {
|
||||||
|
this->highlight = keyTapped[0];
|
||||||
|
|
||||||
|
this->payload = 0x08;
|
||||||
|
|
||||||
|
validEvent = true;
|
||||||
|
|
||||||
|
this->shift = false;
|
||||||
|
} else if (keyTapped == "123" || keyTapped == "ABC") {
|
||||||
|
this->highlight = -1;
|
||||||
|
|
||||||
|
this->payload = 0x00;
|
||||||
|
|
||||||
|
this->charSet = this->charSet == 0 ? 1 : 0;
|
||||||
|
|
||||||
|
validEvent = true;
|
||||||
|
} else if (keyTapped == " ") {
|
||||||
|
this->highlight = keyTapped[0];
|
||||||
|
|
||||||
|
this->payload = keyTapped[0];
|
||||||
|
|
||||||
|
validEvent = true;
|
||||||
|
|
||||||
|
this->shift = false;
|
||||||
|
} else if (keyTapped == "↵") {
|
||||||
|
this->highlight = 0x00;
|
||||||
|
|
||||||
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
||||||
|
|
||||||
|
this->payload = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
||||||
|
|
||||||
|
this->currentMessageIndex = event->kbchar - 1;
|
||||||
|
|
||||||
|
validEvent = true;
|
||||||
|
|
||||||
|
this->shift = false;
|
||||||
|
} else if (keyTapped != "") {
|
||||||
|
this->highlight = keyTapped[0];
|
||||||
|
|
||||||
|
this->payload = this->shift ? keyTapped[0] : std::tolower(keyTapped[0]);
|
||||||
|
|
||||||
|
validEvent = true;
|
||||||
|
|
||||||
|
this->shift = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (event->inputEvent == static_cast<char>(MATRIXKEY)) {
|
if (event->inputEvent == static_cast<char>(MATRIXKEY)) {
|
||||||
LOG_DEBUG("Canned message event Matrix key pressed\n");
|
|
||||||
// this will send the text immediately on matrix press
|
// this will send the text immediately on matrix press
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
||||||
this->payload = MATRIXKEY;
|
this->payload = MATRIXKEY;
|
||||||
@@ -311,17 +403,24 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
|
|
||||||
|
#ifndef T_WATCH_S3
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) &&
|
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) &&
|
||||||
((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
|
((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
|
||||||
// Reset module
|
// Reset module
|
||||||
LOG_DEBUG("Reset due to lack of activity.\n");
|
|
||||||
e.frameChanged = true;
|
e.frameChanged = true;
|
||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
|
|
||||||
|
#ifndef T_WATCH_S3
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
||||||
@@ -330,7 +429,6 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
sendText(this->dest, indexChannels[this->channel], this->freetext.c_str(), true);
|
sendText(this->dest, indexChannels[this->channel], this->freetext.c_str(), true);
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Reset message is empty.\n");
|
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -339,11 +437,15 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
sendText(this->dest, indexChannels[this->channel], this->messages[this->currentMessageIndex], true);
|
||||||
|
#else
|
||||||
sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true);
|
sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Reset message is empty.\n");
|
// LOG_DEBUG("Reset message is empty.\n");
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,7 +453,11 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
|
|
||||||
|
#ifndef T_WATCH_S3
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
return 2000;
|
return 2000;
|
||||||
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
||||||
@@ -364,7 +470,11 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = getPrevIndex();
|
this->currentMessageIndex = getPrevIndex();
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
|
|
||||||
|
#ifndef T_WATCH_S3
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||||
LOG_DEBUG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
LOG_DEBUG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||||
}
|
}
|
||||||
@@ -373,7 +483,11 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = this->getNextIndex();
|
this->currentMessageIndex = this->getNextIndex();
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
|
|
||||||
|
#ifndef T_WATCH_S3
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||||
LOG_DEBUG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
LOG_DEBUG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||||
}
|
}
|
||||||
@@ -457,7 +571,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
switch (this->payload) { // code below all trigger the freetext window (where you type to send a message) or reset the
|
switch (this->payload) { // code below all trigger the freetext window (where you type to send a message) or reset the
|
||||||
// display back to the default window
|
// display back to the default window
|
||||||
case 0x08: // backspace
|
case 0x08: // backspace
|
||||||
if (this->freetext.length() > 0) {
|
if (this->freetext.length() > 0 && this->highlight == 0x00) {
|
||||||
if (this->cursor == this->freetext.length()) {
|
if (this->cursor == this->freetext.length()) {
|
||||||
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
||||||
} else {
|
} else {
|
||||||
@@ -495,13 +609,19 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (this->highlight != 0x00) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->cursor == this->freetext.length()) {
|
if (this->cursor == this->freetext.length()) {
|
||||||
this->freetext += this->payload;
|
this->freetext += this->payload;
|
||||||
} else {
|
} else {
|
||||||
this->freetext =
|
this->freetext =
|
||||||
this->freetext.substring(0, this->cursor) + this->payload + this->freetext.substring(this->cursor);
|
this->freetext.substring(0, this->cursor) + this->payload + this->freetext.substring(this->cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->cursor += 1;
|
this->cursor += 1;
|
||||||
|
|
||||||
uint16_t maxChars = meshtastic_Constants_DATA_PAYLOAD_LEN - (moduleConfig.canned_message.send_bell ? 1 : 0);
|
uint16_t maxChars = meshtastic_Constants_DATA_PAYLOAD_LEN - (moduleConfig.canned_message.send_bell ? 1 : 0);
|
||||||
if (this->freetext.length() > maxChars) {
|
if (this->freetext.length() > maxChars) {
|
||||||
this->cursor = maxChars;
|
this->cursor = maxChars;
|
||||||
@@ -594,6 +714,201 @@ void CannedMessageModule::showTemporaryMessage(const String &message)
|
|||||||
setIntervalFromNow(2000);
|
setIntervalFromNow(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
|
||||||
|
String CannedMessageModule::keyForCoordinates(uint x, uint y)
|
||||||
|
{
|
||||||
|
int outerSize = *(&this->keyboard[this->charSet] + 1) - this->keyboard[this->charSet];
|
||||||
|
|
||||||
|
for (int8_t outerIndex = 0; outerIndex < outerSize; outerIndex++) {
|
||||||
|
int innerSize = *(&this->keyboard[this->charSet][outerIndex] + 1) - this->keyboard[this->charSet][outerIndex];
|
||||||
|
|
||||||
|
for (int8_t innerIndex = 0; innerIndex < innerSize; innerIndex++) {
|
||||||
|
Letter letter = this->keyboard[this->charSet][outerIndex][innerIndex];
|
||||||
|
|
||||||
|
if (x > letter.rectX && x < (letter.rectX + letter.rectWidth) && y > letter.rectY &&
|
||||||
|
y < (letter.rectY + letter.rectHeight)) {
|
||||||
|
return letter.character;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CannedMessageModule::drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
int outerSize = *(&this->keyboard[this->charSet] + 1) - this->keyboard[this->charSet];
|
||||||
|
|
||||||
|
int xOffset = 0;
|
||||||
|
|
||||||
|
int yOffset = 56;
|
||||||
|
|
||||||
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
|
||||||
|
display->setFont(FONT_SMALL);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||||
|
|
||||||
|
display->drawStringMaxWidth(0, 0, display->getWidth(),
|
||||||
|
cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
||||||
|
|
||||||
|
display->setFont(FONT_MEDIUM);
|
||||||
|
|
||||||
|
int cellHeight = round((display->height() - 64) / outerSize);
|
||||||
|
|
||||||
|
int yCorrection = 8;
|
||||||
|
|
||||||
|
for (int8_t outerIndex = 0; outerIndex < outerSize; outerIndex++) {
|
||||||
|
yOffset += outerIndex > 0 ? cellHeight : 0;
|
||||||
|
|
||||||
|
int innerSizeBound = *(&this->keyboard[this->charSet][outerIndex] + 1) - this->keyboard[this->charSet][outerIndex];
|
||||||
|
|
||||||
|
int innerSize = 0;
|
||||||
|
|
||||||
|
for (int8_t innerIndex = 0; innerIndex < innerSizeBound; innerIndex++) {
|
||||||
|
if (this->keyboard[this->charSet][outerIndex][innerIndex].character != "") {
|
||||||
|
innerSize++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cellWidth = display->width() / innerSize;
|
||||||
|
|
||||||
|
for (int8_t innerIndex = 0; innerIndex < innerSize; innerIndex++) {
|
||||||
|
xOffset += innerIndex > 0 ? cellWidth : 0;
|
||||||
|
|
||||||
|
Letter letter = this->keyboard[this->charSet][outerIndex][innerIndex];
|
||||||
|
|
||||||
|
Letter updatedLetter = {letter.character, letter.width, xOffset, yOffset, cellWidth, cellHeight};
|
||||||
|
|
||||||
|
this->keyboard[this->charSet][outerIndex][innerIndex] = updatedLetter;
|
||||||
|
|
||||||
|
float characterOffset = ((cellWidth / 2) - (letter.width / 2));
|
||||||
|
|
||||||
|
if (letter.character == "⇧") {
|
||||||
|
if (this->shift) {
|
||||||
|
display->fillRect(xOffset, yOffset, cellWidth, cellHeight);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::BLACK);
|
||||||
|
|
||||||
|
drawShiftIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||||
|
} else {
|
||||||
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
||||||
|
|
||||||
|
drawShiftIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
||||||
|
}
|
||||||
|
} else if (letter.character == "⌫") {
|
||||||
|
if (this->highlight == letter.character[0]) {
|
||||||
|
display->fillRect(xOffset, yOffset, cellWidth, cellHeight);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::BLACK);
|
||||||
|
|
||||||
|
drawBackspaceIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||||
|
|
||||||
|
setIntervalFromNow(0);
|
||||||
|
} else {
|
||||||
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
||||||
|
|
||||||
|
drawBackspaceIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
||||||
|
}
|
||||||
|
} else if (letter.character == "↵") {
|
||||||
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
||||||
|
|
||||||
|
drawEnterIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.7);
|
||||||
|
} else {
|
||||||
|
if (this->highlight == letter.character[0]) {
|
||||||
|
display->fillRect(xOffset, yOffset, cellWidth, cellHeight);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::BLACK);
|
||||||
|
|
||||||
|
display->drawString(xOffset + characterOffset, yOffset + yCorrection,
|
||||||
|
letter.character == " " ? "space" : letter.character);
|
||||||
|
|
||||||
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||||
|
|
||||||
|
setIntervalFromNow(0);
|
||||||
|
} else {
|
||||||
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
||||||
|
|
||||||
|
display->drawString(xOffset + characterOffset, yOffset + yCorrection,
|
||||||
|
letter.character == " " ? "space" : letter.character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->highlight = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CannedMessageModule::drawShiftIcon(OLEDDisplay *display, int x, int y, float scale)
|
||||||
|
{
|
||||||
|
PointStruct shiftIcon[10] = {{8, 0}, {15, 7}, {15, 8}, {12, 8}, {12, 12}, {4, 12}, {4, 8}, {1, 8}, {1, 7}, {8, 0}};
|
||||||
|
|
||||||
|
int size = 10;
|
||||||
|
|
||||||
|
for (int i = 0; i < size - 1; i++) {
|
||||||
|
int x0 = x + (shiftIcon[i].x * scale);
|
||||||
|
int y0 = y + (shiftIcon[i].y * scale);
|
||||||
|
int x1 = x + (shiftIcon[i + 1].x * scale);
|
||||||
|
int y1 = y + (shiftIcon[i + 1].y * scale);
|
||||||
|
|
||||||
|
display->drawLine(x0, y0, x1, y1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CannedMessageModule::drawBackspaceIcon(OLEDDisplay *display, int x, int y, float scale)
|
||||||
|
{
|
||||||
|
PointStruct backspaceIcon[6] = {{0, 7}, {5, 2}, {15, 2}, {15, 12}, {5, 12}, {0, 7}};
|
||||||
|
|
||||||
|
int size = 6;
|
||||||
|
|
||||||
|
for (int i = 0; i < size - 1; i++) {
|
||||||
|
int x0 = x + (backspaceIcon[i].x * scale);
|
||||||
|
int y0 = y + (backspaceIcon[i].y * scale);
|
||||||
|
int x1 = x + (backspaceIcon[i + 1].x * scale);
|
||||||
|
int y1 = y + (backspaceIcon[i + 1].y * scale);
|
||||||
|
|
||||||
|
display->drawLine(x0, y0, x1, y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
PointStruct backspaceIconX[4] = {{7, 4}, {13, 10}, {7, 10}, {13, 4}};
|
||||||
|
|
||||||
|
size = 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < size - 1; i++) {
|
||||||
|
int x0 = x + (backspaceIconX[i].x * scale);
|
||||||
|
int y0 = y + (backspaceIconX[i].y * scale);
|
||||||
|
int x1 = x + (backspaceIconX[i + 1].x * scale);
|
||||||
|
int y1 = y + (backspaceIconX[i + 1].y * scale);
|
||||||
|
|
||||||
|
display->drawLine(x0, y0, x1, y1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CannedMessageModule::drawEnterIcon(OLEDDisplay *display, int x, int y, float scale)
|
||||||
|
{
|
||||||
|
PointStruct enterIcon[6] = {{0, 7}, {4, 3}, {4, 11}, {0, 7}, {15, 7}, {15, 0}};
|
||||||
|
|
||||||
|
int size = 6;
|
||||||
|
|
||||||
|
for (int i = 0; i < size - 1; i++) {
|
||||||
|
int x0 = x + (enterIcon[i].x * scale);
|
||||||
|
int y0 = y + (enterIcon[i].y * scale);
|
||||||
|
int x1 = x + (enterIcon[i + 1].x * scale);
|
||||||
|
int y1 = y + (enterIcon[i + 1].y * scale);
|
||||||
|
|
||||||
|
display->drawLine(x0, y0, x1, y1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
@@ -614,6 +929,16 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
}
|
}
|
||||||
display->drawStringf(display->getWidth() / 2 + x, 0 + y + 12, buffer, displayString,
|
display->drawStringf(display->getWidth() / 2 + x, 0 + y + 12, buffer, displayString,
|
||||||
cannedMessageModule->getNodeName(this->incoming));
|
cannedMessageModule->getNodeName(this->incoming));
|
||||||
|
|
||||||
|
display->setFont(FONT_SMALL);
|
||||||
|
|
||||||
|
String snrString = "Last Rx SNR: %f";
|
||||||
|
String rssiString = "Last Rx RSSI: %d";
|
||||||
|
|
||||||
|
if (this->ack) {
|
||||||
|
display->drawStringf(display->getWidth() / 2 + x, y + 100, buffer, snrString, this->lastRxSnr);
|
||||||
|
display->drawStringf(display->getWidth() / 2 + x, y + 130, buffer, rssiString, this->lastRxRssi);
|
||||||
|
}
|
||||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_MEDIUM);
|
||||||
@@ -623,6 +948,11 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
|
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
|
||||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
drawKeyboard(display, state, 0, 0);
|
||||||
|
#else
|
||||||
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
if (this->destSelect != CANNED_MESSAGE_DESTINATION_TYPE_NONE) {
|
if (this->destSelect != CANNED_MESSAGE_DESTINATION_TYPE_NONE) {
|
||||||
@@ -663,6 +993,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
display->drawStringMaxWidth(
|
display->drawStringMaxWidth(
|
||||||
0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(),
|
0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(),
|
||||||
cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (this->messagesCount > 0) {
|
if (this->messagesCount > 0) {
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
|||||||
@@ -22,6 +22,17 @@ enum cannedMessageDestinationType {
|
|||||||
CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL
|
CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CannedMessageModuleIconType { shift, backspace, space, enter };
|
||||||
|
|
||||||
|
struct Letter {
|
||||||
|
String character;
|
||||||
|
float width;
|
||||||
|
int rectX;
|
||||||
|
int rectY;
|
||||||
|
int rectWidth;
|
||||||
|
int rectHeight;
|
||||||
|
};
|
||||||
|
|
||||||
#define CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT 50
|
#define CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT 50
|
||||||
/**
|
/**
|
||||||
* Sum of CannedMessageModuleConfig part sizes.
|
* Sum of CannedMessageModuleConfig part sizes.
|
||||||
@@ -61,6 +72,14 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
*/
|
*/
|
||||||
virtual bool wantPacket(const meshtastic_MeshPacket *p) override
|
virtual bool wantPacket(const meshtastic_MeshPacket *p) override
|
||||||
{
|
{
|
||||||
|
if (p->rx_rssi != 0) {
|
||||||
|
this->lastRxRssi = p->rx_rssi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->rx_snr > 0) {
|
||||||
|
this->lastRxSnr = p->rx_snr;
|
||||||
|
}
|
||||||
|
|
||||||
switch (p->decoded.portnum) {
|
switch (p->decoded.portnum) {
|
||||||
case meshtastic_PortNum_TEXT_MESSAGE_APP:
|
case meshtastic_PortNum_TEXT_MESSAGE_APP:
|
||||||
case meshtastic_PortNum_ROUTING_APP:
|
case meshtastic_PortNum_ROUTING_APP:
|
||||||
@@ -79,6 +98,18 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
int getNextIndex();
|
int getNextIndex();
|
||||||
int getPrevIndex();
|
int getPrevIndex();
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
void drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
String keyForCoordinates(uint x, uint y);
|
||||||
|
bool shift = false;
|
||||||
|
int charSet = 0;
|
||||||
|
void drawShiftIcon(OLEDDisplay *display, int x, int y, float scale = 1);
|
||||||
|
void drawBackspaceIcon(OLEDDisplay *display, int x, int y, float scale = 1);
|
||||||
|
void drawEnterIcon(OLEDDisplay *display, int x, int y, float scale = 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char highlight = 0x00;
|
||||||
|
|
||||||
int handleInputEvent(const InputEvent *event);
|
int handleInputEvent(const InputEvent *event);
|
||||||
virtual bool wantUIFrame() override { return this->shouldDraw(); }
|
virtual bool wantUIFrame() override { return this->shouldDraw(); }
|
||||||
virtual Observable<const UIFrameEvent *> *getUIFrameObservable() override { return this; }
|
virtual Observable<const UIFrameEvent *> *getUIFrameObservable() override { return this; }
|
||||||
@@ -110,12 +141,84 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
ChannelIndex indexChannels[MAX_NUM_CHANNELS] = {0};
|
ChannelIndex indexChannels[MAX_NUM_CHANNELS] = {0};
|
||||||
NodeNum incoming = NODENUM_BROADCAST;
|
NodeNum incoming = NODENUM_BROADCAST;
|
||||||
bool ack = false; // True means ACK, false means NAK (error_reason != NONE)
|
bool ack = false; // True means ACK, false means NAK (error_reason != NONE)
|
||||||
|
float lastRxSnr = 0;
|
||||||
|
int32_t lastRxRssi = 0;
|
||||||
|
|
||||||
char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE + 1];
|
char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE + 1];
|
||||||
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
|
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
|
||||||
int messagesCount = 0;
|
int messagesCount = 0;
|
||||||
unsigned long lastTouchMillis = 0;
|
unsigned long lastTouchMillis = 0;
|
||||||
String temporaryMessage;
|
String temporaryMessage;
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
Letter keyboard[2][4][10] = {{{{"Q", 20, 0, 0, 0, 0},
|
||||||
|
{"W", 22, 0, 0, 0, 0},
|
||||||
|
{"E", 17, 0, 0, 0, 0},
|
||||||
|
{"R", 16.5, 0, 0, 0, 0},
|
||||||
|
{"T", 14, 0, 0, 0, 0},
|
||||||
|
{"Y", 15, 0, 0, 0, 0},
|
||||||
|
{"U", 16.5, 0, 0, 0, 0},
|
||||||
|
{"I", 5, 0, 0, 0, 0},
|
||||||
|
{"O", 19.5, 0, 0, 0, 0},
|
||||||
|
{"P", 15.5, 0, 0, 0, 0}},
|
||||||
|
{{"A", 14, 0, 0, 0, 0},
|
||||||
|
{"S", 15, 0, 0, 0, 0},
|
||||||
|
{"D", 16.5, 0, 0, 0, 0},
|
||||||
|
{"F", 15, 0, 0, 0, 0},
|
||||||
|
{"G", 17, 0, 0, 0, 0},
|
||||||
|
{"H", 15.5, 0, 0, 0, 0},
|
||||||
|
{"J", 12, 0, 0, 0, 0},
|
||||||
|
{"K", 15.5, 0, 0, 0, 0},
|
||||||
|
{"L", 14, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0}},
|
||||||
|
{{"⇧", 20, 0, 0, 0, 0},
|
||||||
|
{"Z", 14, 0, 0, 0, 0},
|
||||||
|
{"X", 14.5, 0, 0, 0, 0},
|
||||||
|
{"C", 15.5, 0, 0, 0, 0},
|
||||||
|
{"V", 13.5, 0, 0, 0, 0},
|
||||||
|
{"B", 15, 0, 0, 0, 0},
|
||||||
|
{"N", 15, 0, 0, 0, 0},
|
||||||
|
{"M", 17, 0, 0, 0, 0},
|
||||||
|
{"⌫", 20, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0}},
|
||||||
|
{{"123", 42, 0, 0, 0, 0},
|
||||||
|
{" ", 64, 0, 0, 0, 0},
|
||||||
|
{"↵", 36, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0},
|
||||||
|
{"", 0, 0, 0, 0, 0}}},
|
||||||
|
{{{"1", 12, 0, 0, 0, 0},
|
||||||
|
{"2", 13.5, 0, 0, 0, 0},
|
||||||
|
{"3", 12.5, 0, 0, 0, 0},
|
||||||
|
{"4", 14, 0, 0, 0, 0},
|
||||||
|
{"5", 14, 0, 0, 0, 0},
|
||||||
|
{"6", 14, 0, 0, 0, 0},
|
||||||
|
{"7", 13.5, 0, 0, 0, 0},
|
||||||
|
{"8", 14, 0, 0, 0, 0},
|
||||||
|
{"9", 14, 0, 0, 0, 0},
|
||||||
|
{"0", 14, 0, 0, 0, 0}},
|
||||||
|
{{"-", 8, 0, 0, 0, 0},
|
||||||
|
{"/", 8, 0, 0, 0, 0},
|
||||||
|
{":", 4.5, 0, 0, 0, 0},
|
||||||
|
{";", 4.5, 0, 0, 0, 0},
|
||||||
|
{"(", 7, 0, 0, 0, 0},
|
||||||
|
{")", 6.5, 0, 0, 0, 0},
|
||||||
|
{"$", 12.5, 0, 0, 0, 0},
|
||||||
|
{"&", 15, 0, 0, 0, 0},
|
||||||
|
{"@", 21.5, 0, 0, 0, 0},
|
||||||
|
{"\"", 8, 0, 0, 0, 0}},
|
||||||
|
{{".", 8, 0, 0, 0, 0},
|
||||||
|
{",", 8, 0, 0, 0, 0},
|
||||||
|
{"?", 10, 0, 0, 0, 0},
|
||||||
|
{"!", 10, 0, 0, 0, 0},
|
||||||
|
{"'", 10, 0, 0, 0, 0},
|
||||||
|
{"⌫", 20, 0, 0, 0, 0}},
|
||||||
|
{{"ABC", 50, 0, 0, 0, 0}, {" ", 64, 0, 0, 0, 0}, {"↵", 36, 0, 0, 0, 0}}}};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CannedMessageModule *cannedMessageModule;
|
extern CannedMessageModule *cannedMessageModule;
|
||||||
|
|||||||
@@ -157,7 +157,9 @@ void NimbleBluetooth::setup()
|
|||||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
|
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
|
||||||
|
|
||||||
if (config.bluetooth.mode != meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN) {
|
if (config.bluetooth.mode != meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN) {
|
||||||
NimBLEDevice::setSecurityAuth(true, true, true);
|
NimBLEDevice::setSecurityAuth(BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM | BLE_SM_PAIR_AUTHREQ_SC);
|
||||||
|
NimBLEDevice::setSecurityInitKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID);
|
||||||
|
NimBLEDevice::setSecurityRespKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID);
|
||||||
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
||||||
}
|
}
|
||||||
bleServer = NimBLEDevice::createServer();
|
bleServer = NimBLEDevice::createServer();
|
||||||
|
|||||||
@@ -218,7 +218,12 @@ void cpuDeepSleep(uint32_t msecToWake)
|
|||||||
// just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN);
|
// just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN);
|
||||||
|
|
||||||
#if SOC_PM_SUPPORT_EXT_WAKEUP
|
#if SOC_PM_SUPPORT_EXT_WAKEUP
|
||||||
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
|
// ESP_EXT1_WAKEUP_ALL_LOW has been deprecated since esp-idf v5.4 for any other target.
|
||||||
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
|
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
|
||||||
|
#else
|
||||||
|
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ANY_LOW);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ void powerCommandsCheck()
|
|||||||
Serial1.end();
|
Serial1.end();
|
||||||
if (screen)
|
if (screen)
|
||||||
delete screen;
|
delete screen;
|
||||||
|
LOG_DEBUG("final reboot!\n");
|
||||||
reboot();
|
reboot();
|
||||||
#else
|
#else
|
||||||
rebootAtMsec = -1;
|
rebootAtMsec = -1;
|
||||||
|
|||||||
@@ -11,15 +11,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) \
|
|
||||||
(((p) < 48) ? (p) : -1) // Maybe it should be <= 48 but this is from a trustworthy source so it is likely correct
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
// Serial
|
// Serial
|
||||||
static const uint8_t TX = UART_TX;
|
static const uint8_t TX = UART_TX;
|
||||||
static const uint8_t RX = UART_RX;
|
static const uint8_t RX = UART_RX;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
[env:CDEBYTE_EoRa-S3]
|
[env:CDEBYTE_EoRa-S3]
|
||||||
extends = esp32s3_base
|
extends = esp32s3_base
|
||||||
board = CDEBYTE_EoRa-S3
|
board = CDEBYTE_EoRa-S3
|
||||||
board_level = extra
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D CDEBYTE_EORA_S3
|
-D CDEBYTE_EORA_S3
|
||||||
|
|||||||
@@ -11,15 +11,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) \
|
|
||||||
(((p) < 48) ? (p) : -1) // Maybe it should be <= 48 but this is from a trustworthy source so it is likely correct
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
// Serial
|
// Serial
|
||||||
static const uint8_t TX = UART_TX;
|
static const uint8_t TX = UART_TX;
|
||||||
static const uint8_t RX = UART_RX;
|
static const uint8_t RX = UART_RX;
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
// The default Wire will be mapped to PMU and RTC
|
// The default Wire will be mapped to PMU and RTC
|
||||||
static const uint8_t SDA = 15;
|
static const uint8_t SDA = 15;
|
||||||
static const uint8_t SCL = 16;
|
static const uint8_t SCL = 16;
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 22
|
|
||||||
#define NUM_DIGITAL_PINS 22
|
|
||||||
#define NUM_ANALOG_INPUTS 6
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < NUM_ANALOG_INPUTS) ? (esp32_adc2gpio[(p)]) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < NUM_DIGITAL_PINS) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < EXTERNAL_NUM_INTERRUPTS)
|
|
||||||
|
|
||||||
static const uint8_t TX = 21;
|
static const uint8_t TX = 21;
|
||||||
static const uint8_t RX = 20;
|
static const uint8_t RX = 20;
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,6 @@
|
|||||||
#define DISPLAY_HEIGHT 64
|
#define DISPLAY_HEIGHT 64
|
||||||
#define DISPLAY_WIDTH 128
|
#define DISPLAY_WIDTH 128
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
|
||||||
#define NUM_DIGITAL_PINS 40
|
|
||||||
#define NUM_ANALOG_INPUTS 16
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 34)
|
|
||||||
|
|
||||||
static const uint8_t LED_BUILTIN = 35;
|
static const uint8_t LED_BUILTIN = 35;
|
||||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
#define LED_BUILTIN LED_BUILTIN
|
#define LED_BUILTIN LED_BUILTIN
|
||||||
|
|||||||
@@ -7,14 +7,6 @@
|
|||||||
#define DISPLAY_HEIGHT 64
|
#define DISPLAY_HEIGHT 64
|
||||||
#define DISPLAY_WIDTH 128
|
#define DISPLAY_WIDTH 128
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
|
||||||
#define NUM_DIGITAL_PINS 40
|
|
||||||
#define NUM_ANALOG_INPUTS 16
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 34)
|
|
||||||
|
|
||||||
static const uint8_t LED_BUILTIN = 35;
|
static const uint8_t LED_BUILTIN = 35;
|
||||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
#define LED_BUILTIN LED_BUILTIN
|
#define LED_BUILTIN LED_BUILTIN
|
||||||
|
|||||||
@@ -11,18 +11,10 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
static const uint8_t LED_BUILTIN = 18;
|
static const uint8_t LED_BUILTIN = 18;
|
||||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
#define LED_BUILTIN LED_BUILTIN
|
#define LED_BUILTIN LED_BUILTIN
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -11,18 +11,10 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
static const uint8_t LED_BUILTIN = 18;
|
static const uint8_t LED_BUILTIN = 18;
|
||||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
#define LED_BUILTIN LED_BUILTIN
|
#define LED_BUILTIN LED_BUILTIN
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 22
|
|
||||||
#define NUM_DIGITAL_PINS 22
|
|
||||||
#define NUM_ANALOG_INPUTS 6
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < NUM_ANALOG_INPUTS) ? (esp32_adc2gpio[(p)]) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < NUM_DIGITAL_PINS) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < EXTERNAL_NUM_INTERRUPTS)
|
|
||||||
|
|
||||||
static const uint8_t TX = -1; // 21;
|
static const uint8_t TX = -1; // 21;
|
||||||
static const uint8_t RX = -1; // 20;
|
static const uint8_t RX = -1; // 20;
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
|
||||||
#define NUM_DIGITAL_PINS 20
|
|
||||||
#define NUM_ANALOG_INPUTS 16
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 34)
|
|
||||||
|
|
||||||
static const uint8_t TX = 1;
|
static const uint8_t TX = 1;
|
||||||
static const uint8_t RX = 3;
|
static const uint8_t RX = 3;
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
|
||||||
#define NUM_DIGITAL_PINS 40
|
|
||||||
#define NUM_ANALOG_INPUTS 16
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (esp32_adc2gpio[(p)]) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 34)
|
|
||||||
|
|
||||||
#define TX2 -1
|
#define TX2 -1
|
||||||
#define RX2 -1
|
#define RX2 -1
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
// The default Wire will be mapped to PMU and RTC
|
// The default Wire will be mapped to PMU and RTC
|
||||||
static const uint8_t SDA = 18;
|
static const uint8_t SDA = 18;
|
||||||
static const uint8_t SCL = 17;
|
static const uint8_t SCL = 17;
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
// The default Wire will be mapped to PMU and RTC
|
// The default Wire will be mapped to PMU and RTC
|
||||||
static const uint8_t SDA = 18;
|
static const uint8_t SDA = 18;
|
||||||
static const uint8_t SCL = 17;
|
static const uint8_t SCL = 17;
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
|
||||||
#define NUM_DIGITAL_PINS 40
|
|
||||||
#define NUM_ANALOG_INPUTS 16
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (esp32_adc2gpio[(p)]) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 34)
|
|
||||||
|
|
||||||
#define LED_GREEN 12
|
#define LED_GREEN 12
|
||||||
#define LED_BLUE 2
|
#define LED_BLUE 2
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
|
||||||
#define NUM_DIGITAL_PINS 40
|
|
||||||
#define NUM_ANALOG_INPUTS 16
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (esp32_adc2gpio[(p)]) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 34)
|
|
||||||
|
|
||||||
#define LED_GREEN 12
|
#define LED_GREEN 12
|
||||||
#define LED_BLUE 2
|
#define LED_BLUE 2
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) <= 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
// GPIO48 Reference: https://github.com/espressif/arduino-esp32/pull/8600
|
// GPIO48 Reference: https://github.com/espressif/arduino-esp32/pull/8600
|
||||||
|
|
||||||
// The default Wire will be mapped to Screen and Sensors
|
// The default Wire will be mapped to Screen and Sensors
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ upload_protocol = esptool
|
|||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
build_unflags = -DARDUINO_USB_MODE=1
|
build_unflags =
|
||||||
|
${esp32s3_base.build_unflags}
|
||||||
|
-DARDUINO_USB_MODE=1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags} -D STATION_G2 -I variants/station-g2
|
${esp32s3_base.build_flags} -D STATION_G2 -I variants/station-g2
|
||||||
-DBOARD_HAS_PSRAM
|
-DBOARD_HAS_PSRAM
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < NUM_ANALOG_INPUTS) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < NUM_DIGITAL_PINS) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < EXTERNAL_NUM_INTERRUPTS)
|
|
||||||
|
|
||||||
// static const uint8_t LED_BUILTIN = -1;
|
// static const uint8_t LED_BUILTIN = -1;
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < NUM_ANALOG_INPUTS) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < NUM_DIGITAL_PINS) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < EXTERNAL_NUM_INTERRUPTS)
|
|
||||||
|
|
||||||
// static const uint8_t LED_BUILTIN = -1;
|
// static const uint8_t LED_BUILTIN = -1;
|
||||||
|
|
||||||
// static const uint8_t TX = 43;
|
// static const uint8_t TX = 43;
|
||||||
|
|||||||
@@ -6,6 +6,14 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
|
#define EXTERNAL_NUM_INTERRUPTS 46
|
||||||
|
#define NUM_DIGITAL_PINS 48
|
||||||
|
#define NUM_ANALOG_INPUTS 20
|
||||||
|
|
||||||
|
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
||||||
|
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
||||||
|
#define digitalPinHasPWM(p) (p < 46)
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ extends = esp32s3_base
|
|||||||
board = tbeam-s3-core
|
board = tbeam-s3-core
|
||||||
board_check = true
|
board_check = true
|
||||||
|
|
||||||
platform = platformio/espressif32@6.7.0
|
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
// The default Wire will be mapped to PMU and RTC
|
// The default Wire will be mapped to PMU and RTC
|
||||||
static const uint8_t SDA = 18;
|
static const uint8_t SDA = 18;
|
||||||
static const uint8_t SCL = 17;
|
static const uint8_t SCL = 17;
|
||||||
|
|||||||
@@ -11,18 +11,10 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
static const uint8_t LED_BUILTIN = 18;
|
static const uint8_t LED_BUILTIN = 18;
|
||||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
#define LED_BUILTIN LED_BUILTIN
|
#define LED_BUILTIN LED_BUILTIN
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -11,18 +11,10 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
static const uint8_t LED_BUILTIN = 18;
|
static const uint8_t LED_BUILTIN = 18;
|
||||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
#define LED_BUILTIN LED_BUILTIN
|
#define LED_BUILTIN LED_BUILTIN
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -11,18 +11,10 @@
|
|||||||
#define USB_VID 0x303a
|
#define USB_VID 0x303a
|
||||||
#define USB_PID 0x1001
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
|
||||||
#define NUM_DIGITAL_PINS 48
|
|
||||||
#define NUM_ANALOG_INPUTS 20
|
|
||||||
|
|
||||||
static const uint8_t LED_BUILTIN = 18;
|
static const uint8_t LED_BUILTIN = 18;
|
||||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
#define LED_BUILTIN LED_BUILTIN
|
#define LED_BUILTIN LED_BUILTIN
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 46)
|
|
||||||
|
|
||||||
static const uint8_t TX = 43;
|
static const uint8_t TX = 43;
|
||||||
static const uint8_t RX = 44;
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ monitor_speed = 115200
|
|||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
|
|
||||||
build_unflags =
|
build_unflags =
|
||||||
|
${esp32s3_base.build_unflags}
|
||||||
-D ARDUINO_USB_MODE
|
-D ARDUINO_USB_MODE
|
||||||
|
|
||||||
build_flags = ${esp32_base.build_flags}
|
build_flags = ${esp32_base.build_flags}
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
|
||||||
#define NUM_DIGITAL_PINS 20
|
|
||||||
#define NUM_ANALOG_INPUTS 16
|
|
||||||
|
|
||||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (esp32_adc2gpio[(p)]) : -1)
|
|
||||||
#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1)
|
|
||||||
#define digitalPinHasPWM(p) (p < 34)
|
|
||||||
|
|
||||||
static const uint8_t TX = 1;
|
static const uint8_t TX = 1;
|
||||||
static const uint8_t RX = 3;
|
static const uint8_t RX = 3;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 3
|
minor = 3
|
||||||
build = 10
|
build = 11
|
||||||
|
|||||||
Reference in New Issue
Block a user