mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-25 22:20:27 +00:00
only show time on OLED if we have a valid UTC clock
This commit is contained in:
parent
620d336e55
commit
2b74260e2b
@ -11,11 +11,15 @@ You probably don't care about this section - skip to the next one.
|
|||||||
* DONE channel sharing in android
|
* DONE channel sharing in android
|
||||||
* DONE test 1.0 firmware update on android
|
* DONE test 1.0 firmware update on android
|
||||||
* DONE test 1.1 firmware update on android
|
* DONE test 1.1 firmware update on android
|
||||||
* test 1.2.10 firmware update on android
|
* DONE test 1.2.10 firmware update on android
|
||||||
* DONE test link sharing on android
|
* DONE test link sharing on android
|
||||||
* luxon bug report - seeing rx acks for nodes that are not on the network
|
* luxon bug report - seeing rx acks for nodes that are not on the network
|
||||||
* document how to do remote admin
|
* document how to do remote admin
|
||||||
* release py, android, device
|
* release py
|
||||||
|
* DONE show GPS time only if we know what global time is
|
||||||
|
* android should always provide time to nodes - so that it is easier for the mesh to learn the current time
|
||||||
|
* nrf52 should preserve local time across reset
|
||||||
|
* firmware OTA updates of is_router true nodes fails?
|
||||||
|
|
||||||
## 1.2 cleanup & multichannel support:
|
## 1.2 cleanup & multichannel support:
|
||||||
|
|
||||||
|
@ -1,58 +1,56 @@
|
|||||||
#include "RedirectablePrint.h"
|
#include "RedirectablePrint.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "RTC.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A printer that doesn't go anywhere
|
* A printer that doesn't go anywhere
|
||||||
*/
|
*/
|
||||||
NoopPrint noopPrint;
|
NoopPrint noopPrint;
|
||||||
|
|
||||||
void RedirectablePrint::setDestination(Print *_dest) {
|
void RedirectablePrint::setDestination(Print *_dest)
|
||||||
assert(_dest);
|
{
|
||||||
dest = _dest;
|
assert(_dest);
|
||||||
|
dest = _dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RedirectablePrint::write(uint8_t c) {
|
size_t RedirectablePrint::write(uint8_t c)
|
||||||
// Always send the characters to our segger JTAG debugger
|
{
|
||||||
|
// Always send the characters to our segger JTAG debugger
|
||||||
#ifdef SEGGER_STDOUT_CH
|
#ifdef SEGGER_STDOUT_CH
|
||||||
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
|
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dest->write(c);
|
dest->write(c);
|
||||||
return 1; // We always claim one was written, rather than trusting what the
|
return 1; // We always claim one was written, rather than trusting what the
|
||||||
// serial port said (which could be zero)
|
// serial port said (which could be zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
va_list copy;
|
va_list copy;
|
||||||
|
|
||||||
va_copy(copy, arg);
|
|
||||||
int len = vsnprintf(printBuf, printBufLen, format, copy);
|
|
||||||
va_end(copy);
|
|
||||||
if (len < 0) {
|
|
||||||
va_end(arg);
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
if (len >= printBufLen) {
|
|
||||||
delete[] printBuf;
|
|
||||||
printBufLen *= 2;
|
|
||||||
printBuf = new char[printBufLen];
|
|
||||||
len = vsnprintf(printBuf, printBufLen, format, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = Print::write(printBuf, len);
|
va_copy(copy, arg);
|
||||||
return len;
|
int len = vsnprintf(printBuf, printBufLen, format, copy);
|
||||||
|
va_end(copy);
|
||||||
|
if (len < 0) {
|
||||||
|
va_end(arg);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
if (len >= printBufLen) {
|
||||||
|
delete[] printBuf;
|
||||||
|
printBufLen *= 2;
|
||||||
|
printBuf = new char[printBufLen];
|
||||||
|
len = vsnprintf(printBuf, printBufLen, format, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = Print::write(printBuf, len);
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SEC_PER_DAY 86400
|
|
||||||
#define SEC_PER_HOUR 3600
|
|
||||||
#define SEC_PER_MIN 60
|
|
||||||
|
|
||||||
size_t RedirectablePrint::logDebug(const char *format, ...)
|
size_t RedirectablePrint::logDebug(const char *format, ...)
|
||||||
{
|
{
|
||||||
size_t r = 0;
|
size_t r = 0;
|
||||||
@ -70,7 +68,7 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
|
|||||||
if (!isContinuationMessage) {
|
if (!isContinuationMessage) {
|
||||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
|
||||||
if (rtc_sec > 0) {
|
if (rtc_sec > 0) {
|
||||||
long hms =rtc_sec % SEC_PER_DAY;
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||||
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
||||||
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
||||||
@ -102,5 +100,5 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
|
|||||||
inDebugPrint = false;
|
inDebugPrint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
@ -27,4 +27,8 @@ uint32_t getTime();
|
|||||||
/// Return time since 1970 in secs. If quality is RTCQualityNone return zero
|
/// Return time since 1970 in secs. If quality is RTCQualityNone return zero
|
||||||
uint32_t getValidTime(RTCQuality minQuality);
|
uint32_t getValidTime(RTCQuality minQuality);
|
||||||
|
|
||||||
void readFromRTC();
|
void readFromRTC();
|
||||||
|
|
||||||
|
#define SEC_PER_DAY 86400
|
||||||
|
#define SEC_PER_HOUR 3600
|
||||||
|
#define SEC_PER_MIN 60
|
@ -28,11 +28,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
|
#include "gps/RTC.h"
|
||||||
#include "graphics/images.h"
|
#include "graphics/images.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "plugins/TextMessagePlugin.h"
|
|
||||||
#include "mesh/Channels.h"
|
#include "mesh/Channels.h"
|
||||||
|
#include "plugins/TextMessagePlugin.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@ -155,24 +156,22 @@ static void drawPluginFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int
|
|||||||
{
|
{
|
||||||
uint8_t plugin_frame;
|
uint8_t plugin_frame;
|
||||||
// there's a little but in the UI transition code
|
// there's a little but in the UI transition code
|
||||||
// where it invokes the function at the correct offset
|
// where it invokes the function at the correct offset
|
||||||
// in the array of "drawScreen" functions; however,
|
// in the array of "drawScreen" functions; however,
|
||||||
// the passed-state doesn't quite reflect the "current"
|
// the passed-state doesn't quite reflect the "current"
|
||||||
// screen, so we have to detect it.
|
// screen, so we have to detect it.
|
||||||
if (state->frameState == IN_TRANSITION && state->transitionFrameRelationship == INCOMING) {
|
if (state->frameState == IN_TRANSITION && state->transitionFrameRelationship == INCOMING) {
|
||||||
// if we're transitioning from the end of the frame list back around to the first
|
// if we're transitioning from the end of the frame list back around to the first
|
||||||
// frame, then we want this to be `0`
|
// frame, then we want this to be `0`
|
||||||
plugin_frame = state->transitionFrameTarget;
|
plugin_frame = state->transitionFrameTarget;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// otherwise, just display the plugin frame that's aligned with the current frame
|
// otherwise, just display the plugin frame that's aligned with the current frame
|
||||||
plugin_frame = state->currentFrame;
|
plugin_frame = state->currentFrame;
|
||||||
//DEBUG_MSG("Screen is not in transition. Frame: %d\n\n", plugin_frame);
|
// DEBUG_MSG("Screen is not in transition. Frame: %d\n\n", plugin_frame);
|
||||||
}
|
}
|
||||||
//DEBUG_MSG("Drawing Plugin Frame %d\n\n", plugin_frame);
|
// DEBUG_MSG("Drawing Plugin Frame %d\n\n", plugin_frame);
|
||||||
MeshPlugin &pi = *pluginFrames.at(plugin_frame);
|
MeshPlugin &pi = *pluginFrames.at(plugin_frame);
|
||||||
pi.drawFrame(display,state,x,y);
|
pi.drawFrame(display, state, x, y);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
@ -204,11 +203,10 @@ static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
|||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait...");
|
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait...");
|
||||||
|
|
||||||
//display->setFont(FONT_LARGE);
|
// display->setFont(FONT_LARGE);
|
||||||
//display->drawString(64 + x, 26 + y, btPIN);
|
// display->drawString(64 + x, 26 + y, btPIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Draw the last text message we received
|
/// Draw the last text message we received
|
||||||
static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
@ -793,7 +791,7 @@ void Screen::setup()
|
|||||||
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
||||||
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
|
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
|
||||||
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
||||||
if(textMessagePlugin)
|
if (textMessagePlugin)
|
||||||
textMessageObserver.observe(textMessagePlugin);
|
textMessageObserver.observe(textMessagePlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -842,7 +840,7 @@ int32_t Screen::runOnce()
|
|||||||
break;
|
break;
|
||||||
case Cmd::START_FIRMWARE_UPDATE_SCREEN:
|
case Cmd::START_FIRMWARE_UPDATE_SCREEN:
|
||||||
handleStartFirmwareUpdateScreen();
|
handleStartFirmwareUpdateScreen();
|
||||||
break;
|
break;
|
||||||
case Cmd::STOP_BLUETOOTH_PIN_SCREEN:
|
case Cmd::STOP_BLUETOOTH_PIN_SCREEN:
|
||||||
case Cmd::STOP_BOOT_SCREEN:
|
case Cmd::STOP_BOOT_SCREEN:
|
||||||
setFrames();
|
setFrames();
|
||||||
@ -936,7 +934,7 @@ void Screen::setFrames()
|
|||||||
for (auto i = pluginFrames.begin(); i != pluginFrames.end(); ++i) {
|
for (auto i = pluginFrames.begin(); i != pluginFrames.end(); ++i) {
|
||||||
normalFrames[numframes++] = drawPluginFrame;
|
normalFrames[numframes++] = drawPluginFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_MSG("Added plugins. numframes: %d\n", numframes);
|
DEBUG_MSG("Added plugins. numframes: %d\n", numframes);
|
||||||
|
|
||||||
// If we have a critical fault, show it first
|
// If we have a critical fault, show it first
|
||||||
@ -1286,14 +1284,41 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
uint32_t minutes = seconds / 60;
|
uint32_t minutes = seconds / 60;
|
||||||
uint32_t hours = minutes / 60;
|
uint32_t hours = minutes / 60;
|
||||||
uint32_t days = hours / 24;
|
uint32_t days = hours / 24;
|
||||||
currentMillis %= 1000;
|
// currentMillis %= 1000;
|
||||||
seconds %= 60;
|
// seconds %= 60;
|
||||||
minutes %= 60;
|
// minutes %= 60;
|
||||||
hours %= 24;
|
// hours %= 24;
|
||||||
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
|
// Show uptime as days, hours, minutes OR seconds
|
||||||
String(days) + "d " + (hours < 10 ? "0" : "") + String(hours) + ":" + (minutes < 10 ? "0" : "") +
|
String uptime;
|
||||||
String(minutes) + ":" + (seconds < 10 ? "0" : "") + String(seconds));
|
if (days >= 2)
|
||||||
|
uptime += String(days) + "d ";
|
||||||
|
else if (hours >= 2)
|
||||||
|
uptime += String(hours) + "h ";
|
||||||
|
else if (minutes >= 1)
|
||||||
|
uptime += String(minutes) + "m ";
|
||||||
|
else
|
||||||
|
uptime += String(seconds) + "s ";
|
||||||
|
|
||||||
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
|
||||||
|
if (rtc_sec > 0) {
|
||||||
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
|
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||||
|
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
||||||
|
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
||||||
|
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||||
|
|
||||||
|
// Tear apart hms into h:m:s
|
||||||
|
int hour = hms / SEC_PER_HOUR;
|
||||||
|
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||||
|
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||||
|
|
||||||
|
char timebuf[9];
|
||||||
|
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d", hour, min, sec);
|
||||||
|
uptime += timebuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, uptime);
|
||||||
|
|
||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
// Show CPU Frequency.
|
// Show CPU Frequency.
|
||||||
|
Loading…
Reference in New Issue
Block a user