Files
uv-k1-k5v3-firmware-custom/App/screenshot.c
T

121 lines
3.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Copyright 2024 Armel F4HWN
* https://github.com/armel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "debugging.h"
#include "driver/st7565.h"
#include "screenshot.h"
#include "misc.h"
// RAM optimization: Only keep previousFrame static (1024 bytes)
// Build currentFrame on-the-fly and send delta blocks immediately
static uint8_t previousFrame[1024] = {0};
static uint8_t forcedBlock = 0;
static uint8_t keepAlive = 10;
void getScreenShot(bool force)
{
static uint8_t currentFrame[1024]; // Reused static buffer
uint16_t index = 0;
uint8_t acc = 0;
uint8_t bitCount = 0;
if (gUART_LockScreenshot > 0) {
gUART_LockScreenshot--;
return;
}
if (UART_IsCableConnected()) {
keepAlive = 10;
}
if (keepAlive > 0) {
if (--keepAlive == 0) return;
} else {
return;
}
// ==== Build currentFrame (exact same logic as original) ====
// Status line: 8 bit layers × 128 columns
for (uint8_t b = 0; b < 8; b++) {
for (uint8_t i = 0; i < 128; i++) {
uint8_t bit = (gStatusLine[i] >> b) & 0x01;
acc |= (bit << bitCount++);
if (bitCount == 8) {
currentFrame[index++] = acc;
acc = 0;
bitCount = 0;
}
}
}
// Frame buffer: 7 lines × 8 bit layers × 128 columns
for (uint8_t l = 0; l < 7; l++) {
for (uint8_t b = 0; b < 8; b++) {
for (uint8_t i = 0; i < 128; i++) {
uint8_t bit = (gFrameBuffer[l][i] >> b) & 0x01;
acc |= (bit << bitCount++);
if (bitCount == 8) {
currentFrame[index++] = acc;
acc = 0;
bitCount = 0;
}
}
}
}
if (bitCount > 0)
currentFrame[index++] = acc;
if (index != 1024)
return; // Frame size mismatch, abort
// ==== Generate delta frame ====
uint16_t deltaLen = 0;
uint8_t deltaFrame[128 * 9]; // Worst case: all 128 blocks changed
for (uint8_t block = 0; block < 128; block++) {
uint8_t *cur = &currentFrame[block * 8];
uint8_t *prev = &previousFrame[block * 8];
bool changed = memcmp(cur, prev, 8) != 0;
bool isForced = (block == forcedBlock);
bool fullUpdate = force;
if (changed || isForced || fullUpdate) {
deltaFrame[deltaLen++] = block;
memcpy(&deltaFrame[deltaLen], cur, 8);
deltaLen += 8;
memcpy(prev, cur, 8); // Update stored frame
}
}
forcedBlock = (forcedBlock + 1) % 128;
if (deltaLen == 0)
return; // No update needed
// ==== Send frame ====
uint8_t header[5] = {
0xAA, 0x55, 0x02,
(uint8_t)(deltaLen >> 8),
(uint8_t)(deltaLen & 0xFF)
};
UART_Send(header, 5);
UART_Send(deltaFrame, deltaLen);
uint8_t end = 0x0A;
UART_Send(&end, 1);
}