diff --git a/firmware/.clangd b/firmware/.clangd new file mode 100644 index 0000000..d186728 --- /dev/null +++ b/firmware/.clangd @@ -0,0 +1,8 @@ +CompileFlags: + Remove: + - "-mlongcalls" + - "-fno-shrink-wrap" + - "-fstrict-volatile-bitfields" + - "-fno-tree-switch-conversion" + - "-std=gnu17" + Compiler: xtensa-esp32-elf-g++ \ No newline at end of file diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 0000000..e9063b9 --- /dev/null +++ b/firmware/.gitignore @@ -0,0 +1,6 @@ +.cache +.vscode +.devcontainer +build +sdkconfig +sdkconfig.ci \ No newline at end of file diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt new file mode 100644 index 0000000..42300d1 --- /dev/null +++ b/firmware/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(candytuft-firmware) diff --git a/firmware/README.md b/firmware/README.md new file mode 100644 index 0000000..9aa03ba --- /dev/null +++ b/firmware/README.md @@ -0,0 +1,53 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | ----- | + +# Hello World Example + +Starts a FreeRTOS task to print "Hello World". + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +## How to use example + +Follow detailed instructions provided specifically for this example. + +Select the instructions depending on Espressif chip installed on your development board: + +- [ESP32 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html) +- [ESP32-S2 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html) + + +## Example folder contents + +The project **hello_world** contains one source file in C language [hello_world_main.c](main/hello_world_main.c). The file is located in folder [main](main). + +ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` files that provide set of directives and instructions describing the project's source files and targets (executable, library, or both). + +Below is short explanation of remaining files in the project folder. + +``` +├── CMakeLists.txt +├── pytest_hello_world.py Python script used for automated testing +├── main +│ ├── CMakeLists.txt +│ └── hello_world_main.c +└── README.md This is the file you are currently reading +``` + +For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html) of the ESP-IDF Programming Guide. + +## Troubleshooting + +* Program upload failure + + * Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs. + * The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again. + +## Technical support and feedback + +Please use the following feedback channels: + +* For technical queries, go to the [esp32.com](https://esp32.com/) forum +* For a feature request or bug report, create a [GitHub issue](https://github.com/espressif/esp-idf/issues) + +We will get back to you as soon as possible. diff --git a/firmware/main/CMakeLists.txt b/firmware/main/CMakeLists.txt new file mode 100644 index 0000000..8c9e9cd --- /dev/null +++ b/firmware/main/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register(SRCS "src/hello_world_main.c" + "src/iic.c" + "src/lcd/ssd1306.c" + "src/ui/inputs.c" + "src/led/ws2811.c" + INCLUDE_DIRS "include") diff --git a/firmware/main/Kconfig.projbuild b/firmware/main/Kconfig.projbuild new file mode 100644 index 0000000..fa24f12 --- /dev/null +++ b/firmware/main/Kconfig.projbuild @@ -0,0 +1,68 @@ +menu "Candytuft Pin Mapping" + menu "Inputs" + config PIN_WHEEL_A + int "Rotary encoder pin A" + range 0 39 + default 21 + help + If using a non-standard mainboard, set this value to the GPIO connected to pin A of the rotary encoder. + + config PIN_WHEEL_B + int "Rotary encoder pin B" + range 0 39 + default 22 + help + If using a non-standard mainboard, set this value to the GPIO connected to pin B of the rotary encoder. + + config KEY_FORWARD + int "Front Panel Forward Key Mapping" + range 0 39 + default 4 + help + If using a non-standard mainboard, set this value to the GPIO connected to the Forward key. + + config KEY_BACKSPACE + int "Front Panel Backspace Key Mapping" + range 0 39 + default 13 + help + If using a non-standard mainboard, set this value to the GPIO connected to the Backspace key. + + config KEY_DONE + int "Front Panel Done Key Mapping" + range 0 39 + default 14 + help + If using a non-standard mainboard, set this value to the GPIO connected to the Done key. + + config KEY_CANCEL + int "Front Panel Cancel Key Mapping" + range 0 39 + default 18 + help + If using a non-standard mainboard, set this value to the GPIO connected to the Cancel key. + + config KEY_OPTION + int "Front Panel Option Key Mapping" + range 0 39 + default 19 + help + If using a non-standard mainboard, set this value to the GPIO connected to the Option key. + endmenu + + menu "LCD" + config LCD_SCL + int "LCD panel SCL pin mapping" + range 0 39 + default 25 + help + If using a non-standard mainboard, set this value to the GPIO connected to the LCD panel's SCL pin. + + config LCD_SDA + int "LCD panel SDA pin mapping" + range 0 39 + default 26 + help + If using a non-standard mainboard, set this value to the GPIO connected to the LCD panel's SDA pin. + endmenu +endmenu \ No newline at end of file diff --git a/firmware/main/component.mk b/firmware/main/component.mk new file mode 100644 index 0000000..e69de29 diff --git a/firmware/main/include/iic.h b/firmware/main/include/iic.h new file mode 100644 index 0000000..fcffb2f --- /dev/null +++ b/firmware/main/include/iic.h @@ -0,0 +1,23 @@ +/* MX-008 "Onyx Sovereign" -02 "Kingmaker" + * ============================================================================ + * === IIC interface configuration + * ============================================================================ + * + * Alexis Maya-Isabelle Shuping + * 29th March 2021 + * University of Florida + */ + +#pragma once + +#include + +#define T_IIC_INIT ("IIC INIT") +#define T_IIC_LCD ("IICL") + +#define IIC_NUM_LCD (I2C_NUM_0) + +void iicInit(i2c_port_t port, int sclNum, int sdaNum, bool pullUps, int clkRate); + +void iicCommand(i2c_port_t port, uint_fast8_t targetAddress, uint_fast8_t toSend); +void iicData(i2c_port_t port, uint_fast8_t targetAddress, uint_fast8_t toSend); diff --git a/firmware/main/include/lcd/FontBase.h b/firmware/main/include/lcd/FontBase.h new file mode 100644 index 0000000..940696b --- /dev/null +++ b/firmware/main/include/lcd/FontBase.h @@ -0,0 +1,9 @@ +#pragma once +#include + +typedef struct font_t { + const char* fTable; + uint16_t width; + uint16_t height; + uint16_t cSize; +} font_t; \ No newline at end of file diff --git a/firmware/main/include/lcd/FontComicSansMS16.h b/firmware/main/include/lcd/FontComicSansMS16.h new file mode 100644 index 0000000..8e1fda4 --- /dev/null +++ b/firmware/main/include/lcd/FontComicSansMS16.h @@ -0,0 +1,1756 @@ +/** + * This file provides 'Comic Sans MS' [16px] text font + * + * Generated using "STM32-LCD_Font_Generator" + * + * https://github.com/zst-embedded/STM32-LCD_Font_Generator + * + * on 2020-12-23 17:10:08 + * + * NOTE: Font generator modified for better vertical centering. + */ +#pragma once + +#include + +#include "FontBase.h" + +#define FontComicSansMS16_Name ("Comic Sans MS 16px") + +// 4608 bytes +static const char FontComicSansMS16_Table [] = { + // @0 ' ' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @48 '!' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @96 '"' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @144 '#' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x18, /* | # ## | */ + 0x06, 0x10, /* | ## # | */ + 0x3F, 0xFC, /* | ############ | */ + 0x3F, 0xFC, /* | ############ | */ + 0x04, 0x20, /* | # # | */ + 0x0C, 0x20, /* | ## # | */ + 0x08, 0x60, /* | # ## | */ + 0x7F, 0xF8, /* | ############ | */ + 0x7F, 0xF8, /* | ############ | */ + 0x18, 0x40, /* | ## # | */ + 0x10, 0xC0, /* | # ## | */ + 0x10, 0x80, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @192 '$' (16 pixels wide) + 0x00, 0x80, /* | # | */ + 0x01, 0xE0, /* | #### | */ + 0x07, 0xF0, /* | ####### | */ + 0x06, 0x80, /* | ## # | */ + 0x0C, 0x80, /* | ## # | */ + 0x0C, 0x80, /* | ## # | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xF0, /* | ###### | */ + 0x00, 0xB0, /* | # ## | */ + 0x00, 0x98, /* | # ## | */ + 0x0C, 0xB0, /* | ## # ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + + // @240 '%' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0E, 0x30, /* | ### ## | */ + 0x1F, 0x20, /* | ##### # | */ + 0x1B, 0x60, /* | ## ## ## | */ + 0x1F, 0x40, /* | ##### # | */ + 0x0E, 0xC0, /* | ### ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x38, /* | # ### | */ + 0x03, 0x3C, /* | ## #### | */ + 0x02, 0x66, /* | # ## ## | */ + 0x06, 0x3C, /* | ## #### | */ + 0x04, 0x38, /* | # ### | */ + 0x00, 0x00, /* | | */ + + // @288 '&' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0x60, /* | # ## | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x90, /* | ### # | */ + 0x04, 0xD0, /* | # ## # | */ + 0x08, 0x70, /* | # ### | */ + 0x08, 0x70, /* | # ### | */ + 0x0C, 0x70, /* | ## ### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0x98, /* | #### ## | */ + 0x00, 0x00, /* | | */ + + // @336 ''' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @384 '(' (16 pixels wide) + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + + // @432 ')' (16 pixels wide) + 0x02, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + + // @480 '*' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0x80, /* | ### | */ + 0x06, 0xC0, /* | ## ## | */ + 0x04, 0x60, /* | # ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @528 '+' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @576 ',' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + + // @624 '-' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xE0, /* | ##### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @672 '.' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @720 '/' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @768 '0' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xC0, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x10, /* | # # | */ + 0x08, 0x10, /* | # # | */ + 0x08, 0x10, /* | # # | */ + 0x08, 0x30, /* | # ## | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x70, /* | ## ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @816 '1' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x40, /* | # | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x03, 0xE0, /* | ##### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @864 '2' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xC0, /* | ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x06, 0x60, /* | ## ## | */ + 0x0C, 0x20, /* | ## # | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x07, 0xE0, /* | ###### | */ + 0x00, 0x00, /* | | */ + + // @912 '3' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xC0, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x04, 0x60, /* | # ## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xE0, /* | #### | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x20, /* | # | */ + 0x0C, 0x60, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @960 '4' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xE0, /* | ### | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0x60, /* | # ## | */ + 0x03, 0x60, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x04, 0x60, /* | # ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1008 '5' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0E, 0x30, /* | ### ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x30, /* | ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @1056 '6' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @1104 '7' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x06, 0x00, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @1152 '8' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xC0, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0xE0, /* | ###### | */ + 0x0E, 0x60, /* | ### ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @1200 '9' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xC0, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x0C, 0x70, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x01, 0xC0, /* | ### | */ + 0x07, 0x80, /* | #### | */ + 0x06, 0x00, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @1248 ':' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1296 ';' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1344 '<' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x07, 0x00, /* | ### | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1392 '=' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1440 '>' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xC0, /* | #### | */ + 0x03, 0x80, /* | ### | */ + 0x02, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1488 '?' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0x80, /* | ### | */ + 0x07, 0xC0, /* | ##### | */ + 0x04, 0x60, /* | # ## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0xE0, /* | ### | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0x80, /* | ### | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x02, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1536 '@' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x03, 0xE0, /* | ##### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x1C, 0x18, /* | ### ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x31, 0x84, /* | ## ## # | */ + 0x33, 0x06, /* | ## ## ## | */ + 0x36, 0x46, /* | ## ## # ## | */ + 0x26, 0xC6, /* | # ## ## ## | */ + 0x37, 0xFC, /* | ## ######### | */ + 0x33, 0x78, /* | ## ## #### | */ + 0x30, 0x00, /* | ## | */ + 0x18, 0x00, /* | ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0xE0, /* | ##### | */ + + // @1584 'A' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0x60, /* | ## ## | */ + 0x02, 0x20, /* | # # | */ + 0x07, 0xE0, /* | ###### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x30, /* | # ## | */ + 0x18, 0x10, /* | ## # | */ + 0x10, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @1632 'B' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0x80, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x04, 0x60, /* | # ## | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x60, /* | # ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x10, /* | # # | */ + 0x04, 0x70, /* | # ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0x80, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @1680 'C' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xF0, /* | #### | */ + 0x01, 0xF0, /* | ##### | */ + 0x03, 0x10, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x0C, 0x00, /* | ## | */ + 0x08, 0x00, /* | # | */ + 0x08, 0x00, /* | # | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x70, /* | ## ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0x80, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @1728 'D' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0x00, /* | #### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x08, 0xE0, /* | # ### | */ + 0x08, 0x30, /* | # ## | */ + 0x08, 0x10, /* | # # | */ + 0x08, 0x18, /* | # ## | */ + 0x08, 0x18, /* | # ## | */ + 0x18, 0x10, /* | ## # | */ + 0x18, 0x30, /* | ## ## | */ + 0x1F, 0xE0, /* | ######## | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @1776 'E' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0xE0, /* | ###### | */ + 0x00, 0x00, /* | | */ + + // @1824 'F' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xF0, /* | ####### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1872 'G' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xE0, /* | ### | */ + 0x03, 0xF0, /* | ###### | */ + 0x03, 0x10, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0D, 0xF8, /* | ## ###### | */ + 0x09, 0xF8, /* | # ###### | */ + 0x08, 0x18, /* | # ## | */ + 0x08, 0x18, /* | # ## | */ + 0x0C, 0x70, /* | ## ### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @1920 'H' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x08, 0x08, /* | # # | */ + 0x08, 0x08, /* | # # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0xF8, /* | ## ##### | */ + 0x1F, 0xF8, /* | ########## | */ + 0x1E, 0x08, /* | #### # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x00, 0x00, /* | | */ + + // @1968 'I' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x00, /* | | */ + + // @2016 'J' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xF8, /* | ####### | */ + 0x03, 0xF8, /* | ####### | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x08, 0x40, /* | # # | */ + 0x0C, 0x40, /* | ## # | */ + 0x0C, 0xC0, /* | ## ## | */ + 0x07, 0xC0, /* | ##### | */ + 0x03, 0x80, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @2064 'K' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x10, /* | # # | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x60, /* | # ## | */ + 0x04, 0xC0, /* | # ## | */ + 0x05, 0x80, /* | # ## | */ + 0x07, 0x00, /* | ### | */ + 0x07, 0x00, /* | ### | */ + 0x07, 0x80, /* | #### | */ + 0x05, 0xC0, /* | # ### | */ + 0x04, 0xE0, /* | # ### | */ + 0x04, 0x70, /* | # ### | */ + 0x04, 0x18, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @2112 'L' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x00, /* | | */ + + // @2160 'M' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x10, /* | # # | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0E, 0x38, /* | ### ### | */ + 0x1E, 0x38, /* | #### ### | */ + 0x1E, 0x68, /* | #### ## # | */ + 0x1A, 0x48, /* | ## # # # | */ + 0x12, 0x48, /* | # # # # | */ + 0x33, 0xCC, /* | ## #### ## | */ + 0x33, 0xCC, /* | ## #### ## | */ + 0x31, 0x8C, /* | ## ## ## | */ + 0x31, 0x84, /* | ## ## # | */ + 0x00, 0x00, /* | | */ + + // @2208 'N' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x0C, /* | ## ## | */ + 0x1C, 0x0C, /* | ### ## | */ + 0x1E, 0x0C, /* | #### ## | */ + 0x1B, 0x0C, /* | ## ## ## | */ + 0x19, 0x0C, /* | ## # ## | */ + 0x19, 0x84, /* | ## ## # | */ + 0x18, 0xC4, /* | ## ## # | */ + 0x18, 0x64, /* | ## ## # | */ + 0x18, 0x3C, /* | ## #### | */ + 0x18, 0x1C, /* | ## ### | */ + 0x10, 0x0C, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @2256 'O' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xF0, /* | ##### | */ + 0x07, 0xF8, /* | ######## | */ + 0x0E, 0x1C, /* | ### ### | */ + 0x0C, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @2304 'P' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0xE0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x70, /* | # ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0x80, /* | #### | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @2352 'Q' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x03, 0xE0, /* | ##### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x1C, 0x38, /* | ### ### | */ + 0x30, 0x0C, /* | ## ## | */ + 0x30, 0x0C, /* | ## ## | */ + 0x20, 0x0C, /* | # ## | */ + 0x20, 0x04, /* | # # | */ + 0x30, 0x04, /* | ## # | */ + 0x31, 0x8C, /* | ## ## ## | */ + 0x1C, 0xD8, /* | ### ## ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x1C, /* | ### | */ + 0x00, 0x0C, /* | ## | */ + 0x00, 0x04, /* | # | */ + + // @2400 'R' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0x00, /* | #### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0C, 0xE0, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0C, 0xE0, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @2448 'S' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xF0, /* | #### | */ + 0x03, 0xF8, /* | ####### | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xF8, /* | ####### | */ + 0x00, 0x18, /* | ## | */ + 0x00, 0x08, /* | # | */ + 0x08, 0x08, /* | # # | */ + 0x0C, 0x38, /* | ## ### | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @2496 'T' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x1F, 0xF8, /* | ########## | */ + 0x1F, 0xF8, /* | ########## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + + // @2544 'U' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x08, 0x18, /* | # ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x10, /* | ## # | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x70, /* | ## ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @2592 'V' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0C, 0x08, /* | ## # | */ + 0x0C, 0x18, /* | ## ## | */ + 0x0C, 0x18, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x20, /* | ## # | */ + 0x02, 0x60, /* | # ## | */ + 0x03, 0x60, /* | ## ## | */ + 0x03, 0x40, /* | ## # | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @2640 'W' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x60, 0x81, /* | ## # #| */ + 0x60, 0xC3, /* | ## ## ##| */ + 0x21, 0xC3, /* | # ### ##| */ + 0x31, 0xC2, /* | ## ### # | */ + 0x31, 0xC6, /* | ## ### ## | */ + 0x13, 0x46, /* | # ## # ## | */ + 0x13, 0x64, /* | # ## ## # | */ + 0x1A, 0x6C, /* | ## # ## ## | */ + 0x1E, 0x68, /* | #### ## # | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x00, 0x00, /* | | */ + + // @2688 'X' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x18, 0x18, /* | ## ## | */ + 0x1C, 0x18, /* | ### ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0xC0, /* | #### | */ + 0x06, 0x60, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x18, 0x30, /* | ## ## | */ + 0x10, 0x18, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @2736 'Y' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x18, 0x10, /* | ## # | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x60, /* | ## ## | */ + 0x03, 0x60, /* | ## ## | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @2784 'Z' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xFC, /* | ########## | */ + 0x0F, 0xF8, /* | ######### | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xFC, /* | ########## | */ + 0x0F, 0xFC, /* | ########## | */ + 0x00, 0x00, /* | | */ + + // @2832 '[' (16 pixels wide) + 0x01, 0xC0, /* | ### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @2880 '\' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x02, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x10, /* | # | */ + 0x00, 0x00, /* | | */ + + // @2928 ']' (16 pixels wide) + 0x01, 0xC0, /* | ### | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @2976 '^' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0x20, /* | ## # | */ + 0x02, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @3024 '_' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x3F, 0xF0, /* | ########## | */ + + // @3072 '`' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @3120 'a' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x0C, 0x20, /* | ## # | */ + 0x0C, 0x20, /* | ## # | */ + 0x04, 0x60, /* | # ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0x90, /* | ### # | */ + 0x00, 0x00, /* | | */ + + // @3168 'b' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x00, /* | # | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x20, /* | ## # | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x00, 0x00, /* | | */ + + // @3216 'c' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x06, 0x20, /* | ## # | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @3264 'd' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x10, /* | # | */ + 0x00, 0x18, /* | ## | */ + 0x00, 0x18, /* | ## | */ + 0x00, 0x10, /* | # | */ + 0x00, 0x10, /* | # | */ + 0x01, 0xF0, /* | ##### | */ + 0x03, 0xF0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x10, /* | # # | */ + 0x04, 0x10, /* | # # | */ + 0x06, 0x30, /* | ## ## | */ + 0x03, 0xF0, /* | ###### | */ + 0x01, 0xF0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @3312 'e' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xF0, /* | ###### | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x60, /* | ## ## | */ + 0x05, 0x80, /* | # ## | */ + 0x06, 0x10, /* | ## # | */ + 0x07, 0xF0, /* | ####### | */ + 0x01, 0xE0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @3360 'f' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xE0, /* | ### | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3408 'g' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xF0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x04, 0x60, /* | # ## | */ + 0x07, 0xA0, /* | #### # | */ + 0x03, 0xA0, /* | ### # | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x07, 0xE0, /* | ###### | */ + + // @3456 'h' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0xE0, /* | ## ### | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0x30, /* | ### ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x10, /* | ## # | */ + 0x06, 0x10, /* | ## # | */ + 0x06, 0x10, /* | ## # | */ + 0x00, 0x00, /* | | */ + + // @3504 'i' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3552 'j' (16 pixels wide) + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x04, 0x40, /* | # # | */ + 0x06, 0xC0, /* | ## ## | */ + 0x03, 0xC0, /* | #### | */ + + // @3600 'k' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x06, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x02, 0x10, /* | # # | */ + 0x02, 0x30, /* | # ## | */ + 0x06, 0x70, /* | ## ### | */ + 0x06, 0xE0, /* | ## ### | */ + 0x06, 0xC0, /* | ## ## | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0x60, /* | ### ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x10, /* | ## # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @3648 'l' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3696 'm' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x13, 0x30, /* | # ## ## | */ + 0x1F, 0xF8, /* | ########## | */ + 0x1D, 0xD8, /* | ### ### ## | */ + 0x19, 0x88, /* | ## ## # | */ + 0x19, 0x88, /* | ## ## # | */ + 0x18, 0x8C, /* | ## # ## | */ + 0x18, 0x8C, /* | ## # ## | */ + 0x10, 0x8C, /* | # # ## | */ + 0x00, 0x00, /* | | */ + + // @3744 'n' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0xE0, /* | ## ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0x20, /* | ### # | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @3792 'o' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x60, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @3840 'p' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x00, /* | # | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0xE0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xC0, /* | ##### | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + + // @3888 'q' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x04, 0x20, /* | # # | */ + 0x0C, 0x20, /* | ## # | */ + 0x06, 0x60, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + + // @3936 'r' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0xE0, /* | # ### | */ + 0x07, 0x20, /* | ### # | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3984 's' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xE0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x00, /* | ## | */ + 0x07, 0x00, /* | ### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x60, /* | ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @4032 't' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @4080 'u' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x20, /* | # # | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x20, /* | ## # | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @4128 'v' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x20, /* | # # | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x60, /* | ## ## | */ + 0x02, 0x60, /* | # ## | */ + 0x02, 0x40, /* | # # | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @4176 'w' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x08, 0x88, /* | # # # | */ + 0x09, 0xC8, /* | # ### # | */ + 0x09, 0xC8, /* | # ### # | */ + 0x0D, 0xD8, /* | ## ### ## | */ + 0x0F, 0x50, /* | #### # # | */ + 0x0E, 0x70, /* | ### ### | */ + 0x06, 0x70, /* | ## ### | */ + 0x04, 0x20, /* | # # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @4224 'x' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x18, /* | # ## | */ + 0x03, 0x30, /* | ## ## | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x07, 0x30, /* | ### ## | */ + 0x04, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @4272 'y' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x03, 0x40, /* | ## # | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + + // @4320 'z' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x00, /* | | */ + + // @4368 '{' (16 pixels wide) + 0x00, 0xC0, /* | ## | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0xC0, /* | ## | */ + + // @4416 '|' (16 pixels wide) + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + + // @4464 '}' (16 pixels wide) + 0x07, 0x00, /* | ### | */ + 0x07, 0x80, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x07, 0x00, /* | ### | */ + 0x07, 0x00, /* | ### | */ + + // @4512 '~' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x07, 0x10, /* | ### # | */ + 0x0D, 0xB0, /* | ## ## ## | */ + 0x08, 0xF0, /* | # #### | */ + 0x08, 0xE0, /* | # ### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @4560 '°' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x02, 0x20, /* | # # | */ + 0x02, 0x60, /* | # ## | */ + 0x03, 0xE0, /* | ##### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ +}; + +static const font_t FontComicSansMS16 = { + .fTable = FontComicSansMS16_Table, + .width = 16, + .height = 16, + .cSize = 32 +}; diff --git a/firmware/main/include/lcd/FontLiberationMono12.h b/firmware/main/include/lcd/FontLiberationMono12.h new file mode 100644 index 0000000..852aa4b --- /dev/null +++ b/firmware/main/include/lcd/FontLiberationMono12.h @@ -0,0 +1,1351 @@ +/** + * This file provides 'Liberation Mono' [12px] text font + * for STM32xx-EVAL's LCD driver. + * + * Generated by zst123 on 2021-04-02 19:24:42 + */ +#pragma once + +#include "lcd/FontBase.h" + +#define FontLiberationMono12_Name ("Liberation Mono 12px") + +// 2280 bytes +static const char FontLiberationMono12_Table [] = { + // @0 ' ' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @24 '!' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @48 '"' (8 pixels wide) + 0x00, /* | | */ + 0x16, /* | # # | */ + 0x14, /* | # # | */ + 0x14, /* | # # | */ + 0x14, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @72 '#' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x02, /* | | */ + 0x12, /* | # | */ + 0x3F, /* | ##### | */ + 0x10, /* | # | */ + 0x04, /* | # | */ + 0x3E, /* | #### | */ + 0x24, /* | # # | */ + 0x24, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @96 '$' (8 pixels wide) + 0x08, /* | # | */ + 0x1E, /* | ### | */ + 0x2A, /* | # # | */ + 0x28, /* | # # | */ + 0x1C, /* | ### | */ + 0x0A, /* | # | */ + 0x09, /* | # # | */ + 0x2B, /* | # # # | */ + 0x3E, /* | #### | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @120 '%' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x60, /* | ## | */ + 0xA4, /* |# # # | */ + 0xA8, /* |# # # | */ + 0x70, /* | ### | */ + 0x1E, /* | #### | */ + 0x2A, /* | # # # | */ + 0x4A, /* | # # # | */ + 0x4E, /* | # ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @144 '&' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x14, /* | # # | */ + 0x18, /* | ## | */ + 0x2A, /* | # # # | */ + 0x4A, /* | # # # | */ + 0x46, /* | # ## | */ + 0x3B, /* | ### # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @168 ''' (8 pixels wide) + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @192 '(' (8 pixels wide) + 0x04, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x04, /* | # | */ + 0x00, /* | | */ + + // @216 ')' (8 pixels wide) + 0x10, /* | # | */ + 0x08, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x08, /* | # | */ + 0x10, /* | # | */ + 0x00, /* | | */ + + // @240 '*' (8 pixels wide) + 0x00, /* | | */ + 0x08, /* | # | */ + 0x1A, /* | ## # | */ + 0x08, /* | # | */ + 0x0C, /* | ## | */ + 0x14, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @264 '+' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x3E, /* | ##### | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @288 ',' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x18, /* | ## | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @312 '-' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @336 '.' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @360 '/' (8 pixels wide) + 0x00, /* | | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x10, /* | # | */ + 0x30, /* | ## | */ + 0x20, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @384 '0' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x2A, /* | # # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @408 '1' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x0C, /* | ## | */ + 0x3C, /* | #### | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x3F, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @432 '2' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x0C, /* | ## | */ + 0x18, /* | ## | */ + 0x30, /* | ## | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @456 '3' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x02, /* | # | */ + 0x0C, /* | ## | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @480 '4' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x04, /* | # | */ + 0x0C, /* | ## | */ + 0x14, /* | # # | */ + 0x14, /* | # # | */ + 0x24, /* | # # | */ + 0x3E, /* | ##### | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @504 '5' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x3C, /* | #### | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @528 '6' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x32, /* | ## # | */ + 0x20, /* | # | */ + 0x3C, /* | #### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x32, /* | ## # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @552 '7' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x02, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x18, /* | ## | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @576 '8' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @600 '9' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1E, /* | #### | */ + 0x02, /* | # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @624 ':' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @648 ';' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x00, /* | | */ + + // @672 '<' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x02, /* | # | */ + 0x1C, /* | ### | */ + 0x20, /* | # | */ + 0x1C, /* | ### | */ + 0x02, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @696 '=' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @720 '>' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x20, /* | # | */ + 0x0C, /* | ## | */ + 0x03, /* | # | */ + 0x0C, /* | ## | */ + 0x20, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @744 '?' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x0C, /* | ## | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @768 '@' (8 pixels wide) + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x21, /* | # | */ + 0x0B, /* | # # | */ + 0x51, /* | # # | */ + 0x45, /* | # # | */ + 0x45, /* | # # | */ + 0x5A, /* | # ## # | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + + // @792 'A' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x10, /* | # | */ + 0x38, /* | ### | */ + 0x28, /* | # # | */ + 0x2C, /* | # ## | */ + 0x44, /* | # # | */ + 0x7C, /* | ##### | */ + 0x46, /* | # ## | */ + 0x82, /* |# # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @816 'B' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x3C, /* | #### | */ + 0x22, /* | # # | */ + 0x21, /* | # | */ + 0x23, /* | # # | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @840 'C' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1E, /* | #### | */ + 0x32, /* | ## # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x32, /* | ## # | */ + 0x1E, /* | #### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @864 'D' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3C, /* | #### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x23, /* | # # | */ + 0x23, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x3C, /* | #### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @888 'E' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x3E, /* | ##### | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x3F, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @912 'F' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x3E, /* | ##### | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @936 'G' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x32, /* | ## # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x26, /* | # ## | */ + 0x22, /* | # # | */ + 0x32, /* | ## # | */ + 0x1E, /* | #### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @960 'H' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x3E, /* | ##### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @984 'I' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1008 'J' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x0E, /* | ### | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x26, /* | # ## | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1032 'K' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x44, /* | # # | */ + 0x48, /* | # # | */ + 0x58, /* | # ## | */ + 0x70, /* | ### | */ + 0x68, /* | ## # | */ + 0x48, /* | # # | */ + 0x44, /* | # # | */ + 0x42, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1056 'L' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x30, /* | ## | */ + 0x30, /* | ## | */ + 0x30, /* | ## | */ + 0x30, /* | ## | */ + 0x30, /* | ## | */ + 0x30, /* | ## | */ + 0x30, /* | ## | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1080 'M' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x32, /* | ## # | */ + 0x36, /* | ## ## | */ + 0x2E, /* | # ### | */ + 0x2A, /* | # # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1104 'N' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x32, /* | ## # | */ + 0x32, /* | ## # | */ + 0x2A, /* | # # # | */ + 0x2A, /* | # # # | */ + 0x26, /* | # ## | */ + 0x26, /* | # ## | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1128 'O' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x23, /* | # ##| */ + 0x23, /* | # ##| */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1152 'P' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3C, /* | #### | */ + 0x22, /* | # # | */ + 0x23, /* | # ##| */ + 0x22, /* | # # | */ + 0x3C, /* | #### | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1176 'Q' (8 pixels wide) + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x23, /* | # ##| */ + 0x23, /* | # ##| */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x0C, /* | ## | */ + 0x07, /* | ###| */ + 0x00, /* | | */ + + // @1200 'R' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x3C, /* | #### | */ + 0x24, /* | # # | */ + 0x26, /* | # ## | */ + 0x22, /* | # # | */ + 0x23, /* | # ##| */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1224 'S' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x20, /* | # | */ + 0x18, /* | ## | */ + 0x06, /* | ## | */ + 0x03, /* | ##| */ + 0x22, /* | # # | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1248 'T' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x7F, /* | #######| */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1272 'U' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1296 'V' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x82, /* |# # | */ + 0x46, /* | # ## | */ + 0x44, /* | # # | */ + 0x44, /* | # # | */ + 0x28, /* | # # | */ + 0x28, /* | # # | */ + 0x38, /* | ### | */ + 0x10, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1320 'W' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x82, /* |# # | */ + 0x82, /* |# # | */ + 0x92, /* |# # # | */ + 0x52, /* | # # # | */ + 0x6A, /* | ## # # | */ + 0x6C, /* | ## ## | */ + 0x6C, /* | ## ## | */ + 0x64, /* | ## # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1344 'X' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x32, /* | ## # | */ + 0x14, /* | # # | */ + 0x08, /* | # | */ + 0x0C, /* | ## | */ + 0x14, /* | # # | */ + 0x22, /* | # # | */ + 0x23, /* | # ##| */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1368 'Y' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x23, /* | # ##| */ + 0x22, /* | # # | */ + 0x14, /* | # # | */ + 0x0C, /* | ## | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1392 'Z' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x02, /* | # | */ + 0x04, /* | # | */ + 0x08, /* | # | */ + 0x18, /* | ## | */ + 0x10, /* | # | */ + 0x20, /* | # | */ + 0x7F, /* | #######| */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1416 '[' (8 pixels wide) + 0x1C, /* | ### | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + + // @1440 '\' (8 pixels wide) + 0x00, /* | | */ + 0x20, /* | # | */ + 0x30, /* | ## | */ + 0x10, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1464 ']' (8 pixels wide) + 0x1C, /* | ### | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + + // @1488 '^' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x08, /* | # | */ + 0x14, /* | # # | */ + 0x14, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1512 '_' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0xFE, /* |####### | */ + 0x00, /* | | */ + + // @1536 '`' (8 pixels wide) + 0x08, /* | # | */ + 0x04, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1560 'a' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x02, /* | # | */ + 0x1E, /* | #### | */ + 0x22, /* | # # | */ + 0x26, /* | # ## | */ + 0x3B, /* | ### ##| */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1584 'b' (8 pixels wide) + 0x00, /* | | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x2C, /* | # ## | */ + 0x32, /* | ## # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x32, /* | ## # | */ + 0x2C, /* | # ## | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1608 'c' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1632 'd' (8 pixels wide) + 0x00, /* | | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x1E, /* | #### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1A, /* | ## # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1656 'e' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x3E, /* | ##### | */ + 0x20, /* | # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1680 'f' (8 pixels wide) + 0x00, /* | | */ + 0x0E, /* | ### | */ + 0x18, /* | ## | */ + 0x3E, /* | ##### | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1704 'g' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1A, /* | ## # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1A, /* | ## # | */ + 0x02, /* | # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + + // @1728 'h' (8 pixels wide) + 0x00, /* | | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x2C, /* | # ## | */ + 0x32, /* | ## # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1752 'i' (8 pixels wide) + 0x00, /* | | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x18, /* | ## | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1776 'j' (8 pixels wide) + 0x04, /* | # | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x04, /* | # | */ + 0x38, /* | ### | */ + 0x00, /* | | */ + + // @1800 'k' (8 pixels wide) + 0x00, /* | | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x22, /* | # # | */ + 0x24, /* | # # | */ + 0x28, /* | # # | */ + 0x38, /* | ### | */ + 0x34, /* | ## # | */ + 0x26, /* | # ## | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1824 'l' (8 pixels wide) + 0x00, /* | | */ + 0x18, /* | ## | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1848 'm' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x29, /* | # # #| */ + 0x29, /* | # # #| */ + 0x29, /* | # # #| */ + 0x29, /* | # # #| */ + 0x29, /* | # # #| */ + 0x29, /* | # # #| */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1872 'n' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x2C, /* | # ## | */ + 0x32, /* | ## # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1896 'o' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1920 'p' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x2C, /* | # ## | */ + 0x32, /* | ## # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x32, /* | ## # | */ + 0x3C, /* | #### | */ + 0x20, /* | # | */ + 0x20, /* | # | */ + 0x00, /* | | */ + + // @1944 'q' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x1E, /* | #### | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1A, /* | ## # | */ + 0x02, /* | # | */ + 0x02, /* | # | */ + 0x00, /* | | */ + + // @1968 'r' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x16, /* | # ## | */ + 0x18, /* | ## | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @1992 's' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x1C, /* | ### | */ + 0x22, /* | # # | */ + 0x30, /* | ## | */ + 0x1C, /* | ### | */ + 0x02, /* | # | */ + 0x22, /* | # # | */ + 0x1C, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @2016 't' (8 pixels wide) + 0x00, /* | | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x3E, /* | ##### | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x10, /* | # | */ + 0x0E, /* | ### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @2040 'u' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x1A, /* | ## # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @2064 'v' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x23, /* | # ##| */ + 0x22, /* | # # | */ + 0x22, /* | # # | */ + 0x14, /* | # # | */ + 0x14, /* | # # | */ + 0x1C, /* | ### | */ + 0x08, /* | # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @2088 'w' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x82, /* |# # | */ + 0x82, /* |# # | */ + 0x52, /* | # # # | */ + 0x5A, /* | # ## # | */ + 0x6C, /* | ## ## | */ + 0x6C, /* | ## ## | */ + 0x64, /* | ## # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @2112 'x' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x22, /* | # # | */ + 0x14, /* | # # | */ + 0x1C, /* | ### | */ + 0x08, /* | # | */ + 0x1C, /* | ### | */ + 0x16, /* | # ## | */ + 0x22, /* | # # | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @2136 'y' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x23, /* | # ##| */ + 0x22, /* | # # | */ + 0x12, /* | # # | */ + 0x14, /* | # # | */ + 0x1C, /* | ### | */ + 0x0C, /* | ## | */ + 0x08, /* | # | */ + 0x18, /* | ## | */ + 0x30, /* | ## | */ + 0x00, /* | | */ + + // @2160 'z' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x3E, /* | ##### | */ + 0x06, /* | ## | */ + 0x04, /* | # | */ + 0x08, /* | # | */ + 0x10, /* | # | */ + 0x30, /* | ## | */ + 0x3E, /* | ##### | */ + 0x00, /* | | */ + 0x00, /* | | */ + + // @2184 '{' (8 pixels wide) + 0x0E, /* | ### | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x30, /* | ## | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x06, /* | ## | */ + 0x00, /* | | */ + + // @2208 '|' (8 pixels wide) + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x00, /* | | */ + + // @2232 '}' (8 pixels wide) + 0x38, /* | ### | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x0C, /* | ## | */ + 0x06, /* | ## | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x08, /* | # | */ + 0x38, /* | ### | */ + 0x00, /* | | */ + + // @2256 '~' (8 pixels wide) + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x38, /* | ### | */ + 0x06, /* | ## | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ + 0x00, /* | | */ +}; + +static const font_t FontLiberationMono12 = { + .fTable = FontLiberationMono12_Table, + .width = 8, /* Width */ + .height = 12, /* Height */ + .cSize = 12 +}; diff --git a/firmware/main/include/lcd/SymbolsFont.h b/firmware/main/include/lcd/SymbolsFont.h new file mode 100644 index 0000000..2ca467a --- /dev/null +++ b/firmware/main/include/lcd/SymbolsFont.h @@ -0,0 +1,1748 @@ +/** + * A font for various symbols + */ +#pragma once + +#include + +#include "FontBase.h" + +#define FontSymbols16_Name ("Symbols Font 16px") + +// 4608 bytes +static const char FontSymbols16_Table [] = { + // @0 ' ' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @48 '!' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @96 '"' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x02, 0x40, /* | # # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @144 '#' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x18, /* | # ## | */ + 0x06, 0x10, /* | ## # | */ + 0x3F, 0xFC, /* | ############ | */ + 0x3F, 0xFC, /* | ############ | */ + 0x04, 0x20, /* | # # | */ + 0x0C, 0x20, /* | ## # | */ + 0x08, 0x60, /* | # ## | */ + 0x7F, 0xF8, /* | ############ | */ + 0x7F, 0xF8, /* | ############ | */ + 0x18, 0x40, /* | ## # | */ + 0x10, 0xC0, /* | # ## | */ + 0x10, 0x80, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @192 '$' (16 pixels wide) + 0x00, 0x80, /* | # | */ + 0x01, 0xE0, /* | #### | */ + 0x07, 0xF0, /* | ####### | */ + 0x06, 0x80, /* | ## # | */ + 0x0C, 0x80, /* | ## # | */ + 0x0C, 0x80, /* | ## # | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xF0, /* | ###### | */ + 0x00, 0xB0, /* | # ## | */ + 0x00, 0x98, /* | # ## | */ + 0x0C, 0xB0, /* | ## # ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + + // @240 '%' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0E, 0x30, /* | ### ## | */ + 0x1F, 0x20, /* | ##### # | */ + 0x1B, 0x60, /* | ## ## ## | */ + 0x1F, 0x40, /* | ##### # | */ + 0x0E, 0xC0, /* | ### ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x38, /* | # ### | */ + 0x03, 0x3C, /* | ## #### | */ + 0x02, 0x66, /* | # ## ## | */ + 0x06, 0x3C, /* | ## #### | */ + 0x04, 0x38, /* | # ### | */ + 0x00, 0x00, /* | | */ + + // @288 '&' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0x60, /* | # ## | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x90, /* | ### # | */ + 0x04, 0xD0, /* | # ## # | */ + 0x08, 0x70, /* | # ### | */ + 0x08, 0x70, /* | # ### | */ + 0x0C, 0x70, /* | ## ### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0x98, /* | #### ## | */ + 0x00, 0x00, /* | | */ + + // @336 ''' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @384 '(' (16 pixels wide) + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + + // @432 ')' (16 pixels wide) + 0x02, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + + // @480 '*' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0x80, /* | ### | */ + 0x06, 0xC0, /* | ## ## | */ + 0x04, 0x60, /* | # ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @528 '+' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @576 ',' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + + // @624 '-' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xE0, /* | ##### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @672 '.' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @720 '/' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @768 '0' (16 pixels wide) + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFE, 0x7F, /* |#######..#######| */ + 0xFE, 0x7F, /* |#######..#######| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + + // @816 '1' (16 pixels wide) + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFC, 0x3F, /* |######....######| */ + 0xF8, 0x1F, /* |#####......#####| */ + 0xF3, 0xCF, /* |####..####..####| */ + 0xF6, 0x6F, /* |####.##..##.####| */ + 0xFE, 0x7F, /* |#######..#######| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + + // @864 '2' (16 pixels wide) + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xF8, 0x1F, /* |#####......#####| */ + 0xF0, 0x0F, /* |####........####| */ + 0xE3, 0xC7, /* |###...####...###| */ + 0xC7, 0xE3, /* |##...######...##| */ + 0x8C, 0x31, /* |#...##....##...#| */ + 0x98, 0x19, /* |#..##......##..#| */ + 0xD3, 0xCB, /* |##.#..####..#.##| */ + 0xF6, 0x6F, /* |####.##..##.####| */ + 0xFE, 0x7F, /* |#######..#######| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + 0xFF, 0xFF, /* |################| */ + + // @912 '3' (16 pixels wide) + 0xFF, 0xFF, /* |################| */ + 0xCF, 0xF3, /* |##..########..##| */ + 0xCE, 0x73, /* |##..###..###..##| */ + 0xC0, 0x03, /* |##............##| */ + 0xFF, 0xFF, /* |################| */ + 0xC0, 0x03, /* |##............##| */ + 0xDF, 0xFB, /* |##.##########.##| */ + 0xC0, 0x03, /* |##............##| */ + 0xDF, 0xFF, /* |##.#############| */ + 0xFF, 0xFF, /* |################| */ + 0xC0, 0x03, /* |##............##| */ + 0xDF, 0xFF, /* |##.#############| */ + 0xC0, 0x03, /* |##............##| */ + 0xFF, 0xFB, /* |#############.##| */ + 0xC0, 0x03, /* |##............##| */ + 0xFF, 0xFF, /* |################| */ + + // @960 '4' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xE0, /* | ### | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0x60, /* | # ## | */ + 0x03, 0x60, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x04, 0x60, /* | # ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1008 '5' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0E, 0x30, /* | ### ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x30, /* | ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @1056 '6' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @1104 '7' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x06, 0x00, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @1152 '8' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xC0, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0xE0, /* | ###### | */ + 0x0E, 0x60, /* | ### ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @1200 '9' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xC0, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x0C, 0x70, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x01, 0xC0, /* | ### | */ + 0x07, 0x80, /* | #### | */ + 0x06, 0x00, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @1248 ':' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1296 ';' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1344 '<' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x07, 0x00, /* | ### | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1392 '=' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1440 '>' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xC0, /* | #### | */ + 0x03, 0x80, /* | ### | */ + 0x02, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @1488 '?' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0x80, /* | ### | */ + 0x07, 0xC0, /* | ##### | */ + 0x04, 0x60, /* | # ## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0xE0, /* | ### | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0x80, /* | ### | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x02, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1536 '@' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x03, 0xE0, /* | ##### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x1C, 0x18, /* | ### ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x31, 0x84, /* | ## ## # | */ + 0x33, 0x06, /* | ## ## ## | */ + 0x36, 0x46, /* | ## ## # ## | */ + 0x26, 0xC6, /* | # ## ## ## | */ + 0x37, 0xFC, /* | ## ######### | */ + 0x33, 0x78, /* | ## ## #### | */ + 0x30, 0x00, /* | ## | */ + 0x18, 0x00, /* | ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0xE0, /* | ##### | */ + + // @1584 'A' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x40, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0x60, /* | ## ## | */ + 0x02, 0x20, /* | # # | */ + 0x07, 0xE0, /* | ###### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x30, /* | # ## | */ + 0x18, 0x10, /* | ## # | */ + 0x10, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @1632 'B' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0x80, /* | #### | */ + 0x07, 0xE0, /* | ###### | */ + 0x04, 0x60, /* | # ## | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x60, /* | # ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x10, /* | # # | */ + 0x04, 0x70, /* | # ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0x80, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @1680 'C' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xF0, /* | #### | */ + 0x01, 0xF0, /* | ##### | */ + 0x03, 0x10, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x0C, 0x00, /* | ## | */ + 0x08, 0x00, /* | # | */ + 0x08, 0x00, /* | # | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x70, /* | ## ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0x80, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @1728 'D' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0x00, /* | #### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x08, 0xE0, /* | # ### | */ + 0x08, 0x30, /* | # ## | */ + 0x08, 0x10, /* | # # | */ + 0x08, 0x18, /* | # ## | */ + 0x08, 0x18, /* | # ## | */ + 0x18, 0x10, /* | ## # | */ + 0x18, 0x30, /* | ## ## | */ + 0x1F, 0xE0, /* | ######## | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @1776 'E' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0xE0, /* | ###### | */ + 0x00, 0x00, /* | | */ + + // @1824 'F' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xF0, /* | ####### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @1872 'G' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xE0, /* | ### | */ + 0x03, 0xF0, /* | ###### | */ + 0x03, 0x10, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0D, 0xF8, /* | ## ###### | */ + 0x09, 0xF8, /* | # ###### | */ + 0x08, 0x18, /* | # ## | */ + 0x08, 0x18, /* | # ## | */ + 0x0C, 0x70, /* | ## ### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @1920 'H' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x08, 0x08, /* | # # | */ + 0x08, 0x08, /* | # # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0xF8, /* | ## ##### | */ + 0x1F, 0xF8, /* | ########## | */ + 0x1E, 0x08, /* | #### # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x08, /* | ## # | */ + 0x00, 0x00, /* | | */ + + // @1968 'I' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x00, /* | | */ + + // @2016 'J' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x03, 0xF8, /* | ####### | */ + 0x03, 0xF8, /* | ####### | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x08, 0x40, /* | # # | */ + 0x0C, 0x40, /* | ## # | */ + 0x0C, 0xC0, /* | ## ## | */ + 0x07, 0xC0, /* | ##### | */ + 0x03, 0x80, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @2064 'K' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x10, /* | # # | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x60, /* | # ## | */ + 0x04, 0xC0, /* | # ## | */ + 0x05, 0x80, /* | # ## | */ + 0x07, 0x00, /* | ### | */ + 0x07, 0x00, /* | ### | */ + 0x07, 0x80, /* | #### | */ + 0x05, 0xC0, /* | # ### | */ + 0x04, 0xE0, /* | # ### | */ + 0x04, 0x70, /* | # ### | */ + 0x04, 0x18, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @2112 'L' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x00, /* | | */ + + // @2160 'M' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x10, /* | # # | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0E, 0x38, /* | ### ### | */ + 0x1E, 0x38, /* | #### ### | */ + 0x1E, 0x68, /* | #### ## # | */ + 0x1A, 0x48, /* | ## # # # | */ + 0x12, 0x48, /* | # # # # | */ + 0x33, 0xCC, /* | ## #### ## | */ + 0x33, 0xCC, /* | ## #### ## | */ + 0x31, 0x8C, /* | ## ## ## | */ + 0x31, 0x84, /* | ## ## # | */ + 0x00, 0x00, /* | | */ + + // @2208 'N' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x18, 0x08, /* | ## # | */ + 0x18, 0x0C, /* | ## ## | */ + 0x1C, 0x0C, /* | ### ## | */ + 0x1E, 0x0C, /* | #### ## | */ + 0x1B, 0x0C, /* | ## ## ## | */ + 0x19, 0x0C, /* | ## # ## | */ + 0x19, 0x84, /* | ## ## # | */ + 0x18, 0xC4, /* | ## ## # | */ + 0x18, 0x64, /* | ## ## # | */ + 0x18, 0x3C, /* | ## #### | */ + 0x18, 0x1C, /* | ## ### | */ + 0x10, 0x0C, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @2256 'O' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xF0, /* | ##### | */ + 0x07, 0xF8, /* | ######## | */ + 0x0E, 0x1C, /* | ### ### | */ + 0x0C, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x0C, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @2304 'P' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0xE0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x70, /* | # ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0x80, /* | #### | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @2352 'Q' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x03, 0xE0, /* | ##### | */ + 0x0F, 0xF0, /* | ######## | */ + 0x1C, 0x38, /* | ### ### | */ + 0x30, 0x0C, /* | ## ## | */ + 0x30, 0x0C, /* | ## ## | */ + 0x20, 0x0C, /* | # ## | */ + 0x20, 0x04, /* | # # | */ + 0x30, 0x04, /* | ## # | */ + 0x31, 0x8C, /* | ## ## ## | */ + 0x1C, 0xD8, /* | ### ## ## | */ + 0x0F, 0xF0, /* | ######## | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x1C, /* | ### | */ + 0x00, 0x0C, /* | ## | */ + 0x00, 0x04, /* | # | */ + + // @2400 'R' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0x00, /* | #### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0C, 0xE0, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0C, 0xE0, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x08, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @2448 'S' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xF0, /* | #### | */ + 0x03, 0xF8, /* | ####### | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xF8, /* | ####### | */ + 0x00, 0x18, /* | ## | */ + 0x00, 0x08, /* | # | */ + 0x08, 0x08, /* | # # | */ + 0x0C, 0x38, /* | ## ### | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @2496 'T' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x1F, 0xF8, /* | ########## | */ + 0x1F, 0xF8, /* | ########## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + + // @2544 'U' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x08, 0x18, /* | # ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x18, /* | ## ## | */ + 0x18, 0x10, /* | ## # | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x70, /* | ## ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @2592 'V' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0C, 0x08, /* | ## # | */ + 0x0C, 0x18, /* | ## ## | */ + 0x0C, 0x18, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x20, /* | ## # | */ + 0x02, 0x60, /* | # ## | */ + 0x03, 0x60, /* | ## ## | */ + 0x03, 0x40, /* | ## # | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @2640 'W' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x60, 0x81, /* | ## # #| */ + 0x60, 0xC3, /* | ## ## ##| */ + 0x21, 0xC3, /* | # ### ##| */ + 0x31, 0xC2, /* | ## ### # | */ + 0x31, 0xC6, /* | ## ### ## | */ + 0x13, 0x46, /* | # ## # ## | */ + 0x13, 0x64, /* | # ## ## # | */ + 0x1A, 0x6C, /* | ## # ## ## | */ + 0x1E, 0x68, /* | #### ## # | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0C, 0x38, /* | ## ### | */ + 0x0C, 0x30, /* | ## ## | */ + 0x00, 0x00, /* | | */ + + // @2688 'X' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x18, 0x18, /* | ## ## | */ + 0x1C, 0x18, /* | ### ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0xC0, /* | #### | */ + 0x06, 0x60, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x18, 0x30, /* | ## ## | */ + 0x10, 0x18, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @2736 'Y' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x18, 0x10, /* | ## # | */ + 0x08, 0x30, /* | # ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x60, /* | ## ## | */ + 0x03, 0x60, /* | ## ## | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x00, 0x00, /* | | */ + + // @2784 'Z' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0F, 0xFC, /* | ########## | */ + 0x0F, 0xF8, /* | ######### | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xFC, /* | ########## | */ + 0x0F, 0xFC, /* | ########## | */ + 0x00, 0x00, /* | | */ + + // @2832 '[' (16 pixels wide) + 0x01, 0xC0, /* | ### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @2880 '\' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x02, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x30, /* | ## | */ + 0x00, 0x10, /* | # | */ + 0x00, 0x00, /* | | */ + + // @2928 ']' (16 pixels wide) + 0x01, 0xC0, /* | ### | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x40, /* | # | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @2976 '^' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xC0, /* | ## | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0x20, /* | ## # | */ + 0x02, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @3024 '_' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x3F, 0xF0, /* | ########## | */ + + // @3072 '`' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @3120 'a' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x0C, 0x20, /* | ## # | */ + 0x0C, 0x20, /* | ## # | */ + 0x04, 0x60, /* | # ## | */ + 0x07, 0xF0, /* | ####### | */ + 0x03, 0x90, /* | ### # | */ + 0x00, 0x00, /* | | */ + + // @3168 'b' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x00, /* | # | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0C, 0x00, /* | ## | */ + 0x0F, 0xC0, /* | ###### | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0C, 0x20, /* | ## # | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x60, /* | ## ## | */ + 0x0F, 0xE0, /* | ####### | */ + 0x0F, 0xC0, /* | ###### | */ + 0x00, 0x00, /* | | */ + + // @3216 'c' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x06, 0x20, /* | ## # | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + + // @3264 'd' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x10, /* | # | */ + 0x00, 0x18, /* | ## | */ + 0x00, 0x18, /* | ## | */ + 0x00, 0x10, /* | # | */ + 0x00, 0x10, /* | # | */ + 0x01, 0xF0, /* | ##### | */ + 0x03, 0xF0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x10, /* | # # | */ + 0x04, 0x10, /* | # # | */ + 0x06, 0x30, /* | ## ## | */ + 0x03, 0xF0, /* | ###### | */ + 0x01, 0xF0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @3312 'e' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xF0, /* | ###### | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x60, /* | ## ## | */ + 0x05, 0x80, /* | # ## | */ + 0x06, 0x10, /* | ## # | */ + 0x07, 0xF0, /* | ####### | */ + 0x01, 0xE0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @3360 'f' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xE0, /* | ### | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3408 'g' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xF0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x04, 0x60, /* | # ## | */ + 0x07, 0xA0, /* | #### # | */ + 0x03, 0xA0, /* | ### # | */ + 0x00, 0x20, /* | # | */ + 0x00, 0x60, /* | ## | */ + 0x07, 0xE0, /* | ###### | */ + + // @3456 'h' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0xE0, /* | ## ### | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0x30, /* | ### ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x10, /* | ## # | */ + 0x06, 0x10, /* | ## # | */ + 0x06, 0x10, /* | ## # | */ + 0x00, 0x00, /* | | */ + + // @3504 'i' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3552 'j' (16 pixels wide) + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x04, 0x40, /* | # # | */ + 0x06, 0xC0, /* | ## ## | */ + 0x03, 0xC0, /* | #### | */ + + // @3600 'k' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x06, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + 0x02, 0x10, /* | # # | */ + 0x02, 0x30, /* | # ## | */ + 0x06, 0x70, /* | ## ### | */ + 0x06, 0xE0, /* | ## ### | */ + 0x06, 0xC0, /* | ## ## | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0x60, /* | ### ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x10, /* | ## # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @3648 'l' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3696 'm' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x13, 0x30, /* | # ## ## | */ + 0x1F, 0xF8, /* | ########## | */ + 0x1D, 0xD8, /* | ### ### ## | */ + 0x19, 0x88, /* | ## ## # | */ + 0x19, 0x88, /* | ## ## # | */ + 0x18, 0x8C, /* | ## # ## | */ + 0x18, 0x8C, /* | ## # ## | */ + 0x10, 0x8C, /* | # # ## | */ + 0x00, 0x00, /* | | */ + + // @3744 'n' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x06, 0xE0, /* | ## ### | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0x20, /* | ### # | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x00, 0x00, /* | | */ + + // @3792 'o' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x60, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x00, /* | | */ + + // @3840 'p' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x00, /* | # | */ + 0x07, 0xC0, /* | ##### | */ + 0x07, 0xE0, /* | ###### | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x06, 0x30, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xC0, /* | ##### | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + + // @3888 'q' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0xE0, /* | #### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x20, /* | ## # | */ + 0x04, 0x20, /* | # # | */ + 0x0C, 0x20, /* | ## # | */ + 0x06, 0x60, /* | ## ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x60, /* | ## | */ + + // @3936 'r' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0xE0, /* | # ### | */ + 0x07, 0x20, /* | ### # | */ + 0x06, 0x20, /* | ## # | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x04, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @3984 's' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0xE0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x06, 0x00, /* | ## | */ + 0x07, 0x00, /* | ### | */ + 0x03, 0xC0, /* | #### | */ + 0x00, 0x60, /* | ## | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xC0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @4032 't' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xE0, /* | ###### | */ + 0x07, 0xE0, /* | ###### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x00, 0x00, /* | | */ + + // @4080 'u' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x30, /* | ## ## | */ + 0x04, 0x30, /* | # ## | */ + 0x04, 0x20, /* | # # | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x20, /* | ## # | */ + 0x07, 0xE0, /* | ###### | */ + 0x03, 0xE0, /* | ##### | */ + 0x00, 0x00, /* | | */ + + // @4128 'v' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x04, 0x20, /* | # # | */ + 0x04, 0x20, /* | # # | */ + 0x06, 0x60, /* | ## ## | */ + 0x02, 0x60, /* | # ## | */ + 0x02, 0x40, /* | # # | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @4176 'w' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x08, 0x88, /* | # # # | */ + 0x09, 0xC8, /* | # ### # | */ + 0x09, 0xC8, /* | # ### # | */ + 0x0D, 0xD8, /* | ## ### ## | */ + 0x0F, 0x50, /* | #### # # | */ + 0x0E, 0x70, /* | ### ### | */ + 0x06, 0x70, /* | ## ### | */ + 0x04, 0x20, /* | # # | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @4224 'x' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x18, /* | # ## | */ + 0x03, 0x30, /* | ## ## | */ + 0x01, 0xE0, /* | #### | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x07, 0x30, /* | ### ## | */ + 0x04, 0x10, /* | # # | */ + 0x00, 0x00, /* | | */ + + // @4272 'y' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x0C, 0x30, /* | ## ## | */ + 0x0C, 0x30, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x06, 0x60, /* | ## ## | */ + 0x03, 0x40, /* | ## # | */ + 0x03, 0xC0, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x02, 0x00, /* | # | */ + + // @4320 'z' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x60, /* | ## | */ + 0x00, 0x40, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x07, 0xF0, /* | ####### | */ + 0x07, 0xF0, /* | ####### | */ + 0x00, 0x00, /* | | */ + + // @4368 '{' (16 pixels wide) + 0x00, 0xC0, /* | ## | */ + 0x01, 0xC0, /* | ### | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x01, 0x00, /* | # | */ + 0x03, 0x00, /* | ## | */ + 0x06, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x03, 0x00, /* | ## | */ + 0x01, 0x00, /* | # | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0xC0, /* | ## | */ + + // @4416 '|' (16 pixels wide) + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + + // @4464 '}' (16 pixels wide) + 0x07, 0x00, /* | ### | */ + 0x07, 0x80, /* | #### | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0xC0, /* | ## | */ + 0x00, 0x80, /* | # | */ + 0x00, 0x80, /* | # | */ + 0x01, 0x80, /* | ## | */ + 0x01, 0x80, /* | ## | */ + 0x07, 0x00, /* | ### | */ + 0x07, 0x00, /* | ### | */ + + // @4512 '~' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x02, 0x00, /* | # | */ + 0x07, 0x10, /* | ### # | */ + 0x0D, 0xB0, /* | ## ## ## | */ + 0x08, 0xF0, /* | # #### | */ + 0x08, 0xE0, /* | # ### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + + // @4560 '°' (16 pixels wide) + 0x00, 0x00, /* | | */ + 0x01, 0xC0, /* | ### | */ + 0x03, 0xE0, /* | ##### | */ + 0x02, 0x20, /* | # # | */ + 0x02, 0x60, /* | # ## | */ + 0x03, 0xE0, /* | ##### | */ + 0x01, 0xC0, /* | ### | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ + 0x00, 0x00, /* | | */ +}; + +static const font_t FontSymbols16 = { + .fTable = FontSymbols16_Table, + .width = 16, + .height = 16, + .cSize = 32 +}; diff --git a/firmware/main/include/lcd/ssd1306.h b/firmware/main/include/lcd/ssd1306.h new file mode 100644 index 0000000..c48dc59 --- /dev/null +++ b/firmware/main/include/lcd/ssd1306.h @@ -0,0 +1,97 @@ +/** + * ============================================================================ + * === SSD1306 128x64 IIC LCD Interface + * ============================================================================ + * + * Provides a simple interface for rendering text to an SSD1306 LCD. + * + * digimint + */ + +#pragma once + +#include "FontComicSansMS16.h" + +#include +#include + +#include +#include + +// LCD target address +#define IIC_LCD_ADDR (0x3C) + +#define LCD_TAG "LCD" + +extern uint8_t LCD_data[8][128]; +extern bool LCD_rowChanged[8]; + +/** + * Initialize the LCD interface. + * + * This command configures the IIC bus, sends the proper initialization commands + * to the LCD, and spawns a task to update the display regularly. + * + * @param updateTaskHandle If this variable is not NULL, a handle to the display + * update task will be stored in it. + */ +void LCD_init(TaskHandle_t* updateTaskHandle); + + +/** + * Render a single character to the LCD buffer. + * + * @warning This function does not perform bounds checking. + * + * @param font The font to use for text rendering. + * @param oChr The character to render. + * @param x The x-coordinate for the top-left of the character. + * @param y The y-coordinate for the top-left of the character. + * @param invert Whether the character should be inverted before display. + */ +void LCD_renderChar(font_t font, const char oChr, uint16_t x, uint16_t y, bool invert); + +/** + * Render text to the LCD buffer. + * + * @warning This function does not protect against buffer overrun. + * + * @param font The font to use for text rendering. + * @param str The text to render. + * @param x The x-coordinate for the top-left of the first character. + * @param y The y-coordinate for the top-left of the first character. + * @param invert Whether the character should be inverted before display. + */ +void LCD_renderText(font_t font, const char* str, uint16_t x, uint16_t y, bool invert); + +/** + * Render text in Comic Sans + * + * A convenience macro that expands to + * + * `LCD_renderText(FontComicSansMS16, str, x, y);` + */ +static inline void LCD_renderTextCS(const char* str, uint16_t x, uint16_t y){ + LCD_renderText(FontComicSansMS16, str, x, y, false); +} + +/** + * Manually force an immediate update of the LCD. + * + * Note that this function will be called automatically by the LCD update task + * during normal operation, so it generally should not be manually invoked. + * + * A semaphore is used to ensure that only one task attempts to communicate with + * the display at a time. + * + * @param block If true, then the calling task will block until the LCD is + * available for communication. Otherwise, if the LCD is not immediately + * available, the function will simply return `false`. + * + * @return `true` if the LCD was successfully updated; `false` otherwise. + * + * @note This function will only return false if two conditions apply: + * (1) `block` is false; and + * (2) The LCD semaphore has been taken (i.e. the LCD is currently busy) + */ +bool LCD_updateDisplay(bool block); \ No newline at end of file diff --git a/firmware/main/include/led/ws2811.h b/firmware/main/include/led/ws2811.h new file mode 100644 index 0000000..2da092e --- /dev/null +++ b/firmware/main/include/led/ws2811.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +#define LED_PIN (23) + +typedef enum LEDStripSpeed{ + WS2811_LOW_SPEED = 10000000, // One tick == 0.1us + WS2811_HIGH_SPEED = 20000000 // One tick == 0.05us +} LEDStripSpeed_t; + +typedef struct PACKED_ATTR rgbPacket { + uint8_t r; + uint8_t g; + uint8_t b; +} rgbPacket_t; + +typedef void (*ledRenderFunction_t)( + rgbPacket_t* buf, + size_t led_count, + unsigned long frame +); + +extern uint8_t saturation; + +void init_leds(); \ No newline at end of file diff --git a/firmware/main/include/ui/inputs.h b/firmware/main/include/ui/inputs.h new file mode 100644 index 0000000..7a42b00 --- /dev/null +++ b/firmware/main/include/ui/inputs.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#define INPUTS_TAG ("INPUT") + +extern TaskHandle_t T_ReadInputs_Handle; +extern EventGroupHandle_t EV_InputEventGroupHandle; + +typedef enum InputEventGroupFlags { + INPUT_EVENT_WHEEL = (1 << 0), + INPUT_EVENT_KEY_FORWARD = (1 << 1), + INPUT_EVENT_KEY_BACKSPACE = (1 << 2), + INPUT_EVENT_KEY_DONE = (1 << 3), + INPUT_EVENT_KEY_CANCEL = (1 << 4), + INPUT_EVENT_KEY_OPTION = (1 << 5) +} UIEventGroupFlags_t; + +typedef struct InputState { + bool forward, backspace, done, cancel, option; + int wheel; + uint8_t _wheelQuadrant; +} InputState_t; + +void init_inputs(); + +InputState_t waitForInputEvents(UIEventGroupFlags_t events, BaseType_t xWaitForAll, TickType_t xTicksToWait); + +InputState_t getInputState(); \ No newline at end of file diff --git a/firmware/main/src/hello_world_main.c b/firmware/main/src/hello_world_main.c new file mode 100644 index 0000000..9b28db7 --- /dev/null +++ b/firmware/main/src/hello_world_main.c @@ -0,0 +1,163 @@ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include "driver/i2c_types.h" +#include "esp_err.h" +#include "esp_log.h" +#include "freertos/projdefs.h" +#include "hal/gpio_types.h" +#include "hal/i2c_types.h" +// #include "portmacro.h" +// #include "portmacro.h" +// #include "portmacro.h" +// #include "portmacro.h" +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "esp_chip_info.h" +#include "esp_flash.h" +#include "esp_system.h" + +#include "lcd/ssd1306.h" +#include "led/ws2811.h" + +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "soc/clk_tree_defs.h" + +#include "ui/inputs.h" + +void T_watchInputs(void* params){ + while(1){ + EventBits_t changed = xEventGroupWaitBits( + EV_InputEventGroupHandle, + ( + INPUT_EVENT_KEY_BACKSPACE + | INPUT_EVENT_KEY_FORWARD + | INPUT_EVENT_KEY_CANCEL + | INPUT_EVENT_KEY_DONE + | INPUT_EVENT_KEY_OPTION + | INPUT_EVENT_WHEEL + ), + pdTRUE, + pdFALSE, + portMAX_DELAY + ); + + InputState_t curInputs = getInputState(); + + if(changed & INPUT_EVENT_KEY_FORWARD){ + if(curInputs.forward){ + ESP_LOGI("UI", "Forward Pressed"); + }else{ + ESP_LOGI("UI", "Forward Released"); + } + } + + if(changed & INPUT_EVENT_KEY_BACKSPACE){ + if(curInputs.backspace){ + ESP_LOGI("UI", "Backspace Pressed"); + }else{ + ESP_LOGI("UI", "Backspace Released"); + } + } + + if(changed & INPUT_EVENT_KEY_DONE){ + if(curInputs.done){ + ESP_LOGI("UI", "Done Pressed"); + }else{ + ESP_LOGI("UI", "Done Released"); + } + } + + if(changed & INPUT_EVENT_KEY_CANCEL){ + if(curInputs.cancel){ + ESP_LOGI("UI", "Cancel Pressed"); + }else{ + ESP_LOGI("UI", "Cancel Released"); + } + } + + if(changed & INPUT_EVENT_KEY_OPTION){ + if(curInputs.option){ + ESP_LOGI("UI", "Option Pressed"); + }else{ + ESP_LOGI("UI", "Option Released"); + } + } + + if(changed & INPUT_EVENT_WHEEL){ + ESP_LOGI("UI", "Wheel: %d", curInputs.wheel); + if(curInputs.wheel < 0){ + saturation = 0; + }else if(curInputs.wheel > 255){ + saturation = 255; + }else{ + saturation = (uint8_t)curInputs.wheel; + } + } + + } +} + +void app_main(void) +{ + printf("Hello world! This is Candytuft 40M9K!\n"); + + LCD_init(NULL); + + LCD_renderTextCS("Comic", 0, 0); + LCD_renderTextCS("Sans", 0, 16); + LCD_renderTextCS("LCD", 0, 32); + + LCD_updateDisplay(true); + + init_inputs(); + init_leds(); + + + xTaskCreate(T_watchInputs, "Watch inputs", 2048, NULL, 2, NULL); + + /* Print chip information */ + esp_chip_info_t chip_info; + uint32_t flash_size; + esp_chip_info(&chip_info); + printf("This is %s chip with %d CPU core(s), %s%s%s%s, ", + CONFIG_IDF_TARGET, + chip_info.cores, + (chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "", + (chip_info.features & CHIP_FEATURE_BT) ? "BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "", + (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : ""); + + unsigned major_rev = chip_info.revision / 100; + unsigned minor_rev = chip_info.revision % 100; + printf("silicon revision v%d.%d, ", major_rev, minor_rev); + if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) { + printf("Get flash size failed"); + return; + } + + printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); + + printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); + + while(1){ + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + + // for (int i = 10; i >= 0; i--) { + // printf("Restarting in %d seconds...\n", i); + // vTaskDelay(1000 / portTICK_PERIOD_MS); + // } + // printf("Restarting now.\n"); + // fflush(stdout); + // esp_restart(); +} diff --git a/firmware/main/src/iic.c b/firmware/main/src/iic.c new file mode 100644 index 0000000..3c27560 --- /dev/null +++ b/firmware/main/src/iic.c @@ -0,0 +1,57 @@ +/* MX-008 "Onyx Sovereign" -02 "Kingmaker" + * ============================================================================ + * === IIC interface configuration + * ============================================================================ + * + * Alexis Maya-Isabelle Shuping + * 29th March 2021 + * University of Florida + */ + +#include "iic.h" + +#include +#include +#include + +#include +#include +#include + +void iicInit(i2c_port_t port, int sclNum, int sdaNum, bool pullUps, int clkRate){ + ESP_LOGI(T_IIC_INIT, "Initializing LCD interface %d at %dHz (SCL pin %d; SDA pin %d; pullups %s)", (int)port, clkRate, sclNum, sdaNum, pullUps ? "enabled" : "disabled"); + + i2c_config_t my2c = (i2c_config_t) { + .mode = I2C_MODE_MASTER, + .sda_io_num = sdaNum, + .scl_io_num = sclNum, + .sda_pullup_en = pullUps ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, + .scl_pullup_en = pullUps ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, + .master.clk_speed = clkRate + }; + + i2c_param_config(port, &my2c); + i2c_driver_install(port, my2c.mode, 0, 0, 0); +} + +void iicCommand(i2c_port_t port, uint_fast8_t targetAddress, uint_fast8_t toSend){ + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, targetAddress << 1 | 0, true)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x00, true)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, toSend, true)); + i2c_master_stop(cmd); + ESP_ERROR_CHECK(i2c_master_cmd_begin(port, cmd, 1000 / portTICK_PERIOD_MS)); + i2c_cmd_link_delete(cmd); +} + +void iicData(i2c_port_t port, uint_fast8_t targetAddress, uint_fast8_t toSend){ + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, targetAddress << 1 | 0, true)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x40, true)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, toSend, true)); + i2c_master_stop(cmd); + ESP_ERROR_CHECK(i2c_master_cmd_begin(port, cmd, 1000 / portTICK_PERIOD_MS)); + i2c_cmd_link_delete(cmd); +} diff --git a/firmware/main/src/lcd/ssd1306.c b/firmware/main/src/lcd/ssd1306.c new file mode 100644 index 0000000..0434c15 --- /dev/null +++ b/firmware/main/src/lcd/ssd1306.c @@ -0,0 +1,189 @@ +/** + * ============================================================================ + * === SSD1306 128x64 IIC LCD Interface + * ============================================================================ + * + * Provides a simple interface for rendering text to an SSD1306 LCD. + * + * digimint + */ + +#include "iic.h" +#include "lcd/FontComicSansMS16.h" +#include "lcd/ssd1306.h" +#include "lcd/SymbolsFont.h" +#include "sdkconfig.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +uint8_t LCD_data[8][128]; +bool LCD_rowChanged[8]; +StaticSemaphore_t _lcSemaphore_buf; + +volatile bool _lcDirty = false; +SemaphoreHandle_t _lcSemaphore = NULL; + +static inline void _setPx(uint16_t x, uint16_t y){ + uint16_t bank = y >> 3; + uint16_t posi = y & 0b111; + + LCD_data[bank][x] |= (1 << posi); + LCD_rowChanged[bank] = true; +} + +static inline void _clrPx(uint16_t x, uint16_t y){ + uint16_t bank = y >> 3; + uint16_t posi = y & 0b111; + + LCD_data[bank][x] &= ~(1 << posi); + LCD_rowChanged[bank] = true; +} + +void LCD_renderChar(font_t font, const char oChr, uint16_t x, uint16_t y, bool invert){ + char chr = oChr; + if(chr < ' ' || chr > '~'){ + chr = ' '; + } + + chr -= ' '; + uint_fast16_t charsPerRow = ((font.width & 0b111) == 0) ? (font.width >> 3) : ((font.width >> 3) + 1); + const char* toRender = &(font.fTable)[chr*(font.cSize)]; + for(uint16_t xx = 0; xx < font.width; ++xx){ + for(uint16_t yy = 0; yy < font.height; ++yy){ + if( + toRender[yy*charsPerRow + (xx >> 3)] + & (1 << (7-(xx & 0b111))) + ){ + invert ? _clrPx(xx+x, yy+y) : _setPx(xx+x, yy+y); + }else{ + invert ? _setPx(xx+x, yy+y) : _clrPx(xx+x, yy+y); + } + } + } +} + +void LCD_renderText(font_t font, const char* str, uint16_t x, uint16_t y, bool invert){ + uint_fast16_t i = 0; + while(*str != 0){ + LCD_renderChar(font, *str, font.width*i+x, y, invert); + ++str; + ++i; + } +} + +bool LCD_updateDisplay(bool block){ + if(!xSemaphoreTake(_lcSemaphore, 0)){ + if(!block) return false; + else xSemaphoreTake(_lcSemaphore, portMAX_DELAY); + } + for(uint32_t j = 0; j < 8; ++j){ + // if(LCD_rowChanged[j] == false) continue; + for(uint32_t i = 0; i < 128; ++i){ + iicData(IIC_NUM_LCD, IIC_LCD_ADDR, LCD_data[j][i]); + } + LCD_rowChanged[j] = false; + } + xSemaphoreGive(_lcSemaphore); + return true; +} + +// void T_LCD_updateTask(void* params){ +// while(1){ +// Display_render(); +// vTaskDelay(50 / portTICK_PERIOD_MS); +// bool needsUpdate = false; +// for(uint8_t i = 0; i < 8; ++i) needsUpdate = needsUpdate || LCD_rowChanged[i]; +// if(needsUpdate == true) LCD_updateDisplay(true); +// } +// } + +void LCD_init(TaskHandle_t* updateTaskHandle){ + ESP_LOGI(LCD_TAG, "Initializing SSD1306 LCD Interface..."); + + // Initialize the semaphore for LCD access. + _lcSemaphore = xSemaphoreCreateBinaryStatic(&_lcSemaphore_buf); + xSemaphoreGive(_lcSemaphore); + + ESP_LOGD(LCD_TAG, " Initializing IIC"); + iicInit( + IIC_NUM_LCD, + CONFIG_LCD_SCL, + CONFIG_LCD_SDA, + true, + 200000 + ); + + ESP_LOGD(LCD_TAG, " Sending LCD initialization commands"); + + /* Shouldn't be necessary to take the semaphore here, but better safe than + * sorry. + */ + if(!xSemaphoreTake(_lcSemaphore, 0)) esp_system_abort("Semaphore error during LCD initialization!"); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xAE); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xD5); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x80); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xA8); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x3F); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xD3); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x00); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x40); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x8D); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x14); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x20); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x00); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xA1); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xC8); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xDA); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x12); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x81); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xCF); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xD9); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xF1); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xDB); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x40); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xA4); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xA6); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0xAF); + + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x00); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x10); + + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x21); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x00); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x7F); + + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x22); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x00); + iicCommand(IIC_NUM_LCD, IIC_LCD_ADDR, 0x07); + xSemaphoreGive(_lcSemaphore); + + ESP_LOGD(LCD_TAG, " Initializing data buffer"); + for(uint32_t j = 0; j < 8; ++j){ + for(uint32_t i = 0; i < 128; ++i){ + LCD_data[j][i] = 0; + } + } + + ESP_LOGD(LCD_TAG, " Clearing Display"); + if(!LCD_updateDisplay(false)){ + ESP_LOGW(LCD_TAG, "Unable to clear LCD display (communication semaphore already in use)."); + } + + // ESP_LOGD(LCD_TAG, " Spawning LCD update task"); + // TaskHandle_t tsk; + // if(updateTaskHandle == NULL){ + // updateTaskHandle = &tsk; + // } + // xTaskCreate(&T_LCD_updateTask, "LCD Update Task", 2048, NULL, 2, updateTaskHandle); + + ESP_LOGI(LCD_TAG, "Ready."); +} \ No newline at end of file diff --git a/firmware/main/src/led/ws2811.c b/firmware/main/src/led/ws2811.c new file mode 100644 index 0000000..bbe0413 --- /dev/null +++ b/firmware/main/src/led/ws2811.c @@ -0,0 +1,303 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "led/ws2811.h" +#include "driver/rmt_common.h" +#include "driver/rmt_types.h" +#include "esp_err.h" +#include "hal/rmt_types.h" +#include "soc/clk_tree_defs.h" +#include "soc/gpio_num.h" + +#define SYMBOLS_PER_LED (8) +#define SYMBOLS_PER_PACKET (3*SYMBOLS_PER_LED) + +uint8_t saturation = 255; + +// The 'duration' here is in ticks - the actual time is controlled by the tick +// rate. In our case, low-speed == 10MHz tick rate; high-speed == 20MHz tick +// rate. Thus, a high-duration of 5 means 0.5us at low-speed and 0.25 at +// high-speed, which matches the datasheet. +const rmt_symbol_word_t ws2811_0 = { + .duration0 = 5, + .level0 = 1, + .duration1 = 20, + .level1 = 0 +}; + +const rmt_symbol_word_t ws2811_1 = { + .duration0 = 12, + .level0 = 1, + .duration1 = 13, + .level1 = 0 +}; + +const rmt_symbol_word_t ws2811_rst = { + .duration0 = 10, + .level0 = 1, + .duration1 = 202, // >= 51uS even at high-speed. + .level1 = 0 +}; + +typedef struct _renderFunctionLL { + ledRenderFunction_t fn; + struct _renderFunctionLL* next; +} _renderFunctionLL_t; + +typedef struct _ledTaskParams { + size_t ledCount; +} _ledTaskParams_t; + +IRAM_ATTR size_t _encodeOne( + const rgbPacket_t* pkt, + unsigned int offset, + unsigned int write_limit, + rmt_symbol_word_t* to_write, + size_t buf_offset +){ + if(offset > SYMBOLS_PER_PACKET){ + return 0; + } + + size_t symbols_written = 0; + + for(int i = offset; i < SYMBOLS_PER_PACKET; ++i){ + if(symbols_written == write_limit) break; + + if(i < SYMBOLS_PER_LED){ + to_write[buf_offset + i] = (pkt -> r) & (1 << (7 - i)) ? ws2811_1 : ws2811_0; + }else if(i < 2*SYMBOLS_PER_LED){ + unsigned int ii = i - SYMBOLS_PER_LED; + to_write[buf_offset + i] = (pkt -> g) & (1 << (7 - ii)) ? ws2811_1 : ws2811_0; + }else{ + unsigned int ii = i - 2*SYMBOLS_PER_LED; + to_write[buf_offset + i] = (pkt -> b) & (1 << (7 - ii)) ? ws2811_1 : ws2811_0; + } + ++symbols_written; + } + + return symbols_written; +} + +volatile int tmp = 0; + +IRAM_ATTR size_t _encode( + const void* data, + size_t data_size, + size_t symbols_written, + size_t symbols_free, + rmt_symbol_word_t* symbol_buf, + bool* done, + void* arg +){ + tmp = data_size; + if(symbols_free == 0) return 0; // Can't write anything. + + const rgbPacket_t* packets = (rgbPacket_t*)data; + + unsigned int packet_index = symbols_written / SYMBOLS_PER_PACKET; + unsigned int packet_offset = symbols_written % SYMBOLS_PER_PACKET; + unsigned int packet_count = data_size / sizeof(rgbPacket_t); + + // ESP_LOGI("LED", "sz %lu", (unsigned long)data_size); + + if(packet_index >= packet_count){ + // Write the reset symbol and finish + symbol_buf[0] = ws2811_rst; + (*done) = true; + return 1; + }else{ + if(symbols_free < 24) return 0; + (*done) = false; + return (size_t)_encodeOne( + &packets[packet_index], + /*packet_offset */ 0, + /* symbols_free */ 24, + symbol_buf, + 0 + ); + } +} + +rgbPacket_t fromHSV(uint8_t h, uint8_t s, uint8_t v){ + double sd = (double)s / 255.0; + double vd = (double)v / 255.0; + double hd = (double)h * (360.0 / 255.0); + + double max = vd; + double chroma = sd * vd; + double min = max - chroma; + + double hPrime = hd >= 300.0 ? (hd - 360.0) / 60.0 : hd / 60.0; + + double r, g, b; + + if(hPrime < 1.0){ + if(hPrime < 0.0){ + r = max; + g = min; + b = min - hPrime * chroma; + }else{ + r = max; + g = min + hPrime * chroma; + b = min; + } + }else if(hPrime < 3.0){ + if(hPrime < 2.0){ + r = min - (hPrime - 2.0) * chroma; + g = max; + b = min; + }else{ + r = min; + g = max; + b = min + (hPrime - 2.0) * chroma; + } + }else{ + if(hPrime < 4.0){ + r = min; + g = min - (hPrime - 4.0) * chroma; + b = max; + }else{ + r = min + (hPrime - 4.0) * chroma; + g = min; + b = max; + } + } + + return (rgbPacket_t){ + .r = (uint8_t)(r * 255.0), + .g = (uint8_t)(g * 255.0), + .b = (uint8_t)(b * 255.0) + }; +} + +void _testRenderer(rgbPacket_t* buf, size_t led_count, unsigned long frame){ + for(size_t i = 0; i < led_count; ++i){ + buf[i] = fromHSV( + (uint8_t)(((frame + (unsigned long)i)*2) % 255UL), + saturation, + 255 + ); + // buf[i] = (rgbPacket_t){ + // .r = ((ii % 3UL) == 0UL) ? (uint8_t)255 : (uint8_t)0, + // .g = ((ii % 3UL) == 1UL) ? (uint8_t)255 : (uint8_t)0, + // .b = ((ii % 3UL) == 2UL) ? (uint8_t)255 : (uint8_t)0 + // }; + } +} + +rmt_channel_handle_t ledChannel; +rmt_encoder_handle_t ledEncoder; +TaskHandle_t ledTask; + +void T_ledTask(void* params_raw){ + _ledTaskParams_t params = *((_ledTaskParams_t*)params_raw); + + + rgbPacket_t* packetBufA = (rgbPacket_t*) malloc( + (params.ledCount)*sizeof(rgbPacket_t) + ); + + rgbPacket_t* packetBufB = (rgbPacket_t*) malloc( + (params.ledCount)*sizeof(rgbPacket_t) + ); + + const rmt_transmit_config_t myTxConfig = { + .loop_count = 0, + }; + + unsigned long frame = 0; + rgbPacket_t* active_buf = packetBufA; + rgbPacket_t* next_buf = packetBufB; + + _testRenderer( + next_buf, + params.ledCount, + frame++ + ); + + while(1){ + active_buf = next_buf; + next_buf = (active_buf == packetBufA) ? packetBufB : packetBufA; + ESP_ERROR_CHECK( + rmt_transmit( + ledChannel, + ledEncoder, + active_buf, + (params.ledCount)*sizeof(rgbPacket_t), + &myTxConfig + ) + ); + + _testRenderer( + next_buf, + params.ledCount, + frame++ + ); + + ESP_ERROR_CHECK( + rmt_tx_wait_all_done( + ledChannel, + portMAX_DELAY + ) + ); + vTaskDelay(20 / portTICK_PERIOD_MS); + } +} + +void init_leds(){ + ESP_LOGI("LED", "Initializing RMT channel..."); + rmt_tx_channel_config_t ledChannelCfg = { + .gpio_num = (gpio_num_t)LED_PIN, + .clk_src = RMT_CLK_SRC_DEFAULT, + .resolution_hz = WS2811_HIGH_SPEED, + .mem_block_symbols = 128, + .trans_queue_depth = 4, + .intr_priority = 2 + }; + ESP_ERROR_CHECK( + rmt_new_tx_channel( + &ledChannelCfg, + &ledChannel + ) + ); + + ESP_LOGI("LED", "Configuring encoder..."); + const rmt_simple_encoder_config_t ledCfg = { + .callback = _encode, + .min_chunk_size = 24, + .arg = NULL + }; + ESP_ERROR_CHECK( + rmt_new_simple_encoder( + &ledCfg, + &ledEncoder + ) + ); + + _ledTaskParams_t params = { + .ledCount = 100 + }; + + ESP_LOGI("LED", "Activating RMT channel..."); + ESP_ERROR_CHECK( + rmt_enable(ledChannel) + ); + + ESP_LOGI("LED", "Spawning task..."); + xTaskCreate( + T_ledTask, + "LED update task", + 2048, + (void*)¶ms, + 2, + &ledTask + ); + ESP_LOGI("LED", "Done!"); +} \ No newline at end of file diff --git a/firmware/main/src/ui/inputs.c b/firmware/main/src/ui/inputs.c new file mode 100644 index 0000000..498fc6a --- /dev/null +++ b/firmware/main/src/ui/inputs.c @@ -0,0 +1,240 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ui/inputs.h" + +TaskHandle_t T_ReadInputs_Handle; +EventGroupHandle_t EV_InputEventGroupHandle; +SemaphoreHandle_t inputSemaphore; + +StaticSemaphore_t _inputSemaphoreBuf; +StaticEventGroup_t _inputEventGroupBuf; + +InputState_t _curInputState = { + .forward = false, + .backspace = false, + .done = false, + .cancel = false, + .option = false, + .wheel = 0, + ._wheelQuadrant = 0b11 +}; // NOTE: take inputSemaphore before accessing + +typedef enum _InputEventType{ + INPUT_EVENT_TYPE_KEY, + INPUT_EVENT_TYPE_WHEEL +} _InputEventType_t; + +void IRAM_ATTR ISR_keyEvent(void* params){ + BaseType_t higherTaskWoken = pdFALSE; + + xTaskNotifyIndexedFromISR( + T_ReadInputs_Handle, + 0, + INPUT_EVENT_TYPE_KEY, + eSetValueWithOverwrite, + &higherTaskWoken + ); + + if(higherTaskWoken){ + portYIELD_FROM_ISR(higherTaskWoken); + } +} + +void IRAM_ATTR ISR_wheelEvent(void* params){ + BaseType_t higherTaskWoken = pdFALSE; + + xTaskNotifyIndexedFromISR( + T_ReadInputs_Handle, + 0, + INPUT_EVENT_TYPE_WHEEL, + eSetValueWithOverwrite, + &higherTaskWoken + ); + + if(higherTaskWoken){ + portYIELD_FROM_ISR(higherTaskWoken); + } +} + +InputState_t _getNewInputs(bool doDebounceDelay){ + + if(doDebounceDelay){ + vTaskDelay(10 / portTICK_PERIOD_MS); + } + + xSemaphoreTake(inputSemaphore, portMAX_DELAY); + + + InputState_t newInputs = { + .forward = !gpio_get_level(CONFIG_KEY_FORWARD), + .backspace = !gpio_get_level(CONFIG_KEY_BACKSPACE), + .done = !gpio_get_level(CONFIG_KEY_DONE), + .cancel = !gpio_get_level(CONFIG_KEY_CANCEL), + .option = !gpio_get_level(CONFIG_KEY_OPTION), + .wheel = _curInputState.wheel, + ._wheelQuadrant = ( + (gpio_get_level(CONFIG_PIN_WHEEL_B) << 1) + | (gpio_get_level(CONFIG_PIN_WHEEL_A)) + ) + }; + + if(newInputs._wheelQuadrant == 0b11 && _curInputState._wheelQuadrant != 0b11){ + if(_curInputState._wheelQuadrant == 0b01){ + ++newInputs.wheel; + }else if(_curInputState._wheelQuadrant == 0b10){ + --newInputs.wheel; + } + } + + xSemaphoreGive(inputSemaphore); + + return newInputs; +} + +EventBits_t _calcInputDeltas(InputState_t newState){ + EventBits_t deltas = 0; + + xSemaphoreTake(inputSemaphore, portMAX_DELAY); + + if(newState.forward != _curInputState.forward) deltas |= INPUT_EVENT_KEY_FORWARD; + if(newState.backspace != _curInputState.backspace) deltas |= INPUT_EVENT_KEY_BACKSPACE; + if(newState.done != _curInputState.done) deltas |= INPUT_EVENT_KEY_DONE; + if(newState.cancel != _curInputState.cancel) deltas |= INPUT_EVENT_KEY_CANCEL; + if(newState.option != _curInputState.option) deltas |= INPUT_EVENT_KEY_OPTION; + if(newState.wheel != _curInputState.wheel) deltas |= INPUT_EVENT_WHEEL; + + xSemaphoreGive(inputSemaphore); + + return deltas; +} + +/** + * Task that handles reading inputs, updating the internal state, and generating + * events in the EV_InputEventGroup. + */ +void T_ReadInputs(void* params){ + while(1){ + _InputEventType_t evt = (_InputEventType_t)ulTaskNotifyTakeIndexed( + 0, + pdTRUE, + portMAX_DELAY + ); + + InputState_t newInputs = _getNewInputs( + evt == INPUT_EVENT_TYPE_KEY + ); + + EventBits_t deltas = _calcInputDeltas(newInputs); + + xSemaphoreTake(inputSemaphore, portMAX_DELAY); + _curInputState = newInputs; + xSemaphoreGive(inputSemaphore); + + xEventGroupSetBits(EV_InputEventGroupHandle, deltas); + } +} + +/** + * Task to ensure that all event-bits are cleared immediately. + * + * If a task starts listening on a UI event, it should *not* receive any UI + * event sent before it started listening. Thus, UI events should be cleared + * immediately. This task perpetually waits for any UI event and clears it. + */ +void T_EnsureInputEGClear(void* params){ + while(1){ + xEventGroupWaitBits( + EV_InputEventGroupHandle, + 0xf, + pdTRUE, + pdFALSE, + portMAX_DELAY + ); + } +} + +void init_inputs(){ + ESP_LOGI(INPUTS_TAG, "Configuring input GPIOs..."); + + gpio_config_t _wheelConfig = { + .pin_bit_mask = ( + (1ULL << CONFIG_PIN_WHEEL_A) + | (1ULL << CONFIG_PIN_WHEEL_B) + ), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_POSEDGE + }; + + gpio_config_t _keyConfig = { + .pin_bit_mask = ( + (1ULL << CONFIG_KEY_FORWARD) + | (1ULL << CONFIG_KEY_BACKSPACE) + | (1ULL << CONFIG_KEY_DONE) + | (1ULL << CONFIG_KEY_CANCEL) + | (1ULL << CONFIG_KEY_OPTION) + ), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_ANYEDGE + }; + + ESP_ERROR_CHECK(gpio_config(&_wheelConfig)); + ESP_ERROR_CHECK(gpio_config(&_keyConfig)); + + ESP_LOGI(INPUTS_TAG, "Creating event queue..."); + EV_InputEventGroupHandle = xEventGroupCreateStatic(&_inputEventGroupBuf); + inputSemaphore = xSemaphoreCreateBinaryStatic(&_inputSemaphoreBuf); + xSemaphoreGive(inputSemaphore); // Starting value of 1 + + ESP_LOGI(INPUTS_TAG, "Configuring GPIO interrupts..."); + ESP_ERROR_CHECK(gpio_install_isr_service(0)); + ESP_ERROR_CHECK(gpio_isr_handler_add(CONFIG_KEY_FORWARD, ISR_keyEvent, NULL)); + ESP_ERROR_CHECK(gpio_isr_handler_add(CONFIG_KEY_BACKSPACE, ISR_keyEvent, NULL)); + ESP_ERROR_CHECK(gpio_isr_handler_add(CONFIG_KEY_DONE, ISR_keyEvent, NULL)); + ESP_ERROR_CHECK(gpio_isr_handler_add(CONFIG_KEY_CANCEL, ISR_keyEvent, NULL)); + ESP_ERROR_CHECK(gpio_isr_handler_add(CONFIG_KEY_OPTION, ISR_keyEvent, NULL)); + ESP_ERROR_CHECK(gpio_isr_handler_add(CONFIG_PIN_WHEEL_A, ISR_wheelEvent, NULL)); + ESP_ERROR_CHECK(gpio_isr_handler_add(CONFIG_PIN_WHEEL_B, ISR_wheelEvent, NULL)); + + ESP_LOGI(INPUTS_TAG, "Spawning tasks..."); + xTaskCreate(T_EnsureInputEGClear, "Keeps Input EG Clear", 2048, NULL, 2, NULL); + xTaskCreate(T_ReadInputs, "Reads front-panel inputs", 2048, NULL, 4, &T_ReadInputs_Handle); + + ESP_LOGI(INPUTS_TAG, "Complete!"); +} + +InputState_t waitForInputEvents(UIEventGroupFlags_t events, BaseType_t xWaitForAll, TickType_t xTicksToWait){ + xEventGroupWaitBits( + EV_InputEventGroupHandle, + events, + pdTRUE, + xWaitForAll, + xTicksToWait + ); + + return getInputState(); +} + +InputState_t getInputState(){ + xSemaphoreTake(inputSemaphore, portMAX_DELAY); + InputState_t curInputs = _curInputState; + xSemaphoreGive(inputSemaphore); + + return curInputs; +} \ No newline at end of file diff --git a/firmware/sdkconfig.defaults b/firmware/sdkconfig.defaults new file mode 100644 index 0000000..9533c37 --- /dev/null +++ b/firmware/sdkconfig.defaults @@ -0,0 +1,3 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.3.1 Project Minimal Configuration +#