mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-19 11:32:06 +00:00
Merge branch 'master' into tft-gui-work
This commit is contained in:
commit
e24e4d99a6
1
.github/workflows/build_esp32.yml
vendored
1
.github/workflows/build_esp32.yml
vendored
@ -35,6 +35,7 @@ jobs:
|
|||||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
||||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
||||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
|
||||||
|
|
||||||
- name: Build ESP32
|
- name: Build ESP32
|
||||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||||
|
62
.github/workflows/build_esp32_c3.yml
vendored
Normal file
62
.github/workflows/build_esp32_c3.yml
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
name: Build ESP32-C3
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
board:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-esp32-c3:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Build base
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
|
- name: Pull web ui
|
||||||
|
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
|
||||||
|
with:
|
||||||
|
repo: meshtastic/web
|
||||||
|
file: build.tar
|
||||||
|
target: build.tar
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Unpack web ui
|
||||||
|
run: |
|
||||||
|
tar -xf build.tar -C data/static
|
||||||
|
rm build.tar
|
||||||
|
- name: Remove debug flags for release
|
||||||
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
|
run: |
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
|
||||||
|
- name: Build ESP32
|
||||||
|
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||||
|
|
||||||
|
- name: Pull OTA Firmware
|
||||||
|
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
|
||||||
|
with:
|
||||||
|
repo: meshtastic/firmware-ota
|
||||||
|
file: firmware-c3.bin
|
||||||
|
target: release/bleota-c3.bin
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
shell: bash
|
||||||
|
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-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||||
|
path: |
|
||||||
|
release/*.bin
|
||||||
|
release/*.elf
|
1
.github/workflows/build_esp32_s3.yml
vendored
1
.github/workflows/build_esp32_s3.yml
vendored
@ -34,6 +34,7 @@ jobs:
|
|||||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
||||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
||||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
|
||||||
- name: Build ESP32
|
- name: Build ESP32
|
||||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||||
|
|
||||||
|
14
.github/workflows/main_matrix.yml
vendored
14
.github/workflows/main_matrix.yml
vendored
@ -67,7 +67,6 @@ jobs:
|
|||||||
- board: tlora-v2-1-1_6-tcxo
|
- board: tlora-v2-1-1_6-tcxo
|
||||||
- board: tlora-v2-1-1_8
|
- board: tlora-v2-1-1_8
|
||||||
- board: tbeam
|
- board: tbeam
|
||||||
- board: heltec-ht62-esp32c3-sx1262
|
|
||||||
- board: heltec-v2_0
|
- board: heltec-v2_0
|
||||||
- board: heltec-v2_1
|
- board: heltec-v2_1
|
||||||
- board: tbeam0_7
|
- board: tbeam0_7
|
||||||
@ -105,6 +104,16 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
board: ${{ matrix.board }}
|
board: ${{ matrix.board }}
|
||||||
|
|
||||||
|
build-esp32-c3:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- board: heltec-ht62-esp32c3-sx1262
|
||||||
|
uses: ./.github/workflows/build_esp32_c3.yml
|
||||||
|
with:
|
||||||
|
board: ${{ matrix.board }}
|
||||||
|
|
||||||
build-nrf52:
|
build-nrf52:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@ -226,6 +235,7 @@ jobs:
|
|||||||
[
|
[
|
||||||
build-esp32,
|
build-esp32,
|
||||||
build-esp32-s3,
|
build-esp32-s3,
|
||||||
|
build-esp32-c3,
|
||||||
build-nrf52,
|
build-nrf52,
|
||||||
build-raspbian,
|
build-raspbian,
|
||||||
build-native,
|
build-native,
|
||||||
@ -251,7 +261,7 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- 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_v2.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat ./firmware-raspbian-*/release/meshtasticd_linux_aarch64 ./firmware-raspbian-*/bin/config-dist.yaml
|
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./*esp32c3*/bleota-c3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase_v2.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat ./firmware-raspbian-*/release/meshtasticd_linux_aarch64 ./firmware-raspbian-*/bin/config-dist.yaml
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
@ -31,9 +31,13 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
|||||||
%PYTHON% -m esptool --baud 115200 erase_flash
|
%PYTHON% -m esptool --baud 115200 erase_flash
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
||||||
|
|
||||||
@REM Account for S3 board's different OTA partition
|
@REM Account for S3 and C3 board's different OTA partition
|
||||||
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% (
|
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% (
|
||||||
|
IF x%FILENAME:esp32c3=%==x%FILENAME% (
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
||||||
|
) else (
|
||||||
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-c3.bin
|
||||||
|
)
|
||||||
) else (
|
) else (
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-s3.bin
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-s3.bin
|
||||||
)
|
)
|
||||||
|
@ -18,18 +18,20 @@ Flash image file to device, but first erasing and writing system information"
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while getopts ":hp:P:f:" opt; do
|
while getopts ":hp:P:f:" opt; do
|
||||||
case "${opt}" in
|
case "${opt}" in
|
||||||
h)
|
h)
|
||||||
show_help
|
show_help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
p) export ESPTOOL_PORT=${OPTARG}
|
p)
|
||||||
|
export ESPTOOL_PORT=${OPTARG}
|
||||||
;;
|
;;
|
||||||
P) PYTHON=${OPTARG}
|
P)
|
||||||
|
PYTHON=${OPTARG}
|
||||||
;;
|
;;
|
||||||
f) FILENAME=${OPTARG}
|
f)
|
||||||
|
FILENAME=${OPTARG}
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid flag."
|
echo "Invalid flag."
|
||||||
@ -45,13 +47,17 @@ shift "$((OPTIND-1))"
|
|||||||
shift
|
shift
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -f "${FILENAME}" ] && [ ! -z "${FILENAME##*"update"*}" ]; then
|
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
||||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||||
"$PYTHON" -m esptool erase_flash
|
"$PYTHON" -m esptool erase_flash
|
||||||
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
||||||
# Account for S3 board's different OTA partition
|
# Account for S3 board's different OTA partition
|
||||||
if [ ! -z "${FILENAME##*"s3"*}" ] && [ ! -z "${FILENAME##*"-v3"*}" ] && [ ! -z "${FILENAME##*"t-deck"*}" ] && [ ! -z "${FILENAME##*"wireless-paper"*}" ] && [ ! -z "${FILENAME##*"wireless-tracker"*}" ]; then
|
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ]; then
|
||||||
|
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
||||||
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
||||||
|
else
|
||||||
|
"$PYTHON" -m esptool write_flash 0x260000 bleota-c3.bin
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
"$PYTHON" -m esptool write_flash 0x260000 bleota-s3.bin
|
"$PYTHON" -m esptool write_flash 0x260000 bleota-s3.bin
|
||||||
fi
|
fi
|
||||||
|
@ -242,4 +242,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define MESHTASTIC_EXCLUDE_NEIGHBORINFO 1
|
#define MESHTASTIC_EXCLUDE_NEIGHBORINFO 1
|
||||||
#define MESHTASTIC_EXCLUDE_TRACEROUTE 1
|
#define MESHTASTIC_EXCLUDE_TRACEROUTE 1
|
||||||
#define MESHTASTIC_EXCLUDE_WAYPOINT 1
|
#define MESHTASTIC_EXCLUDE_WAYPOINT 1
|
||||||
|
#define MESHTASTIC_EXCLUDE_INPUTBROKER 1
|
||||||
|
#define MESHTASTIC_EXCLUDE_SERIAL 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -71,28 +71,24 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trigger the refresh in GxEPD2
|
||||||
LOG_DEBUG("Updating E-Paper... ");
|
LOG_DEBUG("Updating E-Paper... ");
|
||||||
|
|
||||||
#if false
|
|
||||||
// Currently unused; rescued from commented-out line during a refactor
|
|
||||||
// Use a meaningful macro here if variant doesn't want fast refresh
|
|
||||||
|
|
||||||
// Full update mode (slow)
|
|
||||||
adafruitDisplay->display(false)
|
|
||||||
#else
|
|
||||||
// Fast update mode
|
|
||||||
adafruitDisplay->nextPage();
|
adafruitDisplay->nextPage();
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EINK_NO_HIBERNATE // Only hibernate if controller IC will preserve image memory
|
// End the update process
|
||||||
// Put screen to sleep to save power (possibly not necessary because we already did poweroff inside of display)
|
endUpdate();
|
||||||
adafruitDisplay->hibernate();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOG_DEBUG("done\n");
|
LOG_DEBUG("done\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End the update process - virtual method, overriden in derived class
|
||||||
|
void EInkDisplay::endUpdate()
|
||||||
|
{
|
||||||
|
// Power off display hardware, then deep-sleep (Except Wireless Paper V1.1, no deep-sleep)
|
||||||
|
adafruitDisplay->hibernate();
|
||||||
|
}
|
||||||
|
|
||||||
// Write the buffer to the display memory
|
// Write the buffer to the display memory
|
||||||
void EInkDisplay::display(void)
|
void EInkDisplay::display(void)
|
||||||
{
|
{
|
||||||
@ -188,6 +184,7 @@ bool EInkDisplay::connect()
|
|||||||
// Init GxEPD2
|
// Init GxEPD2
|
||||||
adafruitDisplay->init();
|
adafruitDisplay->init();
|
||||||
adafruitDisplay->setRotation(3);
|
adafruitDisplay->setRotation(3);
|
||||||
|
adafruitDisplay->clearScreen(); // Clearing now, so the boot logo will draw nice and smoothe (fast refresh)
|
||||||
}
|
}
|
||||||
#elif defined(PCA10059)
|
#elif defined(PCA10059)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,13 @@ class EInkDisplay : public OLEDDisplay
|
|||||||
*/
|
*/
|
||||||
virtual bool forceDisplay(uint32_t msecLimit = 1000);
|
virtual bool forceDisplay(uint32_t msecLimit = 1000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run any code needed to complete an update, after the physical refresh has completed.
|
||||||
|
* Split from forceDisplay(), to enable async refresh in derived EInkDynamicDisplay class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual void endUpdate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shim to make the abstraction happy
|
* shim to make the abstraction happy
|
||||||
*
|
*
|
||||||
|
@ -94,19 +94,29 @@ void EInkDynamicDisplay::adjustRefreshCounters()
|
|||||||
// Trigger the display update by calling base class
|
// Trigger the display update by calling base class
|
||||||
bool EInkDynamicDisplay::update()
|
bool EInkDynamicDisplay::update()
|
||||||
{
|
{
|
||||||
|
// Detemine the refresh mode to use, and start the update
|
||||||
bool refreshApproved = determineMode();
|
bool refreshApproved = determineMode();
|
||||||
if (refreshApproved)
|
if (refreshApproved)
|
||||||
EInkDisplay::forceDisplay(0); // Bypass base class' own rate-limiting system
|
EInkDisplay::forceDisplay(0); // Bypass base class' own rate-limiting system
|
||||||
|
|
||||||
|
#if defined(HAS_EINK_ASYNCFULL)
|
||||||
|
if (refreshApproved)
|
||||||
|
endOrDetach(); // Either endUpdate() right now (fast refresh), or set the async flag (full refresh)
|
||||||
|
#endif
|
||||||
|
|
||||||
return refreshApproved; // (Unutilized) Base class promises to return true if update ran
|
return refreshApproved; // (Unutilized) Base class promises to return true if update ran
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assess situation, pick a refresh type
|
// Assess situation, pick a refresh type
|
||||||
bool EInkDynamicDisplay::determineMode()
|
bool EInkDynamicDisplay::determineMode()
|
||||||
{
|
{
|
||||||
checkWasFlooded();
|
checkForPromotion();
|
||||||
|
#if defined(HAS_EINK_ASYNCFULL)
|
||||||
|
checkAsyncFullRefresh();
|
||||||
|
#endif
|
||||||
checkRateLimiting();
|
checkRateLimiting();
|
||||||
|
|
||||||
// If too soon for a new time, abort here
|
// If too soon for a new frame, or display busy, abort early
|
||||||
if (refresh == SKIPPED) {
|
if (refresh == SKIPPED) {
|
||||||
storeAndReset();
|
storeAndReset();
|
||||||
return false; // No refresh
|
return false; // No refresh
|
||||||
@ -116,7 +126,7 @@ bool EInkDynamicDisplay::determineMode()
|
|||||||
|
|
||||||
resetRateLimiting(); // Once determineMode() ends, will have to wait again
|
resetRateLimiting(); // Once determineMode() ends, will have to wait again
|
||||||
hashImage(); // Generate here, so we can still copy it to previousImageHash, even if we skip the comparison check
|
hashImage(); // Generate here, so we can still copy it to previousImageHash, even if we skip the comparison check
|
||||||
LOG_DEBUG("EInkDynamicDisplay: "); // Begin log entry
|
LOG_DEBUG("determineMode(): "); // Begin log entry
|
||||||
|
|
||||||
// Once mode determined, any remaining checks will bypass
|
// Once mode determined, any remaining checks will bypass
|
||||||
checkCosmetic();
|
checkCosmetic();
|
||||||
@ -151,13 +161,25 @@ bool EInkDynamicDisplay::determineMode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Did RESPONSIVE frames previously exceed the rate-limit for fast refresh?
|
// Was a frame skipped (rate, display busy) that should have been a FAST refresh?
|
||||||
void EInkDynamicDisplay::checkWasFlooded()
|
void EInkDynamicDisplay::checkForPromotion()
|
||||||
{
|
{
|
||||||
if (previousReason == EXCEEDED_RATELIMIT_FAST) {
|
// If a frame was skipped (rate, display busy), then promote a BACKGROUND frame
|
||||||
// If so, allow a BACKGROUND frame to draw as RESPONSIVE
|
// Because we DID want a RESPONSIVE/COSMETIC/DEMAND_FULL frame last time, we just didn't get it
|
||||||
// Because we DID want a RESPONSIVE frame last time, we just didn't get it
|
|
||||||
|
switch (previousReason) {
|
||||||
|
case ASYNC_REFRESH_BLOCKED_DEMANDFAST:
|
||||||
|
setFrameFlag(DEMAND_FAST);
|
||||||
|
break;
|
||||||
|
case ASYNC_REFRESH_BLOCKED_COSMETIC:
|
||||||
|
setFrameFlag(COSMETIC);
|
||||||
|
break;
|
||||||
|
case ASYNC_REFRESH_BLOCKED_RESPONSIVE:
|
||||||
|
case EXCEEDED_RATELIMIT_FAST:
|
||||||
setFrameFlag(RESPONSIVE);
|
setFrameFlag(RESPONSIVE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,4 +403,54 @@ void EInkDynamicDisplay::resetGhostPixelTracking()
|
|||||||
}
|
}
|
||||||
#endif // EINK_LIMIT_GHOSTING_PX
|
#endif // EINK_LIMIT_GHOSTING_PX
|
||||||
|
|
||||||
|
#ifdef HAS_EINK_ASYNCFULL
|
||||||
|
// Check the status of an "async full-refresh", and run the finish-up code if the hardware is ready
|
||||||
|
void EInkDynamicDisplay::checkAsyncFullRefresh()
|
||||||
|
{
|
||||||
|
// No refresh taking place, continue with determineMode()
|
||||||
|
if (!asyncRefreshRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Full refresh still running
|
||||||
|
if (adafruitDisplay->epd2.isBusy()) {
|
||||||
|
// No refresh
|
||||||
|
refresh = SKIPPED;
|
||||||
|
|
||||||
|
// Set the reason, marking what type of frame we're skipping
|
||||||
|
if (frameFlags & DEMAND_FAST)
|
||||||
|
reason = ASYNC_REFRESH_BLOCKED_DEMANDFAST;
|
||||||
|
else if (frameFlags & COSMETIC)
|
||||||
|
reason = ASYNC_REFRESH_BLOCKED_COSMETIC;
|
||||||
|
else if (frameFlags & RESPONSIVE)
|
||||||
|
reason = ASYNC_REFRESH_BLOCKED_RESPONSIVE;
|
||||||
|
else
|
||||||
|
reason = ASYNC_REFRESH_BLOCKED_BACKGROUND;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we asyncRefreshRunning flag is still set, but display's BUSY pin reports the refresh is done
|
||||||
|
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
|
||||||
|
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
|
||||||
|
asyncRefreshRunning = false; // Unset the flag
|
||||||
|
LOG_DEBUG("Async full-refresh complete\n");
|
||||||
|
|
||||||
|
// Note: this code only works because of a modification to meshtastic/GxEPD2.
|
||||||
|
// It is only equipped to intercept calls to nextPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out who runs the post-update code
|
||||||
|
void EInkDynamicDisplay::endOrDetach()
|
||||||
|
{
|
||||||
|
if (previousRefresh == FULL) { // Note: previousRefresh is the refresh from this loop.
|
||||||
|
asyncRefreshRunning = true; // Set the flag - picked up at start of determineMode(), next loop.
|
||||||
|
LOG_DEBUG("Async full-refresh begins\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast Refresh
|
||||||
|
else
|
||||||
|
EInkDisplay::endUpdate(); // Still block while updating, but EInkDisplay needs us to call endUpdate() ourselves.
|
||||||
|
}
|
||||||
|
#endif // HAS_EINK_ASYNCFULL
|
||||||
|
|
||||||
#endif // USE_EINK_DYNAMICDISPLAY
|
#endif // USE_EINK_DYNAMICDISPLAY
|
@ -44,6 +44,11 @@ class EInkDynamicDisplay : public EInkDisplay
|
|||||||
};
|
};
|
||||||
enum reasonTypes : uint8_t { // How was the decision reached
|
enum reasonTypes : uint8_t { // How was the decision reached
|
||||||
NO_OBJECTIONS,
|
NO_OBJECTIONS,
|
||||||
|
ASYNC_REFRESH_BLOCKED_DEMANDFAST,
|
||||||
|
ASYNC_REFRESH_BLOCKED_COSMETIC,
|
||||||
|
ASYNC_REFRESH_BLOCKED_RESPONSIVE,
|
||||||
|
ASYNC_REFRESH_BLOCKED_BACKGROUND,
|
||||||
|
DISPLAY_NOT_READY_FOR_FULL,
|
||||||
EXCEEDED_RATELIMIT_FAST,
|
EXCEEDED_RATELIMIT_FAST,
|
||||||
EXCEEDED_RATELIMIT_FULL,
|
EXCEEDED_RATELIMIT_FULL,
|
||||||
FLAGGED_COSMETIC,
|
FLAGGED_COSMETIC,
|
||||||
@ -64,7 +69,7 @@ class EInkDynamicDisplay : public EInkDisplay
|
|||||||
bool update(); // Trigger the display update - determine mode, then call base class
|
bool update(); // Trigger the display update - determine mode, then call base class
|
||||||
|
|
||||||
// Checks as part of determineMode()
|
// Checks as part of determineMode()
|
||||||
void checkWasFlooded(); // Was the previous frame skipped for exceeding EINK_LIMIT_RATE_RESPONSIVE_SEC?
|
void checkForPromotion(); // Was a frame skipped (rate, display busy) that should have been a FAST refresh?
|
||||||
void checkRateLimiting(); // Is this frame too soon?
|
void checkRateLimiting(); // Is this frame too soon?
|
||||||
void checkCosmetic(); // Was the COSMETIC flag set?
|
void checkCosmetic(); // Was the COSMETIC flag set?
|
||||||
void checkDemandingFast(); // Was the DEMAND_FAST flag set?
|
void checkDemandingFast(); // Was the DEMAND_FAST flag set?
|
||||||
@ -99,6 +104,14 @@ class EInkDynamicDisplay : public EInkDisplay
|
|||||||
uint8_t *dirtyPixels; // Any pixels that have been black since last full-refresh (dynamically allocated mem)
|
uint8_t *dirtyPixels; // Any pixels that have been black since last full-refresh (dynamically allocated mem)
|
||||||
uint32_t ghostPixelCount = 0; // Number of pixels with problematic ghosting. Retained here for LOG_DEBUG use
|
uint32_t ghostPixelCount = 0; // Number of pixels with problematic ghosting. Retained here for LOG_DEBUG use
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Conditional - async full refresh - only with modified meshtastic/GxEPD2
|
||||||
|
#if defined(HAS_EINK_ASYNCFULL)
|
||||||
|
void checkAsyncFullRefresh(); // Check the status of "async full-refresh"; run the post-update code if the hardware is ready
|
||||||
|
void endOrDetach(); // Run the post-update code, or delegate it off to checkAsyncFullRefresh()
|
||||||
|
void endUpdate() override {} // Disable base-class behavior of running post-update immediately after forceDisplay()
|
||||||
|
bool asyncRefreshRunning = false; // Flag, checked by checkAsyncFullRefresh()
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -39,11 +39,11 @@
|
|||||||
#if HAS_TELEMETRY
|
#if HAS_TELEMETRY
|
||||||
#include "modules/Telemetry/DeviceTelemetry.h"
|
#include "modules/Telemetry/DeviceTelemetry.h"
|
||||||
#endif
|
#endif
|
||||||
#if HAS_SENSOR && !EXCLUDE_ENVIRONMENTAL_SENSOR
|
#if HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||||
#include "modules/Telemetry/AirQualityTelemetry.h"
|
#include "modules/Telemetry/AirQualityTelemetry.h"
|
||||||
#include "modules/Telemetry/EnvironmentTelemetry.h"
|
#include "modules/Telemetry/EnvironmentTelemetry.h"
|
||||||
#endif
|
#endif
|
||||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !EXCLUDE_POWER_TELEMETRY
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
|
||||||
#include "modules/Telemetry/PowerTelemetry.h"
|
#include "modules/Telemetry/PowerTelemetry.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
@ -138,13 +138,13 @@ void setupModules()
|
|||||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
new DeviceTelemetryModule();
|
new DeviceTelemetryModule();
|
||||||
#endif
|
#endif
|
||||||
#if HAS_SENSOR && !EXCLUDE_ENVIRONMENTAL_SENSOR
|
#if HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||||
new EnvironmentTelemetryModule();
|
new EnvironmentTelemetryModule();
|
||||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) {
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) {
|
||||||
new AirQualityTelemetryModule();
|
new AirQualityTelemetryModule();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !EXCLUDE_POWER_TELEMETRY
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
|
||||||
new PowerTelemetryModule();
|
new PowerTelemetryModule();
|
||||||
#endif
|
#endif
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
|
||||||
|
@ -12,7 +12,7 @@ int32_t SHT31Sensor::runOnce()
|
|||||||
if (!hasSensor()) {
|
if (!hasSensor()) {
|
||||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||||
}
|
}
|
||||||
status = sht31.begin();
|
status = sht31.begin(nodeTelemetrySensorsMap[sensorType].first);
|
||||||
return initI2CSensor();
|
return initI2CSensor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
class SHT31Sensor : public TelemetrySensor
|
class SHT31Sensor : public TelemetrySensor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Adafruit_SHT31 sht31 = Adafruit_SHT31();
|
Adafruit_SHT31 sht31 = Adafruit_SHT31(nodeTelemetrySensorsMap[sensorType].second);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setup() override;
|
virtual void setup() override;
|
||||||
|
@ -16,7 +16,7 @@ build_flags =
|
|||||||
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
https://github.com/meshtastic/GxEPD2
|
https://github.com/meshtastic/GxEPD2/
|
||||||
adafruit/Adafruit BusIO@^1.13.2
|
adafruit/Adafruit BusIO@^1.13.2
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
@ -5,7 +5,6 @@
|
|||||||
#define I2C_SCL SCL
|
#define I2C_SCL SCL
|
||||||
|
|
||||||
#define USE_EINK
|
#define USE_EINK
|
||||||
#define EINK_NO_HIBERNATE
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* eink display pins
|
* eink display pins
|
||||||
|
@ -11,10 +11,16 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo
|
|||||||
-DEINK_DISPLAY_MODEL=GxEPD2_154_D67
|
-DEINK_DISPLAY_MODEL=GxEPD2_154_D67
|
||||||
-DEINK_WIDTH=200
|
-DEINK_WIDTH=200
|
||||||
-DEINK_HEIGHT=200
|
-DEINK_HEIGHT=200
|
||||||
|
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
|
||||||
|
-DEINK_LIMIT_FASTREFRESH=20 ; How many consecutive fast-refreshes are permitted
|
||||||
|
-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
|
||||||
|
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
|
||||||
|
-DEINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
|
||||||
|
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/t-echo>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/t-echo>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52840_base.lib_deps}
|
${nrf52840_base.lib_deps}
|
||||||
https://github.com/meshtastic/GxEPD2#afce87a97dda1ac31d8a28dc8fa7c6f55dc96a61
|
https://github.com/meshtastic/GxEPD2
|
||||||
adafruit/Adafruit BusIO@^1.13.2
|
adafruit/Adafruit BusIO@^1.13.2
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
;upload_protocol = fs
|
;upload_protocol = fs
|
||||||
|
Loading…
Reference in New Issue
Block a user