summaryrefslogtreecommitdiff
path: root/src/compile_eeprom.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile_eeprom.py')
-rwxr-xr-xsrc/compile_eeprom.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/compile_eeprom.py b/src/compile_eeprom.py
new file mode 100755
index 0000000..52dbbfc
--- /dev/null
+++ b/src/compile_eeprom.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+from PIL import BdfFontFile, Image
+import os
+import serial
+import argparse
+
+compiled_output_path = 'compiled_eeprom'
+header_path = 'eeprom_address.h'
+eeprom_length = 131072 # 128 kib
+
+data_path = "./eeprom_data"
+
+output = open(compiled_output_path, 'wb')
+header = open(header_path, 'w')
+
+page_bit_width = 128
+page_bit_height = 8
+page_cnt = 4
+
+
+
+#fonts
+# for some reason BdfFontFile.BdfFontFile.bitmap doesn't have proper spacing
+# so we'll just manually go through each character ourselves
+# it's expected I'll rename fonts to how I think they should be refrenced beorehand
+# also note we have no protection from using unsed chars, I can't let this project
+# get to big for litteraly no reason
+
+header.write("/** GENERATED BY EEPROM COMPILER SCRIPT **/\n\n")
+header.write("// FONTS\n")
+
+for file in os.listdir("{}/fonts/".format(data_path)):
+ path = "{}/fonts/{}".format(data_path, file)
+ if os.path.isfile(path) and path.split('.')[-1] == 'bdf':
+ with open(path, 'rb') as font_fd:
+ font_bdf = BdfFontFile.BdfFontFile(font_fd)
+ font_name = file.split('.')[0].capitalize()
+
+ header.write("#define FONT_{}_ADDR\t0x{:04x}\n".format(font_name, output.tell()))
+
+ first_char = False
+ for char in enumerate(font_bdf.glyph):
+ if char[1]:
+ if not first_char:
+ first_char = True
+ header.write(("#define FONT_{}_FIRST_CHAR\t{}\n"
+ "#define FONT_{}_WIDTH\t{}\n"
+ "#define FONT_{}_HEIGHT\t{}\n").format(
+ font_name, char[0],
+ font_name, char[1][-1].size[0],
+ font_name, char[1][-1].size[1]))
+ output.write(char[1][-1].tobytes('raw'))
+
+header.write("\n\n// IMAGES\n#define IMG_BEGIN\t0x{:04x}\n".format(output.tell()))
+
+image_cnt = 0
+
+# images
+for file in os.listdir("{}/images/".format(data_path)):
+ path = "{}/images/{}".format(data_path, file)
+ if os.path.isfile(path) and path.split('.')[-1] == 'png':
+ with open(path, 'rb') as image_fd:
+ image_cnt += 1
+ image_bitmap = []
+ image_bitmap_remapped = []
+ image = Image.open(image_fd)
+ if not image.mode == 'RGB':
+ print("this script only compiles RGB formatted photos! (I'm lazy\n")
+ exit(1)
+ header.write("#define IMG_{}_ADDR\t0x{:04x}\n".format(
+ file.split('.')[0].capitalize(),
+ output.tell()))
+ for byte in range(0, len(image.tobytes()), 3):
+ if (byte / 3) % 8 == 0:
+ image_bitmap.append(0)
+ if sum(image.tobytes()[byte:byte+3]) > 0:
+ image_bitmap[-1] |= (int(byte / 3)) % 8
+
+ # is this supposed to be big endian?
+ image_bitmap_remapped = [0] * len(image_bitmap)
+ for bit in range(0, page_bit_width * page_bit_height * page_cnt):
+ w = page_bit_width
+ h = page_bit_height
+ i = bit
+ #I am so sorry.
+ extract_bit = (((i % w) * page_bit_height) +
+ (int(i / w) % page_bit_height) +
+ (int(i / (w * page_bit_height)) *
+ (w * page_bit_height)))
+
+ if (extract_bit % 8) - (bit % 8) >= 0:
+ image_bitmap_remapped[int(bit / 8)] |= \
+ (image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) >> \
+ ((extract_bit % 8) - (bit % 8))
+ else:
+ image_bitmap_remapped[int(bit / 8)] |= \
+ (image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) << \
+ ((bit % 8) - (extract_bit % 8))
+ [output.write(byte.to_bytes(1, 'big')) for byte in image_bitmap_remapped]
+
+header.write("#define IMG_COUNT\t{}\n\n".format(image_cnt))
+
+
+
+print("EEPROM used: {}% ({} out of {} bits)".format(
+ (output.tell() / eeprom_length) * 100,
+ output.tell(), eeprom_length))
+
+if(output.tell() > eeprom_length):
+ print("WARNING: You've used more eeprom then there is available!\n")
+
+output.close()
+header.close()
+
+
+