From cc3cf039d240f1bbbeec0dad94e9aec2ad3c0233 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 13 Feb 2022 10:34:35 +1100 Subject: [PATCH] Copy over images --- Bootup Logos/Images/IronOS.gif | Bin 0 -> 26202 bytes Bootup Logos/Images/IronOS.png | Bin 0 -> 458 bytes Bootup Logos/Images/IronOS_L.gif | Bin 0 -> 26238 bytes Bootup Logos/Images/IronOS_L.png | Bin 0 -> 300 bytes Bootup Logos/Images/Pinecil.png | Bin 0 -> 258 bytes Bootup Logos/Images/Pinecil_L.png | Bin 0 -> 259 bytes Bootup Logos/Images/TS100.png | Bin 0 -> 251 bytes Bootup Logos/Images/TS100_L.png | Bin 0 -> 245 bytes Bootup Logos/Images/TS80.png | Bin 0 -> 262 bytes Bootup Logos/Images/TS80P.png | Bin 0 -> 267 bytes Bootup Logos/Images/TS80P_L.png | Bin 0 -> 263 bytes Bootup Logos/Images/TS80_L.png | Bin 0 -> 262 bytes Bootup Logos/README.md | 8 + Bootup Logos/img2logo.py | 291 ++++++++++++++++++++++++++++++ 14 files changed, 299 insertions(+) create mode 100644 Bootup Logos/Images/IronOS.gif create mode 100644 Bootup Logos/Images/IronOS.png create mode 100644 Bootup Logos/Images/IronOS_L.gif create mode 100644 Bootup Logos/Images/IronOS_L.png create mode 100644 Bootup Logos/Images/Pinecil.png create mode 100644 Bootup Logos/Images/Pinecil_L.png create mode 100644 Bootup Logos/Images/TS100.png create mode 100644 Bootup Logos/Images/TS100_L.png create mode 100644 Bootup Logos/Images/TS80.png create mode 100644 Bootup Logos/Images/TS80P.png create mode 100644 Bootup Logos/Images/TS80P_L.png create mode 100644 Bootup Logos/Images/TS80_L.png create mode 100644 Bootup Logos/README.md create mode 100644 Bootup Logos/img2logo.py diff --git a/Bootup Logos/Images/IronOS.gif b/Bootup Logos/Images/IronOS.gif new file mode 100644 index 0000000000000000000000000000000000000000..52c2a42512e800bfc5cbc7b8e292512ca318b91d GIT binary patch literal 26202 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 Z00;mC00IC3fB--MAOH{m2>eF`{tYb>0iyr_ literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/IronOS.png b/Bootup Logos/Images/IronOS.png new file mode 100644 index 0000000000000000000000000000000000000000..a728fadc3cb5ec224ee6df151eb818c5c64037e0 GIT binary patch literal 458 zcmV;*0X6=KP)AHIP0004zNklCCbldFo|Re*0=)vYo@(H0Fa_~HQb*wbMxQ6p%wFK?wtvt zu`K}n*wRC2fh%!Q4hoEMj%6rebtitr(%#$xU=%`=Cvh175ql#U^fF`bi+=n3BiV>Z zMN%MV&_CL!3!zO~$(J}F?1Bh;GpEu` zUa_jWZu6uKAnfnfK+kRg&`n}zywdTVxpdF^0r+AXACQp|j{pDw07*qoM6N<$f|_>E AKL7v# literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/IronOS_L.gif b/Bootup Logos/Images/IronOS_L.gif new file mode 100644 index 0000000000000000000000000000000000000000..b7f08857bf37403d0f841d893b0d0b7c1306bc91 GIT binary patch literal 26238 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 literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/IronOS_L.png b/Bootup Logos/Images/IronOS_L.png new file mode 100644 index 0000000000000000000000000000000000000000..befd3aa045eca2893fa42d41ae204b2353047c5e GIT binary patch literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5s!VDy(r=*_(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;wdE{bbMdP|}jIM%d`O_Cd)e)^}0|({lG|60ZZWJq q5%@x8nOer-?SEISFO$#TEdFJSz~Ruv3;2LeXYh3Ob6Mw<&;$TMl5qL} literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/Pinecil.png b/Bootup Logos/Images/Pinecil.png new file mode 100644 index 0000000000000000000000000000000000000000..29d7ce11310bf51c9eea991b0762f53eb69fd6d4 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5s!VDy(r=*_(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;wn$y<2oh1REk{Tx`!JK~zn yPCv_1$dOK*+Vj6_U3_Ntr6(0PGF)m@7cpzc^7#b66!`^o5QC?ypUXO@geCwlYFwuP literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/Pinecil_L.png b/Bootup Logos/Images/Pinecil_L.png new file mode 100644 index 0000000000000000000000000000000000000000..00e50f7ee68c53d5bbc67abf25ecc334917c243e GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5s!VDy(r=*_(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;wjI08Q@=KyQh48V+5govBR=KO zgyk$|byb~9LKo{>^mC^78qRF%VO_l1vxHISEuW9zjmy`8E@JR>^>bP0l+XkK34B_# literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/TS100.png b/Bootup Logos/Images/TS100.png new file mode 100644 index 0000000000000000000000000000000000000000..4af79035b99949ebe95175b6778d8a316d353d61 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5s!VDy(r=*_(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;w+i+ZC3kqrnN>9m)j){uGago@{El7 z!QEk8;f&h99;sd4&bdThF}FU4#aX;1v-=3oiQ8Kz7i~8`&guQ-NY(>BnS+OqOnVu2 sxUzYI(a)x7{axi({wEbLUd*6pd4#Xvf&Y{%K$kFhy85}Sb4q9e02mQlumAu6 literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/TS100_L.png b/Bootup Logos/Images/TS100_L.png new file mode 100644 index 0000000000000000000000000000000000000000..82c5ba2aaa5cd39a8ca33903cabc5ae17f74e0aa GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5s!VDy(r=*_(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;wNT^vI!P9F`7 z=4&wEXqLY4J3g%ONn{1`*#dk*T!Hle|NocXoPQU{;wL2Qf1%p6bol}ndNn{1`*#dk*T!Hle|NocXoPQU{;w(IoxgufFxtliudBlWT1zm91tBjCT0J@h|#7#=_!>3+FYdhbIb&h;TmjSL1E2 z%+pn=6*ur)bM{q?>W$q7slo^JBAR}sctx#r4ZkD1<-2G1Ca)bALJi*Y@jhh`wQ0Qb zc7qf1BTJ2wPl_1SzbyQB=<(l=PqXeE?$G4?`LR~^o=^d!?G7Gy2j-f5pvxFMUHx3v IIVCg!0E5|J%>V!Z literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/TS80P_L.png b/Bootup Logos/Images/TS80P_L.png new file mode 100644 index 0000000000000000000000000000000000000000..beae7b9b296cdd66acc8ed481c864b53a74d4465 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5s!VDy(r=*_(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;wNU@fk)aq^1zDZ!R2`ldB!SvT;#U$nSE$1C3U$$#dIampZ2mK?;k^7o8%6LYdd({W5d=M0$s)6>FVdQ&MBb@ E0OJo{=Kufz literal 0 HcmV?d00001 diff --git a/Bootup Logos/Images/TS80_L.png b/Bootup Logos/Images/TS80_L.png new file mode 100644 index 0000000000000000000000000000000000000000..e2127a93f44bde1c75cc5f4dcda1191a2c7e2617 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5s!VDy(r=*_(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;wDBsh2xg>sJ6q~CGUzp9& zs@Y{KCz?0$d+G`=3(;+EnlOLTgiyZ&i5a)AnjC)MyK?ry*EfZwB&No-y*AX~v2?y- zaX){a;O4`xIj23o%BSpU&c57!K{jLeqxWplnrvnZ(right)|TS100|TS80|TS80P|Pinecil|IronOS +static
(left)|TS100_L|TS80_L|TS80P_L|Pinecil_L|IronOS_L +animated|||||IronOS +notes|||||   ^^^^^^^^
*(This loops just for
demonstration purposes,
the real thing
only plays once.)* diff --git a/Bootup Logos/img2logo.py b/Bootup Logos/img2logo.py new file mode 100644 index 0000000..3e5239f --- /dev/null +++ b/Bootup Logos/img2logo.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python +# coding=utf-8 +from __future__ import division +import os, sys, struct, zlib + + +try: + from PIL import Image, ImageOps +except ImportError as error: + raise ImportError("{}: {} requres Python Imaging Library (PIL). " + "Install with `pip` or OS-specific package " + "management tool." + .format(error, sys.argv[0])) + +VERSION_STRING = '0.03' + +LCD_WIDTH = 96 +LCD_HEIGHT = 16 +LCD_NUM_BYTES = LCD_WIDTH * LCD_HEIGHT // 8 +LCD_PADDED_SIZE = 1024 + +INTELHEX_DATA_RECORD = 0x00 +INTELHEX_END_OF_FILE_RECORD = 0x01 +INTELHEX_EXTENDED_LINEAR_ADDRESS_RECORD = 0x04 +INTELHEX_BYTES_PER_LINE = 16 +INTELHEX_MINIMUM_SIZE = 4096 + +DFU_PINECIL_ALT = 0 +DFU_PINECIL_VENDOR = 0x28e9 +DFU_PINECIL_PRODUCT = 0x0189 +DFU_LOGO_ADDRESS = 0x0801F800 +DFU_TARGET_NAME = b"Pinecil" +DFU_PREFIX_SIZE = 11 +DFU_SUFFIX_SIZE = 16 + +def split16(word): + """return high and low byte of 16-bit word value as tuple""" + return (word >> 8) & 0xff, word & 0xff + + +def compute_crc(data): + return 0xFFFFFFFF & -zlib.crc32(data) - 1 + + +def intel_hex_line(record_type, offset, data): + """generate a line of data in Intel hex format""" + # length, address offset, record type + record_length = len(data) + yield ':{:02X}{:04X}{:02X}'.format(record_length, offset, record_type) + + # data + for byte in data: + yield "{:02X}".format(byte) + + # compute and write checksum (now using unix style line endings for DFU3.45 compatibility + yield "{:02X}\n".format((((sum(data, # sum data ... + record_length # ... and other ... + + sum(split16(offset)) # ... fields ... + + record_type) # ... on line + & 0xff) # low 8 bits + ^ 0xff) # two's ... + + 1) # ... complement + & 0xff) # low 8 bits + + +def intel_hex(file, bytes_, start_address=0x0): + """write block of data in Intel hex format""" + def write(generator): + file.write(''.join(generator)) + + if len(bytes_) % INTELHEX_BYTES_PER_LINE != 0: + raise ValueError("Program error: Size of LCD data is not evenly divisible by {}" + .format(INTELHEX_BYTES_PER_LINE)) + + address_lo = start_address & 0xffff + address_hi = (start_address >> 16) & 0xffff + + write(intel_hex_line(INTELHEX_EXTENDED_LINEAR_ADDRESS_RECORD, 0, + split16(address_hi))) + + size_written = 0 + while size_written < INTELHEX_MINIMUM_SIZE: + offset = address_lo + for line_start in range(0, len(bytes_), INTELHEX_BYTES_PER_LINE): + write(intel_hex_line(INTELHEX_DATA_RECORD, offset, + bytes_[line_start:line_start + INTELHEX_BYTES_PER_LINE])) + size_written += INTELHEX_BYTES_PER_LINE + if size_written >= INTELHEX_MINIMUM_SIZE: + break + offset += INTELHEX_BYTES_PER_LINE + + write(intel_hex_line(INTELHEX_END_OF_FILE_RECORD, 0, ())) + + +def build_dfu(file, bytes_): + data = b"" + for byte in bytes_: + data += byte.to_bytes(1, byteorder="big") + + data = ( + struct.pack("<2I", DFU_LOGO_ADDRESS, len(data)) + data + ) + data = ( + struct.pack( + "<6sBI255s2I", b"Target", DFU_PINECIL_ALT, 1, DFU_TARGET_NAME, len(data), 1 + ) + + data + ) + data = ( + struct.pack( + "<5sBIB", b"DfuSe", 1, DFU_PREFIX_SIZE + len(data) + DFU_SUFFIX_SIZE, 1 + ) + + data + ) + data += struct.pack("<4H3sB", 0, DFU_PINECIL_PRODUCT, DFU_PINECIL_VENDOR, 0x011A, b"UFD", DFU_SUFFIX_SIZE) + crc = compute_crc(data) + data += struct.pack("