Compare commits

..

477 Commits

Author SHA1 Message Date
Ben Meadors
31c4693c66 Missed the version bump apparently 2023-12-02 15:50:17 -06:00
GUVWAF
6ff61b3e04 Pico W: Initial Wi-Fi support (#2980)
* Pico W: Initial WiFi support: connects, but freezes after a while

* Update arduino-pico core to fix hang with Wi-Fi

* Add `picow` to workflow since it's different from `pico` now
2023-12-02 14:47:52 -06:00
S5NC
9e90b4af02 Update variant.h (#2930)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-12-02 07:46:25 -06:00
S5NC
2544733ad4 Standardise order for setting GPIO pin default values (#2942)
* Update SX126xInterface.cpp

* Update GPS.cpp

* Update TFTDisplay.cpp

* Update SX128xInterface.cpp

* Update EInkDisplay2.cpp

* trunk fmt

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2023-12-02 07:40:31 -06:00
Thomas Göttgens
1b6c11c5f1 tryfix crash (#2964)
* tryfix crash

* only use this when wifi is not enabled. (poking around)

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-12-02 07:00:20 -06:00
S5NC
4c69d06ac0 Update Power.cpp (#2979) 2023-12-02 06:30:00 -06:00
code8buster
85cbde75fe Merge pull request #2977 from meshtastic/g2-defaults
Factory Defaults for Nano G2 Ultra
2023-12-02 00:36:31 +00:00
Ben Meadors
a05bab35ad = 2023-12-01 07:17:38 -06:00
Ben Meadors
ac506a581c Merge branch 'master' into g2-defaults 2023-12-01 07:07:59 -06:00
Ben Meadors
def4ec5822 Always set user (nodeinfo) role to device config's current role (#2973) 2023-12-01 07:00:19 -06:00
Ben Meadors
209fb585b0 Default to what G2 comes with 2023-11-30 20:49:00 -06:00
S5NC
fb89482129 Set default LoRa SPI pins individually on ESP32 architecture (#2971)
* Each pin individually

* Correction

---------

Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-11-30 06:39:46 -06:00
Thomas Göttgens
8e742f2f80 Update portduino.ini 2023-11-30 11:53:47 +01:00
Thomas Göttgens
238cf8cdeb fix portduino 2023-11-30 11:53:47 +01:00
Thomas Göttgens
5df7f07f95 unpin radiolib 2023-11-30 11:53:47 +01:00
Thomas Göttgens
6fa026a78b fix radiolib API for 6.3.0 release 2023-11-30 10:59:01 +01:00
Jonathan Bennett
39743832ad Revert Portduino RadioLib to 6.1.0 2023-11-29 20:19:10 -06:00
Jonathan Bennett
bd2675caf1 Temporarily Pin RadioLib to 6.2.0 2023-11-29 20:19:10 -06:00
Jonathan Bennett
c489c251ab Pull in Portduino changes for Raspberry Pi support 2023-11-29 20:19:10 -06:00
Jonathan Bennett
14d03a2bda Initial implementation of I2C 2023-11-29 20:19:10 -06:00
Jonathan Bennett
423b8ad603 Adds real GPS support to Raspberry Pi arch 2023-11-29 20:19:10 -06:00
Jonathan Bennett
ce8342d3e5 Drop Pi HAL 2023-11-29 20:19:10 -06:00
Jonathan Bennett
57227c0f85 Add gpiochip setting 2023-11-29 20:19:10 -06:00
Jonathan Bennett
1ca2923658 Fix missed #if defined() logic 2023-11-29 20:19:10 -06:00
Jonathan Bennett
d10b1e1d00 Add better error reporting for RF95 init failure 2023-11-29 20:19:10 -06:00
Jonathan Bennett
d3e64350d9 Remove RADIOLIB_SPI_PARANOID compile option, as it does nothing 2023-11-29 20:19:10 -06:00
Jonathan Bennett
102efd4954 Move to portduino GPIO, adding user button support 2023-11-29 20:19:10 -06:00
S5NC
18cf8ca4fa Generalise SPI pin names (#2970)
* Generalise SPI pin names

* CS not NSS

* trunk fmt

* Update variant.h

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-11-29 15:51:05 -06:00
Ben Meadors
c7f6071f70 Enable IO2 toggling on RAK if the coast is clear (#2968)
* Enable IO2 toggling on RAK if the coast is clear

* Guard against monteops target which doesn't use 3V3 pin

* Also check for en_gpio = 0 to avoid re-setting the value
2023-11-28 20:40:51 -06:00
Thomas Göttgens
c7e3485dd7 Revert "same change for STM32WL - also update trunk"
This reverts commit f9fdb0f98d.
2023-11-26 14:49:11 +01:00
Thomas Göttgens
603e564db3 same change for STM32WL - also update trunk 2023-11-26 14:49:11 +01:00
Thomas Göttgens
ac318a9850 Swapped out crypto engine for one that also works with AES-256 2023-11-26 14:49:11 +01:00
Ben Meadors
1feb74f525 Add number of sats to default position flags (#2962) 2023-11-25 19:34:30 -06:00
Thomas Göttgens
d6fc1c314f WIP: Add battery level for Nimble 2023-11-25 16:03:39 +01:00
Thomas Göttgens
b3852322ef Add config example for Elecrow Hat
NFC
2023-11-24 14:40:20 +01:00
HookdomPonix
cbb8eb65ba Add USB detection to RAK4631 based boards. (#2956)
* Add support for the rak10701 board, no touch

* Moved tftblack fillin and changed teh src flags

* Added rak10701 to platformio.ini

* Add USB detection to RAK4631 units.

* Eliminate spurious symbol in comment field.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-11-22 10:30:55 -06:00
Jonathan Bennett
4712b1ca65 Add manual run option to package_raspbian.yml (#2954) 2023-11-22 07:17:48 -06:00
Ric In New Mexico
57542ce9e6 Retain device nodeinfo during reset-nodedb (#2951)
* INA3221 bugfixes & refinement
Reorganized and refactored some INA3221 code
Added comments
Added missing shunt resistor value (100mΩ)
Added INA3221 Channel 1 to getINAVoltage() for device battery monitoring
	modified:   src/Power.cpp
	modified:   src/modules/Telemetry/PowerTelemetry.cpp
	modified:   src/modules/Telemetry/Sensor/INA3221Sensor.cpp
	modified:   src/modules/Telemetry/Sensor/INA3221Sensor.h
	modified:   src/power.h

* reset-nodedb retain device nodeinfo
	modified:   src/mesh/NodeDB.cpp

* reset-nodedb #2
	modified:   src/mesh/NodeDB.cpp

---------

Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2023-11-20 06:33:14 -06:00
Jonathan Bennett
1b20a82b55 Update package_raspbian.yml
Trunk
2023-11-19 20:28:37 -06:00
Jonathan Bennett
195706e0e5 Update package_raspbian.yml to pull correct code for PR runs 2023-11-19 20:19:43 -06:00
Jonathan Bennett
c1f5878648 Add Raspbian to firmware zip 2023-11-19 17:11:54 -06:00
Jonathan Bennett
7380f3b170 Trunk fmt fix whitespace 2023-11-19 16:53:00 -06:00
Jonathan Bennett
a9d846c1b3 make package_raspbian.yml a reusable workflow 2023-11-19 16:45:06 -06:00
Jonathan Bennett
cfb09ee115 add .deb to release 2023-11-19 16:41:47 -06:00
Jonathan Bennett
8f0ce606db Update package_raspbian.yml upload .deb as artifact 2023-11-19 16:07:08 -06:00
Jonathan Bennett
d04ff29c2a Update package_raspbian.yml use ubuntu-latest 2023-11-19 15:56:41 -06:00
Jonathan Bennett
8e92754b59 Update package_raspbian.yml 2023-11-19 15:48:43 -06:00
Jonathan Bennett
dad824c0e9 Update package_raspbian.yml -- add checkout step 2023-11-19 15:16:11 -06:00
Jonathan Bennett
31d7c6826d Update package_raspbian.yml
Properly run build_raspbian as a step
2023-11-19 15:03:46 -06:00
Jonathan Bennett
d33521ee86 Add package-raspbian workflow 2023-11-19 14:53:49 -06:00
Jonathan Bennett
5ad12fed60 Chill out, yamllint 2023-11-19 14:53:49 -06:00
Jonathan Bennett
4af90eeb39 Revamp yaml config for Raspbian 2023-11-19 14:53:49 -06:00
Jonathan Bennett
08297bb0b7 Copy and Paste output file location for workflow 2023-11-18 15:36:41 -06:00
Jonathan Bennett
16ef40b21f Add even moar workflow debugging 2023-11-18 15:16:36 -06:00
Jonathan Bennett
7ef4abb974 Add debugging output to main workflow 2023-11-18 14:56:40 -06:00
Jonathan Bennett
297267d037 Try harder to find Raspbian binary 2023-11-18 13:26:05 -06:00
Jonathan Bennett
f8e766ebc7 Include Raspbian in release zip 2023-11-18 12:05:51 -06:00
Jonathan Bennett
7bd2b07024 Disable radiolib debug 2023-11-18 12:05:51 -06:00
Jonathan Bennett
b6ddbd0087 More CI work for Raspbian (#2949)
* More CI work for Raspbian

* Workaround quirks of Arm64/debian runners
2023-11-18 11:04:21 -06:00
Jonathan Bennett
dc8903ec42 Add Raspbian to Main CI (#2948) 2023-11-18 08:55:19 -06:00
Ben Meadors
46bd6ca7ba YAML based config for PI / Portduino (#2943)
* Add configuration via /etc/meshtastic/config.yaml

* Move example config, support more locations

* Fix config check

* Use access() to check for config file presence

* Throw an error and exit on radio init fail

* Adds error check for reading Bluetooth MAC

* Settle on meshtasticd, add install script

* Shell fixes

* Fine. I'll put it back and then disable you

* Get wrekt, shellchekt

* Firat attempt at adding raspbian CI build

* Tickle the workflow

* Beatings will continue til morale improves

* Permissions are overrated

---------

Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2023-11-18 08:12:34 -06:00
Ric In New Mexico
9d4af1146e INA3221 bugfixes & refinement (#2944)
Reorganized and refactored some INA3221 code
Added comments
Added missing shunt resistor value (100mΩ)
Added INA3221 Channel 1 to getINAVoltage() for device battery monitoring
	modified:   src/Power.cpp
	modified:   src/modules/Telemetry/PowerTelemetry.cpp
	modified:   src/modules/Telemetry/Sensor/INA3221Sensor.cpp
	modified:   src/modules/Telemetry/Sensor/INA3221Sensor.h
	modified:   src/power.h
2023-11-17 06:46:59 -06:00
Thomas Göttgens
5ce6ca25f2 Merge pull request #2083 from meshtastic/raspi-portduino
Start working on RF95 attached to Raspberry Pi
2023-11-16 15:07:02 +01:00
Ben Meadors
f2210d8f8d Merge branch 'master' into raspi-portduino 2023-11-16 06:57:52 -06:00
Ben Meadors
5d917885df Added Remove node by nodenum admin message (#2941)
* Remove node by nodenum

* It were backerds! DERP
2023-11-16 06:57:22 -06:00
Jonathan Bennett
e99ae64ece Add Pi library only to Raspbian 2023-11-15 21:16:27 -06:00
Jonathan Bennett
61f888e952 Add missed ifdef 2023-11-15 21:01:17 -06:00
Jonathan Bennett
a144d5d6cc Clean up, fix reboot, minimize changes 2023-11-15 20:33:53 -06:00
Ben Meadors
c3e3569c14 Merge branch 'master' into raspi-portduino 2023-11-15 19:39:19 -06:00
Jonathan Bennett
b1b5bafdda Add PiHal and get Waveshare SX1262 XXXM working 2023-11-15 17:04:41 -06:00
Ben Meadors
91e399a2b6 Added detection sensor en pin to fix issues with RAK microwave (#2940) 2023-11-15 09:26:47 -06:00
HookdomPonix
8b16367597 Add support for the rak10701 board, no touch (#2933)
* Add support for the rak10701 board, no touch

* Moved tftblack fillin and changed teh src flags

* Added rak10701 to platformio.ini

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-11-13 06:20:49 -06:00
S5NC
0b9accc3b6 Remove redundant checks for power of 0 (#2934)
* Add comment explaining necessity for second 0 check

Thank you @GUVWAF

* Update RF95Interface.cpp

* Update STM32WLE5JCInterface.cpp

* Update SX126xInterface.cpp

* Update SX128xInterface.cpp

* remove whitespace...

* Update SX128xInterface.cpp
2023-11-13 06:19:02 -06:00
GUVWAF
590b0bbff4 Merge pull request #2935 from S5NC/add-missing-has-sensor
Add missing defaulting for HAS_SENSOR to configuration.h
2023-11-10 09:57:44 +01:00
S5NC
19be230b24 Update configuration.h 2023-11-08 21:58:33 +00:00
Jonathan Bennett
8df16ad6a6 Add ctime include to fix native compile 2023-11-08 14:36:12 -06:00
Ben Meadors
2d62f00ac3 Merge branch 'master' into raspi-portduino 2023-11-08 09:54:18 -06:00
pdxlocations
9f93b9ab9d fix sizeof error 2023-11-08 12:40:51 +01:00
pdxlocations
fc3200134d party time 2023-11-08 12:40:51 +01:00
Ben Meadors
470264b7f9 Merge branch 'master' into raspi-portduino 2023-11-07 05:58:42 -06:00
Ben Lipsey
600541ac25 Fix Documentation Links in Comments (#2929)
* update external notification

* ContentHandler
2023-11-06 22:03:44 +00:00
github-actions[bot]
298b383127 [create-pull-request] automated change (#2927)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-11-05 06:50:02 -06:00
Ric In New Mexico
f57020412e INA3221 / Power Telemetry Payload Variant Implementation (#2916)
* INA3221 / Power Telemetry Variant Implementation
	modified:   platformio.ini
	modified:   src/configuration.h
	modified:   src/detect/ScanI2C.h
	modified:   src/detect/ScanI2CTwoWire.cpp
	modified:   src/main.cpp
	modified:   src/modules/Modules.cpp
	new file:   src/modules/Telemetry/PowerTelemetry.cpp
	new file:   src/modules/Telemetry/PowerTelemetry.h
	new file:   src/modules/Telemetry/Sensor/INA3221Sensor.cpp
	new file:   src/modules/Telemetry/Sensor/INA3221Sensor.h
	modified:   src/mqtt/MQTT.cpp

* ifdef for portduino / linux native
	modified:   src/modules/Telemetry/PowerTelemetry.cpp

* try #2
	modified:   src/modules/Modules.cpp
	modified:   src/modules/Telemetry/PowerTelemetry.cpp
	deleted:    variants/xiao_ble/1.0.0/libraries/SPI/SPI.cpp

* try #3
	modified:   src/modules/Modules.cpp

* try #4
	modified:   src/modules/Telemetry/PowerTelemetry.cpp

* try #5?
	modified:   src/modules/Telemetry/PowerTelemetry.cpp

* try #6
	modified:   src/modules/Telemetry/PowerTelemetry.cpp

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-11-04 20:07:00 -05:00
Ben Meadors
4a6cc8fd8c Extend packet history expire time to 10 minutes (#2921) 2023-11-03 15:43:26 -05:00
Tyler Jang
45c5e0e730 cleanup disables (#2924)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-11-03 06:50:30 -05:00
github-actions[bot]
527bffb7e0 [create-pull-request] automated change (#2926)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-11-03 06:36:24 -05:00
GUVWAF
4c35a7fb7d Handle AmbientLighting Module config (#2923) 2023-11-03 07:36:36 +00:00
GUVWAF
0f9936a0e0 Change default Coding Rate to 4/5 for <=LongFast (#2920)
Increases througput at the cost of a little bit of sensitivity
Non-breaking as the CR is sent in the LoRa header
2023-11-02 09:21:07 -05:00
Thomas Göttgens
40395bef01 Merge branch 'master' into raspi-portduino 2023-10-31 14:09:38 +01:00
GUVWAF
8b8fffda81 Drop packets if toPhoneQueue is full, unless it's text/RangeTest (#2918) 2023-10-30 06:12:22 -05:00
Ric In New Mexico
4052194dfe Fix for is_licensed save / reboot (#2911)
* Fix is_licensed save / reboot

* Revert "Fix is_licensed save / reboot"

This reverts commit 634151b8ec.

* Changed reloadConfig to saveChanges /w reboot
2023-10-26 06:25:06 -05:00
Ben Meadors
b36ffe5200 Trunk fmt fix 2023-10-24 18:52:46 -05:00
S5NC
a60b4d08bf Hydra variant rectification (#2903)
* Update variant.h

* Update variant.h

* Update platformio.ini
2023-10-24 18:47:36 -05:00
github-actions[bot]
227467f638 [create-pull-request] automated change (#2897)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-10-20 09:52:56 -05:00
Tavis
092e6f2424 add rssi and snr to json output (#2894)
* add rssi and snr to json output

* explicitly cast to int and float
2023-10-17 06:50:36 -05:00
Andre K
e6b20bff77 refactor: simplify MQTT defaults (#2893)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-15 18:56:47 -05:00
Andre K
2c625f6ba1 fix: channel routing for decoded MQTT packets (#2892)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-15 06:41:40 -05:00
Manuel
142d56c663 allow sensors connected to second I2C port (#2891) 2023-10-14 19:33:45 -05:00
Ben Meadors
f4b40562d3 Start of TAK role (#2890)
* Start of TAK role

* Position flags change for CoT friendly altitudes

* Trunk
2023-10-14 06:49:38 -05:00
github-actions[bot]
9e203532d0 [create-pull-request] automated change (#2889) 2023-10-13 20:02:59 -05:00
code8buster
8bd7b5e779 Merge pull request #2887 from yupyvovarov/fix-hwids-address
Fix typo in tbeam-s3-core hwids address
2023-10-13 10:24:49 +00:00
Yurii Pyvovarov
1af970765f Fix typo in tbeam-s3-core hwids address 2023-10-13 11:31:10 +03:00
Ben Meadors
def55ec063 Remove specific upload ports from pio 2023-10-11 10:21:58 -05:00
Ben Meadors
092c6cac66 Convert from inline to static class methods (#2883) 2023-10-11 06:17:05 -05:00
Ben Meadors
e39f129bd6 More comprehensively clear current position info (#2881) 2023-10-10 19:33:58 -05:00
S5NC
9d1fe8c245 Update architecture.h (#2880) 2023-10-10 15:35:07 -05:00
Aciid
786248a6b1 Dragino TrackerD wip (#2324)
* Dragino TrackerD initial variant

* fmt

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-10 06:20:46 -05:00
github-actions[bot]
d1ac2dc6ea [create-pull-request] automated change (#2879)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-10-09 20:43:42 -05:00
Ben Meadors
87396d9105 Refactor away some code duplication in screen frames and display formatter for modem presets (#2872)
* Refactor away some duplication

* Refactor preset names to display formatter method

* Remove unused screen brightness adjustment and extract wifi disconnect reason name to display formatter method

* Tronk

* Let's be more clear with this naming

* Effed

* DisplayFormatters static class and use native wifi disconnect reason names method

* git mv file so casing should match now

* Include titlecase

* Trunk
2023-10-09 20:43:16 -05:00
Ben Meadors
b388f8edcd Merge branch 'master' into raspi-portduino 2023-10-09 19:45:08 -05:00
Ben Meadors
10265aabd5 Fix buggy phone positions (#2876)
* Guard-clause channel util. to reduce nesting

* Try-fix PhoneAPI position not updating

* Trunk

* Missed it

* Really disable GPS when asked to

---------

Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2023-10-09 18:33:04 -05:00
Jonathan Bennett
8780d93941 Remove missed GPS definition (#2878) 2023-10-09 13:30:51 -05:00
Sacha Weatherstone
54f0c045e4 Update README.md 2023-10-09 22:30:02 +10:00
github-actions[bot]
3ddad671a5 [create-pull-request] automated change (#2875)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-10-08 08:12:42 -05:00
pat-trunk-io
dc6f0b8e0b mention trunk is beta on windows (#2871)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-06 15:31:04 -05:00
pat-trunk-io
33f28c3d56 Add trunk githooks to the repo (#2870) 2023-10-06 15:02:27 -05:00
github-actions[bot]
ef1d8c8eee [create-pull-request] automated change (#2869) 2023-10-05 17:51:23 -05:00
Ben Meadors
950d5f0946 Power saving sensor (#2865)
* Trunk

* Again

* This thing just keeps updating itself

* Ignore tools

* Sleepy sensor

* Batrunkadunk
2023-10-05 12:42:03 -05:00
Thomas Göttgens
fc06754e1f Possibly fix #2704 "Heltec Wireless Tracker screen doesn't display anything" (#2749)
* fix #2704


Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2023-10-04 22:24:25 -05:00
github-actions[bot]
fbf74fc0b2 [create-pull-request] automated change (#2863)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-10-04 10:23:55 -05:00
code8buster
7cebd79475 Use doNotEnterOff flag to prevent GNSS poweroff before fix acquisition (#2861)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-03 19:50:27 -05:00
Jonathan Bennett
aa38f53aed Fix for T-Beam 1.2 GPS (#2858)
* Fix for T-Beam 1.2 GPS, with DEBUG enabled

* Don't break other devices

* Saving GPS data on this breaks on next boot. Fix.

* derp

* disable the extra verbosity

* Try the same sort of factory reset as the Lilygo image

* Catch GPS reboots and squash

* trunk

* GPS

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-03 12:05:40 -05:00
Ben Meadors
2a6c8be684 Avoid problematic sleep state transitions for power saving sensors and trackers (#2860)
* Avoid problematic sleep state transitions for power saving sensors and trackers

* Line got duped :-|
2023-10-03 10:09:27 -05:00
GUVWAF
37c3d15978 Check if packet is decrypted before using portnum when converting to JSON (#2857)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-03 06:39:35 -05:00
Manuel
f301e236eb fix crash during shutdown (#2859)
* fix null pointer access

* ptr initialize
2023-10-03 06:37:46 -05:00
Manuel
94c2ade272 make esp32 deepsleep button wakeup functional again (#2854)
* make deepsleep button wakeup functional again

* Remove unused var

* Cleanup comment

* suppress screen wake on button

* add resume screen

* trunk fmt

* added missing #ifdef

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-02 16:16:29 -05:00
Ben Meadors
a6e4402e41 Screen on secs router default (#2855) 2023-10-02 06:28:05 -05:00
Jonathan Bennett
50db2d0e9b Add timeout to ublox PMREQ command (#2851) 2023-10-01 20:39:18 -05:00
Ben Meadors
5ecdbd0dbb Removed non-functional deep sleep button awake functionality (user can RST instead) (#2852)
* Fixed mask length

* Don't want_response if we're a tracker or sensor

* Fixes

* Removing non-functioning deep sleep button awake
2023-10-01 12:48:12 -05:00
Jonathan Bennett
47c6738c0d Fix GPS init bug -- power up even when disabled (#2850) 2023-09-30 23:38:51 -05:00
Ben Meadors
1552aa0081 Tracker role wakeup and sleep cycle when power.is_power_saving true (#2846)
* WIP

* Sleepy sleepy low power tracker

* Sleepy tracker clear

* NRF52 PoC

* Simplify NRF52 "sleep"

* Trackers aren't polite

* Remove unnecessary include

* Removed accidental commit

* Fixed not-so-sleepy T-Beam due to button gpio mask precendence

* Added sleepOnNextExecution for allowing fulfillment of pending messages before shutting down

* Cleanup

* Don't wantResponse for trackers

* Heltec wireless tracker doesn't like the button interrupt (maybe all s3 because user button press doubles as bootloader mode trigger?)
2023-09-30 21:09:17 -05:00
github-actions[bot]
6ebec8fcd9 [create-pull-request] automated change (#2849)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-30 20:40:04 -05:00
Manuel
e9215a5d70 revert KB_POWERON changes (#2847) 2023-09-30 06:43:36 -05:00
Thomas Göttgens
5075849ec0 Add missing endif 2023-09-28 10:50:26 +02:00
Thomas Göttgens
7f16b6b342 Merge branch 'master' into raspi-portduino 2023-09-28 09:29:45 +02:00
S5NC
4e3576ae48 Simplify SX126x variant configuration (#2813)
* Update SX126xInterface.cpp

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update SX126xInterface.cpp

* Update SX126xInterface.cpp

* Update variant.h

* Update variant.h

* trunk fmt

* trunk fmt

* Update variant.h

* trunk fmt

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update pins_arduino.h

* Update pins_arduino.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* trunk fmt

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

Specify behavior

* Update variant.h

Maintain behavior

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-27 16:01:40 -05:00
Tavis
98290e5d7b Re issue: #2496 Populate the position log entries from PositionModule with data fields (#2839)
* Populate the position log entries with data fields

includes datafields with no data as 0

* trunk check formatted.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-27 16:00:56 -05:00
Ben Meadors
ad529924f1 Code duplication cleanup for smart position logic (#2840) 2023-09-27 10:32:35 -05:00
github-actions[bot]
07d51a2ca4 [create-pull-request] automated change (#2837) 2023-09-26 14:54:35 -05:00
github-actions[bot]
47301a5ac0 [create-pull-request] automated change (#2836)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-26 11:11:54 -05:00
Ben Meadors
0d023ea215 Revert "Fix compression (#2806) (#2819)" (#2835)
This reverts commit cdac643749.
2023-09-26 07:02:06 -05:00
Ben Meadors
b5e952db24 No more goober traffic on public mqtt (#2831)
* No more goober traffic on public mqtt

* Oops
2023-09-26 06:19:17 -05:00
GUVWAF
a1c433748a RP2040: Add SerialModule support (#2830)
* Support for SerialModule on RP2040

* Remove one !defined too many

* Increase serial RX_BUFFER: more reliable for long packets
Even results into an error for ESP32

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-26 05:45:34 -05:00
Jonathan Bennett
04b2ab82dc Add GPS pin definitions missed in revamp (#2834) 2023-09-26 05:44:08 -05:00
github-actions[bot]
e96ba7cbcf [create-pull-request] automated change (#2827)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-25 06:31:22 -05:00
Andre K
61f6fb22c5 move STATE_SEND_METADATA to beginning of wantConfig (#2820)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-24 07:22:54 -05:00
github-actions[bot]
db7b77c76e [create-pull-request] automated change (#2823)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-24 07:01:46 -05:00
Andre K
350090ec0d remove residual code for mesh_sds_timeout_secs (#2821)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-24 06:49:35 -05:00
GUVWAF
cdac643749 Fix compression (#2806) (#2819)
* Fix compression: encode to bytes after `decoded` is modified

* Change payload size to decompressed length

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-24 06:49:21 -05:00
Jonathan Bennett
1a2c7f00e1 Gps cleanup and powersave (#2807)
* Refactor GPS to not probe if pins not defined

* Use Named Constructor to clean up code

* Move doGPSPowerSave to GPS class

* Make sure to set GPS awake on triple-click

* Cleanup and remove dead code

* Rename GPS_PIN_WAKE to GPS_PIN_STANDBY

* Actually put GPS to sleep between fixes

* add GPS_POWER_TOGGLE for heltec-tracker and t-deck

* Change GPS_THREAD_INTERVAL to 200 ms

* More dead code, compiler warnings, and add returns

* Add Number of sats to log output

* Add pgs enable and triple-click config

* Track average GPS fix time to judge low-power time

* Feed PositionModule on GPS fix

* Don't turn off the 3v3_s line on RAK4631
when the rotary is present.

* Add GPS power standbyOnly option

* Delay setting time currentQuality
to avoid strange log message.

* Typos, comments, and remove unused variable

* Short-circuit the setAwake logic on GPS disable

* heltec-tracker 0.3 GPS power saving

* set en_gpio to defined state

* Fix fixed_position logic with GPS disabled

* Don't process GPS serial when not isAwake

* Add quirk for Heltec Tracker GPS powersave

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: mverch67 <manuel.verch@gmx.de>
Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com>
2023-09-23 23:45:35 -05:00
Jonathan Bennett
7eff5e7bcb Fix for Pi Pico hang (#2817)
* Fix for Pi Pico hang

* Pi Pico fix part 2: Electric Boogaloo
2023-09-20 19:34:45 -05:00
Jonathan Bennett
17207681ef Remove GPS pins from devices lacking built-in GPS (#2812) 2023-09-19 10:55:14 -05:00
Thomas Göttgens
94f7c7e472 Merge pull request #2814 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-09-19 12:46:26 +02:00
caveman99
0a12d67d19 [create-pull-request] automated change 2023-09-19 10:45:28 +00:00
Thomas Göttgens
3175a3d630 Merge pull request #2811 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-09-19 10:48:41 +02:00
thebentern
4e9bf75340 [create-pull-request] automated change 2023-09-18 19:49:42 +00:00
github-actions[bot]
e8970ad66b [create-pull-request] automated change (#2810)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-18 13:26:09 -05:00
code8buster
f737ee59ec Deny maxhops to anyone who sets >7 (#2808)
* Deny maxhops to anyone who sets >7

* Use reliable hop count instead of 3
2023-09-18 12:58:09 -05:00
Ric In New Mexico
6d211815d9 Temp fix for S3 bluetooth (#2809)
Need to roll back espressif to v6.3.2
2023-09-18 14:26:19 +02:00
Manuel
1bae926576 fix: nodenum 4 (#2798)
* tryfix: nodenum 4

* trunk fmt

* rename vars and fix brackets

* purge invalid db entries

* trunk fmt
2023-09-18 06:16:37 -05:00
Thomas Göttgens
a1514b8b64 Enable (new) ADC and GPS capability. (#2792)
* Enable (new) ADC and GPS capability.
* Make Picomputer a canon device and define ADC for new board revision
2023-09-18 11:38:33 +02:00
Jonathan Bennett
8b82ae6fe3 refactor and avoid needless probe (#2799)
* Use UINT32_MAX to indicate no configured GPS

* Refactor GPS to not probe if pins not defined

* Minor cleanups related to rework

* Use Named Constructor to clean up code

* Actually disable the GPS thread

* Don't actually disable the GPS thread

* Move doGPSPowerSave to GPS class

* Make sure to set GPS awake on triple-click

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-16 23:10:10 -05:00
Ric In New Mexico
822c150e0d Fixing typo in src/mesh/mesh-pb-constants.cpp logging (#2800)
* Update variant.h

Add second i2c channel on external connector for Station G1

* Create trunk-check.yml

* Fix typo in logging

Corrected typo in pb_msgdesc logging for packets failing to be decoded.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-16 15:24:59 -05:00
github-actions[bot]
0731902744 [create-pull-request] automated change (#2791)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-12 18:00:29 -05:00
github-actions[bot]
b53cb38a09 [create-pull-request] automated change (#2790)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-12 16:50:52 -05:00
Jonathan Bennett
b02dd0e964 Move partial GPS initialization earlier in boot (#2788)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-12 16:46:46 -05:00
Ben Meadors
c608f0ba81 Fix time=0 bug for fixed_position nodes (#2789) 2023-09-12 15:54:50 -05:00
Jonathan Bennett
e1839e33f2 Lazy probe of GPS (#2781)
* First attempt at lazy config of GPS

* More GPS rework
Break GPS init into smaller, interruptable steps
Move more GPS commands into ubx.h
Combine Setup functions

* Move the rest of UBX messages to ubs.h
2023-09-10 22:21:14 -05:00
Manuel
d6d51bc3f4 T-Deck/T-Watch: enhancements/fixes (#2786)
* T-Deck: enhancements/fixes

* trunk fmt

* T-Watch board update

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-10 06:54:25 -05:00
github-actions[bot]
44a77a10e1 [create-pull-request] automated change (#2785)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-10 06:34:48 -05:00
Ben Meadors
8255128eae Trunk finally spilled the beans about what it's upset about 2023-09-09 19:40:57 -05:00
Ric In New Mexico
d7a98519f4 Update variant.h (#2778)
* Update variant.h

Add second i2c channel on external connector for Station G1

* Create trunk-check.yml

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-09 19:37:35 -05:00
github-actions[bot]
e256520336 [create-pull-request] automated change (#2782)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-08 14:34:58 -05:00
Ben Meadors
fcf798df98 Experiment with moving gps init (#2780)
* Move it move it

* Moving to the end of the main setup method

* NimBLE version
2023-09-07 16:01:35 -05:00
Ben Meadors
dcdf9b64de Ambient lighting (#2779)
* This was already defined and throwing a ton of warnings

* Ambient lighting module feature

* Use local instance type
2023-09-07 12:24:47 -05:00
Jonathan Bennett
fd563e41f1 Add ubx-cfg-rxm and cfg-pm2 for ublock 6 powersave (#2777) 2023-09-07 12:24:21 -05:00
Jonathan Bennett
0fa3685161 Fix crash in GPS setup when GPS is disabled 2023-09-06 12:38:58 -05:00
code8buster
899f9dd7bf Merge pull request #2775 from GUVWAF/disabledNeighbor
Only update neighbors when module is enabled
2023-09-05 23:43:09 +00:00
GUVWAF
9af4ecf48f Remove unnecessary line when disabled 2023-09-05 21:42:39 +02:00
GUVWAF
cfb6a1394c Only update neighbors when module is enabled 2023-09-05 19:56:42 +02:00
code8buster
1254031f7d Merge pull request #2772 from meshtastic/ubx-pmreq
UBX-RXM-PMREQ soft-off implemented
2023-09-05 17:15:12 +00:00
code8buster
c91e306659 Move packet scratch declaration to header 2023-09-05 11:59:34 -04:00
code8buster
4ff343b20f no byte... just 8 unsigned bits please 2023-09-05 00:32:53 -04:00
code8buster
134fc75b67 UBX-RXM-PMREQ soft-off implemented 2023-09-05 00:26:42 -04:00
Ben Meadors
fb23e479ac Update ESP32 platform (#2770) 2023-09-04 20:20:20 -05:00
github-actions[bot]
5a61695016 [create-pull-request] automated change (#2769)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-04 19:45:46 -05:00
github-actions[bot]
3bcab0e223 [create-pull-request] automated change (#2768)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-04 18:38:58 -05:00
GUVWAF
17617ce031 Fix possible memory leak in NeighborInfo Module (#2765)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-04 18:38:16 -05:00
Jonathan Bennett
97f0c734e0 Fix Neighborinfo crash
neighbors object wasn't initialized when module disabled, this
initializes it to a safe, empty object.
2023-09-04 18:15:27 -05:00
Jonathan Bennett
e943fffe8c GPS fixes
Work aroung Serial reset issue on ESP32
Don't send unsupported command to G60xx GPS
2023-09-04 15:00:05 -05:00
tropho23
ffcb131171 GPS toggle for RAK4631 (patch 2 of 2) (#2764)
* Added triple-press GPS toggle button changes

* Revert edits to extensions.json

* comma'd

* Update variant.h

Added the line:

// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
#define PIN_GPS_EN 34 // GPS power enable pin

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: code8buster <communismisgreat@national.shitposting.agency>
2023-09-04 13:17:01 -05:00
tropho23
bb1fe7cad3 GPS toggle for RAK4631 (patch 1 of 2) (#2763)
* Added triple-press GPS toggle button changes

* Revert edits to extensions.json

* comma'd

* Update platformio.ini

Added line:

-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: code8buster <communismisgreat@national.shitposting.agency>
2023-09-04 13:16:39 -05:00
Ben Meadors
ad40493a39 Add speed, heading, and DOP to default position flags (#2759)
* Add speed and heading

* Add DOP
2023-09-04 06:46:27 -05:00
Jonathan Bennett
ac62330e1c Found lost byte dropped from moduleinfo
Attempt to fix CFG-GNSS for neo-6m
2023-09-03 22:38:03 -05:00
code8buster
53f6a43661 Merge pull request #2752 from meshtastic/nmea-rate
Adds GPS Serial Speed scanning, fixes ublox GNSS setup errors
2023-09-03 21:57:51 +00:00
Jonathan Bennett
7ad94da1c6 Add more to GPS_DEBUG and fix ubx7 CFG-GNSS 2023-09-03 16:20:01 -05:00
Jonathan Bennett
ecdb75aae0 Correct UBX-CFG-PMS message 2023-09-03 02:16:29 -05:00
Jonathan Bennett
7c98445ca3 Cleanup in prep for commiting
Fix some compilation warnings
gate debug code behind GPS_DEBUG
minor fix in u-blox protocol detection
Begin to gate GPS messages based on protover
2023-09-03 01:50:11 -05:00
Jonathan Bennett
b21368ecfa Add delay and debug code for GPS probe 2023-09-02 20:35:38 -05:00
Jonathan Bennett
1a178c7d33 Add check for GPS Frame Errors message 2023-09-02 04:29:48 -05:00
Jonathan Bennett
5d6f0ea6c4 Fix possible edge case in GPS detection 2023-09-01 16:24:28 -05:00
Ben Meadors
5bd861f3d8 Merge branch 'master' into nmea-rate 2023-09-01 15:08:32 -05:00
GUVWAF
6d93fab495 Add neighbor IDs to MQTT JSON (#2756)
* Add neighbor IDs to JSON

* Limit #neighbors to what we can actually save

* Put neighbor IDs in an array

* Add SNR to neighbors in nested objects
2023-09-01 14:35:57 -05:00
Jonathan Bennett
6803fd7949 More fixes for GPS chips with unexpected baud 2023-09-01 12:11:39 -05:00
Jonathan Bennett
a61f969773 Increase GPS detection timeout slightly 2023-08-31 22:19:50 -05:00
Jonathan Bennett
79cfc4b725 Avoid Serial output mangling with RTOS. 2023-08-31 20:40:01 -05:00
Jonathan Bennett
cf762bbd42 Cut down delay times for GPS probe and init 2023-08-31 20:39:23 -05:00
code8buster
3d2c419d0d Remove leftover debug msg 2023-08-30 16:24:56 -04:00
Jonathan Bennett
903f619609 Add GPS serial speed scan 2023-08-28 19:01:14 -05:00
Jonathan Bennett
2e3f762d3d Catch a nullptr return rather than crash 2023-08-28 04:05:45 -05:00
Jonathan Bennett
a42266f74b GPS: Fix checksum and remove spurious returns 2023-08-28 04:05:45 -05:00
github-actions[bot]
a605c69eb4 [create-pull-request] automated change (#2748)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-26 07:36:04 -05:00
Thomas Göttgens
282cc0b16a Merge pull request #2737 from meshtastic/BBQ10Kb-Fix
Bbq10 kb fix
2023-08-26 11:22:35 +02:00
Thomas Göttgens
4ab67f3668 IGOR! Fetch me the brain! 2023-08-25 16:44:39 +02:00
Thomas Göttgens
312028b161 Possble fix ESC 2023-08-25 09:27:09 +02:00
Ben Meadors
ecd48db69c Merge branch 'master' into BBQ10Kb-Fix 2023-08-24 19:57:49 -05:00
Ben Meadors
03dc36ea12 Use fixed position regardless of gps lock (#2744) 2023-08-24 10:55:49 -05:00
Mark Trevor Birss
c2ae38405e Update architecture.h (#2746) 2023-08-24 07:58:24 -05:00
Thomas Göttgens
2a1d8c40b4 add TAB and ESC handling 2023-08-24 14:24:26 +02:00
Ben Meadors
e2441c425a Merge branch 'master' into BBQ10Kb-Fix 2023-08-24 07:06:42 -05:00
Mark Trevor Birss
00ffe73ebd Heltec ESP32-C3 HT-CT62 support (#2741)
* Add files via upload

* Update platformio.ini

* Update variant.h

* Update platformio.ini

* Switch to our new HW_MODEL

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Ben Meadors <thebentern@tuta.io>
2023-08-23 07:59:21 -05:00
Thomas Göttgens
3355019de3 Merge branch 'master' into BBQ10Kb-Fix 2023-08-23 09:45:06 +02:00
Thomas Göttgens
5bb207d88b reset sym after second keypress
also remove debug print and non-working scancodes.
2023-08-23 09:44:20 +02:00
github-actions[bot]
5453e4d123 [create-pull-request] automated change (#2742)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-22 17:11:22 -05:00
Thomas Göttgens
7f1b58a222 trunk fmt 2023-08-22 21:23:37 +02:00
Thomas Göttgens
39357b2686 Merge branch 'BBQ10Kb-Fix' of github.com:meshtastic/firmware into BBQ10Kb-Fix 2023-08-22 21:23:00 +02:00
Thomas Göttgens
d6b629ae04 update SYM Scancode 2023-08-22 21:19:51 +02:00
Thomas Göttgens
7b1aeb60cd Try manual scancode for SYM 2023-08-22 21:19:51 +02:00
Thomas Göttgens
5c7c1cd253 silence compiler warnings 2023-08-22 21:19:51 +02:00
Thomas Göttgens
8cfe130df3 update SYM Scancode 2023-08-22 21:11:19 +02:00
Thomas Göttgens
feef86942d Merge pull request #2738 from meshtastic/neighbourinfo-fix
fix crash and Debug logging in NeighbourInfo
2023-08-22 16:27:52 +02:00
Thomas Göttgens
5f3a8b4924 fix crash and Debug logging in NeighbourInfo 2023-08-22 15:43:21 +02:00
Thomas Göttgens
0fcaaf39b0 Try manual scancode for SYM 2023-08-22 11:23:19 +02:00
Thomas Göttgens
a55eac5c20 silence compiler warnings 2023-08-22 10:58:54 +02:00
github-actions[bot]
b47c9c165a [create-pull-request] automated change (#2733)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-19 18:06:33 -05:00
Thomas Göttgens
ecceb10910 different debug print 2023-08-19 21:28:02 +02:00
Thomas Göttgens
6fc76103a0 temporarily Enable debug print 2023-08-19 20:55:50 +02:00
Ben Meadors
f35c7be917 Just putting back DELAYED_INTERVAL for reliability. Ran into problems 2023-08-19 09:45:48 -05:00
Ben Meadors
364364263b Remove range_test goalie from drawing frames 2023-08-19 09:44:40 -05:00
Manuel
ef957bfac5 support BB Q10 keyboard (#2703)
* support BB Q10 keyboard

* remove debug code

* fix wrong logic

* fix left/right keys for cardkb

* Try to enable Q10 kb after all

* cppcheck

* Only fire on Key release and assume 0x0a is a enter as well

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2023-08-19 08:37:42 -05:00
Ben Meadors
5d78795065 Portnum promiscuity for text messages from other modules (#2732)
* Add interested portnums to TextMessageModule

* Send Detection Sensor Module messages on its own portnum

* Add to Ext. Notification and consolidate logic

* RANGE_TEST_APP portnum for RangeTestModule
2023-08-19 07:46:34 -05:00
github-actions[bot]
2dbdda204f [create-pull-request] automated change (#2731)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-18 10:17:55 -05:00
Jonathan Bennett
4767bd5497 Rename utils.h to avoid collision with library. (#2730) 2023-08-17 20:22:34 -05:00
Thomas Göttgens
05efd68097 Merge pull request #2729 from meshtastic/trunk-fmt
update trunk to latest version
2023-08-17 13:46:44 +02:00
Thomas Göttgens
a90eef432f update trunk to latest version 2023-08-17 12:17:36 +02:00
Thomas Göttgens
762166495f Merge branch 'master' into raspi-portduino 2023-08-17 10:06:34 +02:00
Ben Meadors
929b8f6209 Fix thread to use getConfiguredOrDefaultMs (#2727)
* WIP

* Updates

* Move it out of the macro guard so portduino can build

* Changes from feedback

* Use minimum_broadcast_secs as interval if we just broadcasted to avoid wasting cpu cycles

* Fmt

* Merge conflict resolution boogered me up

* Missed a spot

* getConfiguredOrDefaultMs

* Get the minimum interval
2023-08-16 15:08:06 -05:00
Thomas Göttgens
5d76771fab Permanently Enable Canned Messages on T-Deck and Picomputer (#2728)
* - Permanently Enable Canned Messages on T-Deck and Picomputer
- picomputer has a really dark TFT; switch color to white for better UX.

* well, you know... bullock...
2023-08-16 15:07:22 -05:00
Thomas Göttgens
91eb64d7b7 Fix warning about init order (#2725) 2023-08-15 20:17:15 -05:00
Ben Meadors
03fe4c629a Dection Sensor module duty cycle interval optimization (#2723)
* WIP

* Updates

* Move it out of the macro guard so portduino can build

* Changes from feedback

* Use minimum_broadcast_secs as interval if we just broadcasted to avoid wasting cpu cycles

* Fmt

* Merge conflict resolution boogered me up

* Missed a spot
2023-08-15 12:23:07 -05:00
Ben Meadors
144dfe9805 Initial Detection sensor module feature (#2722)
* WIP

* Updates

* Doh!

* Move it out of the macro guard so portduino can build

* Changes from feedback
2023-08-14 19:00:51 -05:00
rcarteraz
18899fd168 Update variant.h (#2719)
remove HAS_GPS 0 so users can add gps

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-13 23:45:23 -05:00
code8buster
fcfd83bc89 Remove auto GPS shutoff for fixed position nodes (#2720) 2023-08-13 15:56:49 -05:00
github-actions[bot]
a3d2b6166c [create-pull-request] automated change (#2716)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-12 20:49:42 -05:00
Manuel
fb5f2e48a5 fix T-Deck trackball crashes (#2714)
* try-fix: nodenum crash during boot

* Revert "try-fix: nodenum crash during boot"

This reverts commit 632012e197.

* fix/workaround: trackball interrupt crashes

* trunk fmt

* add OSThread to trackballInterrupt
2023-08-12 19:44:05 -05:00
Jonathan Bennett
d29c975e3c Comment out extra-chatty debug message (#2715) 2023-08-12 13:51:31 -05:00
Ben Meadors
00ea6ef5ad Merge branch 'master' into raspi-portduino 2023-08-12 09:40:26 -05:00
Jonathan Bennett
c44986127e More GPS work (#2711)
Increase GPS buffer on esp32
Check for and flush GPS buffer when overfilled and corrupted.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-12 09:29:44 -05:00
Ben Meadors
6e0b6684ee Extend node max to 100 and remove mesh_sds_timeout_secs (#2713)
* Extend node max to 100 and remove mesh_sds_timeout_secs

* Const pointers for you and you and you

* Fixes and supressions

* Missed it

* uint

* Resize

* Derp
2023-08-12 09:29:19 -05:00
Manuel
84ddfea491 try-fix: max nodes crash during boot (#2712)
* try-fix: nodenum crash during boot

* Revert "try-fix: nodenum crash during boot"

This reverts commit 632012e197.

* try-fix: max nodes crash during boot

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-12 09:28:58 -05:00
Ben Meadors
3d6fb13f9a Stop failing on low severity styling issues 2023-08-12 06:43:13 -05:00
Manuel
54c48329c8 Merge pull request #2710 from meshtastic/fix-screen-setup
fix repeater crash during screen setup
2023-08-12 10:46:07 +02:00
mverch67
ede31a2080 fix repeater crash 2023-08-11 19:41:21 +02:00
Jonathan Bennett
9470d4694b Pickier parsing of NMEA to detect an L76K chip (#2699)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-10 11:21:35 -05:00
github-actions[bot]
2074c76780 [create-pull-request] automated change (#2697)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-10 05:53:55 -05:00
Thomas Göttgens
b5b66f43f2 Merge branch 'master' into raspi-portduino 2023-08-09 11:19:23 +02:00
Thomas Göttgens
9f6584bd67 Merge pull request #2694 from mverch67/t-watch-fixes
T-Watch S3 fixes
2023-08-08 22:49:37 +02:00
mverch67
dd69de9f32 trunk fmt 2023-08-08 20:21:20 +02:00
mverch67
616553ed72 doing the math :) 2023-08-08 20:14:12 +02:00
mverch67
1986267d65 check payload size 2023-08-08 20:02:29 +02:00
mverch67
1d0ac2caf7 trunk fmt 2023-08-08 18:55:00 +02:00
mverch67
746d7268a2 fix picomputer 2023-08-08 18:51:11 +02:00
Manuel
9a7777dbdb Merge branch 'master' into t-watch-fixes 2023-08-08 18:21:57 +02:00
mverch67
0fe99b0caa T-Watch fixes 2023-08-08 18:06:39 +02:00
Ben Meadors
f9798b7dda Bump to 2.2 2023-08-08 08:05:43 -05:00
Ben Meadors
23fb377fd7 Don't cancel sending "seen" messages on MQTT enabled nodes (#2690) 2023-08-08 06:27:26 -05:00
Thomas Göttgens
4808a5c57f also update other boards with those (#2691) 2023-08-07 23:22:17 +00:00
Thomas Göttgens
d25c368985 Try enabling the secondary I2C bus on Heltec V3 (#2689)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-07 15:17:26 -05:00
GUVWAF
a5f3dea40b Clarify that when rebooting is not implemented some settings may not apply (#2688)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-07 15:16:56 -05:00
Thomas Göttgens
f026c3308c add picomputer 2023-08-07 21:34:01 +02:00
Thomas Göttgens
ed4e7a4cee Change Target Name 2023-08-07 21:33:42 +02:00
Thomas Göttgens
95f67d70ea Merge pull request #2493 from meshtastic/picomputer-s3
Add variant an plumbing for #2468
2023-08-07 21:17:24 +02:00
Thomas Göttgens
e3260c1d19 Merge branch 'master' into picomputer-s3 2023-08-07 20:27:44 +02:00
Thomas Göttgens
98f3be0665 Merge pull request #2647 from meshtastic/2.2-working-changes
2.2 Changes
2023-08-07 20:27:05 +02:00
Ben Meadors
dc31024764 Merge remote-tracking branch 'origin/master' into 2.2-working-changes 2023-08-07 13:24:10 -05:00
Ben Meadors
5bbcb40f7a Updated protos 2023-08-07 13:23:21 -05:00
Thomas Göttgens
8218a729e0 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-08-07 19:58:48 +02:00
Thomas Göttgens
cbc3e605dd fix building for other platforms 2023-08-07 19:57:47 +02:00
Thomas Göttgens
94c41a4fed Merge branch 'master' into picomputer-s3 2023-08-07 19:47:29 +02:00
caveman99
1afe9f75bd [create-pull-request] automated change 2023-08-07 19:46:28 +02:00
Thomas Göttgens
402f8ba524 Let's see what this breaks... 2023-08-07 19:34:42 +02:00
Ben Meadors
04bbdc6b8a Platform / dep updates (#2684)
* Update nordic platform

* Update sensor libs
2023-08-06 10:06:08 -05:00
Thomas Göttgens
0084c0881d Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-08-06 16:57:03 +02:00
Thomas Göttgens
8552cc44b9 Merge branch 'master' into picomputer-s3 2023-08-06 16:55:28 +02:00
Thomas Göttgens
684cce7640 trunk fmt 2023-08-06 16:53:37 +02:00
Thomas Göttgens
114eb0c952 enable Canned Messages on T-Deck without presets 2023-08-06 16:53:37 +02:00
Thomas Göttgens
bed2bfa074 trunk fmt 2023-08-06 16:47:55 +02:00
Thomas Göttgens
0aef8703b6 - use LovyanGFX for m5stack
- update some comments
2023-08-06 16:47:55 +02:00
Thomas Göttgens
f5d323fdd3 trunk fmt 2023-08-06 16:21:39 +02:00
Thomas Göttgens
568cc259af Don't crash when no radio detected. 2023-08-06 16:21:39 +02:00
Neil Hao
42039e27e7 Initialize the L76K Chip, use GPS + GLONASS + BEIDOU (#2680)
* 'nano-g2-ultra'

* revert overcommit

* nano-g2-ultra-fmt

* revert overcommit

* revert overcommit

* Added BEIDOU support to L76K

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-06 08:28:37 -05:00
Mark Trevor Birss
400b71c152 Update variant.h 2023-08-05 17:42:51 +02:00
Mark Trevor Birss
b1f6ff1280 Update variant.h 2023-08-05 17:42:51 +02:00
Ben Meadors
cfe5c7f31d Tweaking Power FSM states (#2676)
* Tweaking Power FSM states

* Turn bluetooth back on after serial disconnected

* Remove references to deprecated mesh_sds_timeout_secs
2023-08-04 06:01:01 -05:00
Thomas Göttgens
1e71d346ae Merge branch 'master' into raspi-portduino 2023-08-03 21:36:43 +02:00
Thomas Göttgens
4e54bec525 Force small fonts on Low DPI screens, no matter what the driver default uses. Up till now we assumed large fonts on E-Paper and TFT Screens. (#2677) 2023-08-03 06:58:19 -05:00
Thomas Göttgens
e0bf15b80e trunk fmt 2023-08-03 10:05:38 +02:00
Jm Casler
26264fd908 more fixes for trunk 2023-08-03 10:05:38 +02:00
Jm Casler
794948d7e4 fixing trunk problems 2023-08-03 10:05:38 +02:00
Jm Casler
e9cbe54eca add more documentaiton 2023-08-03 10:05:38 +02:00
Jm Casler
641d117106 Update extensions.json 2023-08-03 10:05:38 +02:00
Jm Casler
5f38e79b8f Add documentation to a few areas 2023-08-03 10:05:38 +02:00
Thomas Göttgens
b238aebe38 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-08-03 09:37:32 +02:00
GUVWAF
e05c8e60d9 Save Neighbors to flash 2023-08-02 20:56:24 +02:00
Ben Meadors
f1bcc300d9 Merge branch 'master' into 2.2-working-changes 2023-08-02 12:58:32 -05:00
Jonathan Bennett
06a6a992c2 GPS Fixes for nrf52 (#2675)
Expands board serial buffer from 64 (!) to 1024
Adds some debugging messages when problems are detected.
2023-08-02 10:08:59 -05:00
Ben Meadors
11be856507 Merge branch 'master' into 2.2-working-changes 2023-08-01 21:00:58 -05:00
github-actions[bot]
7fe815a327 [create-pull-request] automated change (#2674)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-01 21:00:34 -05:00
Ben Meadors
191a69dd26 Don't create potential NodeInfo storm on telemetry reponse from Repeater (#2673)
* Don't create potential NodeInfo storm on telemetry reponse from Repeaters

* Check decoded
2023-08-01 18:24:40 -05:00
Ben Meadors
9eeec6c083 Reply to Repeater in DeviceTelemetry module (#2661) 2023-08-01 16:18:10 -05:00
Ben Meadors
919b2d1e48 Merge branch 'master' into raspi-portduino 2023-07-31 19:00:00 -05:00
Ben Meadors
c4474a7b99 Merge branch 'master' into picomputer-s3 2023-07-31 18:59:50 -05:00
Ben Meadors
0821cff1c8 Merge remote-tracking branch 'origin/master' into 2.2-working-changes 2023-07-31 18:54:53 -05:00
github-actions[bot]
b799b7bf62 [create-pull-request] automated change (#2672)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-07-31 18:51:15 -05:00
Ben Meadors
90ec8eae6c Backmerge master protos 2023-07-31 18:28:27 -05:00
Thomas Göttgens
ba172aae32 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-07-31 22:28:04 +02:00
Thomas Göttgens
26338b8f2b Merge branch 'master' into picomputer-s3 2023-07-31 22:27:24 +02:00
Jonathan Bennett
939a359e7e Adds DOP fields to JSON MQTT output (#2671)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-31 15:19:36 -05:00
GUVWAF
5a5af4707c SerialModule SIMPLE mode: use write() instead of printf() 2023-07-31 22:18:42 +02:00
Thomas Göttgens
ef5e21d3da Enable Trunk on Windows 2023-07-31 21:37:55 +02:00
Ben Meadors
8a49221b7f Update version.properties 2023-07-30 20:17:57 -05:00
Ben Meadors
76dc805184 Add Nano-g2-ultra 2023-07-30 14:07:17 -05:00
GUVWAF
297708a50b Manually update protos 2023-07-30 17:27:43 +02:00
GUVWAF
a61a4fad3e Merge pull request #2667 from GUVWAF/removeNeighbors
Remove neighbors after twice their broadcast interval
2023-07-30 17:17:17 +02:00
GUVWAF
c66b68b0cc Remove neighbors after twice their broadcast interval 2023-07-30 16:54:39 +02:00
Ben Meadors
97d7a89644 Update protobufs 2023-07-30 07:58:11 -05:00
Ben Meadors
04cba45c60 Merge branch 'master' into 2.2-working-changes 2023-07-30 07:54:11 -05:00
Manuel
502a6596a3 T deck: support keyboard, trackball and touchscreen (#2665)
* add hwid for auto-detection

* fix: heltec-wireless-tracker USB serial

* T-Deck support

* trunk fmt

* set FRAMERATE to 1

* fix some defines

* trunk fmt

* corrected vendor link

* T-Deck: support keyboard, trackball & touch screen

* T-Watch add touchscreen defs, remove getTouch

* fix warnings

* getTouch uint16 -> int16

* fix touch x,y

* fix I2C port

* CannedMsgModule: use entire display height

* trunk fmt

* fix I2C issue for T-Watch

* allow dest selection in canned mode

* fix: allow dest selection in canned mode

* use tft.setBrightness() to poweroff display

* Increased t-watch framerate and added back haptic feedback

* add da ref

* Move to touched

* improved sensitivity and accuracy of touch events

* use double tap to send canned message

* fix warning

* trunk fmt

* Remove extra hapticFeedback()

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-30 07:51:26 -05:00
Ben Meadors
5aedd84c7d Merge branch 'master' into 2.2-working-changes 2023-07-29 08:15:17 -05:00
Neil Hao
b9c9f0f865 nano-g2-ultra (#2660)
* 'nano-g2-ultra'

* revert overcommit

* nano-g2-ultra-fmt

* revert overcommit

* revert overcommit

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-29 07:54:56 -05:00
GUVWAF
ffcc1a0275 RP2040: Enable ExternalNotification and RangeTest Module, set randomSeed (#2664)
* Enable ExternalNotification (and RangeTest) Module

* Set a random seed at boot
2023-07-29 07:19:58 -05:00
Ben Meadors
3d697f8cf4 Enable SX126X RX Boosted gain by default (#2663) 2023-07-28 10:39:40 -05:00
Ben Meadors
38c9a1ea07 neighborInfo->node_broadcast_interval_secs 2023-07-28 10:36:44 -05:00
Ben Meadors
0eefd0912f Move node_broadcast_interval_secs 2023-07-28 10:28:14 -05:00
Ben Meadors
0cda8e6087 Start plumbing node_broadcast_interval_secs 2023-07-28 06:58:28 -05:00
Ben Meadors
2cf648928a Add node_broadcast_interval_secs to Neighbor 2023-07-28 06:43:21 -05:00
Andre K
3cd7d8d6af update min_app_version to 2.2.0 2023-07-28 06:22:16 -03:00
Ben Meadors
702a83b525 Bumb device state version 2023-07-27 16:03:57 -05:00
GUVWAF
32246850aa Convert protobuf values that are unsigned properly to uint in JSON (#2659) 2023-07-27 13:53:20 -05:00
Ben Meadors
74650ca276 Words are important 2023-07-27 13:23:18 -05:00
Ben Meadors
0141bbe772 Regen 2023-07-27 12:59:06 -05:00
Ben Meadors
049c587ca2 Add phoneapi plumbing. Need to regen protos on my other machine 2023-07-27 12:51:31 -05:00
Ben Meadors
1a28225cd5 Merge branch 'master' into 2.2-working-changes 2023-07-27 08:55:48 -05:00
Ben Meadors
6bd870c454 I guess we have to use SHAs (lame) 2023-07-27 07:59:39 -05:00
Ben Meadors
c782380373 Fix semgrep errors 2023-07-27 07:04:00 -05:00
Ben Meadors
4fd756acd8 Merge branch 'master' into 2.2-working-changes 2023-07-27 06:42:02 -05:00
Ben Meadors
0b509c7e79 Remove concurrency groups for now. They seem to cause CI hangs 2023-07-27 06:41:39 -05:00
Ben Lipsey
86af578df9 Preferred units when distance unknown (#2652)
* units when distance unknown

* replace deleted comment
2023-07-26 18:06:31 -05:00
Thomas Göttgens
ff11506922 Merge pull request #2649 from meshtastic/neighborinfo
add Neighborinfo
2023-07-26 13:07:01 +02:00
Ben Meadors
f35b422365 Trunk 2023-07-25 20:54:01 -05:00
Ben Meadors
08f1ac785a Gut NodeDb and remove deprecated protos 2023-07-25 19:13:19 -05:00
Ben Meadors
146ed067a1 Merge branch 'master' into neighborinfo 2023-07-25 16:14:50 -05:00
Ben Meadors
bdcf17a3f7 Add T-Deck to S3 ota logical branch (#2644)
* Add T-Deck to S3 ota logical branch

* Revert "Add T-Deck to S3 ota logical branch"

This reverts commit d0aef9dc26.

* Add targets

* Get the bat file too
2023-07-25 16:13:32 -05:00
github-actions[bot]
81edf363d7 [create-pull-request] automated change (#2645)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-07-25 05:46:11 -05:00
Ben Meadors
96c6a20e03 Ensure that MQTT is enabled and log initialization (#2643) 2023-07-24 12:33:01 -05:00
Ben Meadors
3fbe2d771c Hopefully this cancels previous CI runs for a branch (#2642) 2023-07-24 09:47:16 -05:00
Jonathan Bennett
ac9c81f6d1 Check Position Request for Primary Channel (#2638)
Prevents leaking location data to secondary channels.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-24 09:37:56 -05:00
Ben Meadors
2e7c95a110 Merge branch 'master' into neighborinfo 2023-07-24 07:24:34 -05:00
Ben Meadors
490abdac96 Whoops 2023-07-24 07:22:04 -05:00
Ben Meadors
b17436a023 Patch gather-artifacts 2023-07-24 06:54:05 -05:00
rcarteraz
b9ae63cb3c Update Bug Report.yml (#2640)
Add T-Deck, T-Watch, Wireless Paper, and Wireless Tacker to device list.
2023-07-24 06:44:19 -05:00
github-actions[bot]
55701692fd [create-pull-request] automated change (#2637)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-07-24 06:43:47 -05:00
Thomas Göttgens
171cca435e Merge branch 'master' into raspi-portduino 2023-07-24 11:00:58 +02:00
Ben Meadors
470363d294 Update Hydra to use new TXEN->DIO2 macro (#2636) 2023-07-22 18:59:33 -05:00
github-actions[bot]
fb21bfe0f5 [create-pull-request] automated change (#2635)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-07-22 09:37:51 -05:00
Ben Meadors
0739bc0cea T-Watch S3 Support (#2632)
* T-Watch WIP

* Updates

* Temp

* Update screen spi bus and and backlight en

* Peripherals progress

* Fixes

* Fixes

* Updates

* DRV scaffolding

* Fixed touch-screen driver selection. WIP on DRV haptic feedback

* DRV2605 pmu channel

* Trunk

* Fixes and defaults

* Dropped an s

* Move PMU and turn off screen that way

* Add t-deck and t-watch-s3 to CI and cleanup

* More cleanup
2023-07-22 09:26:54 -05:00
Ben Meadors
3a24882e76 Merge branch 'master' into neighborinfo 2023-07-22 08:46:27 -05:00
andrew-moroz
1c74479555 xiao-ble: add initial support for the Xiao BLE + Ebyte E22-900M30S (#2633)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-21 20:37:00 -05:00
rcarteraz
084ad1b722 Update main_matrix.yml (#2634)
Add Heltec Wireless Paper to S3 Boards
2023-07-21 19:32:39 -05:00
Manuel
2486892e6d Basic T-Deck support (#2630)
* add hwid for auto-detection

* fix: heltec-wireless-tracker USB serial

* T-Deck support

* trunk fmt

* set FRAMERATE to 1

* fix some defines

* trunk fmt

* corrected vendor link
2023-07-19 08:13:51 -05:00
github-actions[bot]
77efbb3f5d [create-pull-request] automated change (#2626)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-07-18 10:00:12 -05:00
Ben Meadors
eb7025f1b1 Add Hydra specific target to define GPS EN pin and limit tx power (#2608)
* Use DIO2 bridged to TXEN and remove TX/RXEN pin switching altogether

* Add Hydra specific target to limit tx power and define GPS EN

* Whoops
2023-07-18 07:09:55 -05:00
github-actions[bot]
69beef8310 [create-pull-request] automated change (#2625)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-07-18 06:19:37 -05:00
Manuel
468807466c fix BLE PIN screen for not so large screens (#2624)
* add hwid for auto-detection

* fix: heltec-wireless-tracker USB serial

* fix BLE PIN screen for not so large displays
2023-07-18 06:10:39 -05:00
code8buster
8927cffd64 GPS log modifications (#2609)
* Move module info for use in functions outside of probe, refmt MON-VER message

* use checksum function in probe message

* Housekeeping on some comments, unsign the position ctr again
2023-07-17 20:27:14 -05:00
tropho23
5995c7060d Added triple-press GPS toggle button changes for select ESP32 devices (#2617)
* Added triple-press GPS toggle button changes

* Revert edits to extensions.json

* comma'd

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: code8buster <communismisgreat@national.shitposting.agency>
2023-07-17 18:55:40 -05:00
Manuel
541291cc70 resolve heltec-wireless-tracker serial issue (#2621)
* add hwid for auto-detection

* fix: heltec-wireless-tracker USB serial
2023-07-17 13:06:34 -05:00
Ben Meadors
41b07de5a2 Merge branch 'master' into neighborinfo 2023-07-17 09:21:08 -05:00
Mark Trevor Birss
4306c32349 Update variant.h (#2620)
Update M5Stack CoreInk enable GPS/BDS

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-17 09:20:42 -05:00
Manuel
491fe52841 add hwid for auto-detection (#2619) 2023-07-17 09:20:05 -05:00
Manuel
ad5de5a724 increase BT NIMBLE task stack size by 1k (#2618) 2023-07-17 06:23:27 -05:00
Manuel
ab32503601 Heltec-Tracker: GPS support (#2615)
* Heltec-Tracker: GPS support

* trunk fmt

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-16 16:57:14 -05:00
Ben Meadors
e4e26a819b Check if hasSensor an run if not initialized (#2613) 2023-07-16 15:23:31 -05:00
Ben Meadors
6d97d5dfa2 Bump PR artifacts github action 2023-07-16 15:18:42 -05:00
Manuel
c75965480f Heltec-Tracker: TFT LCD support (#2612)
* Heltec-Tracker: TFT LCD support

* trunk fmt

* backwards compatibility  with ST7735 devices

* trunk fmt
2023-07-15 08:53:26 -05:00
luzpaz
003047baaf Fix various typos (#2607)
* Fix various typos

Found via `codespell -q 3 -L acount,clen,dout`

* Trunk reformatting

---------

Co-authored-by: code8buster <communismisgreat@national.shitposting.agency>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-07-14 16:25:20 -05:00
Ben Meadors
4ace59fc18 Partial Heltec Wireless Paper and Wireless Tracker support (#2594)
* WIP

* Comment

* WIP

* TFT_CTRL

* Update platformio.ini

update to current latest version available

* Update EInkDisplay2.cpp

Is the e-ink Display a DEPG0213BN ?

* Logging

* trunk fmt

---------

Co-authored-by: Mark Trevor Birss <markbirss@gmail.com>
2023-07-14 16:12:30 -05:00
Dmitry Galenko
aa0b56e947 GPS: Implement Power Management, Refactor Code and Fix GSA Message Configuration for U-Blox hardware (#2606) 2023-07-12 19:35:41 -05:00
Ben Lipsey
42d79d012e center text based on screen width (#2603) 2023-07-09 20:16:36 -05:00
Ben Meadors
d3e7e45ded Append alpha to release name 2023-07-09 06:17:17 -05:00
github-actions[bot]
0cca7751cd [create-pull-request] automated change (#2600)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-07-09 06:15:48 -05:00
Ben Meadors
de53280ffc PIN_GPS_EN power toggling (#2592)
* PIN_GPS_EN

* Remove extra digitalWrite

* GPS_POWER_TOGGLE macro enabled. Added WSLv3 too

* Update variant.h

* Update variant.h

* Fixed macro guard
2023-07-08 21:01:00 -05:00
Ben Meadors
65aafe7ea1 Update protos 2023-07-08 20:46:34 -05:00
Ben Meadors
6e96216ba3 MQTT client proxying (#2587)
* WIP on MQTT proxy message queue

* Fix copy paste goof

* Progress on uplink

* Has packets

* Avoid trying to connect if we're proxying

* Pointer correctly

* Remove wifi guards

* Client proxy subscribe

* Fixed method that got bababababorked somehow... personally I blame CoPilot

* Short circuit logic

* Remove canned settings

* Missed some stuff in the move

* Guard pubsub client for non-networked variants

* Has networking guard

* else

* Return statement for fall-thru

* More gaurd removals

* Removed source filters. No wonder I was confused

* Bounding

* Scope guard around else and fix return

* Portduino

* Defs instead

* Move macro up to actually fix portduino

* Size_t

* Unsigned int

* Thread interval

* Protos

* Protobufs ref
2023-07-08 20:37:04 -05:00
Max-Plastix
da389eb787 Correct unused variable warning and typo around GNSS_MODEL_UNKNOWN (#2596)
* Small warning and typo cleanup.

* Update GPS.cpp (missed one instance of GNSS_MODEL_UNKONW)
2023-07-08 18:30:52 -05:00
GUVWAF
d8ad2b3f48 RPi Pico screen, CannedMessageModule (CardKB) and reboot support (#2595)
* Make input_source case insensitive

* Implement reboot for RP2040

* Remove EXT_NOTFIFY_OUT as it conflicts with I2C and module is not supported

* RP2040 has screen, button and wire

* Add default I2C pins also for Pico W
2023-07-08 11:32:36 -05:00
Ben Meadors
97606cd382 New platform updates (#2593) 2023-07-07 18:58:49 -05:00
prokrypt
5c34e36bec Temporary band-aid to address mesh [un]reliability after queue "fix" (#2588) 2023-07-06 06:43:21 -05:00
Dmitry Galenko
9c141919f6 Initial support for MonteOps's fixed hardware platform (#2582)
* Initial support for MonteOps's fixed hardware platform

* Update platformio env config + cleanup

* Fix platformio build

* Fix platformio build

* Fix wrong definition logic for NCP5623

* Fix another wrong definition logic for NCP5623, it's not board feature

* Fix wrong definition logic for NCP5623 in External Notification code, it's not board feature

* We need for CI magic here

* Another fix related to NCP5623

* Fix cosmetic issue with redifined variable

* Fix typo

* Cleanup and update defs for HW1

* Fix OEM RAK4631

* Fix AQ sensor reading

* Fix AQ sensor reading (better variant)

* Fix build for other nRF52 devices

* Replace HAS_EINK_RAK to RAK_4631
2023-07-03 09:34:32 -05:00
GUVWAF
b9ad274104 Update retransmission timer based on client offset (#2583) 2023-07-02 16:30:28 -05:00
Dmitry Galenko
4ef61f0f15 GPS: Performance improvment for U-Blox hardware (#2574)
* Add proper configuration procedure for U-Blox modules

* More human friendly getACK

* Fix checksum calculation and payload

* GPS: move unsigned int check

* Introduce UBX protocol payload checksuming

* Fix missed checksums calculation for UBX-CFG-CFG
2023-07-01 19:20:40 -05:00
Thomas Göttgens
1745722dac Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-06-28 09:12:10 +02:00
github-actions[bot]
c120549215 [create-pull-request] automated change (#2580)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-06-27 20:29:11 -05:00
github-actions[bot]
7ca2e818df [create-pull-request] automated change (#2579)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-06-27 19:38:45 -05:00
Thomas Göttgens
f02923435b Fix build warning 2023-06-27 23:10:53 +02:00
Ben Meadors
849599cd8e Merge branch 'master' into picomputer-s3 2023-06-27 15:40:13 -05:00
Ben Meadors
eb0a96a79e Default ext. notification output for RAK to LED #2 (#2570)
* Default ext. notification output for RAK to LED #2

* Enabled by default

* Update

* Wrong macro

* Output and nag
2023-06-27 12:21:06 -05:00
Thomas Göttgens
e878f55ed3 Merge branch 'master' into raspi-portduino 2023-06-27 18:13:24 +02:00
Thomas Göttgens
bfc567ad89 Add variant an plumbing for #2468 2023-06-27 18:11:58 +02:00
Thomas Göttgens
b665786c77 Merge branch 'master' into neighborinfo 2023-06-27 18:00:20 +02:00
Ben Meadors
9e2b86b92c Bump RadioLib to 6.1.0 (#2577)
* Bump RadioLib to 6.1.0

* RP2040

* More excludes

* Jan added a lot of stuff apparently

* Stay back a version on portduino for now

* It wasn't this. I need to remove the docker build from ci
2023-06-27 07:08:32 -05:00
Ben Meadors
d0cf70c8b3 Remove docker steps from PR build process 2023-06-27 06:59:28 -05:00
charminULTRA
44a906dd01 RAK14001 LED - Turn on to 50% at boot (#2571)
* Addition of RAK 14001 functionality to start and stay on for boot

* Fixing via Trunk

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-06-26 19:59:44 -05:00
GUVWAF
ccb682bbb8 Call getMacAddr within pickNewNodeNum() (#2576)
It could be called from within NodeDB::init() before it is set
2023-06-26 19:26:12 -05:00
GUVWAF
e60a5f1cf2 Setter for NeighborInfo 2023-06-25 15:41:19 +02:00
GUVWAF
6bdf67c9be Conversion to NodeInfoLite 2023-06-25 15:41:06 +02:00
Ben Meadors
bbfd62c47e Merge branch 'master' into neighborinfo 2023-06-21 21:11:06 -05:00
Ben Meadors
e677a02273 Map built-in LED on RAK-11310 (#2568) 2023-06-21 12:11:42 -05:00
GUVWAF
47168d5063 Always assign NodeNum based on MAC address (#2567)
* Always assign NodeNum based on MAC address
Step one of trying to fix infinite loop

* Store our mac.addr again to ignore an already existing NodeNum if it's us
2023-06-20 16:29:25 -05:00
Ben Meadors
a07e30544d Merge branch 'master' into neighborinfo 2023-06-19 06:16:42 -05:00
github-actions[bot]
5591b9b9f5 [create-pull-request] automated change (#2564)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-06-18 20:46:06 -05:00
Ben Meadors
9716bd8bec Merge branch 'master' into neighborinfo 2023-06-13 05:44:48 -05:00
Ben Meadors
c2168dd450 Merge branch 'master' into neighborinfo 2023-06-09 19:51:22 -05:00
GUVWAF
66c71250b8 Update last_sent_by_id in FloodingRouter 2023-06-08 20:59:09 +02:00
Ben Meadors
5c438ae792 Merge branch 'master' into neighborinfo 2023-06-06 19:29:59 -05:00
GUVWAF
cdf44ce7fa Move module init out of repeater clause 2023-06-06 21:07:12 +02:00
GUVWAF
d70bd23260 Use float print specifier for SNR 2023-06-06 21:06:19 +02:00
Ben Meadors
b42ead4400 Merge branch 'master' into neighborinfo 2023-06-02 06:46:45 -05:00
Ben Meadors
b2704a0082 Merge branch 'master' into neighborinfo 2023-06-01 06:02:42 -05:00
Ben Meadors
9b94701699 Merge branch 'master' into neighborinfo 2023-05-31 20:08:50 -05:00
Thomas Göttgens
61661aed50 Broadcast neighbor info
also update trunk
2023-05-31 13:18:43 +02:00
Thomas Göttgens
3a25d6d3b3 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-30 14:52:24 +02:00
Ben Meadors
fd4e9daa7f Merge branch 'master' into picomputer-s3 2023-05-30 07:36:53 -05:00
Thomas Göttgens
b6f7b7fa47 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-30 13:07:29 +02:00
Thomas Göttgens
a92a960682 Merge branch 'master' into picomputer-s3 2023-05-30 09:55:33 +02:00
Thomas Göttgens
5d2ab65a81 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-27 13:08:57 +02:00
Thomas Göttgens
f3b7f7251c Add variant an plumbing for #2468 2023-05-27 13:08:27 +02:00
Thomas Göttgens
2f60bbe5f2 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-24 01:48:44 +02:00
Thomas Göttgens
0261754269 Add variant an plumbing for #2468 2023-05-24 01:48:01 +02:00
Thomas Göttgens
d74cbdaa8b update platform def 2023-05-23 21:55:12 +02:00
Ben Meadors
3a5b79e4c1 Merge branch 'master' into raspi-portduino 2023-05-23 07:51:32 -05:00
Ben Meadors
9bee35118f Merge branch 'master' into raspi-portduino 2023-05-18 06:47:56 -05:00
Thomas Göttgens
e6fc2af21f Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-17 20:28:49 +02:00
Ben Meadors
ae41944a89 Merge branch 'master' into picomputer-s3 2023-05-16 10:38:12 -05:00
Thomas Göttgens
62259583e6 Add variant an plumbing for #2468 2023-05-15 17:18:06 +02:00
Thomas Göttgens
c5d87fe581 Add variant an plumbing for #2468 2023-05-15 17:17:14 +02:00
Thomas Göttgens
80f029aa32 Merge branch 'master' into raspi-portduino 2023-05-10 17:13:32 +02:00
Thomas Göttgens
b75aa79da5 Merge branch 'master' into raspi-portduino 2023-05-08 10:32:36 +02:00
Thomas Göttgens
49febc0d9d Merge branch 'master' into raspi-portduino 2023-04-24 14:58:20 +02:00
Thomas Göttgens
85818b8dfd Merge branch 'master' into raspi-portduino 2023-04-21 16:50:48 +02:00
Thomas Göttgens
7d299b06a7 Merge branch 'master' into raspi-portduino 2023-04-04 15:00:31 +02:00
Thomas Göttgens
14080d4667 Merge branch 'master' into raspi-portduino 2023-04-02 21:24:49 +02:00
Thomas Göttgens
8a806efb95 Merge branch 'master' into raspi-portduino 2023-03-27 15:30:05 +02:00
Thomas Göttgens
ef2d0cb830 Merge branch 'master' into raspi-portduino 2023-03-21 09:31:49 +01:00
Ben Meadors
5e779bfb33 Merge branch 'master' into raspi-portduino 2023-03-16 14:43:23 -05:00
Thomas Göttgens
498964e04e Merge branch 'master' into raspi-portduino 2023-03-04 17:24:37 +01:00
Thomas Göttgens
7d0bea267a Merge branch 'master' into raspi-portduino 2023-02-22 10:08:20 +01:00
Thomas Göttgens
ed1aa9ddb0 Merge branch 'master' into raspi-portduino 2023-02-17 12:34:00 +01:00
Thomas Göttgens
97a0b164be Merge branch 'master' into raspi-portduino 2023-02-10 00:21:47 +01:00
Ben Meadors
82706a961f Merge branch 'master' into raspi-portduino 2023-02-08 07:40:36 -06:00
Thomas Göttgens
06a1b079da even more cleanup-ing and revert-ing 2023-02-02 11:47:47 +01:00
Thomas Göttgens
56afed84df revert some more 2023-02-02 11:35:30 +01:00
Thomas Göttgens
945fd7a05c revert readprops change 2023-02-02 11:32:00 +01:00
Thomas Göttgens
e9a55fc296 revert them trunk shite 2023-02-02 11:29:55 +01:00
Thomas Göttgens
472c43aace Merge remote-tracking branch 'remotes/origin/master' into raspi-portduino 2023-02-02 10:49:45 +01:00
Thomas Göttgens
8b5937892b Merge pull request #2100 from meshtastic/develop
Update Raspi branch
2023-01-04 21:11:47 +01:00
Thomas Göttgens
8c20fe5ec4 Start working on RF95 attached to Raspberry Pi 2022-12-30 21:44:51 +01:00
334 changed files with 10632 additions and 2882 deletions

View File

@@ -37,7 +37,9 @@ body:
- T-Lora v1
- T-Lora v1.3
- T-Lora v2 1.6
- T-Deck
- T-Echo
- T-Watch
- Rak4631
- Rak11200
- Rak11310
@@ -45,6 +47,8 @@ body:
- Heltec v2
- Heltec v2.1
- Heltec V3
- Heltec Wireless Paper
- Heltec Wireless Tracker
- Raspberry Pi Pico (W)
- Relay v1
- Relay v2

View File

@@ -7,7 +7,7 @@
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (WSL2 is required on windows),
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the linux version),
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed.

View File

@@ -17,11 +17,11 @@ jobs:
uses: ./.github/actions/setup-base
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
with:
repo: "meshtastic/web"
file: "build.tar"
target: "build.tar"
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unpack web ui
@@ -40,11 +40,11 @@ jobs:
run: bin/build-esp32.sh ${{ inputs.board }}
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
with:
repo: "meshtastic/firmware-ota"
file: "firmware.bin"
target: "release/bleota.bin"
repo: meshtastic/firmware-ota
file: firmware.bin
target: release/bleota.bin
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string

View File

@@ -17,11 +17,11 @@ jobs:
uses: ./.github/actions/setup-base
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
with:
repo: "meshtastic/web"
file: "build.tar"
target: "build.tar"
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unpack web ui
@@ -38,11 +38,11 @@ jobs:
run: bin/build-esp32.sh ${{ inputs.board }}
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
with:
repo: "meshtastic/firmware-ota"
file: "firmware-s3.bin"
target: "release/bleota-s3.bin"
repo: meshtastic/firmware-ota
file: firmware-s3.bin
target: release/bleota-s3.bin
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string

45
.github/workflows/build_raspbian.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: Build Raspbian
on: workflow_call
permissions:
contents: write
packages: write
jobs:
build-raspbian:
runs-on: [self-hosted, linux, ARM64]
steps:
- name: Checkout code
uses: actions/checkout@v3
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@v3
with:
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
path: |
release/meshtasticd_linux_arm64
bin/config-dist.yaml

View File

@@ -1,4 +1,7 @@
name: CI
#concurrency:
# group: ${{ github.ref }}
# cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
on:
# # Triggers the workflow on push but only for the master branch
push:
@@ -33,6 +36,8 @@ jobs:
- board: m5stack-coreink
- board: tbeam-s3-core
- board: tlora-t3s3-v1
- board: t-watch-s3
- board: t-deck
#- board: rak11310
runs-on: ubuntu-latest
@@ -44,7 +49,7 @@ jobs:
- name: Trunk Check
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: trunk-io/trunk-action@v1
uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b
- name: Check ${{ matrix.board }}
run: bin/check-all.sh ${{ matrix.board }}
@@ -66,6 +71,7 @@ jobs:
- board: heltec-v2_1
- board: tbeam0_7
- board: meshtastic-diy-v1
- board: hydra
- board: meshtastic-dr-dev
- board: nano-g1
- board: station-g1
@@ -83,8 +89,13 @@ jobs:
include:
- board: heltec-v3
- board: heltec-wsl-v3
- board: heltec-wireless-tracker
- board: heltec-wireless-paper
- board: tbeam-s3-core
- board: tlora-t3s3-v1
- board: t-watch-s3
- board: t-deck
- board: picomputer-s3
uses: ./.github/workflows/build_esp32_s3.yml
with:
board: ${{ matrix.board }}
@@ -92,14 +103,15 @@ jobs:
build-nrf52:
strategy:
fail-fast: false
max-parallel: 2
matrix:
include:
- board: rak4631
- board: rak4631_eink
- board: monteops_hw1
- board: t-echo
- board: pca10059_diy_eink
- board: feather_diy
- board: nano-g2-ultra
uses: ./.github/workflows/build_nrf52.yml
with:
board: ${{ matrix.board }}
@@ -111,11 +123,21 @@ jobs:
matrix:
include:
- board: pico
- board: picow
- board: rak11310
uses: ./.github/workflows/build_rpi2040.yml
with:
board: ${{ matrix.board }}
build-raspbian:
strategy:
fail-fast: false
max-parallel: 1
uses: ./.github/workflows/build_raspbian.yml
package-raspbian:
uses: ./.github/workflows/package_raspbian.yml
build-native:
runs-on: ubuntu-latest
steps:
@@ -150,12 +172,14 @@ jobs:
release/device-*.bat
- name: Docker login
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/login-action@v2
with:
username: meshtastic
password: ${{ secrets.DOCKER_TOKEN }}
- name: Docker setup
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/setup-buildx-action@v2
- name: Docker build and push tagged versions
@@ -168,7 +192,7 @@ jobs:
tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
- name: Docker build and push
if: github.ref == 'refs/heads/master'
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/build-push-action@v3
with:
context: .
@@ -189,7 +213,15 @@ jobs:
gather-artifacts:
runs-on: ubuntu-latest
needs:
[build-esp32, build-esp32-s3, build-nrf52, build-native, build-rpi2040]
[
build-esp32,
build-esp32-s3,
build-nrf52,
build-raspbian,
build-native,
build-rpi2040,
package-raspbian,
]
steps:
- name: Checkout code
uses: actions/checkout@v3
@@ -201,12 +233,15 @@ jobs:
with:
path: ./
- name: Display structure of downloaded files
run: ls -R
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Move files up
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat ./firmware-raspbian-*/release/meshtasticd_linux_arm64 ./firmware-raspbian-*/bin/config-dist.yaml
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v3
@@ -218,6 +253,8 @@ jobs:
./firmware-*-ota.zip
./device-*.sh
./device-*.bat
./meshtasticd_linux_arm64
./config-dist.yaml
retention-days: 90
- uses: actions/download-artifact@v3
@@ -245,8 +282,9 @@ jobs:
retention-days: 30
- name: Create request artifacts
continue-on-error: true # FIXME: Why are we getting 502, but things still work?
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v1.0.0
uses: gavv/pull-request-artifacts@v1.1.0
with:
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
@@ -278,6 +316,13 @@ jobs:
name: firmware-${{ steps.version.outputs.version }}
path: ./output
- uses: actions/download-artifact@v3
with:
name: artifact-deb
- name: Display structure of downloaded files
run: ls -R
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
@@ -304,7 +349,7 @@ jobs:
with:
draft: true
prerelease: true
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }}
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }} Alpha
tag_name: v${{ steps.version.outputs.version }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
@@ -331,6 +376,16 @@ jobs:
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add raspbian .deb
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
asset_name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
asset_content_type: application/vnd.debian.binary-package
- name: Bump version.properties
run: >-
bin/bump_version.py

View File

@@ -14,6 +14,6 @@ jobs:
uses: actions/checkout@v3
- name: Trunk Check
uses: trunk-io/trunk-action@v1
uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b
with:
trunk-token: ${{ secrets.TRUNK_TOKEN }}

62
.github/workflows/package_raspbian.yml vendored Normal file
View File

@@ -0,0 +1,62 @@
name: Package Raspbian
on:
workflow_call:
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
build-raspbian:
uses: ./.github/workflows/build_raspbian.yml
package-raspbian:
runs-on: ubuntu-latest
needs: build-raspbian
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
- name: Display structure of downloaded files
run: ls -R
- name: build .debpkg
run: |
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/usr/lib/systemd/system/
cp release/meshtasticd_linux_arm64 .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
- uses: jiro4989/build-deb-action@v3
with:
package: meshtasticd
package_root: .debpkg
maintainer: Jonathan Bennett
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
arch: arm64
depends: libyaml-cpp0.7
desc: Native Linux Meshtastic binary.
- uses: actions/upload-artifact@v3
with:
name: artifact-deb
path: |
./*.deb

22
.github/workflows/trunk-check.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Pull Request
on: [pull_request]
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions: read-all
jobs:
trunk_check:
name: Trunk Check Runner
runs-on: ubuntu-latest
permissions:
checks: write # For trunk to post annotations
contents: read # For repo checkout
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Trunk Check
uses: trunk-io/trunk-action@v1

2
.trunk/.gitignore vendored
View File

@@ -2,7 +2,7 @@
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml
shims

View File

@@ -1,7 +1,10 @@
enable=all
source-path=SCRIPTDIR
disable=SC2154
disable=SC2248
disable=SC2250
# If you're having issues with shellcheck following source, disable the errors via:
# disable=SC1090
# disable=SC1091
#

View File

@@ -3,7 +3,7 @@ rules:
required: only-when-needed
extra-allowed: ["{|}"]
empty-values:
forbid-in-block-mappings: true
forbid-in-block-mappings: false
forbid-in-flow-mappings: true
key-duplicates: {}
octal-values:

View File

@@ -1,48 +1,44 @@
version: 0.1
cli:
version: 1.9.1
version: 1.17.1
plugins:
sources:
- id: trunk
ref: v0.0.17
ref: v1.2.6
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- taplo@0.7.0
- ruff@0.0.265
- yamllint@1.31.0
- bandit@1.7.5
- checkov@3.0.16
- terrascan@1.18.3
- trivy@0.46.1
- trufflehog@3.62.1
- taplo@0.8.1
- ruff@0.1.3
- yamllint@1.32.0
- isort@5.12.0
- markdownlint@0.34.0
- oxipng@8.0.0
- markdownlint@0.37.0
- oxipng@9.0.0
- svgo@3.0.2
- actionlint@1.6.24
- flake8@6.0.0
- actionlint@1.6.26
- flake8@6.1.0
- hadolint@2.12.0
- shfmt@3.5.0
- shfmt@3.6.0
- shellcheck@0.9.0
- black@23.3.0
- black@23.9.1
- git-diff-check
- gitleaks@8.16.3
- clang-format@14.0.0
- prettier@2.8.8
disabled:
- taplo@0.7.0
- shellcheck@0.9.0
- shfmt@3.5.0
- oxipng@8.0.0
- actionlint@1.6.22
- markdownlint@0.34.0
- hadolint@2.12.0
- svgo@3.0.2
- gitleaks@8.18.0
- clang-format@16.0.3
- prettier@3.0.3
runtimes:
enabled:
- python@3.10.8
- go@1.19.5
- go@1.21.0
- node@18.12.1
actions:
disabled:
- trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
enabled:
- trunk-fmt-pre-commit
- trunk-check-pre-push
- trunk-upgrade-available

View File

@@ -6,4 +6,4 @@
"platformio.platformio-ide",
"trunk.io"
],
}
}

View File

@@ -1,4 +1,5 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "trunk.io"
"editor.defaultFormatter": "trunk.io",
"trunk.enableWindows": true
}

View File

@@ -10,8 +10,8 @@
This repository contains the device firmware for the Meshtastic project.
**[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
- **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
- **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
## Stats

View File

@@ -1,7 +1,7 @@
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
extends = arduino_base
platform = platformio/espressif32@^6.2.0
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.
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
@@ -28,7 +28,9 @@ build_flags =
-DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096
;-DDEBUG_HEAP
lib_deps =
@@ -36,8 +38,8 @@ lib_deps =
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
jgromes/RadioLib@^6.0.0
h2zero/NimBLE-Arduino@^1.4.1
jgromes/RadioLib@^6.2.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
@@ -55,4 +57,4 @@ lib_ignore =
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
board_build.partitions = partition-table.csv
board_build.partitions = partition-table.csv

View File

@@ -1,20 +1,21 @@
[nrf52_base]
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
platform = platformio/nordicnrf52@^9.6.0
platform = platformio/nordicnrf52@^10.1.0
extends = arduino_base
build_type = debug ; I'm debugging with ICE a lot now
build_flags =
${arduino_base.build_flags} -Wno-unused-variable
${arduino_base.build_flags}
-DSERIAL_BUFFER_SIZE=1024
-Wno-unused-variable
-Isrc/platform/nrf52
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2040> -<mesh/eth/>
lib_deps=
${arduino_base.lib_deps}
jgromes/RadioLib@^6.0.0
jgromes/RadioLib@^6.2.0
lib_ignore =
BluetoothOTA
BluetoothOTA

View File

@@ -1,6 +1,6 @@
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[portduino_base]
platform = https://github.com/meshtastic/platform-native.git#489ff929dca0bb768256ba2de45f95815111490f
platform = https://github.com/meshtastic/platform-native.git#05255283879a0c65a7d3eba6c468b9186438bb14
framework = arduino
build_src_filter =
@@ -10,6 +10,7 @@ build_src_filter =
-<platform/nrf52/>
-<platform/stm32wl/>
-<platform/rp2040>
-<mesh/wifi/>
-<mesh/http/>
-<mesh/eth/>
-<modules/esp32>
@@ -22,9 +23,11 @@ lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
jgromes/RadioLib@^6.0.0
jgromes/RadioLib@^6.1.0
build_flags =
${arduino_base.build_flags}
-fPIC
-Isrc/platform/portduino
-Isrc/platform/portduino
-DRADIOLIB_EEPROM_UNSUPPORTED

View File

@@ -1,8 +1,8 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#612de5399d68b359053f1307ed223d400aea975c
extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.2
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#d2461a14ad5aa920e44508d236c2f459e3befbf8
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
@@ -12,7 +12,7 @@ build_flags =
-D__PLAT_RP2040__
# -D _POSIX_THREADS
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/>
lib_ignore =
BluetoothOTA
@@ -20,5 +20,5 @@ lib_ignore =
lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
jgromes/RadioLib@^6.0.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
jgromes/RadioLib@^6.2.0
rweather/Crypto

View File

@@ -13,17 +13,17 @@ build_flags =
-DVECT_TAB_OFFSET=0x08000000
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
board_upload.offset_address = 0x08000000
upload_protocol = stlink
lib_deps =
${env.lib_deps}
jgromes/RadioLib@^6.0.0
jgromes/RadioLib@^6.2.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
https://github.com/littlefs-project/littlefs.git#v2.5.1
https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
lib_ignore =
https://github.com/mathertel/OneButton#2.1.0
https://github.com/mathertel/OneButton#2.1.0

View File

@@ -2,8 +2,8 @@
set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
VERSION=$(bin/buildinfo.py long)
SHORT_VERSION=$(bin/buildinfo.py short)
OUTDIR=release/
@@ -13,11 +13,15 @@ mkdir -p $OUTDIR/
rm -r $OUTDIR/* || true
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio pkg update
platformio pkg update
pio run --environment native
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
if command -v raspi-config &>/dev/null; then
pio run --environment raspbian
cp .pio/build/raspbian/program $OUTDIR/meshtasticd_linux_arm64
else
pio run --environment native
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
fi
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR

View File

@@ -4,23 +4,23 @@
set -e
VERSION=`bin/buildinfo.py long`
VERSION=$(bin/buildinfo.py long)
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
if [[ $# -gt 0 ]]; then
# can override which environment by passing arg
BOARDS="$@"
# can override which environment by passing arg
BOARDS="$@"
else
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631 rak4631_eink rak11200 t-echo pca10059_diy_eink"
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631 rak4631_eink rak11200 t-echo pca10059_diy_eink"
fi
echo "BOARDS:${BOARDS}"
CHECK=""
for BOARD in $BOARDS; do
CHECK="${CHECK} -e ${BOARD}"
CHECK="${CHECK} -e ${BOARD}"
done
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=medium --fail-on-defect=high

40
bin/config-dist.yaml Normal file
View File

@@ -0,0 +1,40 @@
# Define your devices here using Broadcom pin numbering
# Uncomment the block that corresponds to your hardware
---
Lora:
# Module: sx1262 # Waveshare SX126X XXXM
# DIO2_AS_RF_SWITCH: true
# CS: 21
# IRQ: 16
# Busy: 20
# Reset: 18
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
# CS: 7
# IRQ: 17
# Reset: 22
# Module: RF95 # Adafruit RFM9x
# Reset: 25
# CS: 7
# IRQ: 22
# Busy: 23
# Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html
# Reset: 22
# CS: 7
# IRQ: 25
# Set gpio chip to use in /dev/. Defaults to 0.
# Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
# gpiochip: 4
# Define GPIO buttons here:
GPIO:
# User: 6
# Define GPS
GPS:
# SerialPath: /dev/ttyS0

View File

@@ -32,7 +32,7 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
@REM Account for S3 board's different OTA partition
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% (
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% (
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
) else (
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-s3.bin

View File

@@ -50,7 +50,7 @@ if [ -f "${FILENAME}" ] && [ ! -z "${FILENAME##*"update"*}" ]; then
"$PYTHON" -m esptool erase_flash
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
# Account for S3 board's different OTA partition
if [ ! -z "${FILENAME##*"s3"*}" ] && [ ! -z "${FILENAME##*"-v3"*}" ]; then
if [ ! -z "${FILENAME##*"s3"*}" ] && [ ! -z "${FILENAME##*"-v3"*}" ] && [ ! -z "${FILENAME##*"t-deck"*}" ] && [ ! -z "${FILENAME##*"wireless-paper"*}" ] && [ ! -z "${FILENAME##*"wireless-tracker"*}" ]; then
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
else
"$PYTHON" -m esptool write_flash 0x260000 bleota-s3.bin

9
bin/meshtasticd.service Normal file
View File

@@ -0,0 +1,9 @@
[unit]
description=Meshtastic Native Daemon
[Service]
Type=simple
ExecStart=/usr/sbin/meshtasticd
[Install]
WantedBy=multi-user.target

10
bin/native-install.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
cp release/meshtasticd_linux_arm64 /usr/sbin/meshtasticd
mkdir /etc/meshtasticd
if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml
else
cp bin/config-dist.yaml /etc/meshtasticd/config.yaml
fi
cp bin/meshtasticd.service /usr/lib/systemd/system/meshtasticd.service

View File

@@ -28,8 +28,6 @@
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},

View File

@@ -0,0 +1,38 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DHELTEC_WIRELESS_TRACKER",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "heltec_wireless_tracker"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "Heltec Wireless Tracker",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://heltec.org/project/wireless-tracker/",
"vendor": "Heltec"
}

51
boards/nano-g2-ultra.json Normal file
View File

@@ -0,0 +1,51 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"usb_product": "BQ nRF52840",
"mcu": "nrf52840",
"variant": "nano-g2-ultra",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
},
"frameworks": ["arduino"],
"name": "BQ nRF52840",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra",
"vendor": "BQ Consulting"
}

41
boards/t-deck.json Normal file
View File

@@ -0,0 +1,41 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "t-deck"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "Espressif Systems LilyGO T-Deck (16 MB FLASH, 8 MB PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.lilygo.cc/en-pl/products/t-deck",
"vendor": "LilyGO"
}

View File

@@ -7,7 +7,10 @@
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4405"]],
"hwids": [
["0x239A", "0x4405"],
["0x239A", "0x002A"]
],
"usb_product": "TTGO_eink",
"mcu": "nrf52840",
"variant": "t-echo",

40
boards/t-watch-s3.json Normal file
View File

@@ -0,0 +1,40 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DT_WATCH_S3",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "t-watch-s3"
},
"connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino"],
"name": "LilyGo T-Watch 2020 V3",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"speed": 921600
},
"url": "https://www.lilygo.cc/en-pl/products/t-watch-s3",
"vendor": "LilyGo"
}

View File

@@ -15,7 +15,7 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [["0X303A", "0x1001"]],
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "tbeam-s3-core"
},

View File

@@ -0,0 +1,57 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v7.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_MDBT50Q_RX -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x810B"],
["0x239A", "0x010B"],
["0x239A", "0x810C"]
],
"usb_product": "XIAO-BOOT",
"mcu": "nrf52840",
"variant": "Seeed_XIAO_nRF52840_Sense",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "7.3.0",
"sd_fwid": "0x0123"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
},
"frameworks": ["arduino"],
"name": "Seeed Xiao BLE Sense",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink",
"cmsis-dap",
"blackmagic"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.seeedstudio.com/Seeed-XIAO-BLE-Sense-nRF52840-p-5253.html",
"vendor": "Seeed Studio"
}

View File

@@ -9,6 +9,7 @@
;default_envs = heltec-v1
;default_envs = heltec-v2_0
;default_envs = heltec-v2_1
;default_envs = heltec-wireless-tracker
;default_envs = tlora-v1
;default_envs = tlora_v1_3
;default_envs = tlora-v2
@@ -25,6 +26,7 @@
;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink
;default_envs = rak4631
;default_envs = rak10701
default_envs = wio-e5
extra_configs =
@@ -56,6 +58,12 @@ build_flags = -Wno-missing-field-initializers
-DRADIOLIB_EXCLUDE_MORSE
-DRADIOLIB_EXCLUDE_RTTY
-DRADIOLIB_EXCLUDE_SSTV
-DRADIOLIB_EXCLUDE_AX25
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE
-DRADIOLIB_EXCLUDE_BELL
-DRADIOLIB_EXCLUDE_PAGER
-DRADIOLIB_EXCLUDE_FSK4
-DRADIOLIB_EXCLUDE_APRS
monitor_speed = 115200
@@ -63,7 +71,7 @@ lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
https://github.com/mathertel/OneButton#2.1.0 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
nanopb/Nanopb@^0.4.7
erriez/ErriezCRC32@^1.0.1
@@ -81,11 +89,11 @@ check_flags =
framework = arduino
lib_deps =
${env.lib_deps}
mprograms/QMC5883LCompass@^1.1.1
mprograms/QMC5883LCompass@^1.2.0
end2endzone/NonBlockingRTTTL@^1.3.0
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#5cf62b36c6f30bc72a07bdb2c11fc9a22d1e31da
build_flags = ${env.build_flags} -Os -DRADIOLIB_SPI_PARANOID=0
build_flags = ${env.build_flags} -Os
build_src_filter = ${env.build_src_filter} -<platform/portduino/>
; Common libs for communicating over TCP/IP networks such as MQTT
@@ -100,17 +108,19 @@ lib_deps =
[environmental_base]
lib_deps =
adafruit/Adafruit BusIO@^1.11.4
adafruit/Adafruit Unified Sensor@^1.1.9
adafruit/Adafruit BMP280 Library@^2.6.6
adafruit/Adafruit Unified Sensor@^1.1.11
adafruit/Adafruit BMP280 Library@^2.6.8
adafruit/Adafruit BME280 Library@^2.2.2
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.5.2400
boschsensortec/BME68x Sensor Library@^1.1.40407
adafruit/Adafruit MCP9808 Library@^2.0.0
https://github.com/Tinyu-Zhao/INA3221@^0.0.1
adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0
adafruit/Adafruit SHTC3 Library@^1.0.0
adafruit/Adafruit LPS2X@^2.0.4
adafruit/Adafruit SHT31 Library@^2.2.0
adafruit/Adafruit SHT31 Library@^2.2.2
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
adafruit/Adafruit MPU6050@^2.2.4
adafruit/Adafruit LIS3DH@^1.2.4
adafruit/Adafruit LIS3DH@^1.2.4
https://github.com/lewisxhe/BMA423_Library@^0.0.1

View File

@@ -6,10 +6,37 @@
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MPU6050.h>
#include <Arduino.h>
#include <Wire.h>
#include <bma.h>
BMA423 bmaSensor;
bool BMA_IRQ = false;
#define ACCELEROMETER_CHECK_INTERVAL_MS 100
#define ACCELEROMETER_CLICK_THRESHOLD 40
uint16_t readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len)
{
Wire.beginTransmission(address);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom((uint8_t)address, (uint8_t)len);
uint8_t i = 0;
while (Wire.available()) {
data[i++] = Wire.read();
}
return 0; // Pass
}
uint16_t writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len)
{
Wire.beginTransmission(address);
Wire.write(reg);
Wire.write(data, len);
return (0 != Wire.endTransmission());
}
namespace concurrency
{
class AccelerometerThread : public concurrency::OSThread
@@ -29,10 +56,10 @@ class AccelerometerThread : public concurrency::OSThread
return;
}
accleremoter_type = type;
acceleremoter_type = type;
LOG_DEBUG("AccelerometerThread initializing\n");
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) {
if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) {
LOG_DEBUG("MPU6050 initializing\n");
// setup motion detection
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
@@ -40,11 +67,60 @@ class AccelerometerThread : public concurrency::OSThread
mpu.setMotionDetectionDuration(20);
mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized.
mpu.setInterruptPinPolarity(true);
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
LOG_DEBUG("LIS3DH initializing\n");
lis.setRange(LIS3DH_RANGE_2_G);
// Adjust threshhold, higher numbers are less sensitive
// Adjust threshold, higher numbers are less sensitive
lis.setClick(config.device.double_tap_as_button_press ? 2 : 1, ACCELEROMETER_CLICK_THRESHOLD);
} else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.begin(readRegister, writeRegister, delay)) {
LOG_DEBUG("BMA423 initializing\n");
Acfg cfg;
cfg.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
cfg.range = BMA4_ACCEL_RANGE_2G;
cfg.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
cfg.perf_mode = BMA4_CONTINUOUS_MODE;
bmaSensor.setAccelConfig(cfg);
bmaSensor.enableAccel();
struct bma4_int_pin_config pin_config;
pin_config.edge_ctrl = BMA4_LEVEL_TRIGGER;
pin_config.lvl = BMA4_ACTIVE_HIGH;
pin_config.od = BMA4_PUSH_PULL;
pin_config.output_en = BMA4_OUTPUT_ENABLE;
pin_config.input_en = BMA4_INPUT_DISABLE;
// The correct trigger interrupt needs to be configured as needed
bmaSensor.setINTPinConfig(pin_config, BMA4_INTR1_MAP);
#ifdef BMA423_INT
pinMode(BMA4XX_INT, INPUT);
attachInterrupt(
BMA4XX_INT,
[] {
// Set interrupt to set irq value to true
BMA_IRQ = true;
},
RISING); // Select the interrupt mode according to the actual circuit
#endif
struct bma423_axes_remap remap_data;
remap_data.x_axis = 0;
remap_data.x_axis_sign = 1;
remap_data.y_axis = 1;
remap_data.y_axis_sign = 0;
remap_data.z_axis = 2;
remap_data.z_axis_sign = 1;
// Need to raise the wrist function, need to set the correct axis
bmaSensor.setRemapAxes(&remap_data);
// sensor.enableFeature(BMA423_STEP_CNTR, true);
bmaSensor.enableFeature(BMA423_TILT, true);
bmaSensor.enableFeature(BMA423_WAKEUP, true);
// sensor.resetStepCounter();
// Turn on feature interrupt
bmaSensor.enableStepCountInterrupt();
bmaSensor.enableTiltInterrupt();
// It corresponds to isDoubleClick interrupt
bmaSensor.enableWakeupInterrupt();
}
}
@@ -53,9 +129,9 @@ class AccelerometerThread : public concurrency::OSThread
{
canSleep = true; // Assume we should not keep the board awake
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
wakeScreen();
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
uint8_t click = lis.getClick();
if (!config.device.double_tap_as_button_press) {
wakeScreen();
@@ -65,7 +141,13 @@ class AccelerometerThread : public concurrency::OSThread
buttonPress();
return 500;
}
} else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.getINT()) {
if (bmaSensor.isTilt() || bmaSensor.isDoubleClick()) {
wakeScreen();
return 500;
}
}
return ACCELEROMETER_CHECK_INTERVAL_MS;
}
@@ -84,9 +166,9 @@ class AccelerometerThread : public concurrency::OSThread
powerFSM.trigger(EVENT_PRESS);
}
ScanI2C::DeviceType accleremoter_type;
ScanI2C::DeviceType acceleremoter_type;
Adafruit_MPU6050 mpu;
Adafruit_LIS3DH lis;
};
} // namespace concurrency
} // namespace concurrency

View File

@@ -0,0 +1,75 @@
#include "configuration.h"
#ifdef HAS_NCP5623
#include <graphics/RAKled.h>
NCP5623 rgb;
#endif
namespace concurrency
{
class AmbientLightingThread : public concurrency::OSThread
{
public:
AmbientLightingThread(ScanI2C::DeviceType type) : OSThread("AmbientLightingThread")
{
// Uncomment to test module
// moduleConfig.ambient_lighting.led_state = true;
// moduleConfig.ambient_lighting.current = 10;
// // Default to a color based on our node number
// moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16;
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
#ifdef HAS_NCP5623
_type = type;
if (_type == ScanI2C::DeviceType::NONE) {
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus\n");
disable();
return;
}
if (!moduleConfig.ambient_lighting.led_state) {
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
disable();
return;
}
LOG_DEBUG("AmbientLightingThread initializing\n");
if (_type == ScanI2C::NCP5623) {
rgb.begin();
setLighting();
}
#endif
}
protected:
int32_t runOnce() override
{
#ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
setLighting();
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
} else {
return disable();
}
#else
return disable();
#endif
}
private:
ScanI2C::DeviceType _type = ScanI2C::DeviceType::NONE;
void setLighting()
{
#ifdef HAS_NCP5623
rgb.setCurrent(moduleConfig.ambient_lighting.current);
rgb.setRed(moduleConfig.ambient_lighting.red);
rgb.setGreen(moduleConfig.ambient_lighting.green);
rgb.setBlue(moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue);
#endif
}
};
} // namespace concurrency

View File

@@ -4,6 +4,7 @@
#include "concurrency/OSThread.h"
#include "configuration.h"
#include "graphics/Screen.h"
#include "main.h"
#include "power.h"
#include <OneButton.h>
@@ -35,6 +36,9 @@ class ButtonThread : public concurrency::OSThread
#endif
#ifdef BUTTON_PIN_TOUCH
OneButton userButtonTouch;
#endif
#if defined(ARCH_RASPBERRY_PI)
OneButton userButton;
#endif
static bool shutdown_on_long_stop;
@@ -44,8 +48,14 @@ class ButtonThread : public concurrency::OSThread
// callback returns the period for the next callback invocation (or 0 if we should no longer be called)
ButtonThread() : OSThread("Button")
{
#ifdef BUTTON_PIN
#if defined(ARCH_RASPBERRY_PI) || defined(BUTTON_PIN)
#if defined(ARCH_RASPBERRY_PI)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
userButton = OneButton(settingsMap[user], true, true);
#elif defined(BUTTON_PIN)
userButton = OneButton(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, true, true);
#endif
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP_SENSE);
@@ -57,8 +67,13 @@ class ButtonThread : public concurrency::OSThread
userButton.attachMultiClick(userButtonMultiPressed);
userButton.attachLongPressStart(userButtonPressedLongStart);
userButton.attachLongPressStop(userButtonPressedLongStop);
#if defined(ARCH_RASPBERRY_PI)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
wakeOnIrq(settingsMap[user], FALLING);
#else
wakeOnIrq(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, FALLING);
#endif
#endif
#ifdef BUTTON_PIN_ALT
userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
#ifdef INPUT_PULLUP_SENSE
@@ -86,9 +101,14 @@ class ButtonThread : public concurrency::OSThread
{
canSleep = true; // Assume we should not keep the board awake
#ifdef BUTTON_PIN
#if defined(BUTTON_PIN)
userButton.tick();
canSleep &= userButton.isIdle();
#elif defined(ARCH_RASPBERRY_PI)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
userButton.tick();
canSleep &= userButton.isIdle();
}
#endif
#ifdef BUTTON_PIN_ALT
userButtonAlt.tick();
@@ -98,10 +118,10 @@ class ButtonThread : public concurrency::OSThread
userButtonTouch.tick();
canSleep &= userButtonTouch.isIdle();
#endif
// if (!canSleep) LOG_DEBUG("Supressing sleep!\n");
// if (!canSleep) LOG_DEBUG("Suppressing sleep!\n");
// else LOG_DEBUG("sleep ok\n");
return 5;
return 50;
}
private:
@@ -120,6 +140,13 @@ class ButtonThread : public concurrency::OSThread
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
#if defined(ARCH_RASPBERRY_PI)
if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) &&
(settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) ||
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
}
static void userButtonPressedLong()
@@ -163,15 +190,17 @@ class ButtonThread : public concurrency::OSThread
static void userButtonMultiPressed()
{
#if defined(GPS_POWER_TOGGLE)
if (config.position.gps_enabled) {
LOG_DEBUG("Flag set to false for gps power\n");
} else {
LOG_DEBUG("Flag set to true to restore power\n");
if (!config.device.disable_triple_click && (gps != nullptr)) {
config.position.gps_enabled = !(config.position.gps_enabled);
if (config.position.gps_enabled) {
LOG_DEBUG("Flag set to true to restore power\n");
gps->enable();
} else {
LOG_DEBUG("Flag set to false for gps power\n");
gps->disable();
}
}
config.position.gps_enabled = !(config.position.gps_enabled);
doGPSpowersave(config.position.gps_enabled);
#endif
}
static void userButtonPressedLongStart()
@@ -196,4 +225,4 @@ class ButtonThread : public concurrency::OSThread
}
};
} // namespace concurrency
} // namespace concurrency

34
src/DisplayFormatters.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include "DisplayFormatters.h"
const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName)
{
switch (preset) {
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
return useShortName ? "ShortS" : "ShortSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
return useShortName ? "ShortF" : "ShortFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
return useShortName ? "MedS" : "MediumSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
return useShortName ? "MedF" : "MediumFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
return useShortName ? "LongS" : "LongSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
return useShortName ? "LongF" : "LongFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
return useShortName ? "LongM" : "LongMod";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
return useShortName ? "VeryL" : "VLongSlow";
break;
default:
return useShortName ? "Custom" : "Invalid";
break;
}
}

8
src/DisplayFormatters.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
#include "NodeDB.h"
class DisplayFormatters
{
public:
static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName);
};

View File

@@ -1,3 +1,13 @@
/**
* @file FSCommon.cpp
* @brief This file contains functions for common filesystem operations such as copying, renaming, listing and deleting files and
* directories.
*
* The functions in this file are used to perform common filesystem operations such as copying, renaming, listing and deleting
* files and directories. These functions are used in the Meshtastic-device project to manage files and directories on the
* device's filesystem.
*
*/
#include "FSCommon.h"
#include "configuration.h"
@@ -8,10 +18,19 @@
#ifdef SDCARD_USE_SPI1
SPIClass SPI1(HSPI);
#define SDHandler SPI1
#else
#define SDHandler SPI
#endif
#endif // HAS_SDCARD
/**
* @brief Copies a file from one location to another.
*
* @param from The path of the source file.
* @param to The path of the destination file.
* @return true if the file was successfully copied, false otherwise.
*/
bool copyFile(const char *from, const char *to)
{
#ifdef FSCom
@@ -41,6 +60,14 @@ bool copyFile(const char *from, const char *to)
#endif
}
/**
* Renames a file from pathFrom to pathTo.
*
* @param pathFrom The original path of the file.
* @param pathTo The new path of the file.
*
* @return True if the file was successfully renamed, false otherwise.
*/
bool renameFile(const char *pathFrom, const char *pathTo)
{
#ifdef FSCom
@@ -57,6 +84,13 @@ bool renameFile(const char *pathFrom, const char *pathTo)
#endif
}
/**
* Lists the contents of a directory.
*
* @param dirname The name of the directory to list.
* @param levels The number of levels of subdirectories to list.
* @param del Whether or not to delete the contents of the directory after listing.
*/
void listDir(const char *dirname, uint8_t levels, bool del = false)
{
#ifdef FSCom
@@ -152,6 +186,13 @@ void listDir(const char *dirname, uint8_t levels, bool del = false)
#endif
}
/**
* @brief Removes a directory and all its contents.
*
* This function recursively removes a directory and all its contents, including subdirectories and files.
*
* @param dirname The name of the directory to remove.
*/
void rmDir(const char *dirname)
{
#ifdef FSCom
@@ -180,6 +221,9 @@ void fsInit()
#endif
}
/**
* Initializes the SD card and mounts the file system.
*/
void setupSDCard()
{
#ifdef HAS_SDCARD
@@ -210,4 +254,4 @@ void setupSDCard()
LOG_DEBUG("Total space: %llu MB\n", SD.totalBytes() / (1024 * 1024));
LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
#endif
}
}

View File

@@ -106,7 +106,7 @@ class GPSStatus : public Status
bool matches(const GPSStatus *newStatus) const
{
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.timestamp, p.timestamp);
#endif
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||

View File

@@ -5,7 +5,8 @@
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)
*
* NOTE! xTimerPend... seems to ignore the time passed in on ESP32 and on NRF52
* The reason this didn't work is bcause xTimerPednFunctCall really isn't a timer function at all - it just means run the callback
* The reason this didn't work is because xTimerPednFunctCall really isn't a timer function at all - it just means run the
callback
* from the timer thread the next time you have spare cycles.
*
* @return true if successful, false if the timer fifo is too full.
@@ -28,6 +29,16 @@ static void IRAM_ATTR onTimer()
(*tCallback)(tParam1, tParam2);
}
/**
* Schedules a hardware callback function to be executed after a specified delay.
*
* @param callback The function to be executed.
* @param param1 The first parameter to be passed to the function.
* @param param2 The second parameter to be passed to the function.
* @param delayMsec The delay time in milliseconds before the function is executed.
*
* @return True if the function was successfully scheduled, false otherwise.
*/
bool scheduleHWCallback(PendableFunction callback, void *param1, uint32_t param2, uint32_t delayMsec)
{
if (!timer) {

View File

@@ -1,11 +1,28 @@
/**
* @file Power.cpp
* @brief This file contains the implementation of the Power class, which is responsible for managing power-related functionality
* of the device. It includes battery level sensing, power management unit (PMU) control, and power state machine management. The
* Power class is used by the main device class to manage power-related functionality.
*
* The file also includes implementations of various battery level sensors, such as the AnalogBatteryLevel class, which assumes
* the battery voltage is attached via a voltage-divider to an analog input.
*
* This file is part of the Meshtastic project.
* For more information, see: https://meshtastic.org/
*/
#include "power.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "buzz/buzz.h"
#include "configuration.h"
#include "main.h"
#include "meshUtils.h"
#include "sleep.h"
#include "utils.h"
// Working USB detection for powered/charging states on the RAK platform
#ifdef NRF_APM
#include "nrfx_power.h"
#endif
#ifdef DEBUG_HEAP_MQTT
#include "mqtt/MQTT.h"
@@ -40,6 +57,7 @@ static const adc_atten_t atten = ADC_ATTENUATION;
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
INA260Sensor ina260Sensor;
INA219Sensor ina219Sensor;
INA3221Sensor ina3221Sensor;
#endif
#ifdef HAS_PMU
@@ -50,7 +68,7 @@ XPowersLibInterface *PMU = NULL;
#else
// Copy of the base class defined in axp20x.h.
// I'd rather not inlude axp20x.h as it brings Wire dependency.
// I'd rather not include axp20x.h as it brings Wire dependency.
class HasBatteryLevel
{
public:
@@ -163,9 +181,21 @@ class AnalogBatteryLevel : public HasBatteryLevel
uint32_t raw = 0;
#ifdef ARCH_ESP32
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
#ifdef ADC_CTRL
if (heltec_version == 5) {
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, HIGH);
delay(10);
}
#endif
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += adc1_get_raw(adc_channel);
}
#ifdef ADC_CTRL
if (heltec_version == 5) {
digitalWrite(ADC_CTRL, LOW);
}
#endif
#else // ADC2
int32_t adc_buf = 0;
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
@@ -209,10 +239,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() override
{
return getBatteryPercent() != -1;
}
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
@@ -233,10 +260,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'?
virtual bool isCharging() override
{
return isBatteryConnect() && isVbusIn();
}
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping
@@ -263,10 +287,14 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage()
{
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
return ina219Sensor.getBusVoltageMv();
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
config.power.device_battery_ina_address) {
return ina260Sensor.getBusVoltageMv();
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA3221].first ==
config.power.device_battery_ina_address) {
return ina3221Sensor.getBusVoltageMv();
}
return 0;
}
@@ -276,11 +304,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
if (!config.power.device_battery_ina_address) {
return false;
}
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
if (!ina219Sensor.isInitialized())
return ina219Sensor.runOnce() > 0;
return ina219Sensor.isRunning();
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
config.power.device_battery_ina_address) {
if (!ina260Sensor.isInitialized())
return ina260Sensor.runOnce() > 0;
return ina260Sensor.isRunning();
@@ -366,6 +395,11 @@ bool Power::analogInit()
#endif
}
/**
* Initializes the Power class.
*
* @return true if the setup was successful, false otherwise.
*/
bool Power::setup()
{
bool found = axpChipInit();
@@ -401,9 +435,9 @@ void Power::shutdown()
ledOff(PIN_LED2);
#endif
#ifdef PIN_LED3
ledOff(PIN_LED2);
ledOff(PIN_LED3);
#endif
doDeepSleep(DELAY_FOREVER);
doDeepSleep(DELAY_FOREVER, false);
#endif
}
@@ -431,10 +465,25 @@ void Power::readPowerStatus()
}
}
OptionalBool NRF_USB = OptFalse;
#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.
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED) {
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
NRF_USB = OptFalse;
} else {
powerFSM.trigger(EVENT_POWER_CONNECTED);
NRF_USB = OptTrue;
}
#endif
// Notify any status instances that are observing us
const PowerStatus powerStatus2 =
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVbusIn() ? OptTrue : OptFalse,
batteryLevel->isCharging() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
const PowerStatus powerStatus2 = PowerStatus(
hasBattery ? OptTrue : OptFalse, batteryLevel->isVbusIn() || NRF_USB == OptTrue ? OptTrue : OptFalse,
batteryLevel->isCharging() || NRF_USB == OptTrue ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2);
@@ -540,10 +589,12 @@ int32_t Power::runOnce()
LOG_DEBUG("Battery removed\n");
}
*/
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
if (PMU->isPekeyLongPressIrq()) {
LOG_DEBUG("PEK long button press\n");
screen->setOn(false);
}
#endif
PMU->clearIrqStatus();
}
@@ -681,7 +732,8 @@ bool Power::axpChipInit()
// GNSS VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE ||
HW_VENDOR == meshtastic_HardwareModel_T_WATCH_S3) {
// t-beam s3 core
/**
* gnss module power channel
@@ -712,10 +764,16 @@ bool Power::axpChipInit()
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO1);
// sdcard power channle
// sdcard power channel
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
PMU->enablePowerOutput(XPOWERS_BLDO1);
#ifdef T_WATCH_S3
// DRV2605 power channel
PMU->setPowerChannelVoltage(XPOWERS_BLDO2, 3300);
PMU->enablePowerOutput(XPOWERS_BLDO2);
#endif
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
// PMU->enablePowerOutput(XPOWERS_DCDC4);
@@ -839,4 +897,4 @@ bool Power::axpChipInit()
#else
return false;
#endif
}
}

View File

@@ -1,5 +1,13 @@
/**
* @file PowerFSM.cpp
* @brief Implements the finite state machine for power management.
*
* This file contains the implementation of the finite state machine (FSM) for power management.
* The FSM controls the power states of the device, including SDS (shallow deep sleep), LS (light sleep),
* NB (normal mode), and POWER (powered mode). The FSM also handles transitions between states and
* actions to be taken upon entering or exiting each state.
*/
#include "PowerFSM.h"
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "configuration.h"
@@ -37,7 +45,7 @@ static void sdsEnter()
{
LOG_DEBUG("Enter state: SDS\n");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs));
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs), false);
}
extern Power *power;
@@ -128,16 +136,16 @@ static void lsIdle()
static void lsExit()
{
LOG_INFO("Exit state: LS\n");
// setGPSPower(true); // restore GPS power
if (gps)
gps->forceWake(true);
}
static void nbEnter()
{
LOG_DEBUG("Enter state: NB\n");
screen->setOn(false);
#ifdef ARCH_ESP32
// Only ESP32 should turn off bluetooth
setBluetoothEnable(false);
#endif
// FIXME - check if we already have packets for phone and immediately trigger EVENT_PACKETS_FOR_PHONE
}
@@ -158,12 +166,14 @@ static void serialEnter()
static void serialExit()
{
// Turn bluetooth back on when we leave serial stream API
setBluetoothEnable(true);
screen->print("Serial disconnected\n");
}
static void powerEnter()
{
LOG_DEBUG("Enter state: POWER\n");
// LOG_DEBUG("Enter state: POWER\n");
if (!isPowered()) {
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
LOG_INFO("Loss of power in Powered\n");
@@ -235,6 +245,8 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup()
{
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
@@ -242,7 +254,11 @@ void PowerFSM_setup()
// wake timer expired or a packet arrived
// if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone)
#ifdef ARCH_ESP32
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
#else // Don't go into a no-bluetooth state on low power platforms
powerFSM.add_transition(&stateLS, &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
#endif
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
// light sleep we _always_ transition to NB or dark and
@@ -279,7 +295,8 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateLS, &stateON, EVENT_INPUT, NULL, "Input Device");
powerFSM.add_transition(&stateNB, &stateON, EVENT_INPUT, NULL, "Input Device");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_INPUT, NULL, "Input Device");
powerFSM.add_transition(&stateON, &stateON, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
powerFSM.add_transition(&stateON, &stateON, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
@@ -333,12 +350,12 @@ void PowerFSM_setup()
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)
#ifdef ARCH_ESP32
State *lowPowerState = &stateLS;
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) {
// Don't add power saving transitions if we are a power saving tracker or sensor. Sleep will be initiatiated through the
// modules
if ((isRouter || config.power.is_power_saving) && !isTrackerOrSensor) {
powerFSM.add_timed_transition(&stateNB, &stateLS,
getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
"Min wake timeout");
@@ -346,11 +363,7 @@ void PowerFSM_setup()
getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
NULL, "Bluetooth timeout");
}
if (config.power.sds_secs != UINT32_MAX)
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL,
"mesh timeout");
#endif
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
}

View File

@@ -21,7 +21,7 @@ class PowerFSMThread : public OSThread
/// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake
/// cpu for serial rx - FIXME)
auto state = powerFSM.getState();
const auto state = powerFSM.getState();
canSleep = (state != &statePOWER) && (state != &stateSERIAL);
if (powerStatus->getHasUSB()) {

View File

@@ -18,6 +18,12 @@ NoopPrint noopPrint;
#if HAS_WIFI || HAS_ETHERNET
extern Syslog syslog;
#endif
void RedirectablePrint::rpInit()
{
#ifdef HAS_FREE_RTOS
inDebugPrint = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
#endif
}
void RedirectablePrint::setDestination(Print *_dest)
{
@@ -66,9 +72,12 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
return 0;
}
size_t r = 0;
#ifdef HAS_FREE_RTOS
if (inDebugPrint != nullptr && xSemaphoreTake(inDebugPrint, portMAX_DELAY) == pdTRUE) {
#else
if (!inDebugPrint) {
inDebugPrint = true;
#endif
va_list arg;
va_start(arg, format);
@@ -141,7 +150,11 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
va_end(arg);
isContinuationMessage = !hasNewline;
#ifdef HAS_FREE_RTOS
xSemaphoreGive(inDebugPrint);
#else
inDebugPrint = false;
#endif
}
return r;

View File

@@ -1,5 +1,6 @@
#pragma once
#include "../freertosinc.h"
#include <Print.h>
#include <stdarg.h>
#include <string>
@@ -16,14 +17,19 @@ class RedirectablePrint : public Print
/// Used to allow multiple logDebug messages to appear on a single log line
bool isContinuationMessage = false;
#ifdef HAS_FREE_RTOS
SemaphoreHandle_t inDebugPrint = nullptr;
StaticSemaphore_t _MutexStorageSpace;
#else
volatile bool inDebugPrint = false;
#endif
public:
explicit RedirectablePrint(Print *_dest) : dest(_dest) {}
/**
* Set a new destination
*/
void rpInit();
void setDestination(Print *dest);
virtual size_t write(uint8_t c);
@@ -54,4 +60,4 @@ class NoopPrint : public Print
/**
* A printer that doesn't go anywhere
*/
extern NoopPrint noopPrint;
extern NoopPrint noopPrint;

View File

@@ -12,6 +12,7 @@ SerialConsole *console;
void consoleInit()
{
new SerialConsole(); // Must be dynamically allocated because we are now inheriting from thread
DEBUG_PORT.rpInit(); // Simply sets up semaphore
}
void consolePrintf(const char *format, ...)

View File

@@ -17,9 +17,9 @@
Example analytics:
TX_LOG + RX_LOG = Total air time for a perticular meshtastic channel.
TX_LOG + RX_LOG = Total air time for a particular meshtastic channel.
TX_LOG + RX_LOG = Total air time for a perticular meshtastic channel, including
TX_LOG + RX_LOG = Total air time for a particular meshtastic channel, including
other lora radios.
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel.

View File

@@ -15,4 +15,6 @@ enum class Cmd {
PRINT,
START_SHUTDOWN_SCREEN,
START_REBOOT_SCREEN,
SHOW_PREV_FRAME,
SHOW_NEXT_FRAME
};

View File

@@ -18,7 +18,7 @@ namespace concurrency
*
* Useful for they top level loop() delay call to keep the CPU powered down until our next scheduled event or some external event.
*
* This is implmented for FreeRTOS but should be easy to port to other operating systems.
* This is implemented for FreeRTOS but should be easy to port to other operating systems.
*/
class InterruptableDelay
{

View File

@@ -53,7 +53,7 @@ class OSThread : public Thread
static void setup();
int32_t disable();
virtual int32_t disable();
/**
* Wait a specified number msecs starting from the current time (rather than the last time we were run)
@@ -67,6 +67,7 @@ class OSThread : public Thread
* Returns desired period for next invocation (or RUN_SAME for no change)
*/
virtual int32_t runOnce() = 0;
bool sleepOnNextExecution = false;
// Do not override this
virtual void run();
@@ -87,4 +88,4 @@ extern bool hasBeenSetup;
void assertIsSetup();
} // namespace concurrency
} // namespace concurrency

View File

@@ -57,8 +57,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
/// Convert a preprocessor name into a quoted string
#define xstr(s) str(s)
#define str(s) #s
#define xstr(s) ystr(s)
#define ystr(s) #s
/// Convert a preprocessor name into a quoted string and if that string is empty use "unset"
#define optstr(s) (xstr(s)[0] ? xstr(s) : "unset")
@@ -98,8 +98,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Define if screen should be mirrored left to right
// #define SCREEN_MIRROR
// The m5stack I2C Keyboard (also RAK14004)
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
#define CARDKB_ADDR 0x5F
#define TDECK_KB_ADDR 0x55
#define BBQ10_KB_ADDR 0x1F
// -----------------------------------------------------------------------------
// SENSOR
@@ -109,6 +111,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MCP9808_ADDR 0x18
#define INA_ADDR 0x40
#define INA_ADDR_ALTERNATE 0x41
#define INA3221_ADDR 0x42
#define QMC6310_ADDR 0x1C
#define QMI8658_ADDR 0x6B
#define QMC5883L_ADDR 0x1E
@@ -123,6 +126,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// -----------------------------------------------------------------------------
#define MPU6050_ADDR 0x68
#define LIS3DH_ADR 0x18
#define BMA423_ADDR 0x19
// -----------------------------------------------------------------------------
// LED
@@ -142,9 +146,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_BAUDRATE 9600
#ifndef GPS_THREAD_INTERVAL
#define GPS_THREAD_INTERVAL 100
#define GPS_THREAD_INTERVAL 200
#endif
// convert 24-bit color to 16-bit (56K)
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
/* Step #1: offer chance for variant-specific defines */
#include "variant.h"
@@ -172,9 +179,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef HAS_BUTTON
#define HAS_BUTTON 0
#endif
#ifndef HAS_TRACKBALL
#define HAS_TRACKBALL 0
#endif
#ifndef HAS_TOUCHSCREEN
#define HAS_TOUCHSCREEN 0
#endif
#ifndef HAS_TELEMETRY
#define HAS_TELEMETRY 0
#endif
#ifndef HAS_SENSOR
#define HAS_SENSOR 0
#endif
#ifndef HAS_RADIO
#define HAS_RADIO 0
#endif
@@ -193,4 +209,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef HW_VENDOR
#error HW_VENDOR must be defined
#endif
#endif

View File

@@ -30,14 +30,14 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
{
ScanI2C::DeviceType types[] = {CARDKB, RAK14004};
return firstOfOrNONE(2, types);
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004};
return firstOfOrNONE(4, types);
}
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
{
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH};
return firstOfOrNONE(2, types);
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423};
return firstOfOrNONE(3, types);
}
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
@@ -73,4 +73,4 @@ bool ScanI2C::DeviceAddress::operator<(const ScanI2C::DeviceAddress &other) cons
|| (port != NO_I2C && other.port != NO_I2C && (address < other.address));
}
ScanI2C::FoundDevice::FoundDevice(ScanI2C::DeviceType type, ScanI2C::DeviceAddress address) : type(type), address(address) {}
ScanI2C::FoundDevice::FoundDevice(ScanI2C::DeviceType type, ScanI2C::DeviceAddress address) : type(type), address(address) {}

View File

@@ -16,6 +16,8 @@ class ScanI2C
RTC_RV3028,
RTC_PCF8563,
CARDKB,
TDECKKB,
BBQ10KB,
RAK14004,
PMU_AXP192_AXP2101,
BME_680,
@@ -23,6 +25,7 @@ class ScanI2C
BMP_280,
INA260,
INA219,
INA3221,
MCP9808,
SHT31,
SHTC3,
@@ -33,7 +36,10 @@ class ScanI2C
PMSA0031,
MPU6050,
LIS3DH,
BMA423,
#ifdef HAS_NCP5623
NCP5623,
#endif
} DeviceType;
// typedef uint8_t DeviceAddress;
@@ -95,4 +101,4 @@ class ScanI2C
private:
bool shouldSuppressScreen = false;
};
};

View File

@@ -2,7 +2,9 @@
#include "concurrency/LockGuard.h"
#include "configuration.h"
#if defined(ARCH_RASPBERRY_PI)
#include "linux/LinuxHardwareI2C.h"
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "main.h" // atecc
#endif
@@ -162,7 +164,14 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
for (addr.address = 1; addr.address < 127; addr.address++) {
i2cBus->beginTransmission(addr.address);
#ifdef ARCH_PORTDUINO
if (i2cBus->read() != -1)
err = 0;
else
err = 2;
#else
err = i2cBus->endTransmission();
#endif
type = NONE;
if (err == 0) {
LOG_DEBUG("I2C device found at address 0x%x\n", addr.address);
@@ -212,9 +221,12 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
}
break;
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n")
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found\n");
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
#ifdef HAS_NCP5623
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
#endif
#ifdef HAS_PMU
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
#endif
@@ -248,7 +260,10 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
type = INA219;
}
break;
case INA3221_ADDR:
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = INA3221;
break;
case MCP9808_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
if (registerValue == 0x0400) {
@@ -273,6 +288,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n");
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n");
default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
@@ -305,4 +321,4 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
size_t ScanI2CTwoWire::countDevices() const
{
return foundDevices.size();
}
}

View File

@@ -18,6 +18,8 @@ class ScanI2CTwoWire : public ScanI2C
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
bool exists(ScanI2C::DeviceType) const override;
size_t countDevices() const override;
@@ -51,6 +53,4 @@ class ScanI2CTwoWire : public ScanI2C
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
};

View File

@@ -1,6 +1,6 @@
#include "../configuration.h"
#ifdef RAK4630
#ifdef RAK_4631
#include "../main.h"
#include <SPI.h>
@@ -64,4 +64,4 @@ void scanEInkDevice(void)
LOG_DEBUG("EInk display not found\n");
SPI1.end();
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,16 @@
#include "GPSStatus.h"
#include "Observer.h"
#include "TinyGPS++.h"
#include "concurrency/OSThread.h"
#include "input/RotaryEncoderInterruptImpl1.h"
#include "input/UpDownInterruptImpl1.h"
#include "modules/PositionModule.h"
// Allow defining the polarity of the ENABLE output. default is active high
#ifndef GPS_EN_ACTIVE
#define GPS_EN_ACTIVE 1
#endif
struct uBloxGnssModelInfo {
char swVersion[30];
@@ -14,9 +23,17 @@ struct uBloxGnssModelInfo {
typedef enum {
GNSS_MODEL_MTK,
GNSS_MODEL_UBLOX,
GNSS_MODEL_UNKONW,
GNSS_MODEL_UC6850,
GNSS_MODEL_UNKNOWN,
} GnssModel_t;
typedef enum {
GNSS_RESPONSE_NONE,
GNSS_RESPONSE_NAK,
GNSS_RESPONSE_FRAME_ERRORS,
GNSS_RESPONSE_OK,
} GPS_RESPONSE;
// Generate a string representation of DOP
const char *getDOPString(uint32_t dop);
@@ -27,8 +44,29 @@ const char *getDOPString(uint32_t dop);
*/
class GPS : private concurrency::OSThread
{
TinyGPSPlus reader;
uint8_t fixQual = 0; // fix quality from GPGGA
uint32_t lastChecksumFailCount = 0;
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
// via optional feature "custom fields", currently disabled (bug #525)
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
uint8_t fixType = 0; // fix type from GPGSA
#endif
private:
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0;
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0;
const int serialSpeeds[6] = {9600, 4800, 38400, 57600, 115200, 9600};
uint32_t rx_gpio = 0;
uint32_t tx_gpio = 0;
uint32_t en_gpio = 0;
int32_t averageLockTime = 0;
uint32_t GPSCycles = 0;
int speedSelect = 0;
int probeTries = 2;
/**
* hasValidLocation - indicates that the position variables contain a complete
@@ -38,15 +76,17 @@ class GPS : private concurrency::OSThread
bool isAwake = false; // true if we want a location right now
bool wakeAllowed = true; // false if gps must be forced to sleep regardless of what time it is
bool isInPowersave = false;
bool shouldPublish = false; // If we've changed GPS state, this will force a publish the next loop()
bool hasGPS = false; // Do we have a GPS we are talking to
bool GPSInitFinished = false; // Init thread finished?
bool GPSInitStarted = false; // Init thread finished?
uint8_t numSatellites = 0;
CallbackObserver<GPS, void *> notifySleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareSleep);
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
CallbackObserver<GPS, void *> notifyGPSSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
@@ -54,6 +94,24 @@ class GPS : private concurrency::OSThread
/** If !NULL we will use this serial port to construct our GPS */
static HardwareSerial *_serial_gps;
static uint8_t _message_PMREQ[];
static const uint8_t _message_CFG_RXM_PSM[];
static const uint8_t _message_CFG_RXM_ECO[];
static const uint8_t _message_CFG_PM2[];
static const uint8_t _message_GNSS_7[];
static const uint8_t _message_GNSS[];
static const uint8_t _message_JAM[];
static const uint8_t _message_NAVX5[];
static const uint8_t _message_1HZ[];
static const uint8_t _message_GGL[];
static const uint8_t _message_GSA[];
static const uint8_t _message_GSV[];
static const uint8_t _message_VTG[];
static const uint8_t _message_RMC[];
static const uint8_t _message_GGA[];
static const uint8_t _message_PMS[];
static const uint8_t _message_SAVE[];
meshtastic_Position p = meshtastic_Position_init_default;
GPS() : concurrency::OSThread("GPS") {}
@@ -68,6 +126,14 @@ class GPS : private concurrency::OSThread
*/
virtual bool setup();
// re-enable the thread
void enable();
// Disable the thread
int32_t disable() override;
void setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime);
/// Returns true if we have acquired GPS lock.
virtual bool hasLock();
@@ -79,65 +145,20 @@ class GPS : private concurrency::OSThread
bool isPowerSaving() const { return !config.position.gps_enabled; }
/**
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
* called after the CPU wakes from light-sleep state
*
* Or set to false, to disallow any sort of waking
* */
void forceWake(bool on);
// Empty the input buffer as quickly as possible
void clearBuffer();
// Some GPS modules (ublock) require factory reset
virtual bool factoryReset() { return true; }
// Create a ublox packet for editing in memory
uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
protected:
/// Do gps chipset specific init, return true for success
virtual bool setupGPS();
// scratch space for creating ublox packets
uint8_t UBXscratch[250] = {0};
/// If possible force the GPS into sleep/low power mode
virtual void sleep();
int rebootsSeen = 0;
/// wake the GPS into normal operation mode
virtual void wake();
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileIdle() = 0;
/** Idle processing while GPS is looking for lock, called once per secondish */
virtual void whileActive() {}
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime() = 0;
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation() = 0;
/// Record that we have a GPS
void setConnected();
void setNumSatellites(uint8_t n);
private:
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep
int prepareSleep(void *unused);
/// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep
int prepareDeepSleep(void *unused);
int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis);
GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis);
GPS_RESPONSE getACK(const char *message, uint32_t waitMillis);
/**
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
@@ -145,6 +166,59 @@ class GPS : private concurrency::OSThread
* calls sleep/wake
*/
void setAwake(bool on);
virtual bool factoryReset();
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
static GPS *createGps();
protected:
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
/// Record that we have a GPS
void setConnected();
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileIdle();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation();
private:
/// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep
int prepareDeepSleep(void *unused);
// Calculate checksum
void UBXChecksum(uint8_t *message, size_t length);
/** Get how long we should stay looking for each aquisition
*/
@@ -154,8 +228,6 @@ class GPS : private concurrency::OSThread
*/
uint32_t getSleepTime() const;
bool getACK(uint8_t c, uint8_t i);
/**
* Tell users we have new GPS readings
*/
@@ -164,19 +236,14 @@ class GPS : private concurrency::OSThread
virtual int32_t runOnce() override;
// Get GNSS model
GnssModel_t probe();
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
String getNMEA();
GnssModel_t probe(int serialSpeed);
// delay counter to allow more sats before fixed position stops GPS thread
uint8_t fixeddelayCtr = 0;
protected:
GnssModel_t gnssModel = GNSS_MODEL_UNKONW;
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
};
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
GPS *createGps();
extern GPS *gps;
extern GPS *gps;

View File

@@ -12,7 +12,7 @@ GeoCoord::GeoCoord(int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _lon
GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
// Change decimial representation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7);
GeoCoord::setCoords();
@@ -20,7 +20,7 @@ GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
GeoCoord::GeoCoord(double lat, double lon, int32_t alt) : _altitude(alt)
{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
// Change decimial representation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7);
GeoCoord::setCoords();
@@ -41,7 +41,7 @@ void GeoCoord::setCoords()
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt)
{
// If marked dirty or new coordiantes
// If marked dirty or new coordinates
if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
_dirty = true;
_latitude = lat;
@@ -55,7 +55,7 @@ void GeoCoord::updateCoords(const double lat, const double lon, const int32_t al
{
int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes
// If marked dirty or new coordinates
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
_dirty = true;
_latitude = iLat;
@@ -69,7 +69,7 @@ void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
{
int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes
// If marked dirty or new coordinates
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
_dirty = true;
_latitude = iLat;
@@ -217,7 +217,7 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr)
double eta2 = v / rho - 1;
double mA = (1 + n + (5 / 4) * n * n + (5 / 4) * n * n * n) * (phi - phi0);
double mB = (3 * n + 3 * n * n + (21 / 8) * n * n * n) * sin(phi - phi0) * cos(phi + phi0);
// loss of precision in mC & mD due to floating point rounding can cause innaccuracy of northing by a few meters
// loss of precision in mC & mD due to floating point rounding can cause inaccuracy of northing by a few meters
double mC = (15 / 8 * n * n + 15 / 8 * n * n * n) * sin(2 * (phi - phi0)) * cos(2 * (phi + phi0));
double mD = (35 / 24) * n * n * n * sin(3 * (phi - phi0)) * cos(3 * (phi + phi0));
double m = b * f0 * (mA - mB + mC - mD);

View File

@@ -65,7 +65,7 @@ struct MGRS {
uint32_t northing;
};
// A struct to hold the data for a OSGR coordiante
// A struct to hold the data for a OSGR coordinate
struct OSGR {
char e100k;
char n100k;

View File

@@ -1,255 +0,0 @@
#include "NMEAGPS.h"
#include "RTC.h"
#include "configuration.h"
#include <TinyGPS++.h>
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
static int32_t toDegInt(RawDegrees d)
{
int32_t degMult = 10000000; // 1e7
int32_t r = d.deg * degMult + d.billionths / 100;
if (d.negative)
r *= -1;
return r;
}
bool NMEAGPS::factoryReset()
{
#ifdef PIN_GPS_REINIT
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
digitalWrite(PIN_GPS_REINIT, 0);
pinMode(PIN_GPS_REINIT, OUTPUT);
delay(150); // The L76K datasheet calls for at least 100MS delay
digitalWrite(PIN_GPS_REINIT, 1);
#endif
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
// Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset, sizeof(_message_reset));
delay(1000);
return true;
}
bool NMEAGPS::setupGPS()
{
GPS::setupGPS();
#ifdef PIN_GPS_PPS
// pulse per second
// FIXME - move into shared GPS code
pinMode(PIN_GPS_PPS, INPUT);
#endif
// Currently disabled per issue #525 (TinyGPS++ crash bug)
// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// see NMEAGPS.h
gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2);
gsapdop.begin(reader, NMEA_MSG_GXGSA, 15);
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n");
#else
LOG_DEBUG("GxGSA NOT available\n");
#endif
return true;
}
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
bool NMEAGPS::lookForTime()
{
auto ti = reader.time;
auto d = reader.date;
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
/* Convert to unix time
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/
struct tm t;
t.tm_sec = ti.second();
t.tm_min = ti.minute();
t.tm_hour = ti.hour();
t.tm_mday = d.day();
t.tm_mon = d.month() - 1;
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
if (t.tm_mon > -1) {
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
t.tm_sec);
perhapsSetRTC(RTCQualityGPS, t);
return true;
} else
return false;
} else
return false;
}
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
bool NMEAGPS::lookForLocation()
{
// By default, TinyGPS++ does not parse GPGSA lines, which give us
// the 2D/3D fixType (see NMEAGPS.h)
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?)
fixQual = reader.fixQuality();
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
fixType = atoi(gsafixtype.value()); // will set to zero if no data
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
#endif
// check if GPS has an acceptable lock
if (!hasLock())
return false;
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
gsafixtype.age(),
#else
0,
#endif
reader.date.age(), reader.time.age());
#endif // GPS_EXTRAVERBOSE
// check if a complete GPS solution set is available for reading
// tinyGPSDatum::age() also includes isValid() test
// FIXME
if (!((reader.location.age() < GPS_SOL_EXPIRY_MS) &&
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
#endif
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
return false;
}
// Is this a new point or are we re-reading the previous one?
if (!reader.location.isUpdated())
return false;
// We know the solution is fresh and valid, so just read the data
auto loc = reader.location.value();
// Bail out EARLY to avoid overwriting previous good data (like #857)
if (toDegInt(loc.lat) > 900000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat));
#endif
return false;
}
if (toDegInt(loc.lng) > 1800000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng));
#endif
return false;
}
p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL;
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.HDOP = reader.hdop.value();
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
// LOG_DEBUG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP);
#else
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
p.HDOP = reader.hdop.value();
p.PDOP = 1.41 * reader.hdop.value();
#endif
// Discard incomplete or erroneous readings
if (reader.hdop.value() == 0)
return false;
p.latitude_i = toDegInt(loc.lat);
p.longitude_i = toDegInt(loc.lng);
p.altitude_geoidal_separation = reader.geoidHeight.meters();
p.altitude_hae = reader.altitude.meters() + p.altitude_geoidal_separation;
p.altitude = reader.altitude.meters();
p.fix_quality = fixQual;
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.fix_type = fixType;
#endif
// positional timestamp
struct tm t;
t.tm_sec = reader.time.second();
t.tm_min = reader.time.minute();
t.tm_hour = reader.time.hour();
t.tm_mday = reader.date.day();
t.tm_mon = reader.date.month() - 1;
t.tm_year = reader.date.year() - 1900;
t.tm_isdst = false;
p.timestamp = mktime(&t);
// Nice to have, if available
if (reader.satellites.isUpdated()) {
p.sats_in_view = reader.satellites.value();
}
if (reader.course.isUpdated() && reader.course.isValid()) {
if (reader.course.value() < 36000) { // sanity check
p.ground_track =
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
} else {
LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
}
}
if (reader.speed.isUpdated() && reader.speed.isValid()) {
p.ground_speed = reader.speed.kmph();
}
return true;
}
bool NMEAGPS::hasLock()
{
// Using GPGGA fix quality indicator
if (fixQual >= 1 && fixQual <= 5) {
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// Use GPGSA fix type 2D/3D (better) if available
if (fixType == 3 || fixType == 0) // zero means "no data received"
#endif
return true;
}
return false;
}
bool NMEAGPS::hasFlow()
{
return reader.passedChecksum() > 0;
}
bool NMEAGPS::whileIdle()
{
bool isValid = false;
// First consume any chars that have piled up at the receiver
while (_serial_gps->available() > 0) {
int c = _serial_gps->read();
// LOG_DEBUG("%c", c);
isValid |= reader.encode(c);
}
return isValid;
}

View File

@@ -1,56 +0,0 @@
#pragma once
#include "GPS.h"
#include "Observer.h"
#include "TinyGPS++.h"
/**
* A gps class thatreads from a NMEA GPS stream (and FIXME - eventually keeps the gps powered down except when reading)
*
* When new data is available it will notify observers.
*/
class NMEAGPS : public GPS
{
TinyGPSPlus reader;
uint8_t fixQual = 0; // fix quality from GPGGA
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
// via optional feature "custom fields", currently disabled (bug #525)
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
uint8_t fixType = 0; // fix type from GPGSA
#endif
public:
virtual bool setupGPS() override;
virtual bool factoryReset() override;
protected:
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileIdle() override;
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime() override;
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation() override;
virtual bool hasLock() override;
virtual bool hasFlow() override;
};

View File

@@ -17,9 +17,13 @@ static uint32_t
timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time
static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock
/**
* Reads the current date and time from the RTC module and updates the system time.
* @return True if the RTC was successfully read and the system time was updated, false otherwise.
*/
void readFromRTC()
{
struct timeval tv; /* btw settimeofday() is helpfull here too*/
struct timeval tv; /* btw settimeofday() is helpful here too*/
#ifdef RV3028_RTC
if (rtc_found.address == RV3028_RTC) {
uint32_t now = millis();
@@ -83,7 +87,15 @@ void readFromRTC()
#endif
}
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
/**
* Sets the RTC (Real-Time Clock) if the provided time is of higher quality than the current RTC time.
*
* @param q The quality of the provided time.
* @param tv A pointer to a timeval struct containing the time to potentially set the RTC to.
* @return True if the RTC was set, false otherwise.
*
* If we haven't yet set our RTC this boot, set it from a GPS derived time
*/
bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
{
static uint32_t lastSetMsec = 0;
@@ -91,9 +103,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
bool shouldSet;
if (q > currentQuality) {
currentQuality = q;
shouldSet = true;
LOG_DEBUG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q);
LOG_DEBUG("Upgrading time to quality %d\n", q);
} else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
shouldSet = true;
@@ -102,12 +113,12 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
shouldSet = false;
if (shouldSet) {
currentQuality = q;
lastSetMsec = now;
// This delta value works on all platforms
timeStartMsec = now;
zeroOffsetSecs = tv->tv_sec;
// If this platform has a setable RTC, set it
#ifdef RV3028_RTC
if (rtc_found.address == RV3028_RTC) {
@@ -151,6 +162,13 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
}
}
/**
* Sets the RTC time if the provided time is of higher quality than the current RTC time.
*
* @param q The quality of the provided time.
* @param t The time to potentially set the RTC to.
* @return True if the RTC was set to the provided time, false otherwise.
*/
bool perhapsSetRTC(RTCQuality q, struct tm &t)
{
/* Convert to unix time
@@ -171,12 +189,23 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
}
}
/**
* Returns the current time in seconds since the Unix epoch (January 1, 1970).
*
* @return The current time in seconds since the Unix epoch.
*/
uint32_t getTime()
{
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
}
/**
* Returns the current time from the RTC if the quality of the time is at least minQuality.
*
* @param minQuality The minimum quality of the RTC time required for it to be considered valid.
* @return The current time from the RTC if it meets the minimum quality requirement, or 0 if the time is not valid.
*/
uint32_t getValidTime(RTCQuality minQuality)
{
return (currentQuality >= minQuality) ? getTime() : 0;
}
}

192
src/gps/ubx.h Normal file
View File

@@ -0,0 +1,192 @@
uint8_t GPS::_message_PMREQ[] PROGMEM = {
0x00, 0x00, // 4 bytes duration of request task
0x00, 0x00, // (milliseconds)
0x02, 0x00, // Task flag bitfield
0x00, 0x00 // byte index 1 = sleep mode
};
const uint8_t GPS::_message_CFG_RXM_PSM[] PROGMEM = {
0x08, // Reserved
0x01 // Power save mode
};
const uint8_t GPS::_message_CFG_RXM_ECO[] PROGMEM = {
0x08, // Reserved
0x04 // eco mode
};
const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
0x01, 0x06, 0x00, 0x00, // version, Reserved
0x0E, 0x81, 0x43, 0x01, // flags
0xE8, 0x03, 0x00, 0x00, // update period 1000 ms
0x10, 0x27, 0x00, 0x00, // search period 10s
0x00, 0x00, 0x00, 0x00, // Grod offset 0
0x01, 0x00, // onTime 1 second
0x00, 0x00, // min search time 0
0x2C, 0x01, // reserved
0x00, 0x00, 0x4F, 0xC1, // reserved
0x03, 0x00, 0x87, 0x02, // reserved
0x00, 0x00, 0xFF, 0x00, // reserved
0x01, 0x00, 0xD6, 0x4D // reserved
};
const uint8_t GPS::_message_GNSS_7[] = {
0x00, // msgVer (0 for this version)
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
// GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01 // SBAS
};
// It's not critical if the module doesn't acknowledge this configuration.
// The module should operate adequately with its factory or previously saved settings.
// It appears that there is a firmware bug in some GPS modules: When an attempt is made
// to overwrite a saved state with identical values, no ACK/NAK is received, contrary to
// what is specified in the Ublox documentation.
// There is also a possibility that the module may be GPS-only.
const uint8_t GPS::_message_GNSS[] = {
0x00, // msgVer (0 for this version)
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
// GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS
0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01 // GLONASS
};
// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board,
// and we need to reduce interference from them
const uint8_t GPS::_message_JAM[] = {
// bbThreshold (Broadband jamming detection threshold) is set to 0x3F (63 in decimal)
// cwThreshold (CW jamming detection threshold) is set to 0x10 (16 in decimal)
// algorithmBits (Reserved algorithm settings) is set to 0x16B156 as recommended
// enable (Enable interference detection) is set to 1 (enabled)
0x3F, 0x10, 0xB1, 0x56, // config: Interference config word
// generalBits (General settings) is set to 0x31E as recommended
// antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown)
// ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info
// enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1
// (enabled)
0x1E, 0x03, 0x00, 0x01 // config2: Extra settings for jamming/interference monitor
};
// Configure navigation engine expert settings:
const uint8_t GPS::_message_NAVX5[] = {
0x00, 0x00, // msgVer (0 for this version)
// minMax flag = 1: apply min/max SVs settings
// minCno flag = 1: apply minimum C/N0 setting
// initial3dfix flag = 0: apply initial 3D fix settings
// aop flag = 1: apply aopCfg (useAOP flag) settings (AssistNow Autonomous)
0x1B, 0x00, // mask1 (First parameters bitmask)
// adr flag = 0: apply ADR sensor fusion on/off setting (useAdr flag)
// If firmware is not ADR/UDR, enabling this flag will fail configuration
// ToDo: check this with UBX-MON-VER
0x00, 0x00, 0x00, 0x00, // mask2 (Second parameters bitmask)
0x00, 0x00, // Reserved
0x03, // minSVs (Minimum number of satellites for navigation) = 3
0x10, // maxSVs (Maximum number of satellites for navigation) = 16
0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
0x00, // Reserved
0x00, // iniFix3D (Initial fix must be 3D) = 0 (disabled)
0x00, 0x00, // Reserved
0x00, // ackAiding (Issue acknowledgements for assistance message input) = 0 (disabled)
0x00, 0x00, // Reserved
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
0x00, // Reserved
0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled)
0x00, 0x00, // Reserved
0x00, 0x00, // Reserved
0x00, 0x00, 0x00, 0x00, // Reserved
0x00, 0x00, 0x00, // Reserved
0x01, // useAdr (Enable/disable ADR sensor fusion) = 1 (enabled)
};
// Set GPS update rate to 1Hz
// Lowering the update rate helps to save power.
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
// is recommended to avoid a known issue with satellites disappearing.
const uint8_t GPS::_message_1HZ[] = {
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
0x01, 0x00, // Navigation rate, always 1 in GPS mode
0x01, 0x00, // Time reference
};
// Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical
// coordinates.
const uint8_t GPS::_message_GGL[] = {
0xF0, 0x01, // NMEA ID for GLL
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x00, // Disable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
// the DOP (Dilution of Precision)
const uint8_t GPS::_message_GSA[] = {
0xF0, 0x02, // NMEA ID for GSA
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x01, // Enable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
const uint8_t GPS::_message_GSV[] = {
0xF0, 0x03, // NMEA ID for GSV
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x00, // Disable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
// the ground.
const uint8_t GPS::_message_VTG[] = {
0xF0, 0x05, // NMEA ID for VTG
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x00, // Disable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
const uint8_t GPS::_message_RMC[] = {
0xF0, 0x04, // NMEA ID for RMC
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x01, // Enable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
const uint8_t GPS::_message_GGA[] = {
0xF0, 0x00, // NMEA ID for GGA
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x01, // Enable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// The Power Management configuration allows the GPS module to operate in different power modes for optimized
// power consumption. The modes supported are: 0x00 = Full power: The module operates at full power with no power
// saving. 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption.
// 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states.
// 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate.
// 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate.
// 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate.
// The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue
// is set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase
// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise,
// it must be set to '0'.
const uint8_t GPS::_message_PMS[] = {
0x00, // Version (0)
0x03, // Power setup value
0x00, 0x00, // period: not applicable, set to 0
0x00, 0x00, // onTime: not applicable, set to 0
0x97, 0x6F // reserved, generated by u-center
};
const uint8_t GPS::_message_SAVE[] = {
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
0x0F // deviceMask: BBR, Flash, EEPROM, and SPI Flash
};

View File

@@ -7,6 +7,10 @@
#include "main.h"
#include <SPI.h>
// #ifdef HELTEC_WIRELESS_PAPER
// SPIClass *hspi = NULL;
// #endif
#define COLORED GxEPD_BLACK
#define UNCOLORED GxEPD_WHITE
@@ -19,13 +23,13 @@
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
// 4.2 inch 300x400 - GxEPD2_420_M01
//#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
// #define TECHO_DISPLAY_MODEL GxEPD2_420_M01
// 2.9 inch 296x128 - GxEPD2_290_T5D
//#define TECHO_DISPLAY_MODEL GxEPD2_290_T5D
// #define TECHO_DISPLAY_MODEL GxEPD2_290_T5D
// 1.54 inch 200x200 - GxEPD2_154_M09
//#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
// #define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#elif defined(MAKERPYTHON)
// 2.9 inch 296x128 - GxEPD2_290_T5D
@@ -41,6 +45,9 @@
// 1.54 inch 200x200 - GxEPD2_154_M09
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#elif defined(HELTEC_WIRELESS_PAPER)
// #define TECHO_DISPLAY_MODEL GxEPD2_213_T5D
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
#endif
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
@@ -62,6 +69,10 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY
// GxEPD2_154_M09
// setGeometry(GEOMETRY_RAWMODE, 200, 200);
#elif defined(HELTEC_WIRELESS_PAPER)
// setGeometry(GEOMETRY_RAWMODE, 212, 104);
setGeometry(GEOMETRY_RAWMODE, 250, 122);
#elif defined(MAKERPYTHON)
// GxEPD2_290_T5D
setGeometry(GEOMETRY_RAWMODE, 296, 128);
@@ -109,7 +120,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
for (uint32_t y = 0; y < displayHeight; y++) {
for (uint32_t x = 0; x < displayWidth; x++) {
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficient
auto b = buffer[x + (y / 8) * displayWidth];
auto isset = b & (1 << (y & 7));
adafruitDisplay->drawPixel(x, y, isset ? COLORED : UNCOLORED);
@@ -182,14 +193,14 @@ bool EInkDisplay::connect()
LOG_INFO("Doing EInk init\n");
#ifdef PIN_EINK_PWR_ON
digitalWrite(PIN_EINK_PWR_ON, HIGH); // If we need to assert a pin to power external peripherals
pinMode(PIN_EINK_PWR_ON, OUTPUT);
digitalWrite(PIN_EINK_PWR_ON, HIGH); // If we need to assert a pin to power external peripherals
#endif
#ifdef PIN_EINK_EN
// backlight power, HIGH is backlight on, LOW is off
digitalWrite(PIN_EINK_EN, LOW);
pinMode(PIN_EINK_EN, OUTPUT);
digitalWrite(PIN_EINK_EN, LOW);
#endif
#if defined(TTGO_T_ECHO)
@@ -218,6 +229,16 @@ bool EInkDisplay::connect()
(void)adafruitDisplay;
}
}
#elif defined(HELTEC_WIRELESS_PAPER)
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
// hspi = new SPIClass(HSPI);
// hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS
adafruitDisplay->init(115200, true, 10, false, SPI, SPISettings(6000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(3);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
}
#elif defined(PCA10059)
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);

View File

@@ -3,7 +3,7 @@
#include <OLEDDisplay.h>
/**
* An adapter class that allows using the TFT_eSPI library as if it was an OLEDDisplay implementation.
* An adapter class that allows using the GxEPD2 library as if it was an OLEDDisplay implementation.
*
* Remaining TODO:
* optimize display() to only draw changed pixels (see other OLED subclasses for examples)

5
src/graphics/RAKled.h Normal file
View File

@@ -0,0 +1,5 @@
#ifdef HAS_NCP5623
#include <NCP5623.h>
extern NCP5623 rgb;
#endif

View File

@@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if HAS_SCREEN
#include <OLEDDisplay.h>
#include "DisplayFormatters.h"
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
@@ -31,19 +32,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "gps/GeoCoord.h"
#include "gps/RTC.h"
#include "graphics/images.h"
#include "input/TouchScreenImpl1.h"
#include "main.h"
#include "mesh-pb-constants.h"
#include "mesh/Channels.h"
#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "meshUtils.h"
#include "modules/ExternalNotificationModule.h"
#include "modules/TextMessageModule.h"
#include "sleep.h"
#include "target_specific.h"
#include "utils.h"
#ifdef ARCH_ESP32
#include "esp_task_wdt.h"
#include "mesh/http/WiFiAPClient.h"
#include "mesh/wifi/WiFiAPClient.h"
#include "modules/esp32/StoreForwardModule.h"
#endif
@@ -102,7 +104,8 @@ static uint16_t displayWidth, displayHeight;
#define SCREEN_WIDTH displayWidth
#define SCREEN_HEIGHT displayHeight
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
@@ -158,17 +161,9 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf);
screen->forceDisplay();
// FIXME - draw serial # somewhere?
}
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
}
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
// draw an xbm image.
@@ -218,6 +213,28 @@ static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
drawOEMIconScreen(region, display, state, x, y);
}
static void drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message)
{
uint16_t x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, 26 + y, message);
}
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
#ifdef ARCH_ESP32
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
drawFrameText(display, state, x, y, "Resuming...");
} else
#endif
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
}
}
// Used on boot when a certificate is being created
static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
@@ -296,7 +313,7 @@ static void drawModuleFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int
static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
int x_offset = display->width() / 2;
int y_offset = display->height() == 64 ? 0 : 32;
int y_offset = display->height() <= 80 ? 0 : 32;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
@@ -318,22 +335,6 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(x_offset + x, y_offset + y, deviceName);
}
static void drawFrameShutdown(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(64 + x, 26 + y, "Shutting down...");
}
static void drawFrameReboot(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(64 + x, 26 + y, "Rebooting...");
}
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
@@ -360,10 +361,10 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
display->drawString(0 + x, FONT_HEIGHT_MEDIUM + y, "For help, please visit \nmeshtastic.org");
}
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled
// Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled
static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
{
return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled;
return packet->from != 0 && !moduleConfig.store_forward.enabled;
}
/// Draw the last text message we received
@@ -372,7 +373,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// the max length of this buffer is much longer than we can possibly print
static char tempBuf[237];
meshtastic_MeshPacket &mp = devicestate.rx_text_message;
const meshtastic_MeshPacket &mp = devicestate.rx_text_message;
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
// mp.decoded.variant.data.decoded.bytes);
@@ -442,7 +443,7 @@ static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, i
}
}
/// Draw a series of fields in a column, wrapping to multiple colums if needed
/// Draw a series of fields in a column, wrapping to multiple columns if needed
static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields)
{
// The coordinates define the left starting point of the text
@@ -488,11 +489,12 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
}
// Draw nodes status
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *nodeStatus)
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStatus *nodeStatus)
{
char usersString[20];
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x, y + 3, 8, 8, imgUser);
#else
display->drawFastImage(x, y, 8, 8, imgUser);
@@ -835,7 +837,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
}
static char distStr[20];
strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
strncpy(distStr, "? mi", sizeof(distStr)); // might not have location data
} else {
strncpy(distStr, "? km", sizeof(distStr));
}
meshtastic_NodeInfoLite *ourNode = nodeDB.getMeshNode(nodeDB.getNodeNum());
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
int16_t compassX = 0, compassY = 0;
@@ -851,14 +857,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
bool hasNodeHeading = false;
if (ourNode && hasValidPosition(ourNode)) {
meshtastic_PositionLite &op = ourNode->position;
const meshtastic_PositionLite &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading);
if (hasValidPosition(node)) {
// display direction toward node
hasNodeHeading = true;
meshtastic_PositionLite &p = node->position;
const meshtastic_PositionLite &p = node->position;
float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
@@ -899,20 +905,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
drawColumns(display, x, y, fields);
}
// #ifdef RAK4630
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl),
// dispdev_oled(address, sda, scl), ui(&dispdev)
// {
// address_found = address;
// cmdQueue.setReader(this);
// if (screen_found) {
// (void)dispdev;
// AutoOLEDWire dispdev = dispdev_oled;
// (void)ui;
// OLEDDisplayUi ui(&dispdev);
// }
// }
// #else
Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_OledType screenType, OLEDDISPLAY_GEOMETRY geometry)
: concurrency::OSThread("Screen"), address_found(address), model(screenType), geometry(geometry), cmdQueue(32),
dispdev(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE),
@@ -920,7 +912,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
{
cmdQueue.setReader(this);
}
// #endif
/**
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
@@ -944,6 +936,9 @@ void Screen::handleSetOn(bool on)
if (on != screenOn) {
if (on) {
LOG_INFO("Turning on screen\n");
#ifdef T_WATCH_S3
PMU->enablePowerOutput(XPOWERS_ALDO2);
#endif
dispdev.displayOn();
dispdev.displayOn();
enabled = true;
@@ -952,6 +947,9 @@ void Screen::handleSetOn(bool on)
} else {
LOG_INFO("Turning off screen\n");
dispdev.displayOff();
#ifdef T_WATCH_S3
PMU->disablePowerOutput(XPOWERS_ALDO2);
#endif
enabled = false;
}
screenOn = on;
@@ -1034,12 +1032,19 @@ void Screen::setup()
#endif
serialSinceMsec = millis();
#if HAS_TOUCHSCREEN
touchScreenImpl1 = new TouchScreenImpl1(dispdev.getWidth(), dispdev.getHeight(), dispdev.getTouch);
touchScreenImpl1->init();
#endif
// Subscribe to status updates
powerStatusObserver.observe(&powerStatus->onNewStatus);
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
if (textMessageModule)
textMessageObserver.observe(textMessageModule);
if (inputBroker)
inputObserver.observe(inputBroker);
// Modules can notify screen about refresh
MeshModule::observeUIEvents(&uiFrameEventObserver);
@@ -1117,6 +1122,12 @@ int32_t Screen::runOnce()
handleOnPress();
}
break;
case Cmd::SHOW_PREV_FRAME:
handleShowPrevFrame();
break;
case Cmd::SHOW_NEXT_FRAME:
handleShowNextFrame();
break;
case Cmd::START_BLUETOOTH_PIN_SCREEN:
handleStartBluetoothPinScreen(cmd.bluetooth_pin);
break;
@@ -1218,11 +1229,8 @@ void Screen::setWelcomeFrames()
{
if (address_found.address) {
// LOG_DEBUG("showing Welcome frames\n");
ui.disableAllIndicators();
static FrameCallback welcomeFrames[] = {drawWelcomeScreen};
ui.setFrames(welcomeFrames, 1);
ui.update();
static FrameCallback frames[] = {drawWelcomeScreen};
setFrameImmediateDraw(frames);
}
}
@@ -1309,12 +1317,15 @@ void Screen::handleStartBluetoothPinScreen(uint32_t pin)
LOG_DEBUG("showing bluetooth screen\n");
showingNormalScreen = false;
static FrameCallback btFrames[] = {drawFrameBluetooth};
static FrameCallback frames[] = {drawFrameBluetooth};
snprintf(btPIN, sizeof(btPIN), "%06u", pin);
setFrameImmediateDraw(frames);
}
void Screen::setFrameImmediateDraw(FrameCallback *drawFrames)
{
ui.disableAllIndicators();
ui.setFrames(btFrames, 1);
ui.setFrames(drawFrames, 1);
setFastFramerate();
}
@@ -1323,11 +1334,12 @@ void Screen::handleShutdownScreen()
LOG_DEBUG("showing shutdown screen\n");
showingNormalScreen = false;
static FrameCallback shutdownFrames[] = {drawFrameShutdown};
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
drawFrameText(display, state, x, y, "Shutting down...");
};
static FrameCallback frames[] = {frame};
ui.disableAllIndicators();
ui.setFrames(shutdownFrames, 1);
setFastFramerate();
setFrameImmediateDraw(frames);
}
void Screen::handleRebootScreen()
@@ -1335,11 +1347,11 @@ void Screen::handleRebootScreen()
LOG_DEBUG("showing reboot screen\n");
showingNormalScreen = false;
static FrameCallback rebootFrames[] = {drawFrameReboot};
ui.disableAllIndicators();
ui.setFrames(rebootFrames, 1);
setFastFramerate();
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
drawFrameText(display, state, x, y, "Rebooting...");
};
static FrameCallback frames[] = {frame};
setFrameImmediateDraw(frames);
}
void Screen::handleStartFirmwareUpdateScreen()
@@ -1347,11 +1359,8 @@ void Screen::handleStartFirmwareUpdateScreen()
LOG_DEBUG("showing firmware screen\n");
showingNormalScreen = false;
static FrameCallback btFrames[] = {drawFrameFirmware};
ui.disableAllIndicators();
ui.setFrames(btFrames, 1);
setFastFramerate();
static FrameCallback frames[] = {drawFrameFirmware};
setFrameImmediateDraw(frames);
}
void Screen::blink()
@@ -1410,6 +1419,28 @@ void Screen::handleOnPress()
}
}
void Screen::handleShowPrevFrame()
{
// If screen was off, just wake it, otherwise go back to previous frame
// If we are in a transition, the press must have bounced, drop it.
if (ui.getUiState()->frameState == FIXED) {
ui.previousFrame();
lastScreenTransition = millis();
setFastFramerate();
}
}
void Screen::handleShowNextFrame()
{
// If screen was off, just wake it, otherwise advance to next frame
// If we are in a transition, the press must have bounced, drop it.
if (ui.getUiState()->frameState == FIXED) {
ui.nextFrame();
lastScreenTransition = millis();
setFastFramerate();
}
}
#ifndef SCREEN_TRANSITION_FRAMERATE
#define SCREEN_TRANSITION_FRAMERATE 30 // fps
#endif
@@ -1482,7 +1513,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
#ifdef ARCH_ESP32
if (millis() - storeForwardModule->lastHeartbeat >
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgQuestionL1);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
@@ -1492,7 +1524,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
imgQuestion);
#endif
} else {
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
imgSFL1);
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8,
@@ -1504,7 +1537,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
}
#endif
} else {
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgInfoL1);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
@@ -1530,7 +1564,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Jm
void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
#if HAS_WIFI
#if HAS_WIFI && !defined(ARCH_RASPBERRY_PI)
const char *wifiName = config.network.wifi_ssid;
display->setFont(FONT_SMALL);
@@ -1584,69 +1618,19 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
} else if (WiFi.status() == WL_IDLE_STATUS) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
} else {
}
#ifdef ARCH_ESP32
else {
// Codes:
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
if (getWifiDisconnectReason() == 2) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Authentication Invalid");
} else if (getWifiDisconnectReason() == 3) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "De-authenticated");
} else if (getWifiDisconnectReason() == 4) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated Expired");
} else if (getWifiDisconnectReason() == 5) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP - Too Many Clients");
} else if (getWifiDisconnectReason() == 6) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_AUTHED");
} else if (getWifiDisconnectReason() == 7) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_ASSOCED");
} else if (getWifiDisconnectReason() == 8) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated");
} else if (getWifiDisconnectReason() == 9) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_NOT_AUTHED");
} else if (getWifiDisconnectReason() == 10) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_PWRCAP_BAD");
} else if (getWifiDisconnectReason() == 11) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_SUPCHAN_BAD");
} else if (getWifiDisconnectReason() == 13) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_INVALID");
} else if (getWifiDisconnectReason() == 14) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "MIC_FAILURE");
} else if (getWifiDisconnectReason() == 15) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Handshake Timeout");
} else if (getWifiDisconnectReason() == 16) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "GROUP_KEY_UPDATE_TIMEOUT");
} else if (getWifiDisconnectReason() == 17) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_IN_4WAY_DIFFERS");
} else if (getWifiDisconnectReason() == 18) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Group Cipher");
} else if (getWifiDisconnectReason() == 19) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Pairwise Cipher");
} else if (getWifiDisconnectReason() == 20) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AKMP_INVALID");
} else if (getWifiDisconnectReason() == 21) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "UNSUPP_RSN_IE_VERSION");
} else if (getWifiDisconnectReason() == 22) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "INVALID_RSN_IE_CAP");
} else if (getWifiDisconnectReason() == 23) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "802_1X_AUTH_FAILED");
} else if (getWifiDisconnectReason() == 24) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "CIPHER_SUITE_REJECTED");
} else if (getWifiDisconnectReason() == 200) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "BEACON_TIMEOUT");
} else if (getWifiDisconnectReason() == 201) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Not Found");
} else if (getWifiDisconnectReason() == 202) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AUTH_FAIL");
} else if (getWifiDisconnectReason() == 203) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_FAIL");
} else if (getWifiDisconnectReason() == 204) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "HANDSHAKE_TIMEOUT");
} else if (getWifiDisconnectReason() == 205) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
} else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unknown Status");
}
display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason())));
}
#else
else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unkown status: " + String(WiFi.status()));
}
#endif
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
@@ -1692,37 +1676,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x + 1, y, String("USB"));
}
auto mode = "";
switch (config.lora.modem_preset) {
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
mode = "ShortS";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
mode = "ShortF";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
mode = "MedS";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
mode = "MedF";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
mode = "LongS";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
mode = "LongF";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
mode = "LongM";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
mode = "VeryL";
break;
default:
mode = "Custom";
break;
}
auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, true);
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
if (config.display.heading_bold)
@@ -1789,23 +1743,6 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
heartbeat = !heartbeat;
#endif
}
// adjust Brightness cycle trough 1 to 254 as long as attachDuringLongPress is true
void Screen::adjustBrightness()
{
if (!useDisplay)
return;
if (brightness == 254) {
brightness = 0;
} else {
brightness++;
}
int width = brightness / (254.00 / SCREEN_WIDTH);
dispdev.drawRect(0, 30, SCREEN_WIDTH, 4);
dispdev.fillRect(0, 31, width, 2);
dispdev.display();
dispdev.setBrightness(brightness);
}
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
{
@@ -1847,6 +1784,20 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
return 0;
}
int Screen::handleInputEvent(const InputEvent *event)
{
if (showingNormalScreen && moduleFrames.size() == 0) {
// LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
showPrevFrame();
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
showNextFrame();
}
}
return 0;
}
} // namespace graphics
#else
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}

View File

@@ -19,7 +19,6 @@ class Screen
void setup() {}
void setOn(bool) {}
void print(const char *) {}
void adjustBrightness() {}
void doDeepSleep() {}
void forceDisplay() {}
void startBluetoothPinScreen(uint32_t pin) {}
@@ -53,6 +52,7 @@ class Screen
#include "commands.h"
#include "concurrency/LockGuard.h"
#include "concurrency/OSThread.h"
#include "input/InputBroker.h"
#include "mesh/MeshModule.h"
#include "power.h"
#include <string>
@@ -118,6 +118,8 @@ class Screen : public concurrency::OSThread
CallbackObserver<Screen, const meshtastic_MeshPacket *>(this, &Screen::handleTextMessage);
CallbackObserver<Screen, const UIFrameEvent *> uiFrameEventObserver =
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
CallbackObserver<Screen, const InputEvent *> inputObserver =
CallbackObserver<Screen, const InputEvent *>(this, &Screen::handleInputEvent);
public:
explicit Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY);
@@ -152,11 +154,12 @@ class Screen : public concurrency::OSThread
void blink();
/// Handles a button press.
/// Handle button press, trackball or swipe action)
void onPress() { enqueueCmd(ScreenCmd{.cmd = Cmd::ON_PRESS}); }
void showPrevFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_PREV_FRAME}); }
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
// Implementation to Adjust Brightness
void adjustBrightness();
uint8_t brightness = BRIGHTNESS_DEFAULT;
/// Starts showing the Bluetooth PIN screen.
@@ -301,9 +304,11 @@ class Screen : public concurrency::OSThread
// Use this handle to set things like battery status, user count, GPS status, etc.
DebugInfo *debug_info() { return &debugInfo; }
// Handle observer events
int handleStatusUpdate(const meshtastic::Status *arg);
int handleTextMessage(const meshtastic_MeshPacket *arg);
int handleUIFrameEvent(const UIFrameEvent *arg);
int handleInputEvent(const InputEvent *arg);
/// Used to force (super slow) eink displays to draw critical frames
void forceDisplay();
@@ -343,6 +348,8 @@ class Screen : public concurrency::OSThread
// Implementations of various commands, called from doTask().
void handleSetOn(bool on);
void handleOnPress();
void handleShowNextFrame();
void handleShowPrevFrame();
void handleStartBluetoothPinScreen(uint32_t pin);
void handlePrint(const char *text);
void handleStartFirmwareUpdateScreen();
@@ -354,6 +361,9 @@ class Screen : public concurrency::OSThread
/// Try to start drawing ASAP
void setFastFramerate();
// Sets frame up for immediate drawing
void setFrameImmediateDraw(FrameCallback *drawFrames);
/// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame.
static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
@@ -380,7 +390,7 @@ class Screen : public concurrency::OSThread
SH1106Wire dispdev;
#elif defined(USE_SSD1306)
SSD1306Wire dispdev;
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER)
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014)
TFTDisplay dispdev;
#elif defined(USE_EINK)
EInkDisplay dispdev;
@@ -394,4 +404,4 @@ class Screen : public concurrency::OSThread
};
} // namespace graphics
#endif
#endif

View File

@@ -1,12 +1,340 @@
#include "configuration.h"
#include "main.h"
#if defined(ST7735_CS) || defined(ILI9341_DRIVER)
#ifndef TFT_BACKLIGHT_ON
#define TFT_BACKLIGHT_ON HIGH
#endif
#ifndef TFT_MESH
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
#endif
#if defined(ST7735S)
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
#if defined(ST7735_BACKLIGHT_EN) && !defined(TFT_BL)
#define TFT_BL ST7735_BACKLIGHT_EN
#endif
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ST7735S _panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
// configure SPI
cfg.spi_host = ST7735_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
cfg.spi_mode = 0;
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
// 80MHz by an integer)
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
cfg.use_lock = true; // Set to true to use transaction locking
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
// SPI_DMA_CH_AUTO=auto setting)
cfg.pin_sclk = ST7735_SCK; // Set SPI SCLK pin number
cfg.pin_mosi = ST7735_SDA; // Set SPI MOSI pin number
cfg.pin_miso = ST7735_MISO; // Set SPI MISO pin number (-1 = disable)
cfg.pin_dc = ST7735_RS; // Set SPI DC pin number (-1 = disable)
_bus_instance.config(cfg); // applies the set value to the bus.
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
}
{ // Set the display panel control.
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
cfg.pin_cs = ST7735_CS; // Pin number where CS is connected (-1 = disable)
cfg.pin_rst = ST7735_RESET; // Pin number where RST is connected (-1 = disable)
cfg.pin_busy = ST7735_BUSY; // Pin number where BUSY is connected (-1 = disable)
// The following setting values are general initial values for each panel, so please comment out any
// unknown items and try them.
cfg.panel_width = TFT_WIDTH; // actual displayable width
cfg.panel_height = TFT_HEIGHT; // actual displayable height
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
cfg.offset_rotation = 0; // Rotation direction value offset 0~7 (4~7 is upside down)
cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
cfg.readable = true; // Set to true if data can be read
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
cfg.dlen_16bit =
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
// ST7735 or ILI9163.
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
_panel_instance.config(cfg);
}
// Set the backlight control
{
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
#ifdef ST7735_BL_V03
if (heltec_version == 3) {
cfg.pin_bl = ST7735_BL_V03;
} else {
cfg.pin_bl = ST7735_BL_V05;
}
#else
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
#endif
cfg.invert = true; // true to invert the brightness of the backlight
// cfg.freq = 44100; // PWM frequency of backlight
// cfg.pwm_channel = 1; // PWM channel number to use
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
setPanel(&_panel_instance);
}
};
static LGFX tft;
#elif defined(RAK14014)
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#elif defined(ST7789_CS)
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
#if defined(ST7789_BACKLIGHT_EN) && !defined(TFT_BL)
#define TFT_BL ST7789_BACKLIGHT_EN
#endif
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ST7789 _panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
#if HAS_TOUCHSCREEN
#ifdef T_WATCH_S3
lgfx::Touch_FT5x06 _touch_instance;
#else
lgfx::Touch_GT911 _touch_instance;
#endif
#endif
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
// SPI
cfg.spi_host = ST7789_SPI_HOST;
cfg.spi_mode = 0;
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
// 80MHz by an integer)
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
cfg.spi_3wire = false;
cfg.use_lock = true; // Set to true to use transaction locking
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
// SPI_DMA_CH_AUTO=auto setting)
cfg.pin_sclk = ST7789_SCK; // Set SPI SCLK pin number
cfg.pin_mosi = ST7789_SDA; // Set SPI MOSI pin number
cfg.pin_miso = ST7789_MISO; // Set SPI MISO pin number (-1 = disable)
cfg.pin_dc = ST7789_RS; // Set SPI DC pin number (-1 = disable)
_bus_instance.config(cfg); // applies the set value to the bus.
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
}
{ // Set the display panel control.
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
cfg.pin_cs = ST7789_CS; // Pin number where CS is connected (-1 = disable)
cfg.pin_rst = -1; // Pin number where RST is connected (-1 = disable)
cfg.pin_busy = -1; // Pin number where BUSY is connected (-1 = disable)
// The following setting values are general initial values for each panel, so please comment out any
// unknown items and try them.
cfg.panel_width = TFT_WIDTH; // actual displayable width
cfg.panel_height = TFT_HEIGHT; // actual displayable height
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
cfg.offset_rotation = TFT_OFFSET_ROTATION; // Rotation direction value offset 0~7 (4~7 is mirrored)
cfg.dummy_read_pixel = 9; // Number of bits for dummy read before pixel readout
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
cfg.readable = true; // Set to true if data can be read
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
cfg.dlen_16bit =
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
// ST7735 or ILI9163.
// cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
// cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
_panel_instance.config(cfg);
}
// Set the backlight control. (delete if not necessary)
{
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
cfg.pin_bl = ST7789_BL; // Pin number to which the backlight is connected
cfg.invert = false; // true to invert the brightness of the backlight
// cfg.pwm_channel = 0;
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
#if HAS_TOUCHSCREEN
// Configure settings for touch screen control.
{
auto cfg = _touch_instance.config();
cfg.pin_cs = -1;
cfg.x_min = 0;
cfg.x_max = TFT_HEIGHT - 1;
cfg.y_min = 0;
cfg.y_max = TFT_WIDTH - 1;
cfg.pin_int = SCREEN_TOUCH_INT;
cfg.bus_shared = true;
cfg.offset_rotation = TFT_OFFSET_ROTATION;
// cfg.freq = 2500000;
// I2C
cfg.i2c_port = TOUCH_I2C_PORT;
cfg.i2c_addr = TOUCH_SLAVE_ADDRESS;
#ifdef SCREEN_TOUCH_USE_I2C1
cfg.pin_sda = I2C_SDA1;
cfg.pin_scl = I2C_SCL1;
#else
cfg.pin_sda = I2C_SDA;
cfg.pin_scl = I2C_SCL;
#endif
// cfg.freq = 400000;
_touch_instance.config(cfg);
_panel_instance.setTouch(&_touch_instance);
}
#endif
setPanel(&_panel_instance); // Sets the panel to use.
}
};
static LGFX tft;
#elif defined(ILI9341_DRIVER)
#include <LovyanGFX.hpp> // Graphics and font library for ILI9341 driver chip
#if defined(ILI9341_BACKLIGHT_EN) && !defined(TFT_BL)
#define TFT_BL ILI9341_BACKLIGHT_EN
#endif
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ILI9341 _panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
// configure SPI
cfg.spi_host = ILI9341_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
cfg.spi_mode = 0;
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
// 80MHz by an integer)
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
cfg.use_lock = true; // Set to true to use transaction locking
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
// SPI_DMA_CH_AUTO=auto setting)
cfg.pin_sclk = TFT_SCLK; // Set SPI SCLK pin number
cfg.pin_mosi = TFT_MOSI; // Set SPI MOSI pin number
cfg.pin_miso = TFT_MISO; // Set SPI MISO pin number (-1 = disable)
cfg.pin_dc = TFT_DC; // Set SPI DC pin number (-1 = disable)
_bus_instance.config(cfg); // applies the set value to the bus.
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
}
{ // Set the display panel control.
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
cfg.pin_cs = TFT_CS; // Pin number where CS is connected (-1 = disable)
cfg.pin_rst = TFT_RST; // Pin number where RST is connected (-1 = disable)
cfg.pin_busy = TFT_BUSY; // Pin number where BUSY is connected (-1 = disable)
// The following setting values are general initial values for each panel, so please comment out any
// unknown items and try them.
cfg.panel_width = TFT_WIDTH; // actual displayable width
cfg.panel_height = TFT_HEIGHT; // actual displayable height
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
cfg.offset_rotation = 0; // Rotation direction value offset 0~7 (4~7 is upside down)
cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
cfg.readable = true; // Set to true if data can be read
cfg.invert = false; // Set to true if the light/darkness of the panel is reversed
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
cfg.dlen_16bit =
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
// ST7735 or ILI9163.
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
_panel_instance.config(cfg);
}
// Set the backlight control
{
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
cfg.pin_bl = TFT_BL; // Pin number to which the backlight is connected
cfg.invert = false; // true to invert the brightness of the backlight
// cfg.freq = 44100; // PWM frequency of backlight
// cfg.pwm_channel = 1; // PWM channel number to use
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
setPanel(&_panel_instance);
}
};
static LGFX tft;
#elif defined(ST7735_CS)
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
#endif
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014)
#include "SPILock.h"
#include "TFTDisplay.h"
#include <SPI.h>
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
{
@@ -30,7 +358,7 @@ void TFTDisplay::display(void)
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
auto dblbuf_isset = buffer_back[x + (y / 8) * displayWidth] & (1 << (y & 7));
if (isset != dblbuf_isset) {
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
tft.drawPixel(x, y, isset ? TFT_MESH : TFT_BLACK);
}
}
}
@@ -46,8 +374,96 @@ void TFTDisplay::display(void)
// Send a command to the display (low level function)
void TFTDisplay::sendCommand(uint8_t com)
{
(void)com;
// Drop all commands to device (we just update the buffer)
// handle display on/off directly
switch (com) {
case DISPLAYON: {
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
if (heltec_version == 3) {
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
} else {
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
}
#endif
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
#endif
#ifdef VTFT_CTRL_V03
if (heltec_version == 3) {
digitalWrite(VTFT_CTRL_V03, LOW);
} else {
digitalWrite(VTFT_CTRL_V05, LOW);
}
#endif
#ifdef VTFT_CTRL
digitalWrite(VTFT_CTRL, LOW);
#endif
#ifdef RAK14014
#elif !defined(M5STACK)
tft.setBrightness(128);
#endif
break;
}
case DISPLAYOFF: {
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
if (heltec_version == 3) {
digitalWrite(ST7735_BACKLIGHT_EN_V03, !TFT_BACKLIGHT_ON);
} else {
digitalWrite(ST7735_BACKLIGHT_EN_V05, !TFT_BACKLIGHT_ON);
}
#endif
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
#endif
#ifdef VTFT_CTRL_V03
if (heltec_version == 3) {
digitalWrite(VTFT_CTRL_V03, HIGH);
} else {
digitalWrite(VTFT_CTRL_V05, HIGH);
}
#endif
#ifdef VTFT_CTRL
digitalWrite(VTFT_CTRL, HIGH);
#endif
#ifdef RAK14014
#elif !defined(M5STACK)
tft.setBrightness(0);
#endif
break;
}
default:
break;
}
// Drop all other commands to device (we just update the buffer)
}
void TFTDisplay::flipScreenVertically()
{
#if defined(T_WATCH_S3)
LOG_DEBUG("Flip TFT vertically\n"); // T-Watch S3 right-handed orientation
tft.setRotation(0);
#endif
}
bool TFTDisplay::hasTouch(void)
{
#ifdef RAK14014
#elif !defined(M5STACK)
return tft.touch() != nullptr;
#else
return false;
#endif
}
bool TFTDisplay::getTouch(int16_t *x, int16_t *y)
{
#ifdef RAK14014
#elif !defined(M5STACK)
return tft.getTouch(x, y);
#else
return false;
#endif
}
void TFTDisplay::setDetected(uint8_t detected)
@@ -62,22 +478,40 @@ bool TFTDisplay::connect()
LOG_INFO("Doing TFT init\n");
#ifdef TFT_BL
digitalWrite(TFT_BL, HIGH);
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
// pinMode(PIN_3V3_EN, OUTPUT);
// digitalWrite(PIN_3V3_EN, HIGH);
LOG_INFO("Power to TFT Backlight\n");
#endif
#ifdef ST7735_BACKLIGHT_EN
digitalWrite(ST7735_BACKLIGHT_EN, HIGH);
pinMode(ST7735_BACKLIGHT_EN, OUTPUT);
#ifdef ST7735_BACKLIGHT_EN_V03
if (heltec_version == 3) {
pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT);
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
} else {
pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT);
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
}
#endif
tft.init();
#ifdef M5STACK
tft.setRotation(1); // M5Stack has the TFT in landscape
#if defined(M5STACK)
tft.setRotation(0);
#elif defined(RAK14014)
tft.setRotation(1);
tft.setSwapBytes(true);
// tft.fillScreen(TFT_BLACK);
#elif defined(T_DECK) || defined(PICOMPUTER_S3)
tft.setRotation(1); // T-Deck has the TFT in landscape
#elif defined(T_WATCH_S3)
tft.setRotation(2); // T-Watch S3 left-handed orientation
#else
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
#endif
tft.fillScreen(TFT_BLACK);
// tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left
return true;
}

View File

@@ -3,11 +3,10 @@
#include <OLEDDisplay.h>
/**
* An adapter class that allows using the TFT_eSPI library as if it was an OLEDDisplay implementation.
* An adapter class that allows using the LovyanGFX library as if it was an OLEDDisplay implementation.
*
* Remaining TODO:
* optimize display() to only draw changed pixels (see other OLED subclasses for examples)
* implement displayOn/displayOff to turn off the TFT device (and backlight)
* Use the fast NRF52 SPI API rather than the slow standard arduino version
*
* turn radio back on - currently with both on spi bus is fucked? or are we leaving chip select asserted?
@@ -23,6 +22,13 @@ class TFTDisplay : public OLEDDisplay
// Write the buffer to the display memory
virtual void display(void) override;
// Turn the display upside down
virtual void flipScreenVertically();
// Touch screen (static handlers)
static bool hasTouch(void);
static bool getTouch(int16_t *x, int16_t *y);
/**
* shim to make the abstraction happy
*
@@ -38,4 +44,4 @@ class TFTDisplay : public OLEDDisplay
// Connect to the display
virtual bool connect() override;
};
};

View File

@@ -14,7 +14,8 @@ 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 imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff};

181
src/input/BBQ10Keyboard.cpp Normal file
View File

@@ -0,0 +1,181 @@
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
#include <Arduino.h>
#include "BBQ10Keyboard.h"
#define _REG_VER 1
#define _REG_CFG 2
#define _REG_INT 3
#define _REG_KEY 4
#define _REG_BKL 5
#define _REG_DEB 6
#define _REG_FRQ 7
#define _REG_RST 8
#define _REG_FIF 9
#define _WRITE_MASK (1 << 7)
#define CFG_OVERFLOW_ON (1 << 0)
#define CFG_OVERFLOW_INT (1 << 1)
#define CFG_CAPSLOCK_INT (1 << 2)
#define CFG_NUMLOCK_INT (1 << 3)
#define CFG_KEY_INT (1 << 4)
#define CFG_PANIC_INT (1 << 5)
#define CFG_REPORT_MODS (1 << 6)
#define CFG_USE_MODS (1 << 7)
#define INT_OVERFLOW (1 << 0)
#define INT_CAPSLOCK (1 << 1)
#define INT_NUMLOCK (1 << 2)
#define INT_KEY (1 << 3)
#define INT_PANIC (1 << 4)
#define KEY_CAPSLOCK (1 << 5)
#define KEY_NUMLOCK (1 << 6)
#define KEY_COUNT_MASK (0x1F)
BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {}
void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire)
{
m_addr = addr;
m_wire = wire;
m_wire->begin();
reset();
}
void BBQ10Keyboard::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
{
m_addr = addr;
m_wire = nullptr;
writeCallback = w;
readCallback = r;
reset();
}
void BBQ10Keyboard::reset()
{
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(_REG_RST);
m_wire->endTransmission();
}
if (writeCallback) {
uint8_t data = 0;
writeCallback(m_addr, _REG_RST, &data, 0);
}
delay(100);
writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS);
delay(100);
}
void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const
{
pinMode(pin, INPUT_PULLUP);
::attachInterrupt(digitalPinToInterrupt(pin), func, RISING);
}
void BBQ10Keyboard::detachInterrupt(uint8_t pin) const
{
::detachInterrupt(pin);
}
void BBQ10Keyboard::clearInterruptStatus()
{
writeRegister(_REG_INT, 0x00);
}
uint8_t BBQ10Keyboard::status() const
{
return readRegister8(_REG_KEY);
}
uint8_t BBQ10Keyboard::keyCount() const
{
return status() & KEY_COUNT_MASK;
}
BBQ10Keyboard::KeyEvent BBQ10Keyboard::keyEvent() const
{
KeyEvent event = {.key = '\0', .state = StateIdle};
if (keyCount() == 0)
return event;
const uint16_t buf = readRegister16(_REG_FIF);
event.key = buf >> 8;
event.state = KeyState(buf & 0xFF);
return event;
}
float BBQ10Keyboard::backlight() const
{
return readRegister8(_REG_BKL) / 255.0f;
}
void BBQ10Keyboard::setBacklight(float value)
{
writeRegister(_REG_BKL, value * 255);
}
uint8_t BBQ10Keyboard::readRegister8(uint8_t reg) const
{
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(reg);
m_wire->endTransmission();
m_wire->requestFrom(m_addr, (uint8_t)1);
if (m_wire->available() < 1)
return 0;
return m_wire->read();
}
if (readCallback) {
uint8_t data;
readCallback(m_addr, reg, &data, 1);
return data;
}
return 0;
}
uint16_t BBQ10Keyboard::readRegister16(uint8_t reg) const
{
uint8_t data[2] = {0};
// uint8_t low = 0, high = 0;
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(reg);
m_wire->endTransmission();
m_wire->requestFrom(m_addr, (uint8_t)2);
if (m_wire->available() < 2)
return 0;
data[0] = m_wire->read();
data[1] = m_wire->read();
}
if (readCallback) {
readCallback(m_addr, reg, data, 2);
}
return (data[1] << 8) | data[0];
}
void BBQ10Keyboard::writeRegister(uint8_t reg, uint8_t value)
{
uint8_t data[2];
data[0] = reg | _WRITE_MASK;
data[1] = value;
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(data, sizeof(uint8_t) * 2);
m_wire->endTransmission();
}
if (writeCallback) {
writeCallback(m_addr, data[0], &(data[1]), 1);
}
}

51
src/input/BBQ10Keyboard.h Normal file
View File

@@ -0,0 +1,51 @@
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
#include "configuration.h"
#include <Wire.h>
#define KEY_MOD_ALT (0x1A)
#define KEY_MOD_SHL (0x1B)
#define KEY_MOD_SHR (0x1C)
#define KEY_MOD_SYM (0x1D)
class BBQ10Keyboard
{
public:
typedef uint8_t (*i2c_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t len);
enum KeyState { StateIdle = 0, StatePress, StateLongPress, StateRelease };
struct KeyEvent {
char key;
KeyState state;
};
BBQ10Keyboard();
void begin(uint8_t addr = BBQ10_KB_ADDR, TwoWire *wire = &Wire);
void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = BBQ10_KB_ADDR);
void reset(void);
void attachInterrupt(uint8_t pin, void (*func)(void)) const;
void detachInterrupt(uint8_t pin) const;
void clearInterruptStatus(void);
uint8_t status(void) const;
uint8_t keyCount(void) const;
KeyEvent keyEvent(void) const;
float backlight() const;
void setBacklight(float value);
uint8_t readRegister8(uint8_t reg) const;
uint16_t readRegister16(uint8_t reg) const;
void writeRegister(uint8_t reg, uint8_t value);
private:
TwoWire *m_wire;
uint8_t m_addr;
i2c_com_fptr_t readCallback;
i2c_com_fptr_t writeCallback;
};

View File

@@ -5,12 +5,12 @@ RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {}
void RotaryEncoderInterruptImpl1::init()
bool RotaryEncoderInterruptImpl1::init()
{
if (!moduleConfig.canned_message.rotary1_enabled) {
// Input device is disabled.
disable();
return;
return false;
}
uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a;
@@ -25,6 +25,7 @@ void RotaryEncoderInterruptImpl1::init()
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
RotaryEncoderInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
return true;
}
void RotaryEncoderInterruptImpl1::handleIntA()
@@ -38,4 +39,4 @@ void RotaryEncoderInterruptImpl1::handleIntB()
void RotaryEncoderInterruptImpl1::handleIntPressed()
{
rotaryEncoderInterruptImpl1->intPressHandler();
}
}

View File

@@ -12,7 +12,7 @@ class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase
{
public:
RotaryEncoderInterruptImpl1();
void init();
bool init();
static void handleIntA();
static void handleIntB();
static void handleIntPressed();

View File

@@ -0,0 +1,137 @@
#include "TouchScreenBase.h"
#include "main.h"
#ifndef TIME_LONG_PRESS
#define TIME_LONG_PRESS 400
#endif
// move a minimum distance over the screen to detect a "swipe"
#ifndef TOUCH_THRESHOLD_X
#define TOUCH_THRESHOLD_X 30
#endif
#ifndef TOUCH_THRESHOLD_Y
#define TOUCH_THRESHOLD_Y 20
#endif
TouchScreenBase::TouchScreenBase(const char *name, uint16_t width, uint16_t height)
: concurrency::OSThread(name), _display_width(width), _display_height(height), _first_x(0), _last_x(0), _first_y(0),
_last_y(0), _start(0), _tapped(false), _originName(name)
{
}
void TouchScreenBase::init(bool hasTouch)
{
if (hasTouch) {
LOG_INFO("TouchScreen initialized %d %d\n", TOUCH_THRESHOLD_X, TOUCH_THRESHOLD_Y);
this->setInterval(100);
} else {
disable();
this->setInterval(UINT_MAX);
}
}
int32_t TouchScreenBase::runOnce()
{
TouchEvent e;
e.touchEvent = static_cast<char>(TOUCH_ACTION_NONE);
// process touch events
int16_t x, y;
bool touched = getTouch(x, y);
if (touched) {
this->setInterval(20);
_last_x = x;
_last_y = y;
}
if (touched != _touchedOld) {
if (touched) {
hapticFeedback();
_state = TOUCH_EVENT_OCCURRED;
_start = millis();
_first_x = x;
_first_y = y;
} else {
_state = TOUCH_EVENT_CLEARED;
time_t duration = millis() - _start;
x = _last_x;
y = _last_y;
this->setInterval(50);
// compute distance
int16_t dx = x - _first_x;
int16_t dy = y - _first_y;
uint16_t adx = abs(dx);
uint16_t ady = abs(dy);
// swipe horizontal
if (adx > ady && adx > TOUCH_THRESHOLD_X) {
if (0 > dx) { // swipe right to left
e.touchEvent = static_cast<char>(TOUCH_ACTION_LEFT);
LOG_DEBUG("action SWIPE: right to left\n");
} else { // swipe left to right
e.touchEvent = static_cast<char>(TOUCH_ACTION_RIGHT);
LOG_DEBUG("action SWIPE: left to right\n");
}
}
// swipe vertical
else if (ady > adx && ady > TOUCH_THRESHOLD_Y) {
if (0 > dy) { // swipe bottom to top
e.touchEvent = static_cast<char>(TOUCH_ACTION_UP);
LOG_DEBUG("action SWIPE: bottom to top\n");
} else { // swipe top to bottom
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOWN);
LOG_DEBUG("action SWIPE: top to bottom\n");
}
}
// tap
else {
if (duration > 0 && duration < TIME_LONG_PRESS) {
if (_tapped) {
_tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOUBLE_TAP);
LOG_DEBUG("action DOUBLE TAP(%d/%d)\n", x, y);
} else {
_tapped = true;
}
} else {
_tapped = false;
}
}
}
}
_touchedOld = touched;
// fire TAP event when no 2nd tap occured within time
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
_tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
}
// fire LONG_PRESS event without the need for release
if (touched && (time_t(millis()) - _start) > TIME_LONG_PRESS) {
// tricky: prevent reoccurring events and another touch event when releasing
_start = millis() + 30000;
e.touchEvent = static_cast<char>(TOUCH_ACTION_LONG_PRESS);
LOG_DEBUG("action LONG PRESS(%d/%d)\n", _last_x, _last_y);
}
if (e.touchEvent != TOUCH_ACTION_NONE) {
e.source = this->_originName;
e.x = _last_x;
e.y = _last_y;
onEvent(e);
}
return interval;
}
void TouchScreenBase::hapticFeedback()
{
#ifdef T_WATCH_S3
drv.setWaveform(0, 75);
drv.setWaveform(1, 0); // end waveform
drv.go();
#endif
}

View File

@@ -0,0 +1,55 @@
#pragma once
#include "InputBroker.h"
#include "concurrency/OSThread.h"
#include "mesh/NodeDB.h"
typedef struct _TouchEvent {
const char *source;
char touchEvent;
uint16_t x;
uint16_t y;
} TouchEvent;
class TouchScreenBase : public Observable<const InputEvent *>, public concurrency::OSThread
{
public:
explicit TouchScreenBase(const char *name, uint16_t width, uint16_t height);
void init(bool hasTouch);
protected:
enum TouchScreenBaseStateType { TOUCH_EVENT_OCCURRED, TOUCH_EVENT_CLEARED };
enum TouchScreenBaseEventType {
TOUCH_ACTION_NONE,
TOUCH_ACTION_UP,
TOUCH_ACTION_DOWN,
TOUCH_ACTION_LEFT,
TOUCH_ACTION_RIGHT,
TOUCH_ACTION_TAP,
TOUCH_ACTION_DOUBLE_TAP,
TOUCH_ACTION_LONG_PRESS
};
virtual int32_t runOnce() override;
virtual bool getTouch(int16_t &x, int16_t &y) = 0;
virtual void onEvent(const TouchEvent &event) = 0;
volatile TouchScreenBaseStateType _state = TOUCH_EVENT_CLEARED;
volatile TouchScreenBaseEventType _action = TOUCH_ACTION_NONE;
void hapticFeedback();
protected:
uint16_t _display_width;
uint16_t _display_height;
private:
bool _touchedOld = false; // previous touch state
int16_t _first_x, _last_x; // horizontal swipe direction
int16_t _first_y, _last_y; // vertical swipe direction
time_t _start; // for LONG_PRESS
bool _tapped; // for DOUBLE_TAP
const char *_originName;
};

View File

@@ -0,0 +1,73 @@
#include "TouchScreenImpl1.h"
#include "InputBroker.h"
#include "PowerFSM.h"
#include "configuration.h"
TouchScreenImpl1 *touchScreenImpl1;
TouchScreenImpl1::TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *))
: TouchScreenBase("touchscreen1", width, height), _getTouch(getTouch)
{
}
void TouchScreenImpl1::init()
{
#if !HAS_TOUCHSCREEN
TouchScreenBase::init(false);
return;
#else
TouchScreenBase::init(true);
inputBroker->registerSource(this);
#endif
}
bool TouchScreenImpl1::getTouch(int16_t &x, int16_t &y)
{
return _getTouch(&x, &y);
}
/**
* @brief forward touchscreen event
*
* @param event
*
* The touchscreen events are translated to input events and reversed
*/
void TouchScreenImpl1::onEvent(const TouchEvent &event)
{
InputEvent e;
e.source = event.source;
switch (event.touchEvent) {
case TOUCH_ACTION_LEFT: {
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT);
break;
}
case TOUCH_ACTION_RIGHT: {
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT);
break;
}
case TOUCH_ACTION_UP: {
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP);
break;
}
case TOUCH_ACTION_DOWN: {
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
break;
}
case TOUCH_ACTION_DOUBLE_TAP: {
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
break;
}
case TOUCH_ACTION_LONG_PRESS: {
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL);
break;
}
case TOUCH_ACTION_TAP: {
powerFSM.trigger(EVENT_INPUT);
break;
}
default:
return;
}
this->notifyObservers(&e);
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "TouchScreenBase.h"
class TouchScreenImpl1 : public TouchScreenBase
{
public:
TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *));
void init(void);
protected:
virtual bool getTouch(int16_t &x, int16_t &y);
virtual void onEvent(const TouchEvent &event);
bool (*_getTouch)(int16_t *, int16_t *);
};
extern TouchScreenImpl1 *touchScreenImpl1;

View File

@@ -0,0 +1,95 @@
#include "TrackballInterruptBase.h"
#include "configuration.h"
TrackballInterruptBase::TrackballInterruptBase(const char *name) : concurrency::OSThread(name), _originName(name) {}
void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress,
char eventDown, char eventUp, char eventLeft, char eventRight, char eventPressed,
void (*onIntDown)(), void (*onIntUp)(), void (*onIntLeft)(), void (*onIntRight)(),
void (*onIntPress)())
{
this->_pinDown = pinDown;
this->_pinUp = pinUp;
this->_pinLeft = pinLeft;
this->_pinRight = pinRight;
this->_eventDown = eventDown;
this->_eventUp = eventUp;
this->_eventLeft = eventLeft;
this->_eventRight = eventRight;
this->_eventPressed = eventPressed;
pinMode(pinPress, INPUT_PULLUP);
pinMode(this->_pinDown, INPUT_PULLUP);
pinMode(this->_pinUp, INPUT_PULLUP);
pinMode(this->_pinLeft, INPUT_PULLUP);
pinMode(this->_pinRight, INPUT_PULLUP);
attachInterrupt(pinPress, onIntPress, RISING);
attachInterrupt(this->_pinDown, onIntDown, RISING);
attachInterrupt(this->_pinUp, onIntUp, RISING);
attachInterrupt(this->_pinLeft, onIntLeft, RISING);
attachInterrupt(this->_pinRight, onIntRight, RISING);
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)\n", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
pinPress);
this->setInterval(100);
}
int32_t TrackballInterruptBase::runOnce()
{
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
if (this->action == TB_ACTION_PRESSED) {
// LOG_DEBUG("Trackball event Press\n");
e.inputEvent = this->_eventPressed;
} else if (this->action == TB_ACTION_UP) {
// LOG_DEBUG("Trackball event UP\n");
e.inputEvent = this->_eventUp;
} else if (this->action == TB_ACTION_DOWN) {
// LOG_DEBUG("Trackball event DOWN\n");
e.inputEvent = this->_eventDown;
} else if (this->action == TB_ACTION_LEFT) {
// LOG_DEBUG("Trackball event LEFT\n");
e.inputEvent = this->_eventLeft;
} else if (this->action == TB_ACTION_RIGHT) {
// LOG_DEBUG("Trackball event RIGHT\n");
e.inputEvent = this->_eventRight;
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
e.source = this->_originName;
e.kbchar = 0x00;
this->notifyObservers(&e);
}
this->action = TB_ACTION_NONE;
return 100;
}
void TrackballInterruptBase::intPressHandler()
{
this->action = TB_ACTION_PRESSED;
}
void TrackballInterruptBase::intDownHandler()
{
this->action = TB_ACTION_DOWN;
}
void TrackballInterruptBase::intUpHandler()
{
this->action = TB_ACTION_UP;
}
void TrackballInterruptBase::intLeftHandler()
{
this->action = TB_ACTION_LEFT;
}
void TrackballInterruptBase::intRightHandler()
{
this->action = TB_ACTION_RIGHT;
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "InputBroker.h"
#include "mesh/NodeDB.h"
class TrackballInterruptBase : public Observable<const InputEvent *>, public concurrency::OSThread
{
public:
explicit TrackballInterruptBase(const char *name);
void init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress, char eventDown, char eventUp,
char eventLeft, char eventRight, char eventPressed, void (*onIntDown)(), void (*onIntUp)(), void (*onIntLeft)(),
void (*onIntRight)(), void (*onIntPress)());
void intPressHandler();
void intDownHandler();
void intUpHandler();
void intLeftHandler();
void intRightHandler();
virtual int32_t runOnce() override;
protected:
enum TrackballInterruptBaseActionType {
TB_ACTION_NONE,
TB_ACTION_PRESSED,
TB_ACTION_UP,
TB_ACTION_DOWN,
TB_ACTION_LEFT,
TB_ACTION_RIGHT
};
volatile TrackballInterruptBaseActionType action = TB_ACTION_NONE;
private:
uint8_t _pinDown = 0;
uint8_t _pinUp = 0;
uint8_t _pinLeft = 0;
uint8_t _pinRight = 0;
char _eventDown = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventUp = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventLeft = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventRight = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventPressed = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
const char *_originName;
};

View File

@@ -0,0 +1,54 @@
#include "TrackballInterruptImpl1.h"
#include "InputBroker.h"
#include "configuration.h"
TrackballInterruptImpl1 *trackballInterruptImpl1;
TrackballInterruptImpl1::TrackballInterruptImpl1() : TrackballInterruptBase("trackball1") {}
void TrackballInterruptImpl1::init()
{
#if !HAS_TRACKBALL
// Input device is disabled.
return;
#else
uint8_t pinUp = TB_UP;
uint8_t pinDown = TB_DOWN;
uint8_t pinLeft = TB_LEFT;
uint8_t pinRight = TB_RIGHT;
uint8_t pinPress = TB_PRESS;
char eventDown = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
char eventUp = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP);
char eventLeft = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT);
char eventRight = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT);
char eventPressed = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
TrackballInterruptBase::init(pinDown, pinUp, pinLeft, pinRight, pinPress, eventDown, eventUp, eventLeft, eventRight,
eventPressed, TrackballInterruptImpl1::handleIntDown, TrackballInterruptImpl1::handleIntUp,
TrackballInterruptImpl1::handleIntLeft, TrackballInterruptImpl1::handleIntRight,
TrackballInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
#endif
}
void TrackballInterruptImpl1::handleIntDown()
{
trackballInterruptImpl1->intDownHandler();
}
void TrackballInterruptImpl1::handleIntUp()
{
trackballInterruptImpl1->intUpHandler();
}
void TrackballInterruptImpl1::handleIntLeft()
{
trackballInterruptImpl1->intLeftHandler();
}
void TrackballInterruptImpl1::handleIntRight()
{
trackballInterruptImpl1->intRightHandler();
}
void TrackballInterruptImpl1::handleIntPressed()
{
trackballInterruptImpl1->intPressHandler();
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include "TrackballInterruptBase.h"
class TrackballInterruptImpl1 : public TrackballInterruptBase
{
public:
TrackballInterruptImpl1();
void init();
static void handleIntDown();
static void handleIntUp();
static void handleIntLeft();
static void handleIntRight();
static void handleIntPressed();
};
extern TrackballInterruptImpl1 *trackballInterruptImpl1;

View File

@@ -23,7 +23,7 @@ void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
attachInterrupt(this->_pinDown, onIntDown, RISING);
attachInterrupt(this->_pinUp, onIntUp, RISING);
LOG_DEBUG("GPIO initialized (%d, %d, %d)\n", this->_pinDown, this->_pinUp, pinPress);
LOG_DEBUG("Up/down/press GPIO initialized (%d, %d, %d)\n", this->_pinUp, this->_pinDown, pinPress);
}
void UpDownInterruptBase::intPressHandler()

View File

@@ -5,12 +5,12 @@ UpDownInterruptImpl1 *upDownInterruptImpl1;
UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {}
void UpDownInterruptImpl1::init()
bool UpDownInterruptImpl1::init()
{
if (!moduleConfig.canned_message.updown1_enabled) {
// Input device is disabled.
return;
return false;
}
uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a;
@@ -24,6 +24,7 @@ void UpDownInterruptImpl1::init()
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
return true;
}
void UpDownInterruptImpl1::handleIntDown()
@@ -37,4 +38,4 @@ void UpDownInterruptImpl1::handleIntUp()
void UpDownInterruptImpl1::handleIntPressed()
{
upDownInterruptImpl1->intPressHandler();
}
}

View File

@@ -5,10 +5,10 @@ class UpDownInterruptImpl1 : public UpDownInterruptBase
{
public:
UpDownInterruptImpl1();
void init();
bool init();
static void handleIntDown();
static void handleIntUp();
static void handleIntPressed();
};
extern UpDownInterruptImpl1 *upDownInterruptImpl1;
extern UpDownInterruptImpl1 *upDownInterruptImpl1;

View File

@@ -7,7 +7,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
void CardKbI2cImpl::init()
{
if (cardkb_found.address != CARDKB_ADDR) {
if (cardkb_found.address == 0x00) {
disable();
return;
}

View File

@@ -28,20 +28,9 @@ uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t len
return readflag;
}
// Unused for now - flagging it off
#if 0
void write_to_14004(const TwoWire * i2cBus, uint8_t reg, uint8_t data)
{
i2cBus->beginTransmission(CARDKB_ADDR);
i2cBus->write(reg);
i2cBus->write(data);
i2cBus->endTransmission(); // stop transmitting
}
#endif
int32_t KbI2cBase::runOnce()
{
if (cardkb_found.address != CARDKB_ADDR) {
if (cardkb_found.address == 0x00) {
// Input device is not detected.
return INT32_MAX;
}
@@ -52,11 +41,19 @@ int32_t KbI2cBase::runOnce()
#ifdef I2C_SDA1
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
i2cBus = &Wire1;
if (cardkb_found.address == BBQ10_KB_ADDR) {
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1);
Q10keyboard.setBacklight(0);
}
break;
#endif
case ScanI2C::WIRE:
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
i2cBus = &Wire;
if (cardkb_found.address == BBQ10_KB_ADDR) {
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire);
Q10keyboard.setBacklight(0);
}
break;
case ScanI2C::NO_I2C:
default:
@@ -64,7 +61,105 @@ int32_t KbI2cBase::runOnce()
}
}
if (kb_model == 0x02) {
switch (kb_model) {
case 0x11: { // BB Q10
int keyCount = Q10keyboard.keyCount();
while (keyCount--) {
const BBQ10Keyboard::KeyEvent key = Q10keyboard.keyEvent();
if ((key.key != 0x00) && (key.state == BBQ10Keyboard::StateRelease)) {
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
switch (key.key) {
case 'p': // TAB
case 't': // TAB as well
if (is_sym) {
e.inputEvent = ANYKEY;
e.kbchar = 0x09; // TAB Scancode
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 'q': // ESC
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
e.kbchar = 0x1b;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 0x08: // Back
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = key.key;
break;
case 'e': // sym e
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = 0xb5;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 'x': // sym x
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = 0xb6;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 's': // sym s
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = 0x00; // tweak for destSelect
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 'f': // sym f
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = 0x00; // tweak for destSelect
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 0x13: // Code scanner says the SYM key is 0x13
is_sym = !is_sym;
break;
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
case 0x00: // nopress
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break;
default: // all other keys
e.inputEvent = ANYKEY;
e.kbchar = key.key;
is_sym = false; // reset sym state after second keypress
break;
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
}
}
break;
}
case 0x02: {
// RAK14004
uint8_t rDataBuf[8] = {0};
uint8_t PrintDataBuf = 0;
@@ -85,9 +180,12 @@ int32_t KbI2cBase::runOnce()
e.kbchar = PrintDataBuf;
this->notifyObservers(&e);
}
} else {
// m5 cardkb
i2cBus->requestFrom(CARDKB_ADDR, 1);
break;
}
case 0x00: // CARDKB
case 0x10: { // T-DECK
i2cBus->requestFrom((int)cardkb_found.address, 1);
while (i2cBus->available()) {
char c = i2cBus->read();
@@ -104,17 +202,19 @@ int32_t KbI2cBase::runOnce()
break;
case 0xb5: // Up
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = 0xb5;
break;
case 0xb6: // Down
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = 0xb6;
break;
case 0xb4: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = c;
e.kbchar = 0xb4;
break;
case 0xb7: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = c;
e.kbchar = 0xb7;
break;
case 0x0d: // Enter
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
@@ -132,6 +232,10 @@ int32_t KbI2cBase::runOnce()
this->notifyObservers(&e);
}
}
break;
}
return 500;
default:
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
}
return 300;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "BBQ10Keyboard.h"
#include "InputBroker.h"
#include "Wire.h"
#include "concurrency/OSThread.h"
@@ -16,4 +17,7 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
const char *_originName;
TwoWire *i2cBus = 0;
BBQ10Keyboard Q10keyboard;
bool is_sym = false;
};

131
src/input/kbMatrixBase.cpp Normal file
View File

@@ -0,0 +1,131 @@
#include "kbMatrixBase.h"
#include "configuration.h"
#ifdef INPUTBROKER_MATRIX_TYPE
const byte keys_cols[] = KEYS_COLS;
const byte keys_rows[] = KEYS_ROWS;
#if INPUTBROKER_MATRIX_TYPE == 1
unsigned char KeyMap[3][sizeof(keys_rows)][sizeof(keys_cols)] = {{{' ', '.', 'm', 'n', 'b', 0xb6},
{0x0d, 'l', 'k', 'j', 'h', 0xb4},
{'p', 'o', 'i', 'u', 'y', 0xb5},
{0x08, 'z', 'x', 'c', 'v', 0xb7},
{'a', 's', 'd', 'f', 'g', 0x09},
{'q', 'w', 'e', 'r', 't', 0x1a}},
{// SHIFT
{':', ';', 'M', 'N', 'B', 0xb6},
{0x0d, 'L', 'K', 'J', 'H', 0xb4},
{'P', 'O', 'I', 'U', 'Y', 0xb5},
{0x08, 'Z', 'X', 'C', 'V', 0xb7},
{'A', 'S', 'D', 'F', 'G', 0x09},
{'Q', 'W', 'E', 'R', 'T', 0x1a}},
{// SHIFT-SHIFT
{'_', ',', '>', '<', '"', '{'},
{'~', '-', '*', '&', '+', '['},
{'0', '9', '8', '7', '6', '}'},
{'=', '(', ')', '?', '/', ']'},
{'!', '@', '#', '$', '%', '\\'},
{'1', '2', '3', '4', '5', 0x1a}}};
#endif
KbMatrixBase::KbMatrixBase(const char *name) : concurrency::OSThread(name)
{
this->_originName = name;
}
int32_t KbMatrixBase::runOnce()
{
if (!INPUTBROKER_MATRIX_TYPE) {
// Input device is not requested.
return disable();
}
if (firstTime) {
// This is the first time the OSThread library has called this function, so do port setup
firstTime = 0;
for (byte i = 0; i < sizeof(keys_rows); i++) {
pinMode(keys_rows[i], OUTPUT);
digitalWrite(keys_rows[i], HIGH);
}
for (byte i = 0; i < sizeof(keys_cols); i++) {
pinMode(keys_cols[i], INPUT_PULLUP);
}
}
key = 0;
if (INPUTBROKER_MATRIX_TYPE == 1) {
// scan for keypresses
for (byte i = 0; i < sizeof(keys_rows); i++) {
digitalWrite(keys_rows[i], LOW);
for (byte j = 0; j < sizeof(keys_cols); j++) {
if (digitalRead(keys_cols[j]) == LOW) {
key = KeyMap[shift][i][j];
}
}
digitalWrite(keys_rows[i], HIGH);
}
// debounce
if (key != prevkey) {
if (key != 0) {
LOG_DEBUG("Key 0x%x pressed\n", key);
// reset shift now that we have a keypress
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
switch (key) {
case 0x1b: // ESC
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
break;
case 0x08: // Back
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = key;
break;
case 0xb5: // Up
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
break;
case 0xb6: // Down
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
break;
case 0xb4: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = key;
break;
case 0xb7: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = key;
break;
case 0x0d: // Enter
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
case 0x00: // nopress
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break;
case 0x1a: // Shift
shift++;
if (shift > 2) {
shift = 0;
}
break;
default: // all other keys
e.inputEvent = ANYKEY;
e.kbchar = key;
break;
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
}
prevkey = key;
}
} else {
LOG_WARN("Unknown kb_model 0x%02x\n", INPUTBROKER_MATRIX_TYPE);
return disable();
}
return 50; // Keyscan every 50msec to avoid key bounce
}
#endif // INPUTBROKER_MATRIX_TYPE

20
src/input/kbMatrixBase.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include "InputBroker.h"
#include "concurrency/OSThread.h"
class KbMatrixBase : public Observable<const InputEvent *>, public concurrency::OSThread
{
public:
explicit KbMatrixBase(const char *name);
protected:
virtual int32_t runOnce() override;
private:
const char *_originName;
bool firstTime = 1;
int shift = 0;
char key = 0;
char prevkey = 0;
};

View File

@@ -0,0 +1,20 @@
#include "kbMatrixImpl.h"
#include "InputBroker.h"
#ifdef INPUTBROKER_MATRIX_TYPE
KbMatrixImpl *kbMatrixImpl;
KbMatrixImpl::KbMatrixImpl() : KbMatrixBase("matrixKB") {}
void KbMatrixImpl::init()
{
if (!INPUTBROKER_MATRIX_TYPE) {
disable();
return;
}
inputBroker->registerSource(this);
}
#endif // INPUTBROKER_MATRIX_TYPE

19
src/input/kbMatrixImpl.h Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#include "kbMatrixBase.h"
#include "main.h"
/**
* @brief The idea behind this class to have static methods for the event handlers.
* Check attachInterrupt() at RotaryEncoderInteruptBase.cpp
* Technically you can have as many rotary encoders hardver attached
* to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/
class KbMatrixImpl : public KbMatrixBase
{
public:
KbMatrixImpl();
void init();
};
extern KbMatrixImpl *kbMatrixImpl;

Some files were not shown because too many files have changed in this diff Show More