Skip to content
Snippets Groups Projects
Verified Commit da3c11dc authored by rahix's avatar rahix
Browse files

feat(bootloader): Add a boot-splash


Signed-off-by: default avatarRahix <rahix@rahix.de>
parent 352b5a97
No related branches found
No related tags found
1 merge request!55Refactor Bootloader & add a boot-splash
Pipeline #1622 passed
#include "bootloader.h"
/* Autogenerated */
#include "splash-screen.h"
#include "GUI_Paint.h"
#include "display.h"
/*
* "Decompress" splash-screen image. The algorithm works as follows:
*
* Each byte encodes up to 127 pixels in either white or black. The most
* significant bit determines the color, the remaining 7 bits determine the
* amount.
*/
static void bootloader_display_splash(void)
{
int idx = 0;
for (int i = 0; i < sizeof(splash); i++) {
uint16_t color = (splash[i] & 0x80) ? 0xffff : 0x0000;
uint8_t length = splash[i] & 0x7f;
for (int j = 0; j < length; j++) {
uint16_t x = idx % 160;
uint16_t y = idx / 160;
Paint_SetPixel(x, y, color);
idx++;
}
}
LCD_Update();
}
/*
* Initialize the display.
*/
void bootloader_display_init(void)
{
;
bootloader_display_splash();
}
/*
......
......@@ -205,10 +205,11 @@ int main(void)
*/
pmic_set_button_callback(pmic_button);
bootloader_display_header();
bootloader_display_init();
// If the button is pressed, we go into MSC mode.
if (PB_Get(3)) {
bootloader_display_header();
bootloader_display_line(2, "USB activated.", 0xffff);
bootloader_display_line(3, "Ready.", 0xffff);
run_usbmsc();
......@@ -224,36 +225,42 @@ int main(void)
int res = check_integrity();
if (res == -ENOENT) {
printf("card10.bin not found!\n");
bootloader_display_line(
2, "card10.bin not found", 0xffff
);
} else if (res == -EINVAL) {
printf("card10.bin CRC is invalid!\n");
bootloader_display_header();
bootloader_display_line(
2, "Integrity check failed", 0xffff
);
bootloader_display_line(4, "Trying to boot", 0xffff);
} else if (res == 0) {
printf("Found valid application image\n");
if (is_update_needed()) {
printf("Trying to update firmware from external flash\n");
bootloader_display_header();
bootloader_display_line(
4, "Updating ...", 0xffff
3, "Updating ...", 0xffff
);
erase_partition();
flash_partition();
bootloader_display_line(
4, "Trying to boot", 0xffff
);
} else {
printf("No update needed\n");
}
}
} else {
bootloader_display_header();
bootloader_display_line(
2, "Failed to mount filesystem", 0xffff
);
printf("Failed to mount the external flash\n");
bootloader_display_line(4, "Trying to boot", 0xffff);
}
printf("Trying to boot\n");
bootloader_display_line(4, "Trying to boot", 0xffff);
boot((uintptr_t *)PARTITION_START);
......
name = 'bootloader'
splash_screen = custom_target(
'splash-screen.h',
output: 'splash-screen.h',
input: 'splash-screen.png',
command: [
python3,
meson.current_source_dir() + '../tools/bootloader-image.py',
'-n', 'splash',
'@INPUT@',
'@OUTPUT@',
],
)
executable(
name + '.elf',
'main.c',
......@@ -7,6 +20,7 @@ executable(
'bootloader-display.c',
'bootloader-usb.c',
'crc16-ccitt.c',
splash_screen,
dependencies: [
libcard10,
max32665_startup_boot,
......
bootloader/splash-screen.png

6.18 KiB

#!/usr/bin/env python3
import argparse
import os
from PIL import Image
def main() -> None:
parser = argparse.ArgumentParser(
description="""\
\"Compress\" an image for the boot-splash.
The boot-splash is a two-color image."""
)
parser.add_argument("image", help="Boot-splash image")
parser.add_argument("-n", "--name", help="Name of the data-block")
parser.add_argument("output", help="Output file name")
args = parser.parse_args()
im = Image.open(args.image)
assert im.size[0] == 160, "Image must be 160 pixels wide"
assert im.size[1] == 80, "Image must be 80 pixels high)"
if args.name is not None:
name = args.name
else:
name = os.path.splitext(os.path.basename(args.image))[0].replace("-", "_")
with open(args.output, "w") as f:
tmp = """\
#include <stdint.h>
/*
* This is the splash-screen image, compressed using a very primitive algorithm:
*
* Each byte encodes up to 127 pixels in either white or black. The most
* significant bit determines the color, the remaining 7 bits determine the
* amount.
*/
const uint8_t {name}[] = {{
"""
f.write(tmp.format(name=name))
total = 0
start = 0
previous_white = False
for i in range(160 * 80):
x = i % 160
y = i // 160
white = im.getpixel((x, y))[0] > 0
if white != previous_white or i - start == 127:
length = i - start
assert length < 128, "Internal error"
value = (length & 0x7F) | (0x80 if previous_white else 0x00)
tmp = """\
/* {length} pixels in {color} */
0x{value:x},
"""
f.write(
tmp.format(
length=length,
color="white" if previous_white else "black",
value=value,
)
)
previous_white = white
start = i
total += length
tmp = """\
}};
"""
f.write(tmp.format())
assert total < (160 * 80), "Internal error"
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment