mirror of
https://github.com/meshtastic/firmware.git
synced 2025-02-26 22:33:24 +00:00
Merge branch 'master' into tft-gui-work
This commit is contained in:
commit
fb4b6329ff
@ -463,10 +463,33 @@ void EInkDynamicDisplay::onNotify(uint32_t notification)
|
||||
}
|
||||
|
||||
#ifdef HAS_EINK_ASYNCFULL
|
||||
// Run the post-update code if the hardware is ready
|
||||
// Public: wait for an refresh already in progress, then run the post-update code. See Screen::setScreensaverFrames()
|
||||
void EInkDynamicDisplay::joinAsyncRefresh()
|
||||
{
|
||||
// If no async refresh running, nothing to do
|
||||
if (!asyncRefreshRunning)
|
||||
return;
|
||||
|
||||
LOG_DEBUG("Joining an async refresh in progress\n");
|
||||
|
||||
// Continually poll the BUSY pin
|
||||
while (adafruitDisplay->epd2.isBusy())
|
||||
yield();
|
||||
|
||||
// If 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("Refresh complete\n");
|
||||
|
||||
// Note: this code only works because of a modification to meshtastic/GxEPD2.
|
||||
// It is only equipped to intercept calls to nextPage()
|
||||
}
|
||||
|
||||
// Called from NotifiedWorkerThread. Run the post-update code if the hardware is ready
|
||||
void EInkDynamicDisplay::pollAsyncRefresh()
|
||||
{
|
||||
// We shouldn't be here..
|
||||
// In theory, this condition should never be met
|
||||
if (!asyncRefreshRunning)
|
||||
return;
|
||||
|
||||
|
@ -119,20 +119,30 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
|
||||
|
||||
// Conditional - async full refresh - only with modified meshtastic/GxEPD2
|
||||
#if defined(HAS_EINK_ASYNCFULL)
|
||||
public:
|
||||
void joinAsyncRefresh(); // Main thread joins an async refresh already in progress. Blocks, then runs post-update code
|
||||
|
||||
protected:
|
||||
void pollAsyncRefresh(); // Run the post-update code if the hardware is ready
|
||||
void checkBusyAsyncRefresh(); // Check if display is busy running an async full-refresh (rejecting new frames)
|
||||
void awaitRefresh(); // Hold control while an async refresh runs
|
||||
void endUpdate() override {} // Disable base-class behavior of running post-update immediately after forceDisplay()
|
||||
bool asyncRefreshRunning = false; // Flag, checked by checkBusyAsyncRefresh()
|
||||
#else
|
||||
public:
|
||||
void joinAsyncRefresh() {} // Dummy method
|
||||
|
||||
protected:
|
||||
void pollAsyncRefresh() {} // Dummy method. In theory, not reachable
|
||||
#endif
|
||||
};
|
||||
|
||||
// Tidier calls to addFrameFlag() from outside class
|
||||
// Hide the ugly casts used in Screen.cpp
|
||||
#define EINK_ADD_FRAMEFLAG(display, flag) static_cast<EInkDynamicDisplay *>(display)->addFrameFlag(EInkDynamicDisplay::flag)
|
||||
#define EINK_JOIN_ASYNCREFRESH(display) static_cast<EInkDynamicDisplay *>(display)->joinAsyncRefresh()
|
||||
|
||||
#else // !USE_EINK_DYNAMICDISPLAY
|
||||
// Dummy-macro, removes the need for include guards
|
||||
#define EINK_ADD_FRAMEFLAG(display, flag)
|
||||
#define EINK_JOIN_ASYNCREFRESH(display)
|
||||
#endif
|
@ -1349,6 +1349,12 @@ void Screen::setScreensaverFrames(FrameCallback einkScreensaver)
|
||||
static FrameCallback screensaverFrame;
|
||||
static OverlayCallback screensaverOverlay;
|
||||
|
||||
#if defined(HAS_EINK_ASYNCFULL) && defined(USE_EINK_DYNAMICDISPLAY)
|
||||
// Join (await) a currently running async refresh, then run the post-update code.
|
||||
// Avoid skipping of screensaver frame. Would otherwise be handled by NotifiedWorkerThread.
|
||||
EINK_JOIN_ASYNCREFRESH(dispdev);
|
||||
#endif
|
||||
|
||||
// If: one-off screensaver frame passed as argument. Handles doDeepSleep()
|
||||
if (einkScreensaver != NULL) {
|
||||
screensaverFrame = einkScreensaver;
|
||||
@ -1370,10 +1376,9 @@ void Screen::setScreensaverFrames(FrameCallback einkScreensaver)
|
||||
ui->update();
|
||||
} while (ui->getUiState()->lastUpdate < startUpdate);
|
||||
|
||||
#ifndef USE_EINK_DYNAMICDISPLAY
|
||||
// Retrofit to EInkDisplay class
|
||||
delay(10);
|
||||
screen->forceDisplay();
|
||||
// Old EInkDisplay class
|
||||
#if !defined(USE_EINK_DYNAMICDISPLAY)
|
||||
static_cast<EInkDisplay *>(dispdev)->forceDisplay(0); // Screen::forceDisplay(), but override rate-limit
|
||||
#endif
|
||||
|
||||
// Prepare now for next frame, shown when display wakes
|
||||
@ -1490,8 +1495,11 @@ void Screen::handleShutdownScreen()
|
||||
{
|
||||
LOG_DEBUG("showing shutdown screen\n");
|
||||
showingNormalScreen = false;
|
||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // E-Ink: Use fast-refresh for next frame, no skip please
|
||||
#ifdef USE_EINK
|
||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // Use fast-refresh for next frame, no skip please
|
||||
EINK_ADD_FRAMEFLAG(dispdev, BLOCKING); // Edge case: if this frame is promoted to COSMETIC, wait for update
|
||||
handleSetOn(true); // Ensure power-on to receive deep-sleep screensaver (PowerFSM should handle?)
|
||||
#endif
|
||||
|
||||
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||
drawFrameText(display, state, x, y, "Shutting down...");
|
||||
@ -1499,14 +1507,17 @@ void Screen::handleShutdownScreen()
|
||||
static FrameCallback frames[] = {frame};
|
||||
|
||||
setFrameImmediateDraw(frames);
|
||||
forceDisplay();
|
||||
}
|
||||
|
||||
void Screen::handleRebootScreen()
|
||||
{
|
||||
LOG_DEBUG("showing reboot screen\n");
|
||||
showingNormalScreen = false;
|
||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // E-Ink: Explicitly use fast-refresh for next frame
|
||||
#ifdef USE_EINK
|
||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // Use fast-refresh for next frame, no skip please
|
||||
EINK_ADD_FRAMEFLAG(dispdev, BLOCKING); // Edge case: if this frame is promoted to COSMETIC, wait for update
|
||||
handleSetOn(true); // Power-on to show rebooting screen (PowerFSM should handle?)
|
||||
#endif
|
||||
|
||||
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||
drawFrameText(display, state, x, y, "Rebooting...");
|
||||
|
@ -150,7 +150,7 @@ class Screen : public concurrency::OSThread
|
||||
// We handle off commands immediately, because they might be called because the CPU is shutting down
|
||||
handleSetOn(false, einkScreensaver);
|
||||
else
|
||||
enqueueCmd(ScreenCmd{.cmd = on ? Cmd::SET_ON : Cmd::SET_OFF});
|
||||
enqueueCmd(ScreenCmd{.cmd = Cmd::SET_ON});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,8 +114,8 @@ size_t NeighborInfoModule::cleanUpNeighbors()
|
||||
(*numNeighbors)--;
|
||||
}
|
||||
|
||||
// Save the neighbor list if we removed any neighbors
|
||||
if (indices_to_remove.size() > 0) {
|
||||
// Save the neighbor list if we removed any neighbors or neighbors were already updated upon receiving a packet
|
||||
if (indices_to_remove.size() > 0 || shouldSave) {
|
||||
saveProtoForModule();
|
||||
}
|
||||
|
||||
@ -210,7 +210,6 @@ meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSen
|
||||
// Only if this is the original sender, the broadcast interval corresponds to it
|
||||
if (originalSender == n && node_broadcast_interval_secs != 0)
|
||||
nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
|
||||
saveProtoForModule(); // Save the updated neighbor
|
||||
return nbr;
|
||||
}
|
||||
}
|
||||
@ -228,7 +227,7 @@ meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSen
|
||||
new_nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
|
||||
else // Assume the same broadcast interval as us for the neighbor if we don't know it
|
||||
new_nbr->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
||||
saveProtoForModule(); // Save the new neighbor
|
||||
shouldSave = true; // Save the new neighbor upon next cleanup
|
||||
return new_nbr;
|
||||
}
|
||||
|
||||
@ -255,6 +254,8 @@ bool NeighborInfoModule::saveProtoForModule()
|
||||
#endif
|
||||
|
||||
okay &= nodeDB->saveProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, &meshtastic_NeighborInfo_msg, &neighborState);
|
||||
if (okay)
|
||||
shouldSave = false;
|
||||
|
||||
return okay;
|
||||
}
|
@ -20,6 +20,9 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
|
||||
|
||||
bool saveProtoForModule();
|
||||
|
||||
private:
|
||||
bool shouldSave = false; // Whether we should save the neighbor info to flash
|
||||
|
||||
protected:
|
||||
// Note: this holds our local info.
|
||||
meshtastic_NeighborInfo neighborState;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "NRF52Bluetooth.h"
|
||||
#include "BluetoothCommon.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "mesh/PhoneAPI.h"
|
||||
@ -318,6 +319,7 @@ void NRF52Bluetooth::onConnectionSecured(uint16_t conn_handle)
|
||||
bool NRF52Bluetooth::onPairingPasskey(uint16_t conn_handle, uint8_t const passkey[6], bool match_request)
|
||||
{
|
||||
LOG_INFO("BLE pairing process started with passkey %.3s %.3s\n", passkey, passkey + 3);
|
||||
powerFSM.trigger(EVENT_BLUETOOTH_PAIR);
|
||||
screen->startBluetoothPinScreen(configuredPasskey);
|
||||
|
||||
if (match_request) {
|
||||
|
Loading…
Reference in New Issue
Block a user