| 481 | } |
| 482 | |
| 483 | void loop() { |
| 484 | static unsigned long maxLoopDuration = 0; |
| 485 | const unsigned long loopStartTime = millis(); |
| 486 | static unsigned long lastMemPrint = 0; |
| 487 | |
| 488 | gpio.update(); |
| 489 | halTiltSensor.update(SETTINGS.tiltPageTurn, SETTINGS.orientation, activityManager.isReaderActivity()); |
| 490 | |
| 491 | renderer.setFadingFix(SETTINGS.fadingFix); |
| 492 | |
| 493 | if (Serial && millis() - lastMemPrint >= 10000) { |
| 494 | LOG_INF("MEM", "Free: %d bytes, Total: %d bytes, Min Free: %d bytes, MaxAlloc: %d bytes", ESP.getFreeHeap(), |
| 495 | ESP.getHeapSize(), ESP.getMinFreeHeap(), ESP.getMaxAllocHeap()); |
| 496 | lastMemPrint = millis(); |
| 497 | } |
| 498 | |
| 499 | // Handle incoming serial commands, |
| 500 | // nb: we use logSerial from logging to avoid deprecation warnings |
| 501 | if (logSerial.available() > 0) { |
| 502 | String line = logSerial.readStringUntil('\n'); |
| 503 | if (line.startsWith("CMD:")) { |
| 504 | String cmd = line.substring(4); |
| 505 | cmd.trim(); |
| 506 | if (cmd == "SCREENSHOT") { |
| 507 | const uint32_t bufferSize = display.getBufferSize(); |
| 508 | logSerial.printf("SCREENSHOT_START:%d\n", bufferSize); |
| 509 | uint8_t* buf = display.getFrameBuffer(); |
| 510 | logSerial.write(buf, bufferSize); |
| 511 | logSerial.printf("SCREENSHOT_END\n"); |
| 512 | } |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | // Check for any user activity (button press or release) or active background work |
| 517 | static unsigned long lastActivityTime = millis(); |
| 518 | if (gpio.wasAnyPressed() || gpio.wasAnyReleased() || halTiltSensor.hadActivity() || |
| 519 | activityManager.preventAutoSleep()) { |
| 520 | lastActivityTime = millis(); // Reset inactivity timer |
| 521 | powerManager.setPowerSaving(false); // Restore normal CPU frequency on user activity |
| 522 | } |
| 523 | |
| 524 | static bool screenshotButtonsReleased = true; |
| 525 | static bool screenshotComboActive = false; |
| 526 | if (gpio.isPressed(HalGPIO::BTN_POWER) && gpio.isPressed(HalGPIO::BTN_DOWN)) { |
| 527 | screenshotComboActive = true; |
| 528 | if (screenshotButtonsReleased) { |
| 529 | screenshotButtonsReleased = false; |
| 530 | { |
| 531 | RenderLock lock; |
| 532 | ScreenshotUtil::takeScreenshot(renderer); |
| 533 | } |
| 534 | } |
| 535 | return; |
| 536 | } |
| 537 | if (screenshotComboActive) { |
| 538 | if (gpio.isPressed(HalGPIO::BTN_POWER)) return; |
| 539 | if (gpio.wasReleased(HalGPIO::BTN_POWER)) { |
| 540 | screenshotButtonsReleased = true; |
no test coverage detected