add proper firmware flashing screen
This commit is contained in:
65
src/images/LockIcon.h
Normal file
65
src/images/LockIcon.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
// Lock icon dimensions (original orientation - shackle on top)
|
||||
static constexpr int LOCK_ICON_WIDTH = 32;
|
||||
static constexpr int LOCK_ICON_HEIGHT = 40;
|
||||
|
||||
// 32x40 pixel padlock icon (1-bit bitmap, MSB first)
|
||||
// 0 = black pixel, 1 = white pixel
|
||||
// Original orientation: shackle on top, body below
|
||||
// Use drawImageRotated() to rotate as needed for different screen orientations
|
||||
static const uint8_t LockIcon[] = {
|
||||
// Row 0-1: Empty space above shackle
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
// Row 2-3: Shackle top curve
|
||||
0x00, 0x0F, 0xF0, 0x00, // ....####....
|
||||
0x00, 0x3F, 0xFC, 0x00, // ..########..
|
||||
// Row 4-5: Shackle upper sides
|
||||
0x00, 0x78, 0x1E, 0x00, // .####..####.
|
||||
0x00, 0xE0, 0x07, 0x00, // ###......###
|
||||
// Row 6-9: Extended shackle legs (longer for better visual)
|
||||
0x00, 0xC0, 0x03, 0x00, // ##........##
|
||||
0x01, 0xC0, 0x03, 0x80, // ###......###
|
||||
0x01, 0x80, 0x01, 0x80, // ##........##
|
||||
0x01, 0x80, 0x01, 0x80, // ##........##
|
||||
// Row 10-13: Shackle legs continue into body
|
||||
0x01, 0x80, 0x01, 0x80, // ##........##
|
||||
0x01, 0x80, 0x01, 0x80, // ##........##
|
||||
0x01, 0x80, 0x01, 0x80, // ##........##
|
||||
0x01, 0x80, 0x01, 0x80, // ##........##
|
||||
// Row 14-15: Body top
|
||||
0x0F, 0xFF, 0xFF, 0xF0, // ############
|
||||
0x1F, 0xFF, 0xFF, 0xF8, // ##############
|
||||
// Row 16-17: Body top edge
|
||||
0x3F, 0xFF, 0xFF, 0xFC, // ################
|
||||
0x3F, 0xFF, 0xFF, 0xFC, // ################
|
||||
// Row 18-29: Solid body (no keyhole)
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
// Row 30-33: Body lower section
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
// Row 34-35: Body bottom edge
|
||||
0x3F, 0xFF, 0xFF, 0xFC,
|
||||
0x1F, 0xFF, 0xFF, 0xF8,
|
||||
// Row 36-37: Body bottom
|
||||
0x0F, 0xFF, 0xFF, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
// Row 38-39: Empty space below
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
116
src/main.cpp
116
src/main.cpp
@@ -26,6 +26,7 @@
|
||||
#include "activities/settings/SettingsActivity.h"
|
||||
#include "activities/util/FullScreenMessageActivity.h"
|
||||
#include "fontIds.h"
|
||||
#include "images/LockIcon.h"
|
||||
|
||||
#define SPI_FQ 40000000
|
||||
// Display SPI pins (custom pins for XteinkX4, not hardware SPI defaults)
|
||||
@@ -128,6 +129,118 @@ void logMemoryState(const char* tag, const char* context) {
|
||||
#define logMemoryState(tag, context) ((void)0)
|
||||
#endif
|
||||
|
||||
// Flash command detection - receives "FLASH\n" from pre_flash.py script
|
||||
static String flashCmdBuffer;
|
||||
|
||||
void checkForFlashCommand() {
|
||||
while (Serial.available()) {
|
||||
char c = Serial.read();
|
||||
if (c == '\n') {
|
||||
if (flashCmdBuffer.startsWith("FLASH")) {
|
||||
// Extract version if provided (format: "FLASH:x.y.z")
|
||||
String newVersion = "";
|
||||
if (flashCmdBuffer.length() > 6 && flashCmdBuffer.charAt(5) == ':') {
|
||||
newVersion = flashCmdBuffer.substring(6);
|
||||
}
|
||||
|
||||
Serial.printf("[%lu] [FLS] Flash command received (version: %s), displaying message\n", millis(),
|
||||
newVersion.length() > 0 ? newVersion.c_str() : "unknown");
|
||||
|
||||
// Display flash message with inverted colors (black background, white text)
|
||||
renderer.clearScreen(0x00); // Black background
|
||||
renderer.drawCenteredText(NOTOSANS_14_FONT_ID, 200, "Flashing firmware...", false, EpdFontFamily::BOLD);
|
||||
|
||||
// Show new version under title if provided
|
||||
if (newVersion.length() > 0) {
|
||||
String versionText = "v" + newVersion;
|
||||
renderer.drawCenteredText(UI_10_FONT_ID, 260, versionText.c_str(), false);
|
||||
}
|
||||
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 300, "Do not disconnect USB", false);
|
||||
|
||||
// Get screen dimensions and orientation for positioning
|
||||
const int screenW = renderer.getScreenWidth();
|
||||
const int screenH = renderer.getScreenHeight();
|
||||
|
||||
// Show current version in bottom-left corner (orientation-aware)
|
||||
// "Bottom-left" is relative to the current orientation
|
||||
constexpr int versionMargin = 10;
|
||||
const int textWidth = renderer.getTextWidth(SMALL_FONT_ID, CROSSPOINT_VERSION);
|
||||
int versionX, versionY;
|
||||
switch (renderer.getOrientation()) {
|
||||
case GfxRenderer::Portrait: // Bottom-left is actual bottom-left
|
||||
versionX = versionMargin;
|
||||
versionY = screenH - 30;
|
||||
break;
|
||||
case GfxRenderer::PortraitInverted: // Bottom-left is actual top-right
|
||||
versionX = screenW - textWidth - versionMargin;
|
||||
versionY = 20;
|
||||
break;
|
||||
case GfxRenderer::LandscapeClockwise: // Bottom-left is actual bottom-right
|
||||
versionX = screenW - textWidth - versionMargin;
|
||||
versionY = screenH - 30;
|
||||
break;
|
||||
case GfxRenderer::LandscapeCounterClockwise: // Bottom-left is actual bottom-left
|
||||
versionX = versionMargin;
|
||||
versionY = screenH - 30;
|
||||
break;
|
||||
}
|
||||
renderer.drawText(SMALL_FONT_ID, versionX, versionY, CROSSPOINT_VERSION, false);
|
||||
|
||||
// Position and rotate lock icon based on current orientation (USB port location)
|
||||
// USB port locations: Portrait=bottom-left, PortraitInverted=top-right,
|
||||
// LandscapeCW=top-left, LandscapeCCW=bottom-right
|
||||
// Position offsets: edge margin + half-width offset to center on USB port
|
||||
constexpr int edgeMargin = 28; // Distance from screen edge
|
||||
constexpr int halfWidth = LOCK_ICON_WIDTH / 2; // 16px offset for centering
|
||||
int iconX, iconY;
|
||||
GfxRenderer::ImageRotation rotation;
|
||||
int outW, outH; // Note: 90/270 rotation swaps output dimensions
|
||||
switch (renderer.getOrientation()) {
|
||||
case GfxRenderer::Portrait: // USB at bottom-left, shackle points right
|
||||
rotation = GfxRenderer::ROTATE_90;
|
||||
outW = LOCK_ICON_HEIGHT;
|
||||
outH = LOCK_ICON_WIDTH;
|
||||
iconX = edgeMargin;
|
||||
iconY = screenH - outH - edgeMargin - halfWidth;
|
||||
break;
|
||||
case GfxRenderer::PortraitInverted: // USB at top-right, shackle points left
|
||||
rotation = GfxRenderer::ROTATE_270;
|
||||
outW = LOCK_ICON_HEIGHT;
|
||||
outH = LOCK_ICON_WIDTH;
|
||||
iconX = screenW - outW - edgeMargin;
|
||||
iconY = edgeMargin + halfWidth;
|
||||
break;
|
||||
case GfxRenderer::LandscapeClockwise: // USB at top-left, shackle points down
|
||||
rotation = GfxRenderer::ROTATE_180;
|
||||
outW = LOCK_ICON_WIDTH;
|
||||
outH = LOCK_ICON_HEIGHT;
|
||||
iconX = edgeMargin + halfWidth;
|
||||
iconY = edgeMargin;
|
||||
break;
|
||||
case GfxRenderer::LandscapeCounterClockwise: // USB at bottom-right, shackle points up
|
||||
rotation = GfxRenderer::ROTATE_0;
|
||||
outW = LOCK_ICON_WIDTH;
|
||||
outH = LOCK_ICON_HEIGHT;
|
||||
iconX = screenW - outW - edgeMargin - halfWidth;
|
||||
iconY = screenH - outH - edgeMargin;
|
||||
break;
|
||||
}
|
||||
renderer.drawImageRotated(LockIcon, iconX, iconY, LOCK_ICON_WIDTH, LOCK_ICON_HEIGHT, rotation);
|
||||
|
||||
renderer.displayBuffer(EInkDisplay::FAST_REFRESH);
|
||||
}
|
||||
flashCmdBuffer = "";
|
||||
} else if (c != '\r') {
|
||||
flashCmdBuffer += c;
|
||||
// Prevent buffer overflow from random serial data (increased for version info)
|
||||
if (flashCmdBuffer.length() > 30) {
|
||||
flashCmdBuffer = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void exitActivity() {
|
||||
if (currentActivity) {
|
||||
logMemoryState("MAIN", "Before onExit");
|
||||
@@ -391,6 +504,9 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Check for flash command from pre_flash.py script (must be first to catch before upload)
|
||||
checkForFlashCommand();
|
||||
|
||||
static unsigned long maxLoopDuration = 0;
|
||||
const unsigned long loopStartTime = millis();
|
||||
static unsigned long lastMemPrint = 0;
|
||||
|
||||
Reference in New Issue
Block a user