From: Nathael Pajani Date: Tue, 30 Jan 2024 21:55:44 +0000 (+0100) Subject: Add tools to dump display (make screenshots) of Scialys module X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=ac8f9782c61780b75eee377a165a14f6d2d805f7;p=soft%2Flpc122x%2Fscialys Add tools to dump display (make screenshots) of Scialys module --- diff --git a/host/display_dump/.gitignore b/host/display_dump/.gitignore new file mode 100644 index 0000000..ea41698 --- /dev/null +++ b/host/display_dump/.gitignore @@ -0,0 +1,3 @@ +dump_cut_to_raw +mono_to_gray +png/ diff --git a/host/display_dump/README b/host/display_dump/README new file mode 100644 index 0000000..f52ab98 --- /dev/null +++ b/host/display_dump/README @@ -0,0 +1,40 @@ +### +# Dump Scialys screen content and convert it to PNG file +### + + +### Step 1 : Patch +Apply dumper.patch to scialys module sources +Compile +Flash binary to module + + +### Step 2 : Dump(s) +In one terminal : + cat /dev/ttyUSB0 > log_images.tmp +On the module, go to the screen you want to dump +In another terminal : + echo "s" > /dev/ttyUSB0 +Repeat last two steps for each screen you need + + +### Step 3 : Cut the dump +Compile dump "cutter" + make dump_cut_to_raw +And cut + mkdir imgs.cut + ./dump_cut_to_raw log_images.tmp imgs.cut/cut_raw +Maybe remove last image +And keep only the 1024 first bytes of each file + cd imgs.cut/ + for i in cut* ; do dd if=$i of=../imgs.raw/$i bs=1024 count=1 ; done + + +### Step 4 : Transform to 8bits grayscale + cd ../imgs.raw/ + for i in * ; do ../mono_to_gray $i ../imgs.ok/$i ; done + +### Step 5 : Convert to PNG + cd ../imgs.ok/ + for i in * ; do convert -size 128x64 -depth 8 -bordercolor black -border 8 -fill yellow -opaque white "gray:$i" "png:../png/$i.png" ; done + diff --git a/host/display_dump/dump_cut_to_raw.c b/host/display_dump/dump_cut_to_raw.c new file mode 100644 index 0000000..49711e1 --- /dev/null +++ b/host/display_dump/dump_cut_to_raw.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include + + +int main(int argc, char** argv) +{ + int src_fd = 0, dest_fd = 0, dest_fd_cnt = 0; + int idx = 0, len = 0; + uint8_t buf = 0, pbuf = 0; + uint8_t mark = 0, start = 0; + + if (argc != 3) { + printf("Need orig file name and destination files prefix as argument\n"); + } + + src_fd = open(argv[1], O_RDONLY, 0); + + while (read(src_fd, &buf, 1) != 0) { + idx++; + if (dest_fd == 0) { + char name[150]; + snprintf(name, 150, "%s_%03d.img", argv[2], dest_fd_cnt); + dest_fd_cnt++; + dest_fd = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + printf("Opened %s\n", name); + } + if (buf == '#') { + if (pbuf == '#') { + mark++; + if (mark >= 3) { + if (start == 0) { + printf("idx: %d\n", idx); + mark = 0; + start = 1; + pbuf = buf; + continue; + } else { + start = 0; + printf("Wrote %d to file\n", len); + printf("idx: %d\n", idx); + len = 0; + close(dest_fd); + dest_fd = 0; + } + } + } else { + mark = 0; + } + } + pbuf = buf; + if (start == 1) { + len++; + write(dest_fd, &buf, 1); + } + } + printf("idx: %d\n", idx); + close(src_fd); + + return 0; +} diff --git a/host/display_dump/dumper.patch b/host/display_dump/dumper.patch new file mode 100644 index 0000000..b7bc3cf --- /dev/null +++ b/host/display_dump/dumper.patch @@ -0,0 +1,68 @@ +diff -ruN back/comm.c dumper/comm.c +--- back/comm.c 2024-01-30 12:08:24.424360768 +0100 ++++ dumper/comm.c 2024-01-30 03:36:01.309621481 +0100 +@@ -40,6 +40,7 @@ + + /***************************************************************************** */ + /* Rx interrupt handler for system configuration over USB */ ++extern volatile uint8_t send_display_data; + void config_rx(uint8_t c) + { + /* FAN control */ +@@ -48,6 +49,9 @@ + } else { + gpio_clear(fan_ctrl); + } ++ if (c == 's') { ++ send_display_data = 1; ++ } + } + + +diff -ruN back/interface.c dumper/interface.c +--- back/interface.c 2024-01-30 12:08:24.424360768 +0100 ++++ dumper/interface.c 2024-01-30 12:09:13.200358768 +0100 +@@ -67,6 +67,19 @@ + /* Oled Display */ + static uint8_t gddram[ 4 + GDDRAM_SIZE ]; + ++volatile uint8_t send_display_data = 0; ++void send_display_data_over_uart(void) ++{ ++ int len = 0; ++ serial_write(UART0, "####", 4); ++ while (len < GDDRAM_SIZE) { ++ len += serial_write(UART0, (char*)(gddram + 4 + len), (GDDRAM_SIZE - len)); ++ msleep(10); ++ } ++ msleep(10); ++ serial_write(UART0, "####", 4); ++} ++ + #define DISPLAY_ADDR 0x78 + struct oled_display display = { + .bus_type = SSD130x_BUS_I2C, +@@ -293,6 +306,11 @@ + } + /* Update Oled display */ + ssd130x_display_full_screen(&display); ++ ++ if (send_display_data == 1) { ++ send_display_data = 0; ++ send_display_data_over_uart(); ++ } + } + + +diff -ruN back/main.c dumper/main.c +--- back/main.c 2024-01-30 12:08:24.424360768 +0100 ++++ dumper/main.c 2024-01-30 03:36:01.309621481 +0100 +@@ -650,7 +650,7 @@ + slave_send_data(); + + /* Data Log */ +- if (1) { ++ if (0) { + external_disable |= linky_test; + uprintf(UART0, "#%c:%d:%d:%d:%d:%d:%d:", + mode, loop++, solar_prod_value, home_conso_value, diff --git a/host/display_dump/mono_to_gray.c b/host/display_dump/mono_to_gray.c new file mode 100644 index 0000000..8404a4a --- /dev/null +++ b/host/display_dump/mono_to_gray.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + + +#define REV1(x) ( (((x) >> 1) & 0x5555555555555555) | (((x) & 0x5555555555555555) << 1) ) +#define REV2(x) ( ((REV1(x) >> 2) & 0x3333333333333333) | ((REV1(x) & 0x3333333333333333) << 2) ) +#define REVERSE(x) ( ((REV2(x) >> 4) & 0x0F0F0F0F0F0F0F0F) | ((REV2(x) & 0x0F0F0F0F0F0F0F0F) << 4) ) + +#define SBV(x, n) ( ((x) & (0x01ULL << (n * 8))) >> (n * 7) ) +#define VER1(x) ( SBV(x, 7) | SBV(x, 6) | SBV(x, 5) | SBV(x, 4) | SBV(x, 3) | SBV(x, 2) | SBV(x, 1) | SBV(x, 0) ) +#define VER2(x, n) ( (VER1((x) >> n)) << (n * 8) ) +#define VERTICAL(x) ( VER2(x, 0) | VER2(x, 1) | VER2(x, 2)| VER2(x, 3)| VER2(x, 4)| VER2(x, 5)| VER2(x, 6)| VER2(x, 7) ) + + +#define SBR(x, n) REVERSE( SBV(x, n) ) +#define VR1(x) ( SBR(x, 7) | SBR(x, 6) | SBR(x, 5) | SBR(x, 4) | SBR(x, 3) | SBR(x, 2) | SBR(x, 1) | SBR(x, 0) ) +#define VR2(x, n) ( (VR1((x) >> (7 - n))) << (n * 8) ) +#define VERTICAL_REV(x) ( VR2(x, 0) | VR2(x, 1) | VR2(x, 2)| VR2(x, 3)| VR2(x, 4)| VR2(x, 5)| VR2(x, 6)| VR2(x, 7) ) + + +int main(int argc, char** argv) +{ + int src_fd = 0, dest_fd = 0; + int idx = 0; + uint64_t buf = 0; + uint8_t image[128*64]; + + if (argc != 3) { + printf("Need orig file name and destination file name as argument\n"); + } + + src_fd = open(argv[1], O_RDONLY, 0); + dest_fd = open(argv[2], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + while (read(src_fd, &buf, 8) != 0) { + uint64_t rev = VERTICAL_REV(buf); + int tline = 0, tcol = 0, shift = 0; + for (tline = 0; tline < 8; tline++) { + for (tcol = 0; tcol < 8; tcol++) { + image[ ((idx%16) * 8) + ((idx/16) * (128 * 8)) + tline * 128 + tcol] = (rev & (0x8000000000000001 >> shift)) ? 0xFF : 0x00; + shift++; + } + } + idx++; + } + write(dest_fd, image, (128*64)); + close(src_fd); + close(dest_fd); + printf("idx: %d\n", idx); + if (0) { + int line = 0, col = 0; + for (line = 0; line < 64; line++) { + for (col = 0; col < 128; col++) { + printf("%c", image[ line * 128 + col] ? '#' : ' '); + } + printf("\n"); + } + } + + return 0; +} +