mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-06 01:48:13 +00:00
Compare commits
1 Commits
v2.7.3.cf5
...
casic-clea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
225c47ede3 |
@@ -1539,6 +1539,13 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
||||
if (perhapsSetRTC(RTCQualityGPS, t) == RTCSetResultInvalidTime) {
|
||||
// Clear the GPS buffer if we got an invalid time
|
||||
clearBuffer();
|
||||
// Clear the RTC from the L76K, L76B, and clones
|
||||
if (IS_ONE_OF(gnssModel, GNSS_MODEL_MTK_L76B, GNSS_MODEL_MTK)) {
|
||||
// Clear the RTC from the L76 and MTK GPS modules
|
||||
LOG_DEBUG("Clearing RTC from L76K/L76B");
|
||||
int msglen = makeCASPacket(0x06, 0x02, sizeof(_message_CAS_CFG_RST_FACTORY), _message_CAS_CFG_RST_FACTORY);
|
||||
_serial_gps->write(_message_CAS_CFG_RST_FACTORY, msglen);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
|
||||
@@ -226,14 +226,7 @@ RTCSetResult perhapsSetRTC(RTCQuality q, struct tm &t)
|
||||
time_t res = gm_mktime(&t);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = res;
|
||||
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
||||
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
||||
#ifdef BUILD_EPOCH
|
||||
if (tv.tv_sec < BUILD_EPOCH) {
|
||||
LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
|
||||
return RTCSetResultInvalidTime;
|
||||
}
|
||||
#endif
|
||||
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
||||
|
||||
// LOG_DEBUG("Got time from GPS month=%d, year=%d, unixtime=%ld", t.tm_mon, t.tm_year, tv.tv_sec);
|
||||
if (t.tm_year < 0 || t.tm_year >= 300) {
|
||||
|
||||
@@ -27,6 +27,13 @@ static const uint8_t _message_CAS_CFG_RST_FACTORY[] = {
|
||||
0x03 // Startup Mode: Factory
|
||||
};
|
||||
|
||||
// Clear RTC data
|
||||
static const uint8_t _message_CAS_CFG_RST_RTC[] = {
|
||||
0x00, 0x01, // NavBbrMask: Clear RTC data
|
||||
0x01, // Reset Mode: Controlled Software reset
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// CFG_RATE (0x06, 0x01)
|
||||
// 1HZ update rate, this should always be the case after
|
||||
// factory reset but update it regardless
|
||||
|
||||
@@ -864,8 +864,6 @@ void Screen::setFrames(FrameFocus focus)
|
||||
uint8_t previousFrameCount = framesetInfo.frameCount;
|
||||
FramesetInfo fsi; // Location of specific frames, for applying focus parameter
|
||||
|
||||
graphics::UIRenderer::rebuildFavoritedNodes();
|
||||
|
||||
LOG_DEBUG("Show standard frames");
|
||||
showingNormalScreen = true;
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
|
||||
}
|
||||
|
||||
// ****************************
|
||||
// * System Screen *
|
||||
// * Memory Screen *
|
||||
// ****************************
|
||||
void drawMemoryUsage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
@@ -593,19 +593,7 @@ void drawMemoryUsage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
|
||||
}
|
||||
line += 1;
|
||||
char appversionstr[35];
|
||||
snprintf(appversionstr, sizeof(appversionstr), "Ver: %s", optstr(APP_VERSION));
|
||||
char appversionstr_formatted[40];
|
||||
char *lastDot = strrchr(appversionstr, '.');
|
||||
if (lastDot) {
|
||||
size_t prefixLen = lastDot - appversionstr;
|
||||
strncpy(appversionstr_formatted, appversionstr, prefixLen);
|
||||
appversionstr_formatted[prefixLen] = '\0';
|
||||
strncat(appversionstr_formatted, " (", sizeof(appversionstr_formatted) - strlen(appversionstr_formatted) - 1);
|
||||
strncat(appversionstr_formatted, lastDot + 1, sizeof(appversionstr_formatted) - strlen(appversionstr_formatted) - 1);
|
||||
strncat(appversionstr_formatted, ")", sizeof(appversionstr_formatted) - strlen(appversionstr_formatted) - 1);
|
||||
strncpy(appversionstr, appversionstr_formatted, sizeof(appversionstr) - 1);
|
||||
appversionstr[sizeof(appversionstr) - 1] = '\0';
|
||||
}
|
||||
snprintf(appversionstr, sizeof(appversionstr), "Ver.: %s", optstr(APP_VERSION));
|
||||
int textWidth = display->getStringWidth(appversionstr);
|
||||
int nameX = (SCREEN_WIDTH - textWidth) / 2;
|
||||
display->drawString(nameX, getTextPositions(display)[line], appversionstr);
|
||||
|
||||
@@ -375,6 +375,12 @@ void menuHandler::textMessageBaseMenu()
|
||||
|
||||
void menuHandler::systemBaseMenu()
|
||||
{
|
||||
// Check if brightness is supported
|
||||
bool hasSupportBrightness = false;
|
||||
#if defined(ST7789_CS) || defined(USE_OLED) || defined(USE_SSD1306) || defined(USE_SH1106) || defined(USE_SH1107) || HAS_TFT
|
||||
hasSupportBrightness = true;
|
||||
#endif
|
||||
|
||||
enum optionsNumbers { Back, Notifications, ScreenOptions, PowerMenu, Test, enumEnd };
|
||||
static const char *optionsArray[enumEnd] = {"Back"};
|
||||
static int optionsEnumArray[enumEnd] = {Back};
|
||||
@@ -444,11 +450,11 @@ void menuHandler::favoriteBaseMenu()
|
||||
bannerOptions.optionsEnumPtr = optionsEnumArray;
|
||||
bannerOptions.optionsCount = options;
|
||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||
if (selected == Preset) {
|
||||
if (selected == 1) {
|
||||
cannedMessageModule->LaunchWithDestination(graphics::UIRenderer::currentFavoriteNodeNum);
|
||||
} else if (selected == Freetext) {
|
||||
} else if (selected == 2 && kb_found) {
|
||||
cannedMessageModule->LaunchFreetextWithDestination(graphics::UIRenderer::currentFavoriteNodeNum);
|
||||
} else if (selected == Remove) {
|
||||
} else if ((!kb_found && selected == 2) || (selected == 3 && kb_found)) {
|
||||
menuHandler::menuQueue = menuHandler::remove_favorite;
|
||||
screen->runNow();
|
||||
}
|
||||
@@ -701,7 +707,6 @@ void menuHandler::TFTColorPickerMenu(OLEDDisplay *display)
|
||||
bannerOptions.optionsArrayPtr = optionsArray;
|
||||
bannerOptions.optionsCount = 10;
|
||||
bannerOptions.bannerCallback = [display](int selected) -> void {
|
||||
#if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) || defined(T_DECK) || HAS_TFT
|
||||
uint8_t TFT_MESH_r = 0;
|
||||
uint8_t TFT_MESH_g = 0;
|
||||
uint8_t TFT_MESH_b = 0;
|
||||
@@ -753,6 +758,7 @@ void menuHandler::TFTColorPickerMenu(OLEDDisplay *display)
|
||||
screen->runNow();
|
||||
}
|
||||
|
||||
#if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) || defined(T_DECK) || HAS_TFT
|
||||
if (selected != 0) {
|
||||
display->setColor(BLACK);
|
||||
display->fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
@@ -850,9 +856,8 @@ void menuHandler::removeFavoriteMenu()
|
||||
bannerOptions.optionsCount = 2;
|
||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||
if (selected == 1) {
|
||||
LOG_INFO("Removing %x as favorite node", graphics::UIRenderer::currentFavoriteNodeNum);
|
||||
nodeDB->set_favorite(false, graphics::UIRenderer::currentFavoriteNodeNum);
|
||||
screen->setFrames(graphics::Screen::FOCUS_DEFAULT);
|
||||
screen->setFrames(graphics::Screen::FOCUS_PRESERVE);
|
||||
}
|
||||
};
|
||||
screen->showOverlayBanner(bannerOptions);
|
||||
|
||||
@@ -156,7 +156,7 @@ void NotificationRenderer::drawNumberPicker(OLEDDisplay *display, OLEDDisplayUiS
|
||||
resetBanner();
|
||||
return;
|
||||
}
|
||||
if (curSelected == static_cast<int8_t>(numDigits)) {
|
||||
if (curSelected == numDigits) {
|
||||
alertBannerCallback(currentNumber);
|
||||
resetBanner();
|
||||
return;
|
||||
|
||||
@@ -24,23 +24,6 @@ extern graphics::Screen *screen;
|
||||
namespace graphics
|
||||
{
|
||||
NodeNum UIRenderer::currentFavoriteNodeNum = 0;
|
||||
std::vector<meshtastic_NodeInfoLite *> graphics::UIRenderer::favoritedNodes;
|
||||
|
||||
void graphics::UIRenderer::rebuildFavoritedNodes()
|
||||
{
|
||||
favoritedNodes.clear();
|
||||
size_t total = nodeDB->getNumMeshNodes();
|
||||
for (size_t i = 0; i < total; i++) {
|
||||
meshtastic_NodeInfoLite *n = nodeDB->getMeshNodeByIndex(i);
|
||||
if (!n || n->num == nodeDB->getNodeNum())
|
||||
continue;
|
||||
if (n->is_favorite)
|
||||
favoritedNodes.push_back(n);
|
||||
}
|
||||
|
||||
std::sort(favoritedNodes.begin(), favoritedNodes.end(),
|
||||
[](const meshtastic_NodeInfoLite *a, const meshtastic_NodeInfoLite *b) { return a->num < b->num; });
|
||||
}
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_GPS
|
||||
// GeoCoord object for coordinate conversions
|
||||
@@ -218,7 +201,27 @@ void UIRenderer::drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const mes
|
||||
// **********************
|
||||
void UIRenderer::drawNodeInfo(OLEDDisplay *display, const OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
// --- Cache favorite nodes for the current frame only, to save computation ---
|
||||
static std::vector<meshtastic_NodeInfoLite *> favoritedNodes;
|
||||
static int prevFrame = -1;
|
||||
|
||||
// --- Only rebuild favorites list if we're on a new frame ---
|
||||
if (state->currentFrame != prevFrame) {
|
||||
prevFrame = state->currentFrame;
|
||||
favoritedNodes.clear();
|
||||
size_t total = nodeDB->getNumMeshNodes();
|
||||
for (size_t i = 0; i < total; i++) {
|
||||
meshtastic_NodeInfoLite *n = nodeDB->getMeshNodeByIndex(i);
|
||||
// Skip nulls and ourself
|
||||
if (!n || n->num == nodeDB->getNodeNum())
|
||||
continue;
|
||||
if (n->is_favorite)
|
||||
favoritedNodes.push_back(n);
|
||||
}
|
||||
// Keep a stable, consistent display order
|
||||
std::sort(favoritedNodes.begin(), favoritedNodes.end(),
|
||||
[](const meshtastic_NodeInfoLite *a, const meshtastic_NodeInfoLite *b) { return a->num < b->num; });
|
||||
}
|
||||
if (favoritedNodes.empty())
|
||||
return;
|
||||
|
||||
@@ -654,7 +657,7 @@ void UIRenderer::drawDeviceFocused(OLEDDisplay *display, OLEDDisplayUiState *sta
|
||||
|
||||
char combinedName[50];
|
||||
snprintf(combinedName, sizeof(combinedName), "%s (%s)", longNameStr.empty() ? "" : longNameStr.c_str(), shortnameble);
|
||||
if (SCREEN_WIDTH - (display->getStringWidth(combinedName)) > 10) {
|
||||
if (SCREEN_WIDTH - (display->getStringWidth(longName) + display->getStringWidth(shortnameble)) > 10) {
|
||||
size_t len = strlen(combinedName);
|
||||
if (len >= 3 && strcmp(combinedName + len - 3, " ()") == 0) {
|
||||
combinedName[len - 3] = '\0'; // Remove the last three characters
|
||||
@@ -665,7 +668,7 @@ void UIRenderer::drawDeviceFocused(OLEDDisplay *display, OLEDDisplayUiState *sta
|
||||
nameX, ((rows == 4) ? getTextPositions(display)[line++] : getTextPositions(display)[line++]) + yOffset, combinedName);
|
||||
} else {
|
||||
// === LongName Centered ===
|
||||
textWidth = display->getStringWidth(longNameStr.c_str());
|
||||
textWidth = display->getStringWidth(longName);
|
||||
nameX = (SCREEN_WIDTH - textWidth) / 2;
|
||||
display->drawString(nameX, getTextPositions(display)[line++], longNameStr.c_str());
|
||||
|
||||
|
||||
@@ -61,8 +61,6 @@ class UIRenderer
|
||||
static void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||
|
||||
static NodeNum currentFavoriteNodeNum;
|
||||
static std::vector<meshtastic_NodeInfoLite *> favoritedNodes;
|
||||
static void rebuildFavoritedNodes();
|
||||
|
||||
// OEM screens
|
||||
#ifdef USERPREFS_OEM_TEXT
|
||||
|
||||
@@ -67,5 +67,4 @@ void CardKbI2cImpl::init()
|
||||
}
|
||||
#endif
|
||||
inputBroker->registerSource(this);
|
||||
kb_found = true;
|
||||
}
|
||||
@@ -850,13 +850,7 @@ void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const cha
|
||||
this->waitingForAck = true;
|
||||
|
||||
// Log outgoing message
|
||||
LOG_INFO("Send message id=%u, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||
|
||||
if (p->to != 0xffffffff) {
|
||||
LOG_INFO("Proactively adding %x as favorite node", p->to);
|
||||
nodeDB->set_favorite(true, p->to);
|
||||
screen->setFrames(graphics::Screen::FOCUS_PRESERVE);
|
||||
}
|
||||
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||
|
||||
// Send to mesh and phone (even if no phone connected, to track ACKs)
|
||||
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
|
||||
Reference in New Issue
Block a user