feat: Add central logging pragma (#843)

## Summary

* Definition and use of a central LOG function, that can later be
extended or completely be removed (for public use where debugging
information may not be required) to save flash by suppressing the
-DENABLE_SERIAL_LOG like in the slim branch

* **What changes are included?**

## Additional Context
* By using the central logger the usual:
```
#include <HardwareSerial.h>
...
  Serial.printf("[%lu] [WCS] Obfuscating/deobfuscating %zu bytes\n", millis(), data.size());
```
would then become
```
#include <Logging.h>
...
  LOG_DBG("WCS", "Obfuscating/deobfuscating %zu bytes", data.size());
```
You do have ``LOG_DBG`` for debug messages, ``LOG_ERR`` for error
messages and ``LOG_INF`` for informational messages. Depending on the
verbosity level defined (see below) soe of these message types will be
suppressed/not-compiled.

* The normal compilation (default) will create a firmware.elf file of
42.194.356 bytes, the same code via slim will create 42.024.048 bytes -
170.308 bytes less
* Firmware.bin : 6.469.984 bytes for default, 6.418.672 bytes for slim -
51.312 bytes less


### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _NO_

---------

Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
This commit is contained in:
jpirnay
2026-02-13 12:16:39 +01:00
committed by GitHub
parent 7a385d78a4
commit cb24947477
50 changed files with 795 additions and 688 deletions

View File

@@ -1,6 +1,6 @@
#pragma once
#include <HardwareSerial.h>
#include <Logging.h>
#include <string>
#include <utility>
@@ -18,8 +18,8 @@ class Activity {
explicit Activity(std::string name, GfxRenderer& renderer, MappedInputManager& mappedInput)
: name(std::move(name)), renderer(renderer), mappedInput(mappedInput) {}
virtual ~Activity() = default;
virtual void onEnter() { Serial.printf("[%lu] [ACT] Entering activity: %s\n", millis(), name.c_str()); }
virtual void onExit() { Serial.printf("[%lu] [ACT] Exiting activity: %s\n", millis(), name.c_str()); }
virtual void onEnter() { LOG_DBG("ACT", "Entering activity: %s", name.c_str()); }
virtual void onExit() { LOG_DBG("ACT", "Exiting activity: %s", name.c_str()); }
virtual void loop() {}
virtual bool skipLoopDelay() { return false; }
virtual bool preventAutoSleep() { return false; }

View File

@@ -50,13 +50,13 @@ void SleepActivity::renderCustomSleepScreen() const {
}
if (filename.substr(filename.length() - 4) != ".bmp") {
Serial.printf("[%lu] [SLP] Skipping non-.bmp file name: %s\n", millis(), name);
LOG_DBG("SLP", "Skipping non-.bmp file name: %s", name);
file.close();
continue;
}
Bitmap bitmap(file);
if (bitmap.parseHeaders() != BmpReaderError::Ok) {
Serial.printf("[%lu] [SLP] Skipping invalid BMP file: %s\n", millis(), name);
LOG_DBG("SLP", "Skipping invalid BMP file: %s", name);
file.close();
continue;
}
@@ -76,7 +76,7 @@ void SleepActivity::renderCustomSleepScreen() const {
const auto filename = "/sleep/" + files[randomFileIndex];
FsFile file;
if (Storage.openFileForRead("SLP", filename, file)) {
Serial.printf("[%lu] [SLP] Randomly loading: /sleep/%s\n", millis(), files[randomFileIndex].c_str());
LOG_DBG("SLP", "Randomly loading: /sleep/%s", files[randomFileIndex].c_str());
delay(100);
Bitmap bitmap(file, true);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
@@ -95,7 +95,7 @@ void SleepActivity::renderCustomSleepScreen() const {
if (Storage.openFileForRead("SLP", "/sleep.bmp", file)) {
Bitmap bitmap(file, true);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
Serial.printf("[%lu] [SLP] Loading: /sleep.bmp\n", millis());
LOG_DBG("SLP", "Loading: /sleep.bmp");
renderBitmapSleepScreen(bitmap);
return;
}
@@ -127,34 +127,33 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap) const {
const auto pageHeight = renderer.getScreenHeight();
float cropX = 0, cropY = 0;
Serial.printf("[%lu] [SLP] bitmap %d x %d, screen %d x %d\n", millis(), bitmap.getWidth(), bitmap.getHeight(),
pageWidth, pageHeight);
LOG_DBG("SLP", "bitmap %d x %d, screen %d x %d", bitmap.getWidth(), bitmap.getHeight(), pageWidth, pageHeight);
if (bitmap.getWidth() > pageWidth || bitmap.getHeight() > pageHeight) {
// image will scale, make sure placement is right
float ratio = static_cast<float>(bitmap.getWidth()) / static_cast<float>(bitmap.getHeight());
const float screenRatio = static_cast<float>(pageWidth) / static_cast<float>(pageHeight);
Serial.printf("[%lu] [SLP] bitmap ratio: %f, screen ratio: %f\n", millis(), ratio, screenRatio);
LOG_DBG("SLP", "bitmap ratio: %f, screen ratio: %f", ratio, screenRatio);
if (ratio > screenRatio) {
// image wider than viewport ratio, scaled down image needs to be centered vertically
if (SETTINGS.sleepScreenCoverMode == CrossPointSettings::SLEEP_SCREEN_COVER_MODE::CROP) {
cropX = 1.0f - (screenRatio / ratio);
Serial.printf("[%lu] [SLP] Cropping bitmap x: %f\n", millis(), cropX);
LOG_DBG("SLP", "Cropping bitmap x: %f", cropX);
ratio = (1.0f - cropX) * static_cast<float>(bitmap.getWidth()) / static_cast<float>(bitmap.getHeight());
}
x = 0;
y = std::round((static_cast<float>(pageHeight) - static_cast<float>(pageWidth) / ratio) / 2);
Serial.printf("[%lu] [SLP] Centering with ratio %f to y=%d\n", millis(), ratio, y);
LOG_DBG("SLP", "Centering with ratio %f to y=%d", ratio, y);
} else {
// image taller than viewport ratio, scaled down image needs to be centered horizontally
if (SETTINGS.sleepScreenCoverMode == CrossPointSettings::SLEEP_SCREEN_COVER_MODE::CROP) {
cropY = 1.0f - (ratio / screenRatio);
Serial.printf("[%lu] [SLP] Cropping bitmap y: %f\n", millis(), cropY);
LOG_DBG("SLP", "Cropping bitmap y: %f", cropY);
ratio = static_cast<float>(bitmap.getWidth()) / ((1.0f - cropY) * static_cast<float>(bitmap.getHeight()));
}
x = std::round((static_cast<float>(pageWidth) - static_cast<float>(pageHeight) * ratio) / 2);
y = 0;
Serial.printf("[%lu] [SLP] Centering with ratio %f to x=%d\n", millis(), ratio, x);
LOG_DBG("SLP", "Centering with ratio %f to x=%d", ratio, x);
}
} else {
// center the image
@@ -162,7 +161,7 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap) const {
y = (pageHeight - bitmap.getHeight()) / 2;
}
Serial.printf("[%lu] [SLP] drawing to %d x %d\n", millis(), x, y);
LOG_DBG("SLP", "drawing to %d x %d", x, y);
renderer.clearScreen();
const bool hasGreyscale = bitmap.hasGreyscale() &&
@@ -218,12 +217,12 @@ void SleepActivity::renderCoverSleepScreen() const {
// Handle XTC file
Xtc lastXtc(APP_STATE.openEpubPath, "/.crosspoint");
if (!lastXtc.load()) {
Serial.printf("[%lu] [SLP] Failed to load last XTC\n", millis());
LOG_ERR("SLP", "Failed to load last XTC");
return (this->*renderNoCoverSleepScreen)();
}
if (!lastXtc.generateCoverBmp()) {
Serial.printf("[%lu] [SLP] Failed to generate XTC cover bmp\n", millis());
LOG_ERR("SLP", "Failed to generate XTC cover bmp");
return (this->*renderNoCoverSleepScreen)();
}
@@ -232,12 +231,12 @@ void SleepActivity::renderCoverSleepScreen() const {
// Handle TXT file - looks for cover image in the same folder
Txt lastTxt(APP_STATE.openEpubPath, "/.crosspoint");
if (!lastTxt.load()) {
Serial.printf("[%lu] [SLP] Failed to load last TXT\n", millis());
LOG_ERR("SLP", "Failed to load last TXT");
return (this->*renderNoCoverSleepScreen)();
}
if (!lastTxt.generateCoverBmp()) {
Serial.printf("[%lu] [SLP] No cover image found for TXT file\n", millis());
LOG_ERR("SLP", "No cover image found for TXT file");
return (this->*renderNoCoverSleepScreen)();
}
@@ -247,12 +246,12 @@ void SleepActivity::renderCoverSleepScreen() const {
Epub lastEpub(APP_STATE.openEpubPath, "/.crosspoint");
// Skip loading css since we only need metadata here
if (!lastEpub.load(true, true)) {
Serial.printf("[%lu] [SLP] Failed to load last epub\n", millis());
LOG_ERR("SLP", "Failed to load last epub");
return (this->*renderNoCoverSleepScreen)();
}
if (!lastEpub.generateCoverBmp(cropped)) {
Serial.printf("[%lu] [SLP] Failed to generate cover bmp\n", millis());
LOG_ERR("SLP", "Failed to generate cover bmp");
return (this->*renderNoCoverSleepScreen)();
}
@@ -265,7 +264,7 @@ void SleepActivity::renderCoverSleepScreen() const {
if (Storage.openFileForRead("SLP", coverBmpPath, file)) {
Bitmap bitmap(file);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
Serial.printf("[%lu] [SLP] Rendering sleep cover: %s\n", millis(), coverBmpPath.c_str());
LOG_DBG("SLP", "Rendering sleep cover: %s", coverBmpPath.c_str());
renderBitmapSleepScreen(bitmap);
return;
}

View File

@@ -2,7 +2,7 @@
#include <Epub.h>
#include <GfxRenderer.h>
#include <HardwareSerial.h>
#include <Logging.h>
#include <OpdsStream.h>
#include <WiFi.h>
@@ -78,14 +78,14 @@ void OpdsBookBrowserActivity::loop() {
// Check if WiFi is still connected
if (WiFi.status() == WL_CONNECTED && WiFi.localIP() != IPAddress(0, 0, 0, 0)) {
// WiFi connected - just retry fetching the feed
Serial.printf("[%lu] [OPDS] Retry: WiFi connected, retrying fetch\n", millis());
LOG_DBG("OPDS", "Retry: WiFi connected, retrying fetch");
state = BrowserState::LOADING;
statusMessage = "Loading...";
updateRequired = true;
fetchFeed(currentPath);
} else {
// WiFi not connected - launch WiFi selection
Serial.printf("[%lu] [OPDS] Retry: WiFi not connected, launching selection\n", millis());
LOG_DBG("OPDS", "Retry: WiFi not connected, launching selection");
launchWifiSelection();
}
} else if (mappedInput.wasReleased(MappedInputManager::Button::Back)) {
@@ -265,7 +265,7 @@ void OpdsBookBrowserActivity::fetchFeed(const std::string& path) {
}
std::string url = UrlUtils::buildUrl(serverUrl, path);
Serial.printf("[%lu] [OPDS] Fetching: %s\n", millis(), url.c_str());
LOG_DBG("OPDS", "Fetching: %s", url.c_str());
OpdsParser parser;
@@ -287,7 +287,7 @@ void OpdsBookBrowserActivity::fetchFeed(const std::string& path) {
}
entries = std::move(parser).getEntries();
Serial.printf("[%lu] [OPDS] Found %d entries\n", millis(), entries.size());
LOG_DBG("OPDS", "Found %d entries", entries.size());
selectorIndex = 0;
if (entries.empty()) {
@@ -351,7 +351,7 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book) {
}
std::string filename = "/" + StringUtils::sanitizeFilename(baseName) + ".epub";
Serial.printf("[%lu] [OPDS] Downloading: %s -> %s\n", millis(), downloadUrl.c_str(), filename.c_str());
LOG_DBG("OPDS", "Downloading: %s -> %s", downloadUrl.c_str(), filename.c_str());
const auto result =
HttpDownloader::downloadToFile(downloadUrl, filename, [this](const size_t downloaded, const size_t total) {
@@ -361,12 +361,12 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book) {
});
if (result == HttpDownloader::OK) {
Serial.printf("[%lu] [OPDS] Download complete: %s\n", millis(), filename.c_str());
LOG_DBG("OPDS", "Download complete: %s", filename.c_str());
// Invalidate any existing cache for this file to prevent stale metadata issues
Epub epub(filename, "/.crosspoint");
epub.clearCache();
Serial.printf("[%lu] [OPDS] Cleared cache for: %s\n", millis(), filename.c_str());
LOG_DBG("OPDS", "Cleared cache for: %s", filename.c_str());
state = BrowserState::BROWSING;
updateRequired = true;
@@ -403,13 +403,13 @@ void OpdsBookBrowserActivity::onWifiSelectionComplete(const bool connected) {
exitActivity();
if (connected) {
Serial.printf("[%lu] [OPDS] WiFi connected via selection, fetching feed\n", millis());
LOG_DBG("OPDS", "WiFi connected via selection, fetching feed");
state = BrowserState::LOADING;
statusMessage = "Loading...";
updateRequired = true;
fetchFeed(currentPath);
} else {
Serial.printf("[%lu] [OPDS] WiFi selection cancelled/failed\n", millis());
LOG_DBG("OPDS", "WiFi selection cancelled/failed");
// Force disconnect to ensure clean state for next retry
// This prevents stale connection status from interfering
WiFi.disconnect();

View File

@@ -73,7 +73,7 @@ void RecentBooksActivity::loop() {
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
if (!recentBooks.empty() && selectorIndex < static_cast<int>(recentBooks.size())) {
Serial.printf("[%lu] [RBA] Selected recent book: %s\n", millis(), recentBooks[selectorIndex].path.c_str());
LOG_DBG("RBA", "Selected recent book: %s", recentBooks[selectorIndex].path.c_str());
onSelectBook(recentBooks[selectorIndex].path);
return;
}

View File

@@ -96,7 +96,7 @@ void CalibreConnectActivity::startWebServer() {
if (MDNS.begin(HOSTNAME)) {
// mDNS is optional for the Calibre plugin but still helpful for users.
Serial.printf("[%lu] [CAL] mDNS started: http://%s.local/\n", millis(), HOSTNAME);
LOG_DBG("CAL", "mDNS started: http://%s.local/", HOSTNAME);
}
webServer.reset(new CrossPointWebServer());
@@ -131,7 +131,7 @@ void CalibreConnectActivity::loop() {
if (webServer && webServer->isRunning()) {
const unsigned long timeSinceLastHandleClient = millis() - lastHandleClientTime;
if (lastHandleClientTime > 0 && timeSinceLastHandleClient > 100) {
Serial.printf("[%lu] [CAL] WARNING: %lu ms gap since last handleClient\n", millis(), timeSinceLastHandleClient);
LOG_DBG("CAL", "WARNING: %lu ms gap since last handleClient", timeSinceLastHandleClient);
}
esp_task_wdt_reset();

View File

@@ -37,7 +37,7 @@ void CrossPointWebServerActivity::taskTrampoline(void* param) {
void CrossPointWebServerActivity::onEnter() {
ActivityWithSubactivity::onEnter();
Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onEnter: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WEBACT] [MEM", "Free heap at onEnter: %d bytes", ESP.getFreeHeap());
renderingMutex = xSemaphoreCreateMutex();
@@ -58,7 +58,7 @@ void CrossPointWebServerActivity::onEnter() {
);
// Launch network mode selection subactivity
Serial.printf("[%lu] [WEBACT] Launching NetworkModeSelectionActivity...\n", millis());
LOG_DBG("WEBACT", "Launching NetworkModeSelectionActivity...");
enterNewActivity(new NetworkModeSelectionActivity(
renderer, mappedInput, [this](const NetworkMode mode) { onNetworkModeSelected(mode); },
[this]() { onGoBack(); } // Cancel goes back to home
@@ -68,7 +68,7 @@ void CrossPointWebServerActivity::onEnter() {
void CrossPointWebServerActivity::onExit() {
ActivityWithSubactivity::onExit();
Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit start: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WEBACT] [MEM", "Free heap at onExit start: %d bytes", ESP.getFreeHeap());
state = WebServerActivityState::SHUTTING_DOWN;
@@ -80,7 +80,7 @@ void CrossPointWebServerActivity::onExit() {
// Stop DNS server if running (AP mode)
if (dnsServer) {
Serial.printf("[%lu] [WEBACT] Stopping DNS server...\n", millis());
LOG_DBG("WEBACT", "Stopping DNS server...");
dnsServer->stop();
delete dnsServer;
dnsServer = nullptr;
@@ -91,39 +91,39 @@ void CrossPointWebServerActivity::onExit() {
// Disconnect WiFi gracefully
if (isApMode) {
Serial.printf("[%lu] [WEBACT] Stopping WiFi AP...\n", millis());
LOG_DBG("WEBACT", "Stopping WiFi AP...");
WiFi.softAPdisconnect(true);
} else {
Serial.printf("[%lu] [WEBACT] Disconnecting WiFi (graceful)...\n", millis());
LOG_DBG("WEBACT", "Disconnecting WiFi (graceful)...");
WiFi.disconnect(false); // false = don't erase credentials, send disconnect frame
}
delay(30); // Allow disconnect frame to be sent
Serial.printf("[%lu] [WEBACT] Setting WiFi mode OFF...\n", millis());
LOG_DBG("WEBACT", "Setting WiFi mode OFF...");
WiFi.mode(WIFI_OFF);
delay(30); // Allow WiFi hardware to power down
Serial.printf("[%lu] [WEBACT] [MEM] Free heap after WiFi disconnect: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WEBACT] [MEM", "Free heap after WiFi disconnect: %d bytes", ESP.getFreeHeap());
// Acquire mutex before deleting task
Serial.printf("[%lu] [WEBACT] Acquiring rendering mutex before task deletion...\n", millis());
LOG_DBG("WEBACT", "Acquiring rendering mutex before task deletion...");
xSemaphoreTake(renderingMutex, portMAX_DELAY);
// Delete the display task
Serial.printf("[%lu] [WEBACT] Deleting display task...\n", millis());
LOG_DBG("WEBACT", "Deleting display task...");
if (displayTaskHandle) {
vTaskDelete(displayTaskHandle);
displayTaskHandle = nullptr;
Serial.printf("[%lu] [WEBACT] Display task deleted\n", millis());
LOG_DBG("WEBACT", "Display task deleted");
}
// Delete the mutex
Serial.printf("[%lu] [WEBACT] Deleting mutex...\n", millis());
LOG_DBG("WEBACT", "Deleting mutex...");
vSemaphoreDelete(renderingMutex);
renderingMutex = nullptr;
Serial.printf("[%lu] [WEBACT] Mutex deleted\n", millis());
LOG_DBG("WEBACT", "Mutex deleted");
Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit end: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WEBACT] [MEM", "Free heap at onExit end: %d bytes", ESP.getFreeHeap());
}
void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode) {
@@ -133,7 +133,7 @@ void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode)
} else if (mode == NetworkMode::CREATE_HOTSPOT) {
modeName = "Create Hotspot";
}
Serial.printf("[%lu] [WEBACT] Network mode selected: %s\n", millis(), modeName);
LOG_DBG("WEBACT", "Network mode selected: %s", modeName);
networkMode = mode;
isApMode = (mode == NetworkMode::CREATE_HOTSPOT);
@@ -155,11 +155,11 @@ void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode)
if (mode == NetworkMode::JOIN_NETWORK) {
// STA mode - launch WiFi selection
Serial.printf("[%lu] [WEBACT] Turning on WiFi (STA mode)...\n", millis());
LOG_DBG("WEBACT", "Turning on WiFi (STA mode)...");
WiFi.mode(WIFI_STA);
state = WebServerActivityState::WIFI_SELECTION;
Serial.printf("[%lu] [WEBACT] Launching WifiSelectionActivity...\n", millis());
LOG_DBG("WEBACT", "Launching WifiSelectionActivity...");
enterNewActivity(new WifiSelectionActivity(renderer, mappedInput,
[this](const bool connected) { onWifiSelectionComplete(connected); }));
} else {
@@ -171,7 +171,7 @@ void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode)
}
void CrossPointWebServerActivity::onWifiSelectionComplete(const bool connected) {
Serial.printf("[%lu] [WEBACT] WifiSelectionActivity completed, connected=%d\n", millis(), connected);
LOG_DBG("WEBACT", "WifiSelectionActivity completed, connected=%d", connected);
if (connected) {
// Get connection info before exiting subactivity
@@ -183,7 +183,7 @@ void CrossPointWebServerActivity::onWifiSelectionComplete(const bool connected)
// Start mDNS for hostname resolution
if (MDNS.begin(AP_HOSTNAME)) {
Serial.printf("[%lu] [WEBACT] mDNS started: http://%s.local/\n", millis(), AP_HOSTNAME);
LOG_DBG("WEBACT", "mDNS started: http://%s.local/", AP_HOSTNAME);
}
// Start the web server
@@ -199,8 +199,8 @@ void CrossPointWebServerActivity::onWifiSelectionComplete(const bool connected)
}
void CrossPointWebServerActivity::startAccessPoint() {
Serial.printf("[%lu] [WEBACT] Starting Access Point mode...\n", millis());
Serial.printf("[%lu] [WEBACT] [MEM] Free heap before AP start: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WEBACT", "Starting Access Point mode...");
LOG_DBG("WEBACT] [MEM", "Free heap before AP start: %d bytes", ESP.getFreeHeap());
// Configure and start the AP
WiFi.mode(WIFI_AP);
@@ -216,7 +216,7 @@ void CrossPointWebServerActivity::startAccessPoint() {
}
if (!apStarted) {
Serial.printf("[%lu] [WEBACT] ERROR: Failed to start Access Point!\n", millis());
LOG_ERR("WEBACT", "ERROR: Failed to start Access Point!");
onGoBack();
return;
}
@@ -230,15 +230,15 @@ void CrossPointWebServerActivity::startAccessPoint() {
connectedIP = ipStr;
connectedSSID = AP_SSID;
Serial.printf("[%lu] [WEBACT] Access Point started!\n", millis());
Serial.printf("[%lu] [WEBACT] SSID: %s\n", millis(), AP_SSID);
Serial.printf("[%lu] [WEBACT] IP: %s\n", millis(), connectedIP.c_str());
LOG_DBG("WEBACT", "Access Point started!");
LOG_DBG("WEBACT", "SSID: %s", AP_SSID);
LOG_DBG("WEBACT", "IP: %s", connectedIP.c_str());
// Start mDNS for hostname resolution
if (MDNS.begin(AP_HOSTNAME)) {
Serial.printf("[%lu] [WEBACT] mDNS started: http://%s.local/\n", millis(), AP_HOSTNAME);
LOG_DBG("WEBACT", "mDNS started: http://%s.local/", AP_HOSTNAME);
} else {
Serial.printf("[%lu] [WEBACT] WARNING: mDNS failed to start\n", millis());
LOG_DBG("WEBACT", "WARNING: mDNS failed to start");
}
// Start DNS server for captive portal behavior
@@ -246,16 +246,16 @@ void CrossPointWebServerActivity::startAccessPoint() {
dnsServer = new DNSServer();
dnsServer->setErrorReplyCode(DNSReplyCode::NoError);
dnsServer->start(DNS_PORT, "*", apIP);
Serial.printf("[%lu] [WEBACT] DNS server started for captive portal\n", millis());
LOG_DBG("WEBACT", "DNS server started for captive portal");
Serial.printf("[%lu] [WEBACT] [MEM] Free heap after AP start: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WEBACT] [MEM", "Free heap after AP start: %d bytes", ESP.getFreeHeap());
// Start the web server
startWebServer();
}
void CrossPointWebServerActivity::startWebServer() {
Serial.printf("[%lu] [WEBACT] Starting web server...\n", millis());
LOG_DBG("WEBACT", "Starting web server...");
// Create the web server instance
webServer.reset(new CrossPointWebServer());
@@ -263,16 +263,16 @@ void CrossPointWebServerActivity::startWebServer() {
if (webServer->isRunning()) {
state = WebServerActivityState::SERVER_RUNNING;
Serial.printf("[%lu] [WEBACT] Web server started successfully\n", millis());
LOG_DBG("WEBACT", "Web server started successfully");
// Force an immediate render since we're transitioning from a subactivity
// that had its own rendering task. We need to make sure our display is shown.
xSemaphoreTake(renderingMutex, portMAX_DELAY);
render();
xSemaphoreGive(renderingMutex);
Serial.printf("[%lu] [WEBACT] Rendered File Transfer screen\n", millis());
LOG_DBG("WEBACT", "Rendered File Transfer screen");
} else {
Serial.printf("[%lu] [WEBACT] ERROR: Failed to start web server!\n", millis());
LOG_ERR("WEBACT", "ERROR: Failed to start web server!");
webServer.reset();
// Go back on error
onGoBack();
@@ -281,9 +281,9 @@ void CrossPointWebServerActivity::startWebServer() {
void CrossPointWebServerActivity::stopWebServer() {
if (webServer && webServer->isRunning()) {
Serial.printf("[%lu] [WEBACT] Stopping web server...\n", millis());
LOG_DBG("WEBACT", "Stopping web server...");
webServer->stop();
Serial.printf("[%lu] [WEBACT] Web server stopped\n", millis());
LOG_DBG("WEBACT", "Web server stopped");
}
webServer.reset();
}
@@ -309,7 +309,7 @@ void CrossPointWebServerActivity::loop() {
lastWifiCheck = millis();
const wl_status_t wifiStatus = WiFi.status();
if (wifiStatus != WL_CONNECTED) {
Serial.printf("[%lu] [WEBACT] WiFi disconnected! Status: %d\n", millis(), wifiStatus);
LOG_DBG("WEBACT", "WiFi disconnected! Status: %d", wifiStatus);
// Show error and exit gracefully
state = WebServerActivityState::SHUTTING_DOWN;
updateRequired = true;
@@ -318,7 +318,7 @@ void CrossPointWebServerActivity::loop() {
// Log weak signal warnings
const int rssi = WiFi.RSSI();
if (rssi < -75) {
Serial.printf("[%lu] [WEBACT] Warning: Weak WiFi signal: %d dBm\n", millis(), rssi);
LOG_DBG("WEBACT", "Warning: Weak WiFi signal: %d dBm", rssi);
}
}
}
@@ -329,8 +329,7 @@ void CrossPointWebServerActivity::loop() {
// Log if there's a significant gap between handleClient calls (>100ms)
if (lastHandleClientTime > 0 && timeSinceLastHandleClient > 100) {
Serial.printf("[%lu] [WEBACT] WARNING: %lu ms gap since last handleClient\n", millis(),
timeSinceLastHandleClient);
LOG_DBG("WEBACT", "WARNING: %lu ms gap since last handleClient", timeSinceLastHandleClient);
}
// Reset watchdog BEFORE processing - HTTP header parsing can be slow
@@ -401,7 +400,7 @@ void drawQRCode(const GfxRenderer& renderer, const int x, const int y, const std
// The structure to manage the QR code
QRCode qrcode;
uint8_t qrcodeBytes[qrcode_getBufferSize(4)];
Serial.printf("[%lu] [WEBACT] QR Code (%lu): %s\n", millis(), data.length(), data.c_str());
LOG_DBG("WEBACT", "QR Code (%lu): %s", data.length(), data.c_str());
qrcode_initText(&qrcode, qrcodeBytes, 4, ECC_LOW, data.c_str());
const uint8_t px = 6; // pixels per module

View File

@@ -1,6 +1,7 @@
#include "WifiSelectionActivity.h"
#include <GfxRenderer.h>
#include <Logging.h>
#include <WiFi.h>
#include <map>
@@ -62,7 +63,7 @@ void WifiSelectionActivity::onEnter() {
if (!lastSsid.empty()) {
const auto* cred = WIFI_STORE.findCredential(lastSsid);
if (cred) {
Serial.printf("[%lu] [WIFI] Attempting to auto-connect to %s\n", millis(), lastSsid.c_str());
LOG_DBG("WIFI", "Attempting to auto-connect to %s", lastSsid.c_str());
selectedSSID = cred->ssid;
enteredPassword = cred->password;
selectedRequiresPassword = !cred->password.empty();
@@ -82,12 +83,12 @@ void WifiSelectionActivity::onEnter() {
void WifiSelectionActivity::onExit() {
Activity::onExit();
Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit start: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WIFI] [MEM", "Free heap at onExit start: %d bytes", ESP.getFreeHeap());
// Stop any ongoing WiFi scan
Serial.printf("[%lu] [WIFI] Deleting WiFi scan...\n", millis());
LOG_DBG("WIFI", "Deleting WiFi scan...");
WiFi.scanDelete();
Serial.printf("[%lu] [WIFI] [MEM] Free heap after scanDelete: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WIFI] [MEM", "Free heap after scanDelete: %d bytes", ESP.getFreeHeap());
// Note: We do NOT disconnect WiFi here - the parent activity
// (CrossPointWebServerActivity) manages WiFi connection state. We just clean
@@ -95,25 +96,25 @@ void WifiSelectionActivity::onExit() {
// Acquire mutex before deleting task to ensure task isn't using it
// This prevents hangs/crashes if the task holds the mutex when deleted
Serial.printf("[%lu] [WIFI] Acquiring rendering mutex before task deletion...\n", millis());
LOG_DBG("WIFI", "Acquiring rendering mutex before task deletion...");
xSemaphoreTake(renderingMutex, portMAX_DELAY);
// Delete the display task (we now hold the mutex, so task is blocked if it
// needs it)
Serial.printf("[%lu] [WIFI] Deleting display task...\n", millis());
LOG_DBG("WIFI", "Deleting display task...");
if (displayTaskHandle) {
vTaskDelete(displayTaskHandle);
displayTaskHandle = nullptr;
Serial.printf("[%lu] [WIFI] Display task deleted\n", millis());
LOG_DBG("WIFI", "Display task deleted");
}
// Now safe to delete the mutex since we own it
Serial.printf("[%lu] [WIFI] Deleting mutex...\n", millis());
LOG_DBG("WIFI", "Deleting mutex...");
vSemaphoreDelete(renderingMutex);
renderingMutex = nullptr;
Serial.printf("[%lu] [WIFI] Mutex deleted\n", millis());
LOG_DBG("WIFI", "Mutex deleted");
Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit end: %d bytes\n", millis(), ESP.getFreeHeap());
LOG_DBG("WIFI] [MEM", "Free heap at onExit end: %d bytes", ESP.getFreeHeap());
}
void WifiSelectionActivity::startWifiScan() {
@@ -211,8 +212,7 @@ void WifiSelectionActivity::selectNetwork(const int index) {
// Use saved password - connect directly
enteredPassword = savedCred->password;
usedSavedPassword = true;
Serial.printf("[%lu] [WiFi] Using saved password for %s, length: %zu\n", millis(), selectedSSID.c_str(),
enteredPassword.size());
LOG_DBG("WiFi", "Using saved password for %s, length: %zu", selectedSSID.c_str(), enteredPassword.size());
attemptConnection();
return;
}
@@ -290,10 +290,9 @@ void WifiSelectionActivity::checkConnectionStatus() {
updateRequired = true;
} else {
// Using saved password or open network - complete immediately
Serial.printf(
"[%lu] [WIFI] Connected with saved/open credentials, "
"completing immediately\n",
millis());
LOG_DBG("WIFI",
"Connected with saved/open credentials, "
"completing immediately");
onComplete(true);
}
return;

View File

@@ -4,6 +4,7 @@
#include <FsHelpers.h>
#include <GfxRenderer.h>
#include <HalStorage.h>
#include <Logging.h>
#include "CrossPointSettings.h"
#include "CrossPointState.h"
@@ -84,7 +85,7 @@ void EpubReaderActivity::onEnter() {
currentSpineIndex = data[0] + (data[1] << 8);
nextPageNumber = data[2] + (data[3] << 8);
cachedSpineIndex = currentSpineIndex;
Serial.printf("[%lu] [ERS] Loaded cache: %d, %d\n", millis(), currentSpineIndex, nextPageNumber);
LOG_DBG("ERS", "Loaded cache: %d, %d", currentSpineIndex, nextPageNumber);
}
if (dataSize == 6) {
cachedChapterTotalPageCount = data[4] + (data[5] << 8);
@@ -97,8 +98,7 @@ void EpubReaderActivity::onEnter() {
int textSpineIndex = epub->getSpineIndexForTextReference();
if (textSpineIndex != 0) {
currentSpineIndex = textSpineIndex;
Serial.printf("[%lu] [ERS] Opened for first time, navigating to text reference at index %d\n", millis(),
textSpineIndex);
LOG_DBG("ERS", "Opened for first time, navigating to text reference at index %d", textSpineIndex);
}
}
@@ -567,7 +567,7 @@ void EpubReaderActivity::renderScreen() {
if (!section) {
const auto filepath = epub->getSpineItem(currentSpineIndex).href;
Serial.printf("[%lu] [ERS] Loading file: %s, index: %d\n", millis(), filepath.c_str(), currentSpineIndex);
LOG_DBG("ERS", "Loading file: %s, index: %d", filepath.c_str(), currentSpineIndex);
section = std::unique_ptr<Section>(new Section(epub, currentSpineIndex, renderer));
const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight;
@@ -576,19 +576,19 @@ void EpubReaderActivity::renderScreen() {
if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle)) {
Serial.printf("[%lu] [ERS] Cache not found, building...\n", millis());
LOG_DBG("ERS", "Cache not found, building...");
const auto popupFn = [this]() { GUI.drawPopup(renderer, "Indexing..."); };
if (!section->createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, popupFn)) {
Serial.printf("[%lu] [ERS] Failed to persist page data to SD\n", millis());
LOG_ERR("ERS", "Failed to persist page data to SD");
section.reset();
return;
}
} else {
Serial.printf("[%lu] [ERS] Cache found, skipping build...\n", millis());
LOG_DBG("ERS", "Cache found, skipping build...");
}
if (nextPageNumber == UINT16_MAX) {
@@ -622,7 +622,7 @@ void EpubReaderActivity::renderScreen() {
renderer.clearScreen();
if (section->pageCount == 0) {
Serial.printf("[%lu] [ERS] No pages to render\n", millis());
LOG_DBG("ERS", "No pages to render");
renderer.drawCenteredText(UI_12_FONT_ID, 300, "Empty chapter", true, EpdFontFamily::BOLD);
renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft);
renderer.displayBuffer();
@@ -630,7 +630,7 @@ void EpubReaderActivity::renderScreen() {
}
if (section->currentPage < 0 || section->currentPage >= section->pageCount) {
Serial.printf("[%lu] [ERS] Page out of bounds: %d (max %d)\n", millis(), section->currentPage, section->pageCount);
LOG_DBG("ERS", "Page out of bounds: %d (max %d)", section->currentPage, section->pageCount);
renderer.drawCenteredText(UI_12_FONT_ID, 300, "Out of bounds", true, EpdFontFamily::BOLD);
renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft);
renderer.displayBuffer();
@@ -640,14 +640,14 @@ void EpubReaderActivity::renderScreen() {
{
auto p = section->loadPageFromSectionFile();
if (!p) {
Serial.printf("[%lu] [ERS] Failed to load page from SD - clearing section cache\n", millis());
LOG_ERR("ERS", "Failed to load page from SD - clearing section cache");
section->clearCache();
section.reset();
return renderScreen();
}
const auto start = millis();
renderContents(std::move(p), orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft);
Serial.printf("[%lu] [ERS] Rendered page in %dms\n", millis(), millis() - start);
LOG_DBG("ERS", "Rendered page in %dms", millis() - start);
}
saveProgress(currentSpineIndex, section->currentPage, section->pageCount);
}
@@ -664,9 +664,9 @@ void EpubReaderActivity::saveProgress(int spineIndex, int currentPage, int pageC
data[5] = (pageCount >> 8) & 0xFF;
f.write(data, 6);
f.close();
Serial.printf("[%lu] [ERS] Progress saved: Chapter %d, Page %d\n", millis(), spineIndex, currentPage);
LOG_DBG("ERS", "Progress saved: Chapter %d, Page %d", spineIndex, currentPage);
} else {
Serial.printf("[%lu] [ERS] Could not save progress!\n", millis());
LOG_ERR("ERS", "Could not save progress!");
}
}
void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int orientedMarginTop,

View File

@@ -1,6 +1,7 @@
#include "KOReaderSyncActivity.h"
#include <GfxRenderer.h>
#include <Logging.h>
#include <WiFi.h>
#include <esp_sntp.h>
@@ -32,9 +33,9 @@ void syncTimeWithNTP() {
}
if (retry < maxRetries) {
Serial.printf("[%lu] [KOSync] NTP time synced\n", millis());
LOG_DBG("KOSync", "NTP time synced");
} else {
Serial.printf("[%lu] [KOSync] NTP sync timeout, using fallback\n", millis());
LOG_DBG("KOSync", "NTP sync timeout, using fallback");
}
}
} // namespace
@@ -48,12 +49,12 @@ void KOReaderSyncActivity::onWifiSelectionComplete(const bool success) {
exitActivity();
if (!success) {
Serial.printf("[%lu] [KOSync] WiFi connection failed, exiting\n", millis());
LOG_DBG("KOSync", "WiFi connection failed, exiting");
onCancel();
return;
}
Serial.printf("[%lu] [KOSync] WiFi connected, starting sync\n", millis());
LOG_DBG("KOSync", "WiFi connected, starting sync");
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = SYNCING;
@@ -88,7 +89,7 @@ void KOReaderSyncActivity::performSync() {
return;
}
Serial.printf("[%lu] [KOSync] Document hash: %s\n", millis(), documentHash.c_str());
LOG_DBG("KOSync", "Document hash: %s", documentHash.c_str());
xSemaphoreTake(renderingMutex, portMAX_DELAY);
statusMessage = "Fetching remote progress...";
@@ -188,12 +189,12 @@ void KOReaderSyncActivity::onEnter() {
}
// Turn on WiFi
Serial.printf("[%lu] [KOSync] Turning on WiFi...\n", millis());
LOG_DBG("KOSync", "Turning on WiFi...");
WiFi.mode(WIFI_STA);
// Check if already connected
if (WiFi.status() == WL_CONNECTED) {
Serial.printf("[%lu] [KOSync] Already connected to WiFi\n", millis());
LOG_DBG("KOSync", "Already connected to WiFi");
state = SYNCING;
statusMessage = "Syncing time...";
updateRequired = true;
@@ -216,7 +217,7 @@ void KOReaderSyncActivity::onEnter() {
}
// Launch WiFi selection subactivity
Serial.printf("[%lu] [KOSync] Launching WifiSelectionActivity...\n", millis());
LOG_DBG("KOSync", "Launching WifiSelectionActivity...");
enterNewActivity(new WifiSelectionActivity(renderer, mappedInput,
[this](const bool connected) { onWifiSelectionComplete(connected); }));
}

View File

@@ -30,7 +30,7 @@ bool ReaderActivity::isTxtFile(const std::string& path) {
std::unique_ptr<Epub> ReaderActivity::loadEpub(const std::string& path) {
if (!Storage.exists(path.c_str())) {
Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str());
LOG_ERR("READER", "File does not exist: %s", path.c_str());
return nullptr;
}
@@ -39,13 +39,13 @@ std::unique_ptr<Epub> ReaderActivity::loadEpub(const std::string& path) {
return epub;
}
Serial.printf("[%lu] [ ] Failed to load epub\n", millis());
LOG_ERR("READER", "Failed to load epub");
return nullptr;
}
std::unique_ptr<Xtc> ReaderActivity::loadXtc(const std::string& path) {
if (!Storage.exists(path.c_str())) {
Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str());
LOG_ERR("READER", "File does not exist: %s", path.c_str());
return nullptr;
}
@@ -54,13 +54,13 @@ std::unique_ptr<Xtc> ReaderActivity::loadXtc(const std::string& path) {
return xtc;
}
Serial.printf("[%lu] [ ] Failed to load XTC\n", millis());
LOG_ERR("READER", "Failed to load XTC");
return nullptr;
}
std::unique_ptr<Txt> ReaderActivity::loadTxt(const std::string& path) {
if (!Storage.exists(path.c_str())) {
Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str());
LOG_ERR("READER", "File does not exist: %s", path.c_str());
return nullptr;
}
@@ -69,7 +69,7 @@ std::unique_ptr<Txt> ReaderActivity::loadTxt(const std::string& path) {
return txt;
}
Serial.printf("[%lu] [ ] Failed to load TXT\n", millis());
LOG_ERR("READER", "Failed to load TXT");
return nullptr;
}

View File

@@ -191,8 +191,7 @@ void TxtReaderActivity::initializeReader() {
linesPerPage = viewportHeight / lineHeight;
if (linesPerPage < 1) linesPerPage = 1;
Serial.printf("[%lu] [TRS] Viewport: %dx%d, lines per page: %d\n", millis(), viewportWidth, viewportHeight,
linesPerPage);
LOG_DBG("TRS", "Viewport: %dx%d, lines per page: %d", viewportWidth, viewportHeight, linesPerPage);
// Try to load cached page index first
if (!loadPageIndexCache()) {
@@ -215,7 +214,7 @@ void TxtReaderActivity::buildPageIndex() {
size_t offset = 0;
const size_t fileSize = txt->getFileSize();
Serial.printf("[%lu] [TRS] Building page index for %zu bytes...\n", millis(), fileSize);
LOG_DBG("TRS", "Building page index for %zu bytes...", fileSize);
GUI.drawPopup(renderer, "Indexing...");
@@ -244,7 +243,7 @@ void TxtReaderActivity::buildPageIndex() {
}
totalPages = pageOffsets.size();
Serial.printf("[%lu] [TRS] Built page index: %d pages\n", millis(), totalPages);
LOG_DBG("TRS", "Built page index: %d pages", totalPages);
}
bool TxtReaderActivity::loadPageAtOffset(size_t offset, std::vector<std::string>& outLines, size_t& nextOffset) {
@@ -259,7 +258,7 @@ bool TxtReaderActivity::loadPageAtOffset(size_t offset, std::vector<std::string>
size_t chunkSize = std::min(CHUNK_SIZE, fileSize - offset);
auto* buffer = static_cast<uint8_t*>(malloc(chunkSize + 1));
if (!buffer) {
Serial.printf("[%lu] [TRS] Failed to allocate %zu bytes\n", millis(), chunkSize);
LOG_ERR("TRS", "Failed to allocate %zu bytes", chunkSize);
return false;
}
@@ -588,7 +587,7 @@ void TxtReaderActivity::loadProgress() {
if (currentPage < 0) {
currentPage = 0;
}
Serial.printf("[%lu] [TRS] Loaded progress: page %d/%d\n", millis(), currentPage, totalPages);
LOG_DBG("TRS", "Loaded progress: page %d/%d", currentPage, totalPages);
}
f.close();
}
@@ -610,7 +609,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
std::string cachePath = txt->getCachePath() + "/index.bin";
FsFile f;
if (!Storage.openFileForRead("TRS", cachePath, f)) {
Serial.printf("[%lu] [TRS] No page index cache found\n", millis());
LOG_DBG("TRS", "No page index cache found");
return false;
}
@@ -618,7 +617,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
uint32_t magic;
serialization::readPod(f, magic);
if (magic != CACHE_MAGIC) {
Serial.printf("[%lu] [TRS] Cache magic mismatch, rebuilding\n", millis());
LOG_DBG("TRS", "Cache magic mismatch, rebuilding");
f.close();
return false;
}
@@ -626,7 +625,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
uint8_t version;
serialization::readPod(f, version);
if (version != CACHE_VERSION) {
Serial.printf("[%lu] [TRS] Cache version mismatch (%d != %d), rebuilding\n", millis(), version, CACHE_VERSION);
LOG_DBG("TRS", "Cache version mismatch (%d != %d), rebuilding", version, CACHE_VERSION);
f.close();
return false;
}
@@ -634,7 +633,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
uint32_t fileSize;
serialization::readPod(f, fileSize);
if (fileSize != txt->getFileSize()) {
Serial.printf("[%lu] [TRS] Cache file size mismatch, rebuilding\n", millis());
LOG_DBG("TRS", "Cache file size mismatch, rebuilding");
f.close();
return false;
}
@@ -642,7 +641,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
int32_t cachedWidth;
serialization::readPod(f, cachedWidth);
if (cachedWidth != viewportWidth) {
Serial.printf("[%lu] [TRS] Cache viewport width mismatch, rebuilding\n", millis());
LOG_DBG("TRS", "Cache viewport width mismatch, rebuilding");
f.close();
return false;
}
@@ -650,7 +649,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
int32_t cachedLines;
serialization::readPod(f, cachedLines);
if (cachedLines != linesPerPage) {
Serial.printf("[%lu] [TRS] Cache lines per page mismatch, rebuilding\n", millis());
LOG_DBG("TRS", "Cache lines per page mismatch, rebuilding");
f.close();
return false;
}
@@ -658,7 +657,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
int32_t fontId;
serialization::readPod(f, fontId);
if (fontId != cachedFontId) {
Serial.printf("[%lu] [TRS] Cache font ID mismatch (%d != %d), rebuilding\n", millis(), fontId, cachedFontId);
LOG_DBG("TRS", "Cache font ID mismatch (%d != %d), rebuilding", fontId, cachedFontId);
f.close();
return false;
}
@@ -666,7 +665,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
int32_t margin;
serialization::readPod(f, margin);
if (margin != cachedScreenMargin) {
Serial.printf("[%lu] [TRS] Cache screen margin mismatch, rebuilding\n", millis());
LOG_DBG("TRS", "Cache screen margin mismatch, rebuilding");
f.close();
return false;
}
@@ -674,7 +673,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
uint8_t alignment;
serialization::readPod(f, alignment);
if (alignment != cachedParagraphAlignment) {
Serial.printf("[%lu] [TRS] Cache paragraph alignment mismatch, rebuilding\n", millis());
LOG_DBG("TRS", "Cache paragraph alignment mismatch, rebuilding");
f.close();
return false;
}
@@ -694,7 +693,7 @@ bool TxtReaderActivity::loadPageIndexCache() {
f.close();
totalPages = pageOffsets.size();
Serial.printf("[%lu] [TRS] Loaded page index cache: %d pages\n", millis(), totalPages);
LOG_DBG("TRS", "Loaded page index cache: %d pages", totalPages);
return true;
}
@@ -702,7 +701,7 @@ void TxtReaderActivity::savePageIndexCache() const {
std::string cachePath = txt->getCachePath() + "/index.bin";
FsFile f;
if (!Storage.openFileForWrite("TRS", cachePath, f)) {
Serial.printf("[%lu] [TRS] Failed to save page index cache\n", millis());
LOG_ERR("TRS", "Failed to save page index cache");
return;
}
@@ -723,5 +722,5 @@ void TxtReaderActivity::savePageIndexCache() const {
}
f.close();
Serial.printf("[%lu] [TRS] Saved page index cache: %d pages\n", millis(), totalPages);
LOG_DBG("TRS", "Saved page index cache: %d pages", totalPages);
}

View File

@@ -206,7 +206,7 @@ void XtcReaderActivity::renderPage() {
// Allocate page buffer
uint8_t* pageBuffer = static_cast<uint8_t*>(malloc(pageBufferSize));
if (!pageBuffer) {
Serial.printf("[%lu] [XTR] Failed to allocate page buffer (%lu bytes)\n", millis(), pageBufferSize);
LOG_ERR("XTR", "Failed to allocate page buffer (%lu bytes)", pageBufferSize);
renderer.clearScreen();
renderer.drawCenteredText(UI_12_FONT_ID, 300, "Memory error", true, EpdFontFamily::BOLD);
renderer.displayBuffer();
@@ -216,7 +216,7 @@ void XtcReaderActivity::renderPage() {
// Load page data
size_t bytesRead = xtc->loadPage(currentPage, pageBuffer, pageBufferSize);
if (bytesRead == 0) {
Serial.printf("[%lu] [XTR] Failed to load page %lu\n", millis(), currentPage);
LOG_ERR("XTR", "Failed to load page %lu", currentPage);
free(pageBuffer);
renderer.clearScreen();
renderer.drawCenteredText(UI_12_FONT_ID, 300, "Page load error", true, EpdFontFamily::BOLD);
@@ -265,8 +265,8 @@ void XtcReaderActivity::renderPage() {
pixelCounts[getPixelValue(x, y)]++;
}
}
Serial.printf("[%lu] [XTR] Pixel distribution: White=%lu, DarkGrey=%lu, LightGrey=%lu, Black=%lu\n", millis(),
pixelCounts[0], pixelCounts[1], pixelCounts[2], pixelCounts[3]);
LOG_DBG("XTR", "Pixel distribution: White=%lu, DarkGrey=%lu, LightGrey=%lu, Black=%lu", pixelCounts[0],
pixelCounts[1], pixelCounts[2], pixelCounts[3]);
// Pass 1: BW buffer - draw all non-white pixels as black
for (uint16_t y = 0; y < pageHeight; y++) {
@@ -329,8 +329,7 @@ void XtcReaderActivity::renderPage() {
free(pageBuffer);
Serial.printf("[%lu] [XTR] Rendered page %lu/%lu (2-bit grayscale)\n", millis(), currentPage + 1,
xtc->getPageCount());
LOG_DBG("XTR", "Rendered page %lu/%lu (2-bit grayscale)", currentPage + 1, xtc->getPageCount());
return;
} else {
// 1-bit mode: 8 pixels per byte, MSB first
@@ -366,8 +365,7 @@ void XtcReaderActivity::renderPage() {
pagesUntilFullRefresh--;
}
Serial.printf("[%lu] [XTR] Rendered page %lu/%lu (%u-bit)\n", millis(), currentPage + 1, xtc->getPageCount(),
bitDepth);
LOG_DBG("XTR", "Rendered page %lu/%lu (%u-bit)", currentPage + 1, xtc->getPageCount(), bitDepth);
}
void XtcReaderActivity::saveProgress() const {
@@ -389,7 +387,7 @@ void XtcReaderActivity::loadProgress() {
uint8_t data[4];
if (f.read(data, 4) == 4) {
currentPage = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
Serial.printf("[%lu] [XTR] Loaded progress: page %lu\n", millis(), currentPage);
LOG_DBG("XTR", "Loaded progress: page %lu", currentPage);
// Validate page number
if (currentPage >= xtc->getPageCount()) {

View File

@@ -2,7 +2,7 @@
#include <GfxRenderer.h>
#include <HalStorage.h>
#include <HardwareSerial.h>
#include <Logging.h>
#include "MappedInputManager.h"
#include "components/UITheme.h"
@@ -104,12 +104,12 @@ void ClearCacheActivity::render() {
}
void ClearCacheActivity::clearCache() {
Serial.printf("[%lu] [CLEAR_CACHE] Clearing cache...\n", millis());
LOG_DBG("CLEAR_CACHE", "Clearing cache...");
// Open .crosspoint directory
auto root = Storage.open("/.crosspoint");
if (!root || !root.isDirectory()) {
Serial.printf("[%lu] [CLEAR_CACHE] Failed to open cache directory\n", millis());
LOG_DBG("CLEAR_CACHE", "Failed to open cache directory");
if (root) root.close();
state = FAILED;
updateRequired = true;
@@ -128,14 +128,14 @@ void ClearCacheActivity::clearCache() {
// Only delete directories starting with epub_ or xtc_
if (file.isDirectory() && (itemName.startsWith("epub_") || itemName.startsWith("xtc_"))) {
String fullPath = "/.crosspoint/" + itemName;
Serial.printf("[%lu] [CLEAR_CACHE] Removing cache: %s\n", millis(), fullPath.c_str());
LOG_DBG("CLEAR_CACHE", "Removing cache: %s", fullPath.c_str());
file.close(); // Close before attempting to delete
if (Storage.removeDir(fullPath.c_str())) {
clearedCount++;
} else {
Serial.printf("[%lu] [CLEAR_CACHE] Failed to remove: %s\n", millis(), fullPath.c_str());
LOG_ERR("CLEAR_CACHE", "Failed to remove: %s", fullPath.c_str());
failedCount++;
}
} else {
@@ -144,7 +144,7 @@ void ClearCacheActivity::clearCache() {
}
root.close();
Serial.printf("[%lu] [CLEAR_CACHE] Cache cleared: %d removed, %d failed\n", millis(), clearedCount, failedCount);
LOG_DBG("CLEAR_CACHE", "Cache cleared: %d removed, %d failed", clearedCount, failedCount);
state = SUCCESS;
updateRequired = true;
@@ -153,7 +153,7 @@ void ClearCacheActivity::clearCache() {
void ClearCacheActivity::loop() {
if (state == WARNING) {
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
Serial.printf("[%lu] [CLEAR_CACHE] User confirmed, starting cache clear\n", millis());
LOG_DBG("CLEAR_CACHE", "User confirmed, starting cache clear");
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = CLEARING;
xSemaphoreGive(renderingMutex);
@@ -164,7 +164,7 @@ void ClearCacheActivity::loop() {
}
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
Serial.printf("[%lu] [CLEAR_CACHE] User cancelled\n", millis());
LOG_DBG("CLEAR_CACHE", "User cancelled");
goBack();
}
return;

View File

@@ -18,12 +18,12 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) {
exitActivity();
if (!success) {
Serial.printf("[%lu] [OTA] WiFi connection failed, exiting\n", millis());
LOG_ERR("OTA", "WiFi connection failed, exiting");
goBack();
return;
}
Serial.printf("[%lu] [OTA] WiFi connected, checking for update\n", millis());
LOG_DBG("OTA", "WiFi connected, checking for update");
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = CHECKING_FOR_UPDATE;
@@ -32,7 +32,7 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) {
vTaskDelay(10 / portTICK_PERIOD_MS);
const auto res = updater.checkForUpdate();
if (res != OtaUpdater::OK) {
Serial.printf("[%lu] [OTA] Update check failed: %d\n", millis(), res);
LOG_DBG("OTA", "Update check failed: %d", res);
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = FAILED;
xSemaphoreGive(renderingMutex);
@@ -41,7 +41,7 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) {
}
if (!updater.isUpdateNewer()) {
Serial.printf("[%lu] [OTA] No new update available\n", millis());
LOG_DBG("OTA", "No new update available");
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = NO_UPDATE;
xSemaphoreGive(renderingMutex);
@@ -68,11 +68,11 @@ void OtaUpdateActivity::onEnter() {
);
// Turn on WiFi immediately
Serial.printf("[%lu] [OTA] Turning on WiFi...\n", millis());
LOG_DBG("OTA", "Turning on WiFi...");
WiFi.mode(WIFI_STA);
// Launch WiFi selection subactivity
Serial.printf("[%lu] [OTA] Launching WifiSelectionActivity...\n", millis());
LOG_DBG("OTA", "Launching WifiSelectionActivity...");
enterNewActivity(new WifiSelectionActivity(renderer, mappedInput,
[this](const bool connected) { onWifiSelectionComplete(connected); }));
}
@@ -116,8 +116,7 @@ void OtaUpdateActivity::render() {
float updaterProgress = 0;
if (state == UPDATE_IN_PROGRESS) {
Serial.printf("[%lu] [OTA] Update progress: %d / %d\n", millis(), updater.getProcessedSize(),
updater.getTotalSize());
LOG_DBG("OTA", "Update progress: %d / %d", updater.getProcessedSize(), updater.getTotalSize());
updaterProgress = static_cast<float>(updater.getProcessedSize()) / static_cast<float>(updater.getTotalSize());
// Only update every 2% at the most
if (static_cast<int>(updaterProgress * 50) == lastUpdaterPercentage / 2) {
@@ -190,7 +189,7 @@ void OtaUpdateActivity::loop() {
if (state == WAITING_CONFIRMATION) {
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
Serial.printf("[%lu] [OTA] New update available, starting download...\n", millis());
LOG_DBG("OTA", "New update available, starting download...");
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = UPDATE_IN_PROGRESS;
xSemaphoreGive(renderingMutex);
@@ -199,7 +198,7 @@ void OtaUpdateActivity::loop() {
const auto res = updater.installUpdate();
if (res != OtaUpdater::OK) {
Serial.printf("[%lu] [OTA] Update failed: %d\n", millis(), res);
LOG_DBG("OTA", "Update failed: %d", res);
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = FAILED;
xSemaphoreGive(renderingMutex);

View File

@@ -1,7 +1,7 @@
#include "SettingsActivity.h"
#include <GfxRenderer.h>
#include <HardwareSerial.h>
#include <Logging.h>
#include "ButtonRemapActivity.h"
#include "CalibreSettingsActivity.h"