diff --git a/board/dongshanpi-aict/CMakeLists.txt b/board/dongshanpi-aict/CMakeLists.txt new file mode 100644 index 00000000..d589023a --- /dev/null +++ b/board/dongshanpi-aict/CMakeLists.txt @@ -0,0 +1,35 @@ +set(APP_COMMON_SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/start.S + ${CMAKE_CURRENT_SOURCE_DIR}/board.c + ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c +) + +add_subdirectory(hello_world) + +add_subdirectory(read_chipsid) + +add_subdirectory(init_dram) + +add_subdirectory(read_chip_efuse) + +add_subdirectory(syter_boot) + +add_subdirectory(syter_bootargs) + +add_subdirectory(load_e907) + +add_subdirectory(syter_amp) + +add_subdirectory(fdt_parser) + +add_subdirectory(cli_test) + +add_subdirectory(fdt_cli) + +add_subdirectory(syter_boot_spi) + +add_subdirectory(i2c_test) + +add_subdirectory(i2c_oled) + +add_subdirectory(spi_lcd) diff --git a/board/dongshanpi-aict/README.md b/board/dongshanpi-aict/README.md new file mode 100644 index 00000000..fc121158 --- /dev/null +++ b/board/dongshanpi-aict/README.md @@ -0,0 +1,29 @@ +# SyterKit Common + +## start.S + +This code snippet is an ARM assembly language program that includes initialization settings and exception handlers. Here's a breakdown of its functionalities: + +1. Initialization Settings: It sets registers and writes specific values to configure the processor's working mode, interrupt enable, etc. + +2. Set Vector Table: It writes the address of the vector table to the Vector Base Address Register, which is used for handling exceptions and interrupts. + +3. Enable NEON/VFP Unit: It configures the processor to enable the NEON (Advanced SIMD) and VFP (Floating-Point) units. + +4. Clear BSS Section: It zeroes out variables in the BSS section. + +5. Disable Interrupts: It disables FIQ and IRQ interrupts and switches the processor to SVC32 mode. + +6. Set Timer Frequency: It sets the timer frequency to 24M. + +7. Call the main Function: It jumps to the main function to execute the main logic. + +## eabi_compat.c + +This code snippet appears to be providing implementations for the functions `abort`, `raise`, and `__aeabi_unwind_cpp_pr0`. Here's a breakdown of their functionalities: + +1. `void abort(void)`: This function creates an infinite loop, causing the program to hang indefinitely. It is typically used to indicate a critical error or unrecoverable condition in a program. + +2. `int raise(int signum)`: This function is a placeholder and always returns 0. In standard C, this function is used to raise a signal and initiate the corresponding signal handler. However, in this implementation, it does nothing and simply returns 0. + +3. `void __aeabi_unwind_cpp_pr0(void)`: This is a dummy function that serves as a placeholder to avoid linker complaints. Its purpose is to satisfy the linker when using C++ exceptions and unwinding, but it does not contain any actual functionality. diff --git a/board/dongshanpi-aict/board.c b/board/dongshanpi-aict/board.c new file mode 100644 index 00000000..636b91ca --- /dev/null +++ b/board/dongshanpi-aict/board.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +sunxi_serial_t uart_dbg = { + .base = 0x02500000, + .id = 0, + .gpio_tx = {GPIO_PIN(GPIO_PORTH, 9), GPIO_PERIPH_MUX5}, + .gpio_rx = {GPIO_PIN(GPIO_PORTH, 10), GPIO_PERIPH_MUX5}, +}; + +sunxi_spi_t sunxi_spi0 = { + .base = 0x04025000, + .id = 0, + .clk_rate = 75 * 1000 * 1000, + .gpio_cs = {GPIO_PIN(GPIO_PORTC, 1), GPIO_PERIPH_MUX4}, + .gpio_sck = {GPIO_PIN(GPIO_PORTC, 0), GPIO_PERIPH_MUX4}, + .gpio_mosi = {GPIO_PIN(GPIO_PORTC, 2), GPIO_PERIPH_MUX4}, + .gpio_miso = {GPIO_PIN(GPIO_PORTC, 3), GPIO_PERIPH_MUX4}, + .gpio_wp = {GPIO_PIN(GPIO_PORTC, 4), GPIO_PERIPH_MUX4}, + .gpio_hold = {GPIO_PIN(GPIO_PORTC, 5), GPIO_PERIPH_MUX4}, +}; + +sdhci_t sdhci0 = { + .name = "sdhci0", + .reg = (sdhci_reg_t *) 0x04020000, + .voltage = MMC_VDD_27_36, + .width = MMC_BUS_WIDTH_4, + .clock = MMC_CLK_50M, + .removable = 0, + .isspi = FALSE, + .gpio_clk = {GPIO_PIN(GPIO_PORTF, 2), GPIO_PERIPH_MUX2}, + .gpio_cmd = {GPIO_PIN(GPIO_PORTF, 3), GPIO_PERIPH_MUX2}, + .gpio_d0 = {GPIO_PIN(GPIO_PORTF, 1), GPIO_PERIPH_MUX2}, + .gpio_d1 = {GPIO_PIN(GPIO_PORTF, 0), GPIO_PERIPH_MUX2}, + .gpio_d2 = {GPIO_PIN(GPIO_PORTF, 5), GPIO_PERIPH_MUX2}, + .gpio_d3 = {GPIO_PIN(GPIO_PORTF, 4), GPIO_PERIPH_MUX2}, +}; + +dram_para_t dram_para = { + .dram_clk = 936, + .dram_type = 3, + .dram_zq = 0x7b7bfb, + .dram_odt_en = 0x1, + .dram_para1 = 0x0010f2, + .dram_para2 = 0x0, + .dram_mr0 = 0x1c70, + .dram_mr1 = 0x42, + .dram_mr2 = 0x18, + .dram_mr3 = 0x0, + .dram_tpr0 = 0x004A2195, + .dram_tpr1 = 0x02423190, + .dram_tpr2 = 0x0008B061, + .dram_tpr3 = 0xB4787896, + .dram_tpr4 = 0x0, + .dram_tpr5 = 0x48484848, + .dram_tpr6 = 0x48, + .dram_tpr7 = 0x1621121e, + .dram_tpr8 = 0x0, + .dram_tpr9 = 0x0, + .dram_tpr10 = 0x0, + .dram_tpr11 = 0x00420000, + .dram_tpr12 = 0x00000048, + .dram_tpr13 = 0x34010100, +}; + +void clean_syterkit_data(void) { + /* Disable MMU, data cache, instruction cache, interrupts */ + arm32_mmu_disable(); + printk(LOG_LEVEL_INFO, "disable mmu ok...\n"); + arm32_dcache_disable(); + printk(LOG_LEVEL_INFO, "disable dcache ok...\n"); + arm32_icache_disable(); + printk(LOG_LEVEL_INFO, "disable icache ok...\n"); + arm32_interrupt_disable(); + printk(LOG_LEVEL_INFO, "free interrupt ok...\n"); +} + +void rtc_set_vccio_det_spare(void) { + u32 val = 0; + val = readl(SUNXI_RTC_BASE + 0x1f4); + val &= ~(0xff << 4); + val |= (VCCIO_THRESHOLD_VOLTAGE_2_9 | FORCE_DETECTER_OUTPUT); + val &= ~VCCIO_DET_BYPASS_EN; + writel(val, SUNXI_RTC_BASE + 0x1f4); +} + +void sys_ldo_check(void) { + uint32_t reg_val = 0; + uint32_t roughtrim_val = 0, finetrim_val = 0; + + /* reset */ + reg_val = readl(CCU_AUDIO_CODEC_BGR_REG); + reg_val &= ~(1 << 16); + writel(reg_val, CCU_AUDIO_CODEC_BGR_REG); + + sdelay(2); + + reg_val |= (1 << 16); + writel(reg_val, CCU_AUDIO_CODEC_BGR_REG); + + /* enable AUDIO gating */ + reg_val = readl(CCU_AUDIO_CODEC_BGR_REG); + reg_val |= (1 << 0); + writel(reg_val, CCU_AUDIO_CODEC_BGR_REG); + + /* enable pcrm CTRL */ + reg_val = readl(ANA_PWR_RST_REG); + reg_val &= ~(1 << 0); + writel(reg_val, ANA_PWR_RST_REG); + + /* read efuse */ + printk(LOG_LEVEL_DEBUG, "Audio: avcc calibration\n"); + reg_val = readl(SUNXI_SID_SRAM_BASE + 0x28); + roughtrim_val = (reg_val >> 0) & 0xF; + reg_val = readl(SUNXI_SID_SRAM_BASE + 0x24); + finetrim_val = (reg_val >> 16) & 0xFF; + + if (roughtrim_val == 0 && finetrim_val == 0) { + reg_val = readl(SUNXI_VER_REG); + reg_val = (reg_val >> 0) & 0x7; + if (reg_val) { + printk(LOG_LEVEL_DEBUG, "Audio: chip not version A\n"); + } else { + roughtrim_val = 0x5; + finetrim_val = 0x19; + printk(LOG_LEVEL_DEBUG, "Audio: chip version A\n"); + } + } + reg_val = readl(AUDIO_POWER_REG); + reg_val &= ~(0xF << 8 | 0xFF); + reg_val |= roughtrim_val << 8 | finetrim_val; + writel(reg_val, AUDIO_POWER_REG); +} \ No newline at end of file diff --git a/board/dongshanpi-aict/cli_test/CMakeLists.txt b/board/dongshanpi-aict/cli_test/CMakeLists.txt new file mode 100644 index 00000000..e2505e8e --- /dev/null +++ b/board/dongshanpi-aict/cli_test/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(cli_test + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/cli_test/main.c b/board/dongshanpi-aict/cli_test/main.c new file mode 100644 index 00000000..4410288f --- /dev/null +++ b/board/dongshanpi-aict/cli_test/main.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +extern sunxi_serial_t uart_dbg; + +msh_declare_command(helloworld); + +msh_define_help(helloworld, "display helloworld", "Usage: helloworld\n"); +int cmd_helloworld(int argc, const char **argv) { + printk(LOG_LEVEL_MUTE, "Hello World!\n"); + return 0; +} + +const msh_command_entry commands[] = { + msh_define_command(helloworld), + msh_command_end, +}; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_clk_init(); + + printk(LOG_LEVEL_INFO, "Hello World!\n"); + + syterkit_shell_attach(commands); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/eabi_compat.c b/board/dongshanpi-aict/eabi_compat.c new file mode 100644 index 00000000..93303d89 --- /dev/null +++ b/board/dongshanpi-aict/eabi_compat.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +void abort(void) { + while (1) + ; +} + +int raise(int signum) { + return 0; +} + +/* Dummy function to avoid linker complaints */ +void __aeabi_unwind_cpp_pr0(void) { +} \ No newline at end of file diff --git a/board/dongshanpi-aict/fdt_cli/CMakeLists.txt b/board/dongshanpi-aict/fdt_cli/CMakeLists.txt new file mode 100644 index 00000000..20c9a649 --- /dev/null +++ b/board/dongshanpi-aict/fdt_cli/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(fdt_cli + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/fdt_cli/main.c b/board/dongshanpi-aict/fdt_cli/main.c new file mode 100644 index 00000000..583292f6 --- /dev/null +++ b/board/dongshanpi-aict/fdt_cli/main.c @@ -0,0 +1,468 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "sys-dram.h" +#include "sys-sdcard.h" +#include "sys-sid.h" + +#include "fdt_wrapper.h" +#include "ff.h" +#include "libfdt.h" + +#define CONFIG_DTB_FILENAME "sunxi.dtb" +#define CONFIG_DTB_LOADADDR (0x41008000) + +#define MAX_LEVEL 32 /* how deeply nested we will go */ +#define SCRATCHPAD 1024 /* bytes of scratchpad memory */ +#define CMD_FDT_MAX_DUMP 64 + +#define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) + +extern sunxi_serial_t uart_dbg; + +extern dram_para_t dram_para; + +extern sdhci_t sdhci0; + +#define FILENAME_MAX_LEN 64 +typedef struct { + unsigned int offset; + unsigned int length; + unsigned char *dest; + + char filename[FILENAME_MAX_LEN]; +} image_info_t; + +image_info_t image; + +#define CHUNK_SIZE 0x20000 + +static int fatfs_loadimage(char *filename, BYTE *dest) { + FIL file; + UINT byte_to_read = CHUNK_SIZE; + UINT byte_read; + UINT total_read = 0; + FRESULT fret; + int ret; + uint32_t start, time; + + fret = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: open, filename: [%s]: error %d\n", filename, fret); + ret = -1; + goto open_fail; + } + + start = time_ms(); + + do { + byte_read = 0; + fret = f_read(&file, (void *) (dest), byte_to_read, &byte_read); + dest += byte_to_read; + total_read += byte_read; + } while (byte_read >= byte_to_read && fret == FR_OK); + + time = time_ms() - start + 1; + + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: read: error %d\n", fret); + ret = -1; + goto read_fail; + } + ret = 0; + +read_fail: + fret = f_close(&file); + + printk(LOG_LEVEL_DEBUG, "FATFS: read in %ums at %.2fMB/S\n", time, + (f32) (total_read / time) / 1024.0f); + +open_fail: + return ret; +} + +static int load_sdcard(image_info_t *image) { + FATFS fs; + FRESULT fret; + int ret; + uint32_t start; + + uint32_t test_time; + start = time_ms(); + sdmmc_blk_read(&card0, (uint8_t *) (SDRAM_BASE), 0, + CONFIG_SDMMC_SPEED_TEST_SIZE); + test_time = time_ms() - start; + printk(LOG_LEVEL_DEBUG, "SDMMC: speedtest %uKB in %ums at %uKB/S\n", + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / 1024, test_time, + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / test_time); + + start = time_ms(); + + fret = f_mount(&fs, "", 1); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: mount error: %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: mount OK\n"); + } + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->filename, + (unsigned int) image->dest); + ret = fatfs_loadimage(image->filename, image->dest); + if (ret) + return ret; + + /* umount fs */ + fret = f_mount(0, "", 0); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: unmount error %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: unmount OK\n"); + } + printk(LOG_LEVEL_DEBUG, "FATFS: done in %ums\n", time_ms() - start); + + return 0; +} + + + +msh_declare_command(fdt); +msh_define_help(fdt, "flattened device tree utility commands", + "fdt print [] - Recursive print starting at \n" + "fdt list [] - Print one level starting at \n" + "fdt set [] - Set [to ]\n" + "fdt mknode - Create a new node after \n" + "fdt rm [] - Delete the node or \n" + "fdt header - Display header info\n" + "fdt rsvmem print - Show current mem reserves\n" + "fdt rsvmem add - Add a mem reserve\n" + "fdt rsvmem delete - Delete a mem reserves\n" + "NOTE: Dereference aliases by omitting the leading '/', " + "e.g. fdt print ethernet0.\n\n"); +int cmd_fdt(int argc, const char **argv) { + if (argc < 2) { + uart_puts(cmd_fdt_usage); + return 0; + } + if (strncmp(argv[1], "mk", 2) == 0) { + char *pathp; /* path */ + char *nodep; /* new node to add */ + int nodeoffset; /* node offset from libfdt */ + int err; + + /* + * Parameters: Node path, new node to be appended to the path. + */ + if (argc < 4) { + uart_puts(cmd_fdt_usage); + return 0; + } + + pathp = argv[2]; + nodep = argv[3]; + + nodeoffset = fdt_path_offset(image.dest, pathp); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printk(LOG_LEVEL_MUTE, "libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); + return 1; + } + err = fdt_add_subnode(image.dest, nodeoffset, nodep); + if (err < 0) { + printk(LOG_LEVEL_MUTE, "libfdt fdt_add_subnode(): %s\n", fdt_strerror(err)); + return 1; + } + } else if (strncmp(argv[1], "set", 3) == 0) { + char *pathp; /* path */ + char *prop; /* property */ + int nodeoffset; /* node offset from libfdt */ + static char data[SCRATCHPAD] __aligned(4); /* property storage */ + const void *ptmp; + int len; /* new length of the property */ + int ret; /* return value */ + + /* + * Parameters: Node path, property, optional value. + */ + if (argc < 4) { + uart_puts(cmd_fdt_usage); + return 0; + } + + pathp = argv[2]; + prop = argv[3]; + + nodeoffset = fdt_path_offset(image.dest, pathp); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printk(LOG_LEVEL_MUTE, "libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); + return 1; + } + + if (argc == 4) { + len = 0; + } else { + ptmp = fdt_getprop(image.dest, nodeoffset, prop, &len); + if (len > SCRATCHPAD) { + printk(LOG_LEVEL_MUTE, "prop (%d) doesn't fit in scratchpad!\n", len); + return 1; + } + if (ptmp != NULL) + memcpy(data, ptmp, len); + + ret = fdt_parse_prop(&argv[4], argc - 4, data, &len); + if (ret != 0) + return ret; + } + + ret = fdt_setprop(image.dest, nodeoffset, prop, data, len); + if (ret < 0) { + printk(LOG_LEVEL_MUTE, "libfdt fdt_setprop(): %s\n", fdt_strerror(ret)); + return 1; + } + } else if ((argv[1][0] == 'p') || (argv[1][0] == 'l')) { + int depth = MAX_LEVEL; /* how deep to print */ + char *pathp; /* path */ + char *prop; /* property */ + int ret; /* return value */ + static char root[2] = "/"; + + /* + * list is an alias for print, but limited to 1 level + */ + if (argv[1][0] == 'l') { + depth = 1; + } + + /* + * Get the starting path. The root node is an oddball, + * the offset is zero and has no name. + */ + if (argc == 2) + pathp = root; + else + pathp = argv[2]; + if (argc > 3) + prop = argv[3]; + else + prop = NULL; + + fdt_print(image.dest, pathp, prop, depth); + } else if (strncmp(argv[1], "rm", 2) == 0) { + int nodeoffset; /* node offset from libfdt */ + int err; + + /* + * Get the path. The root node is an oddball, the offset + * is zero and has no name. + */ + nodeoffset = fdt_path_offset(image.dest, argv[2]); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printk(LOG_LEVEL_MUTE, "libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); + return 1; + } + /* + * Do the delete. A fourth parameter means delete a property, + * otherwise delete the node. + */ + if (argc > 3) { + err = fdt_delprop(image.dest, nodeoffset, argv[3]); + if (err < 0) { + printk(LOG_LEVEL_MUTE, "libfdt fdt_delprop(): %s\n", fdt_strerror(err)); + return 0; + } + } else { + err = fdt_del_node(image.dest, nodeoffset); + if (err < 0) { + printk(LOG_LEVEL_MUTE, "libfdt fdt_del_node(): %s\n", fdt_strerror(err)); + return 0; + } + } + } else if (argv[1][0] == 'h') { + u32 version = fdt_version(image.dest); + printk(LOG_LEVEL_MUTE, "magic:\t\t\t0x%x\n", fdt_magic(image.dest)); + printk(LOG_LEVEL_MUTE, "totalsize:\t\t0x%x (%d)\n", fdt_totalsize(image.dest), + fdt_totalsize(image.dest)); + printk(LOG_LEVEL_MUTE, "off_dt_struct:\t\t0x%x\n", + fdt_off_dt_struct(image.dest)); + printk(LOG_LEVEL_MUTE, "off_dt_strings:\t\t0x%x\n", + fdt_off_dt_strings(image.dest)); + printk(LOG_LEVEL_MUTE, "off_mem_rsvmap:\t\t0x%x\n", + fdt_off_mem_rsvmap(image.dest)); + printk(LOG_LEVEL_MUTE, "version:\t\t%d\n", version); + printk(LOG_LEVEL_MUTE, "last_comp_version:\t%d\n", + fdt_last_comp_version(image.dest)); + if (version >= 2) + printk(LOG_LEVEL_MUTE, "boot_cpuid_phys:\t0x%x\n", + fdt_boot_cpuid_phys(image.dest)); + if (version >= 3) + printk(LOG_LEVEL_MUTE, "size_dt_strings:\t0x%x\n", + fdt_size_dt_strings(image.dest)); + if (version >= 17) + printk(LOG_LEVEL_MUTE, "size_dt_struct:\t\t0x%x\n", + fdt_size_dt_struct(image.dest)); + printk(LOG_LEVEL_MUTE, "number mem_rsv:\t\t0x%x\n", + fdt_num_mem_rsv(image.dest)); + printk(LOG_LEVEL_MUTE, "\n"); + } else if (strncmp(argv[1], "rs", 2) == 0) { + if (argv[2][0] == 'p') { + uint64_t addr, size; + int total = fdt_num_mem_rsv(image.dest); + int j, err; + printk(LOG_LEVEL_MUTE, "index\t\t start\t\t size\n"); + printk(LOG_LEVEL_MUTE, "-------------------------------" + "-----------------\n"); + for (j = 0; j < total; j++) { + err = fdt_get_mem_rsv(image.dest, j, &addr, &size); + if (err < 0) { + printk(LOG_LEVEL_MUTE, "libfdt fdt_get_mem_rsv(): %s\n", fdt_strerror(err)); + return 0; + } + printk(LOG_LEVEL_MUTE, " %x\t%08x%08x\t%08x%08x\n", j, + (u32) (addr >> 32), + (u32) (addr & 0xffffffff), + (u32) (size >> 32), + (u32) (size & 0xffffffff)); + } + } else if (argv[2][0] == 'a') { + uint64_t addr, size; + int err; + addr = simple_strtoull(argv[3], NULL, 16); + size = simple_strtoull(argv[4], NULL, 16); + err = fdt_add_mem_rsv(image.dest, addr, size); + + if (err < 0) { + printk(LOG_LEVEL_MUTE, "libfdt fdt_add_mem_rsv(): %s\n", fdt_strerror(err)); + return 0; + } + } else if (argv[2][0] == 'd') { + unsigned long idx = simple_strtoul(argv[3], NULL, 16); + int err = fdt_del_mem_rsv(image.dest, idx); + + if (err < 0) { + printk(LOG_LEVEL_MUTE, "libfdt fdt_del_mem_rsv(): %s\n", fdt_strerror(err)); + return 0; + } + } else { + uart_puts(cmd_fdt_usage); + return 0; + } + } else { + uart_puts(cmd_fdt_usage); + return 0; + } + return 0; +} + +msh_declare_command(reload); +msh_define_help(reload, "rescan TF Card and reload DTB", + "Usage: reload\n"); +int cmd_reload(int argc, const char **argv) { + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: init failed\n"); + return 0; + } + + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: loading failed\n"); + return 0; + } + return 0; +} + +const msh_command_entry commands[] = { + msh_define_command(fdt), + msh_define_command(reload), + msh_command_end, +}; + +int main(void) { + /* Initialize UART debug interface */ + sunxi_serial_init(&uart_dbg); + + /* Print boot screen */ + show_banner(); + + /* Initialize clock */ + sunxi_clk_init(); + + /* Initialize DRAM */ + sunxi_dram_init(&dram_para); + + /* Print clock information */ + sunxi_clk_dump(); + + /* Clear image structure */ + memset(&image, 0, sizeof(image_info_t)); + + /* Set the target address of image to DTB load address */ + image.dest = (uint8_t *) CONFIG_DTB_LOADADDR; + + /* Copy the DTB filename to the image structure */ + strcpy(image.filename, CONFIG_DTB_FILENAME); + + /* Initialize SD card controller */ + if (sunxi_sdhci_init(&sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: %s controller init failed\n", sdhci0.name); + goto _shell; + } else { + printk(LOG_LEVEL_INFO, "SMHC: %s controller v%x initialized\n", sdhci0.name, sdhci0.reg->vers); + } + + /* Initialize SD card */ + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: init failed\n"); + goto _shell; + } + + /* Load DTB file from SD card */ + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: loading failed\n"); + goto _shell; + } + + /* Force image.dest to be a pointer to fdt_header structure */ + struct fdt_header *dtb_header = (struct fdt_header *) image.dest; + + int err = 0; + + /* Check if DTB header is valid */ + if ((err = fdt_check_header(dtb_header)) != 0) { + printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); + goto _shell; + } + + /* Get the total size of DTB */ + uint32_t size = fdt_totalsize(image.dest); + printk(LOG_LEVEL_INFO, "DTB FDT Size = 0x%x\n", size); + +_shell: + syterkit_shell_attach(commands); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/fdt_parser/CMakeLists.txt b/board/dongshanpi-aict/fdt_parser/CMakeLists.txt new file mode 100644 index 00000000..8014f0ea --- /dev/null +++ b/board/dongshanpi-aict/fdt_parser/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(fdtparser + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/fdt_parser/main.c b/board/dongshanpi-aict/fdt_parser/main.c new file mode 100644 index 00000000..3441fd4c --- /dev/null +++ b/board/dongshanpi-aict/fdt_parser/main.c @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "sys-dram.h" +#include "sys-sdcard.h" +#include "sys-sid.h" +#include "sys-spi.h" + +#include "ff.h" +#include "libfdt.h" +#include "fdt_wrapper.h" + +#define CONFIG_DTB_FILENAME "sunxi.dtb" +#define CONFIG_DTB_LOADADDR (0x41008000) + +#define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) + +extern sunxi_serial_t uart_dbg; + +extern dram_para_t dram_para; + +sunxi_serial_t uart_e907 = { + .base = 0x02500C00, + .id = 3, + .gpio_tx = {GPIO_PIN(GPIO_PORTE, 0), GPIO_PERIPH_MUX7}, + .gpio_rx = {GPIO_PIN(GPIO_PORTE, 1), GPIO_PERIPH_MUX7}, +}; + +extern sdhci_t sdhci0; + +#define FILENAME_MAX_LEN 64 +typedef struct { + unsigned int offset; + unsigned int length; + unsigned char *dest; + + char filename[FILENAME_MAX_LEN]; +} image_info_t; + +image_info_t image; + +#define CHUNK_SIZE 0x20000 + +static int fatfs_loadimage(char *filename, BYTE *dest) { + FIL file; + UINT byte_to_read = CHUNK_SIZE; + UINT byte_read; + UINT total_read = 0; + FRESULT fret; + int ret; + uint32_t start, time; + + fret = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: open, filename: [%s]: error %d\n", filename, fret); + ret = -1; + goto open_fail; + } + + start = time_ms(); + + do { + byte_read = 0; + fret = f_read(&file, (void *) (dest), byte_to_read, &byte_read); + dest += byte_to_read; + total_read += byte_read; + } while (byte_read >= byte_to_read && fret == FR_OK); + + time = time_ms() - start + 1; + + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: read: error %d\n", fret); + ret = -1; + goto read_fail; + } + ret = 0; + +read_fail: + fret = f_close(&file); + + printk(LOG_LEVEL_DEBUG, "FATFS: read in %ums at %.2fMB/S\n", time, + (f32) (total_read / time) / 1024.0f); + +open_fail: + return ret; +} + +static int load_sdcard(image_info_t *image) { + FATFS fs; + FRESULT fret; + int ret; + uint32_t start; + + uint32_t test_time; + start = time_ms(); + sdmmc_blk_read(&card0, (uint8_t *) (SDRAM_BASE), 0, + CONFIG_SDMMC_SPEED_TEST_SIZE); + test_time = time_ms() - start; + printk(LOG_LEVEL_DEBUG, "SDMMC: speedtest %uKB in %ums at %uKB/S\n", + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / 1024, test_time, + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / test_time); + + start = time_ms(); + + fret = f_mount(&fs, "", 1); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: mount error: %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: mount OK\n"); + } + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->filename, + (unsigned int) image->dest); + ret = fatfs_loadimage(image->filename, image->dest); + if (ret) + return ret; + + /* umount fs */ + fret = f_mount(0, "", 0); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: unmount error %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: unmount OK\n"); + } + printk(LOG_LEVEL_DEBUG, "FATFS: done in %ums\n", time_ms() - start); + + return 0; +} + + + +int main(void) { + /* Initialize UART debug interface */ + sunxi_serial_init(&uart_dbg); + + /* Print boot screen */ + show_banner(); + + /* Initialize clock */ + sunxi_clk_init(); + + /* Initialize DRAM */ + sunxi_dram_init(&dram_para); + + /* Print clock information */ + sunxi_clk_dump(); + + /* Clear image structure */ + memset(&image, 0, sizeof(image_info_t)); + + /* Set the target address of image to DTB load address */ + image.dest = (uint8_t *) CONFIG_DTB_LOADADDR; + + /* Copy the DTB filename to the image structure */ + strcpy(image.filename, CONFIG_DTB_FILENAME); + + /* Initialize SD card controller */ + if (sunxi_sdhci_init(&sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: %s controller init failed\n", sdhci0.name); + return 0; + } else { + printk(LOG_LEVEL_INFO, "SMHC: %s controller v%x initialized\n", sdhci0.name, sdhci0.reg->vers); + } + + /* Initialize SD card */ + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: init failed\n"); + return 0; + } + + /* Load DTB file from SD card */ + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: loading failed\n"); + return 0; + } + + /* Force image.dest to be a pointer to fdt_header structure */ + struct fdt_header *dtb_header = (struct fdt_header *) image.dest; + + int err = 0; + + /* Check if DTB header is valid */ + if ((err = fdt_check_header(dtb_header)) != 0) { + printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); + return -1; + } + + /* Get the total size of DTB */ + uint32_t size = fdt_totalsize(image.dest); + printk(LOG_LEVEL_INFO, "DTB FDT Size = 0x%x\n", size); + + /* Print all device tree nodes */ + fdt_print(image.dest, "/", NULL, MAX_LEVEL); + + int len = 0; + /* Get the offset of "/chosen" node */ + uint32_t bootargs_node = fdt_path_offset(image.dest, "/chosen"); + + /* Get bootargs string */ + char *bootargs_str = (void *) fdt_getprop(image.dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_INFO, "DTB OLD bootargs = \"%s\"\n", bootargs_str); + + /* New bootargs string */ + char *new_bootargs_str = "earlyprintk=sunxi-uart,0x02500C00 root=/dev/mmcblk0p3 rootwait loglevel=8 initcall_debug=0 console=ttyS0 init=/init"; + printk(LOG_LEVEL_INFO, "Now set bootargs to \"%s\"\n", new_bootargs_str); + + /* Modify bootargs string */ + err = fdt_setprop(image.dest, bootargs_node, "bootargs", new_bootargs_str, strlen(new_bootargs_str) + 1); + + if (err < 0) { + printk(LOG_LEVEL_ERROR, "libfdt fdt_setprop() error: %s\n", fdt_strerror(err)); + abort(); + } + + /* Get updated bootargs string */ + char *updated_bootargs_str = (void *) fdt_getprop(image.dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_INFO, "DTB NEW bootargs = \"%s\"\n", updated_bootargs_str); + + /* Terminate program execution */ + abort(); + + /* Jump to FEL mode execution */ + jmp_to_fel(); + + return 0; +} diff --git a/board/dongshanpi-aict/hello_world/CMakeLists.txt b/board/dongshanpi-aict/hello_world/CMakeLists.txt new file mode 100644 index 00000000..b5ce1ea5 --- /dev/null +++ b/board/dongshanpi-aict/hello_world/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(helloworld + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/hello_world/main.c b/board/dongshanpi-aict/hello_world/main.c new file mode 100644 index 00000000..b588126a --- /dev/null +++ b/board/dongshanpi-aict/hello_world/main.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +extern sunxi_serial_t uart_dbg; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_clk_init(); + + printk(LOG_LEVEL_INFO, "Hello World!\n"); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/i2c_oled/CMakeLists.txt b/board/dongshanpi-aict/i2c_oled/CMakeLists.txt new file mode 100644 index 00000000..c0ae01a5 --- /dev/null +++ b/board/dongshanpi-aict/i2c_oled/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(i2c_oled + main.c + oled.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/i2c_oled/main.c b/board/dongshanpi-aict/i2c_oled/main.c new file mode 100644 index 00000000..0a9d11ac --- /dev/null +++ b/board/dongshanpi-aict/i2c_oled/main.c @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include + +#include "sys-uart.h" + +#include "oled.h" + +extern sunxi_serial_t uart_dbg; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_clk_init(); + + printk(LOG_LEVEL_INFO, "Hello World\n"); + + OLED_Init(); + + OLED_ShowString(12, 16, "SyterKit", 16, 1); + OLED_ShowString(20, 32, "I2C OLED", 16, 1); + + OLED_Refresh(); + + abort(); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/i2c_oled/oled.c b/board/dongshanpi-aict/i2c_oled/oled.c new file mode 100644 index 00000000..d853dc03 --- /dev/null +++ b/board/dongshanpi-aict/i2c_oled/oled.c @@ -0,0 +1,272 @@ +#include +#include +#include +#include + +#include + +#include + +#include "sys-i2c.h" + +#include "oledfont.h" + +#define OLED_IIC_ADDR 0x3c +#define OLED_IIC_GPIO_PORT 0 + +#define OLED_CMD 0 /*写命令 */ +#define OLED_DATA 1 /* 写数据 */ + +uint8_t OLED_GRAM[144][8]; /* 显存 */ + +sunxi_i2c_t i2c_0 = { + .base = 0x02502000, + .id = 0, + .speed = 4000000, + .gpio_scl = {GPIO_PIN(GPIO_PORTE, 4), GPIO_PERIPH_MUX8}, + .gpio_sda = {GPIO_PIN(GPIO_PORTE, 5), GPIO_PERIPH_MUX8}, +}; + +void OLED_WR_Byte(uint8_t dat, uint8_t mode) { + if (mode) + sunxi_i2c_write(&i2c_0, OLED_IIC_ADDR, 0x40, dat); + else + sunxi_i2c_write(&i2c_0, OLED_IIC_ADDR, 0x00, dat); +} + +uint32_t OLED_Pow(uint8_t m, uint8_t n) { + uint32_t result = 1; + while (n--) + result *= m; + return result; +} + +void OLED_ColorTurn(uint8_t i) { + if (i == 0) { + OLED_WR_Byte(0xA6, OLED_CMD); /* 正常显示 */ + } + if (i == 1) { + OLED_WR_Byte(0xA7, OLED_CMD); /* 反色显示 */ + } +} + +void OLED_DisplayTurn(uint8_t i) { + if (i == 0) { + OLED_WR_Byte(0xC8, OLED_CMD); /* 正常显示 */ + OLED_WR_Byte(0xA1, OLED_CMD); + } + if (i == 1) { + OLED_WR_Byte(0xC0, OLED_CMD); /* 反转显示 */ + OLED_WR_Byte(0xA0, OLED_CMD); + } +} + +void OLED_Refresh(void) { + for (int i = 0; i < 8; i++) { + OLED_WR_Byte(0xb0 + i, OLED_CMD);//设置行起始地址 + OLED_WR_Byte(0x00, OLED_CMD); //设置低列起始地址 + OLED_WR_Byte(0x10, OLED_CMD); //设置高列起始地址 + OLED_WR_Byte(0x78, OLED_DATA); + OLED_WR_Byte(0x40, OLED_DATA); + for (int n = 0; n < 128; n++) { + OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA); + } + } +} + +void OLED_Clear(void) { + for (int i = 0; i < 8; i++) { + OLED_WR_Byte(0xb0 + i, OLED_CMD);//设置页地址(0~7) + OLED_WR_Byte(0x00, OLED_CMD); //设置显示位置—列低地址 + OLED_WR_Byte(0x10, OLED_CMD); //设置显示位置—列高地址 + for (int n = 0; n < 128; n++) + OLED_GRAM[n][i] = 0; + OLED_Refresh();//刷新GRAM内容 + } +} + +void OLED_DrawPoint(uint8_t x, uint8_t y, uint8_t t) { + uint8_t i, m, n; + i = y / 8; + m = y % 8; + n = 1 << m; + if (t) { + OLED_GRAM[x][i] |= n; + } else { + OLED_GRAM[x][i] = ~OLED_GRAM[x][i]; + OLED_GRAM[x][i] |= n; + OLED_GRAM[x][i] = ~OLED_GRAM[x][i]; + } +} + +void OLED_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t mode) { + int xerr = 0, yerr = 0, delta_x, delta_y, distance; + int incx, incy, uRow, uCol; + delta_x = x2 - x1;//计算坐标增量 + delta_y = y2 - y1; + uRow = x1;//画线起点坐标 + uCol = y1; + if (delta_x > 0) + incx = 1;//设置单步方向 + else if (delta_x == 0) + incx = 0;//垂直线 + else { + incx = -1; + delta_x = -delta_x; + } + if (delta_y > 0) + incy = 1; + else if (delta_y == 0) + incy = 0;//水平线 + else { + incy = -1; + delta_y = -delta_x; + } + if (delta_x > delta_y) + distance = delta_x;//选取基本增量坐标轴 + else + distance = delta_y; + for (uint16_t t = 0; t < distance + 1; t++) { + OLED_DrawPoint(uRow, uCol, mode);//画点 + xerr += delta_x; + yerr += delta_y; + if (xerr > distance) { + xerr -= distance; + uRow += incx; + } + if (yerr > distance) { + yerr -= distance; + uCol += incy; + } + } +} + +void OLED_DrawCircle(uint8_t x, uint8_t y, uint8_t r) { + int a, b, num; + a = 0; + b = r; + while (2 * b * b >= r * r) { + OLED_DrawPoint(x + a, y - b, 1); + OLED_DrawPoint(x - a, y - b, 1); + OLED_DrawPoint(x - a, y + b, 1); + OLED_DrawPoint(x + a, y + b, 1); + + OLED_DrawPoint(x + b, y + a, 1); + OLED_DrawPoint(x + b, y - a, 1); + OLED_DrawPoint(x - b, y - a, 1); + OLED_DrawPoint(x - b, y + a, 1); + + a++; + num = (a * a + b * b) - r * r;//计算画的点离圆心的距离 + if (num > 0) { + b--; + a--; + } + } +} + +void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t size1, uint8_t mode) { + uint8_t temp, size2, chr1; + uint8_t x0 = x, y0 = y; + if (size1 == 8) + size2 = 6; + else + size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2);//得到字体一个字符对应点阵集所占的字节数 + chr1 = chr - ' '; //计算偏移后的值 + for (uint8_t i = 0; i < size2; i++) { + if (size1 == 8) { + temp = asc2_0806[chr1][i]; + }//调用0806字体 + else if (size1 == 12) { + temp = asc2_1206[chr1][i]; + }//调用1206字体 + else if (size1 == 16) { + temp = asc2_1608[chr1][i]; + }//调用1608字体 + else if (size1 == 24) { + temp = asc2_2412[chr1][i]; + }//调用2412字体 + else + return; + for (uint8_t m = 0; m < 8; m++) { + if (temp & 0x01) + OLED_DrawPoint(x, y, mode); + else + OLED_DrawPoint(x, y, !mode); + temp >>= 1; + y++; + } + x++; + if ((size1 != 8) && ((x - x0) == size1 / 2)) { + x = x0; + y0 = y0 + 8; + } + y = y0; + } +} + +void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t size1, uint8_t mode) { + while ((*chr >= ' ') && (*chr <= '~'))//判断是不是非法字符! + { + OLED_ShowChar(x, y, *chr, size1, mode); + if (size1 == 8) + x += 6; + else + x += size1 / 2; + chr++; + } +} + +void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1, uint8_t mode) { + uint8_t temp, m = 0; + if (size1 == 8) + m = 2; + for (uint8_t t = 0; t < len; t++) { + temp = (num / OLED_Pow(10, len - t - 1)) % 10; + if (temp == 0) { + OLED_ShowChar(x + (size1 / 2 + m) * t, y, '0', size1, mode); + } else { + OLED_ShowChar(x + (size1 / 2 + m) * t, y, temp + '0', size1, mode); + } + } +} + +void OLED_Set_Pos(uint8_t x, uint8_t y) { + OLED_WR_Byte(0xb0 + y, OLED_CMD); + OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD); + OLED_WR_Byte((x & 0x0f), OLED_CMD); +} + +void OLED_Init(void) { + sunxi_i2c_init(&i2c_0); // Init I2C + + OLED_WR_Byte(0xAE, OLED_CMD);//--turn off oled panel + OLED_WR_Byte(0x00, OLED_CMD);//---set low column address + OLED_WR_Byte(0x10, OLED_CMD);//---set high column address + OLED_WR_Byte(0x40, OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F) + OLED_WR_Byte(0x81, OLED_CMD);//--set contrast control register + OLED_WR_Byte(0xCF, OLED_CMD);// Set SEG Output Current Brightness + OLED_WR_Byte(0xA1, OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 + OLED_WR_Byte(0xC8, OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 + OLED_WR_Byte(0xA6, OLED_CMD);//--set normal display + OLED_WR_Byte(0xA8, OLED_CMD);//--set multiplex ratio(1 to 64) + OLED_WR_Byte(0x3f, OLED_CMD);//--1/64 duty + OLED_WR_Byte(0xD3, OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) + OLED_WR_Byte(0x00, OLED_CMD);//-not offset + OLED_WR_Byte(0xd5, OLED_CMD);//--set display clock divide ratio/oscillator frequency + OLED_WR_Byte(0x80, OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec + OLED_WR_Byte(0xD9, OLED_CMD);//--set pre-charge period + OLED_WR_Byte(0xF1, OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock + OLED_WR_Byte(0xDA, OLED_CMD);//--set com pins hardware configuration + OLED_WR_Byte(0x12, OLED_CMD); + OLED_WR_Byte(0xDB, OLED_CMD);//--set vcomh + OLED_WR_Byte(0x40, OLED_CMD);//Set VCOM Deselect Level + OLED_WR_Byte(0x20, OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02) + OLED_WR_Byte(0x02, OLED_CMD);// + OLED_WR_Byte(0x8D, OLED_CMD);//--set Charge Pump enable/disable + OLED_WR_Byte(0x14, OLED_CMD);//--set(0x10) disable + OLED_WR_Byte(0xA4, OLED_CMD);// Disable Entire Display On (0xa4/0xa5) + OLED_WR_Byte(0xA6, OLED_CMD);// Disable Inverse Display On (0xa6/a7) + OLED_Clear(); + OLED_WR_Byte(0xAF, OLED_CMD); /*display ON*/ +} \ No newline at end of file diff --git a/board/dongshanpi-aict/i2c_oled/oled.h b/board/dongshanpi-aict/i2c_oled/oled.h new file mode 100644 index 00000000..5b7f8456 --- /dev/null +++ b/board/dongshanpi-aict/i2c_oled/oled.h @@ -0,0 +1,74 @@ +#ifndef __OLED_H +#define __OLED_H + +/* 发送一个字节 + * mode:数据/命令标志 0,表示命令;1,表示数据; + */ +void OLED_WR_Byte(uint8_t dat, uint8_t mode); + +/* Pow 函数 */ +uint32_t OLED_Pow(uint8_t m, uint8_t n); + +/* 反显函数 */ +void OLED_ColorTurn(uint8_t i); + +/* 屏幕旋转180度 */ +void OLED_DisplayTurn(uint8_t i); + +/* 更新显存到OLED */ +void OLED_Refresh(void); + +/* OLED 清屏 */ +void OLED_Clear(void); + +/* 画点 + * x: 0~127 + * y: 0~63 + * t: 1 填充 0,清空 + */ +void OLED_DrawPoint(uint8_t x, uint8_t y, uint8_t t); + +/* 画线 + * x1, y1: 起点坐标 + * x2, y2: 结束坐标 + */ +void OLED_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t mode); + +/* 画圆 + * x, y: 圆心坐标 + * r: 圆的半径 + */ + +void OLED_DrawCircle(uint8_t x, uint8_t y, uint8_t r); + +/* 在指定位置显示一个字符,包括部分字符 + * x: 0 ~ 127 + * y: 0 ~ 63 + * size1: 选择字体 6x8/6x12/8x16/12x24 + * mode: 0,反色显示; 1,正常显示 + */ +void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t size1, uint8_t mode); + +/* 显示字符串 + * x: 0 ~ 127 + * y: 0 ~ 63 + * *chr: 字符串起始地址 + * size1: 选择字体 6x8/6x12/8x16/12x24 + * mode: 0,反色显示; 1,正常显示 + */ +void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t size1, uint8_t mode); + +/* 显示数字 + * x: 0 ~ 127 + * y: 0 ~ 63 + * num: 要显示的数字 + * len: 数字的位数 + * size1: 选择字体 6x8/6x12/8x16/12x24 + * mode: 0,反色显示; 1,正常显示 + */ +void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1, uint8_t mode); + +/* 初始化 OLED */ +void OLED_Init(void); + +#endif \ No newline at end of file diff --git a/board/dongshanpi-aict/i2c_oled/oledfont.h b/board/dongshanpi-aict/i2c_oled/oledfont.h new file mode 100644 index 00000000..64547cc6 --- /dev/null +++ b/board/dongshanpi-aict/i2c_oled/oledfont.h @@ -0,0 +1,392 @@ +#ifndef __OLEDFONT_H +#define __OLEDFONT_H +const unsigned char asc2_0806[][6] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp + { 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! + { 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 }, // " + { 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # + { 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ + { 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 }, // % + { 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 }, // & + { 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' + { 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( + { 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) + { 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * + { 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + + { 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 }, // , + { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 }, // - + { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, // . + { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 }, // / + { 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 + { 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 + { 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 + { 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 + { 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 + { 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 + { 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 + { 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 + { 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 + { 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 + { 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // : + { 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; + { 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, // < + { 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 }, // = + { 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 }, // > + { 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? + { 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ + { 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A + { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B + { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C + { 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D + { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E + { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F + { 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G + { 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H + { 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I + { 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J + { 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K + { 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L + { 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M + { 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N + { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O + { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P + { 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q + { 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R + { 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }, // S + { 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T + { 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U + { 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V + { 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W + { 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }, // X + { 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y + { 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z + { 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ + { 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55 + { 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] + { 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ + { 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ + { 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' + { 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 }, // a + { 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b + { 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 }, // c + { 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F }, // d + { 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 }, // e + { 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f + { 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g + { 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h + { 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i + { 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j + { 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k + { 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l + { 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m + { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n + { 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 }, // o + { 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p + { 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC }, // q + { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r + { 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 }, // s + { 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t + { 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u + { 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v + { 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w + { 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 }, // x + { 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y + { 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z + { 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 }, // horiz lines +}; +//12*12 ASCII字符集点阵 +const unsigned char asc2_1206[95][12] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*" ",0*/ + { 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }, /*"!",1*/ + { 0x00, 0x0C, 0x02, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*""",2*/ + { 0x90, 0xD0, 0xBC, 0xD0, 0xBC, 0x90, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00 }, /*"#",3*/ + { 0x18, 0x24, 0xFE, 0x44, 0x8C, 0x00, 0x03, 0x02, 0x07, 0x02, 0x01, 0x00 }, /*"$",4*/ + { 0x18, 0x24, 0xD8, 0xB0, 0x4C, 0x80, 0x00, 0x03, 0x00, 0x01, 0x02, 0x01 }, /*"%",5*/ + { 0xC0, 0x38, 0xE4, 0x38, 0xE0, 0x00, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02 }, /*"&",6*/ + { 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"'",7*/ + { 0x00, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04 }, /*"(",8*/ + { 0x00, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00 }, /*")",9*/ + { 0x90, 0x60, 0xF8, 0x60, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }, /*"*",10*/ + { 0x20, 0x20, 0xFC, 0x20, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }, /*"+",11*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00 }, /*",",12*/ + { 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"-",13*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 }, /*".",14*/ + { 0x00, 0x80, 0x60, 0x1C, 0x02, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00 }, /*"/",15*/ + { 0xF8, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"0",16*/ + { 0x00, 0x08, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00 }, /*"1",17*/ + { 0x18, 0x84, 0x44, 0x24, 0x18, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x00 }, /*"2",18*/ + { 0x08, 0x04, 0x24, 0x24, 0xD8, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"3",19*/ + { 0x40, 0xB0, 0x88, 0xFC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00 }, /*"4",20*/ + { 0x3C, 0x24, 0x24, 0x24, 0xC4, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"5",21*/ + { 0xF8, 0x24, 0x24, 0x2C, 0xC0, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"6",22*/ + { 0x0C, 0x04, 0xE4, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 }, /*"7",23*/ + { 0xD8, 0x24, 0x24, 0x24, 0xD8, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"8",24*/ + { 0x38, 0x44, 0x44, 0x44, 0xF8, 0x00, 0x00, 0x03, 0x02, 0x02, 0x01, 0x00 }, /*"9",25*/ + { 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }, /*":",26*/ + { 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 }, /*";",27*/ + { 0x00, 0x20, 0x50, 0x88, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02 }, /*"<",28*/ + { 0x90, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"=",29*/ + { 0x00, 0x02, 0x04, 0x88, 0x50, 0x20, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00 }, /*">",30*/ + { 0x18, 0x04, 0xC4, 0x24, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }, /*"?",31*/ + { 0xF8, 0x04, 0xE4, 0x94, 0xF8, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00 }, /*"@",32*/ + { 0x00, 0xE0, 0x9C, 0xF0, 0x80, 0x00, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02 }, /*"A",33*/ + { 0x04, 0xFC, 0x24, 0x24, 0xD8, 0x00, 0x02, 0x03, 0x02, 0x02, 0x01, 0x00 }, /*"B",34*/ + { 0xF8, 0x04, 0x04, 0x04, 0x0C, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"C",35*/ + { 0x04, 0xFC, 0x04, 0x04, 0xF8, 0x00, 0x02, 0x03, 0x02, 0x02, 0x01, 0x00 }, /*"D",36*/ + { 0x04, 0xFC, 0x24, 0x74, 0x0C, 0x00, 0x02, 0x03, 0x02, 0x02, 0x03, 0x00 }, /*"E",37*/ + { 0x04, 0xFC, 0x24, 0x74, 0x0C, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00 }, /*"F",38*/ + { 0xF0, 0x08, 0x04, 0x44, 0xCC, 0x40, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00 }, /*"G",39*/ + { 0x04, 0xFC, 0x20, 0x20, 0xFC, 0x04, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02 }, /*"H",40*/ + { 0x04, 0x04, 0xFC, 0x04, 0x04, 0x00, 0x02, 0x02, 0x03, 0x02, 0x02, 0x00 }, /*"I",41*/ + { 0x00, 0x04, 0x04, 0xFC, 0x04, 0x04, 0x06, 0x04, 0x04, 0x03, 0x00, 0x00 }, /*"J",42*/ + { 0x04, 0xFC, 0x24, 0xD0, 0x0C, 0x04, 0x02, 0x03, 0x02, 0x00, 0x03, 0x02 }, /*"K",43*/ + { 0x04, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x02, 0x02, 0x03 }, /*"L",44*/ + { 0xFC, 0x3C, 0xC0, 0x3C, 0xFC, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00 }, /*"M",45*/ + { 0x04, 0xFC, 0x30, 0xC4, 0xFC, 0x04, 0x02, 0x03, 0x02, 0x00, 0x03, 0x00 }, /*"N",46*/ + { 0xF8, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"O",47*/ + { 0x04, 0xFC, 0x24, 0x24, 0x18, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00 }, /*"P",48*/ + { 0xF8, 0x84, 0x84, 0x04, 0xF8, 0x00, 0x01, 0x02, 0x02, 0x07, 0x05, 0x00 }, /*"Q",49*/ + { 0x04, 0xFC, 0x24, 0x64, 0x98, 0x00, 0x02, 0x03, 0x02, 0x00, 0x03, 0x02 }, /*"R",50*/ + { 0x18, 0x24, 0x24, 0x44, 0x8C, 0x00, 0x03, 0x02, 0x02, 0x02, 0x01, 0x00 }, /*"S",51*/ + { 0x0C, 0x04, 0xFC, 0x04, 0x0C, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00 }, /*"T",52*/ + { 0x04, 0xFC, 0x00, 0x00, 0xFC, 0x04, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00 }, /*"U",53*/ + { 0x04, 0x7C, 0x80, 0xE0, 0x1C, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 }, /*"V",54*/ + { 0x1C, 0xE0, 0x3C, 0xE0, 0x1C, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00 }, /*"W",55*/ + { 0x04, 0x9C, 0x60, 0x9C, 0x04, 0x00, 0x02, 0x03, 0x00, 0x03, 0x02, 0x00 }, /*"X",56*/ + { 0x04, 0x1C, 0xE0, 0x1C, 0x04, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00 }, /*"Y",57*/ + { 0x0C, 0x84, 0x64, 0x1C, 0x04, 0x00, 0x02, 0x03, 0x02, 0x02, 0x03, 0x00 }, /*"Z",58*/ + { 0x00, 0x00, 0xFE, 0x02, 0x02, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00 }, /*"[",59*/ + { 0x00, 0x0E, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00 }, /*"\",60*/ + { 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x00, 0x00 }, /*"]",61*/ + { 0x00, 0x04, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"^",62*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /*"_",63*/ + { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"`",64*/ + { 0x00, 0x40, 0xA0, 0xA0, 0xC0, 0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x02 }, /*"a",65*/ + { 0x04, 0xFC, 0x20, 0x20, 0xC0, 0x00, 0x00, 0x03, 0x02, 0x02, 0x01, 0x00 }, /*"b",66*/ + { 0x00, 0xC0, 0x20, 0x20, 0x60, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x00 }, /*"c",67*/ + { 0x00, 0xC0, 0x20, 0x24, 0xFC, 0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x02 }, /*"d",68*/ + { 0x00, 0xC0, 0xA0, 0xA0, 0xC0, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x00 }, /*"e",69*/ + { 0x00, 0x20, 0xF8, 0x24, 0x24, 0x04, 0x00, 0x02, 0x03, 0x02, 0x02, 0x00 }, /*"f",70*/ + { 0x00, 0x40, 0xA0, 0xA0, 0x60, 0x20, 0x00, 0x07, 0x0A, 0x0A, 0x0A, 0x04 }, /*"g",71*/ + { 0x04, 0xFC, 0x20, 0x20, 0xC0, 0x00, 0x02, 0x03, 0x02, 0x00, 0x03, 0x02 }, /*"h",72*/ + { 0x00, 0x20, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00 }, /*"i",73*/ + { 0x00, 0x00, 0x20, 0xE4, 0x00, 0x00, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00 }, /*"j",74*/ + { 0x04, 0xFC, 0x80, 0xE0, 0x20, 0x20, 0x02, 0x03, 0x02, 0x00, 0x03, 0x02 }, /*"k",75*/ + { 0x04, 0x04, 0xFC, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x02, 0x02, 0x00 }, /*"l",76*/ + { 0xE0, 0x20, 0xE0, 0x20, 0xC0, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00 }, /*"m",77*/ + { 0x20, 0xE0, 0x20, 0x20, 0xC0, 0x00, 0x02, 0x03, 0x02, 0x00, 0x03, 0x02 }, /*"n",78*/ + { 0x00, 0xC0, 0x20, 0x20, 0xC0, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00 }, /*"o",79*/ + { 0x20, 0xE0, 0x20, 0x20, 0xC0, 0x00, 0x08, 0x0F, 0x0A, 0x02, 0x01, 0x00 }, /*"p",80*/ + { 0x00, 0xC0, 0x20, 0x20, 0xE0, 0x00, 0x00, 0x01, 0x02, 0x0A, 0x0F, 0x08 }, /*"q",81*/ + { 0x20, 0xE0, 0x40, 0x20, 0x20, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00 }, /*"r",82*/ + { 0x00, 0x60, 0xA0, 0xA0, 0x20, 0x00, 0x00, 0x02, 0x02, 0x02, 0x03, 0x00 }, /*"s",83*/ + { 0x00, 0x20, 0xF8, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00 }, /*"t",84*/ + { 0x20, 0xE0, 0x00, 0x20, 0xE0, 0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x02 }, /*"u",85*/ + { 0x20, 0xE0, 0x20, 0x80, 0x60, 0x20, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00 }, /*"v",86*/ + { 0x60, 0x80, 0xE0, 0x80, 0x60, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00 }, /*"w",87*/ + { 0x20, 0x60, 0x80, 0x60, 0x20, 0x00, 0x02, 0x03, 0x00, 0x03, 0x02, 0x00 }, /*"x",88*/ + { 0x20, 0xE0, 0x20, 0x80, 0x60, 0x20, 0x08, 0x08, 0x07, 0x01, 0x00, 0x00 }, /*"y",89*/ + { 0x00, 0x20, 0xA0, 0x60, 0x20, 0x00, 0x00, 0x02, 0x03, 0x02, 0x02, 0x00 }, /*"z",90*/ + { 0x00, 0x00, 0x20, 0xDE, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x00 }, /*"{",91*/ + { 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00 }, /*"|",92*/ + { 0x00, 0x02, 0xDE, 0x20, 0x00, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x00 }, /*"}",93*/ + { 0x02, 0x01, 0x02, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"~",94*/ +}; +//16*16 ASCII字符集点阵 +const unsigned char asc2_1608[][16] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*" ",0*/ + { 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00 }, /*"!",1*/ + { 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*""",2*/ + { 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00 }, /*"#",3*/ + { 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00 }, /*"$",4*/ + { 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00 }, /*"%",5*/ + { 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10 }, /*"&",6*/ + { 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"'",7*/ + { 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00 }, /*"(",8*/ + { 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00 }, /*")",9*/ + { 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00 }, /*"*",10*/ + { 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00 }, /*"+",11*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*",",12*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, /*"-",13*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*".",14*/ + { 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00 }, /*"/",15*/ + { 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00 }, /*"0",16*/ + { 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00 }, /*"1",17*/ + { 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00 }, /*"2",18*/ + { 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00 }, /*"3",19*/ + { 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00 }, /*"4",20*/ + { 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00 }, /*"5",21*/ + { 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00 }, /*"6",22*/ + { 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00 }, /*"7",23*/ + { 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00 }, /*"8",24*/ + { 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00 }, /*"9",25*/ + { 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00 }, /*":",26*/ + { 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00 }, /*";",27*/ + { 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00 }, /*"<",28*/ + { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00 }, /*"=",29*/ + { 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00 }, /*">",30*/ + { 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00 }, /*"?",31*/ + { 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00 }, /*"@",32*/ + { 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20 }, /*"A",33*/ + { 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00 }, /*"B",34*/ + { 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00 }, /*"C",35*/ + { 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00 }, /*"D",36*/ + { 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00 }, /*"E",37*/ + { 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00 }, /*"F",38*/ + { 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00 }, /*"G",39*/ + { 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20 }, /*"H",40*/ + { 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00 }, /*"I",41*/ + { 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00 }, /*"J",42*/ + { 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00 }, /*"K",43*/ + { 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00 }, /*"L",44*/ + { 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00 }, /*"M",45*/ + { 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00 }, /*"N",46*/ + { 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00 }, /*"O",47*/ + { 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00 }, /*"P",48*/ + { 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00 }, /*"Q",49*/ + { 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20 }, /*"R",50*/ + { 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00 }, /*"S",51*/ + { 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00 }, /*"T",52*/ + { 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00 }, /*"U",53*/ + { 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00 }, /*"V",54*/ + { 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00 }, /*"W",55*/ + { 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20 }, /*"X",56*/ + { 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00 }, /*"Y",57*/ + { 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00 }, /*"Z",58*/ + { 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00 }, /*"[",59*/ + { 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00 }, /*"\",60*/ + { 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00 }, /*"]",61*/ + { 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"^",62*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, /*"_",63*/ + { 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"`",64*/ + { 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20 }, /*"a",65*/ + { 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00 }, /*"b",66*/ + { 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00 }, /*"c",67*/ + { 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20 }, /*"d",68*/ + { 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00 }, /*"e",69*/ + { 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00 }, /*"f",70*/ + { 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00 }, /*"g",71*/ + { 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20 }, /*"h",72*/ + { 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00 }, /*"i",73*/ + { 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00 }, /*"j",74*/ + { 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00 }, /*"k",75*/ + { 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00 }, /*"l",76*/ + { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F }, /*"m",77*/ + { 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20 }, /*"n",78*/ + { 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00 }, /*"o",79*/ + { 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00 }, /*"p",80*/ + { 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80 }, /*"q",81*/ + { 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00 }, /*"r",82*/ + { 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00 }, /*"s",83*/ + { 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00 }, /*"t",84*/ + { 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20 }, /*"u",85*/ + { 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00 }, /*"v",86*/ + { 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00 }, /*"w",87*/ + { 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00 }, /*"x",88*/ + { 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00 }, /*"y",89*/ + { 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00 }, /*"z",90*/ + { 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40 }, /*"{",91*/ + { 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 }, /*"|",92*/ + { 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00 }, /*"}",93*/ + { 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"~",94*/ +}; +//24*24 ASICII字符集点阵 +const unsigned char asc2_2412[][36] = { + { 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, 0x00, 0x00, 0x00, 0x00 }, /*" ",0*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00 }, /*"!",1*/ + { 0x00, 0x00, 0x80, 0x60, 0x30, 0x1C, 0x8C, 0x60, 0x30, 0x1C, 0x0C, 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 }, /*""",2*/ + { 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x86, 0xE6, 0x9F, 0x86, 0x86, 0x86, 0x86, 0xE6, 0x9F, 0x86, 0x00, 0x00, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x00 }, /*"#",3*/ + { 0x00, 0x00, 0x80, 0xC0, 0x60, 0x20, 0xF8, 0x20, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0C, 0x18, 0xFF, 0x70, 0xE1, 0x81, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x10, 0x10, 0x7F, 0x10, 0x0F, 0x07, 0x00, 0x00 }, /*"$",4*/ + { 0x80, 0x60, 0x20, 0x60, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x20, 0x00, 0x00, 0x0F, 0x30, 0x20, 0x30, 0x9F, 0x70, 0xDC, 0x37, 0x10, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x03, 0x00, 0x07, 0x18, 0x10, 0x18, 0x07, 0x00 }, /*"%",5*/ + { 0x00, 0x00, 0xC0, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0x1F, 0x38, 0xE8, 0x87, 0x03, 0xC4, 0x3C, 0x04, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x10, 0x0B, 0x07, 0x0D, 0x10, 0x10, 0x08, 0x00 }, /*"&",6*/ + { 0x00, 0x80, 0x8C, 0x4C, 0x38, 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 }, /*"'",7*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0x30, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x18, 0x20, 0x40, 0x00 }, /*"(",8*/ + { 0x00, 0x04, 0x08, 0x30, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*")",9*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x66, 0x66, 0x3C, 0x18, 0xFF, 0x18, 0x3C, 0x66, 0x66, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"*",10*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"+",11*/ + { 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, 0x80, 0x8C, 0x4C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*",",12*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"-",13*/ + { 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, 0x1C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*".",14*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x38, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"/",15*/ + { 0x00, 0x00, 0x80, 0xC0, 0x60, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0x07, 0x0E, 0x18, 0x10, 0x10, 0x18, 0x0E, 0x07, 0x01, 0x00 }, /*"0",16*/ + { 0x00, 0x00, 0x80, 0x80, 0x80, 0xC0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x00, 0x00 }, /*"1",17*/ + { 0x00, 0x80, 0x40, 0x20, 0x20, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x80, 0x40, 0x20, 0x38, 0x1F, 0x07, 0x00, 0x00, 0x00, 0x1C, 0x1A, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00 }, /*"2",18*/ + { 0x00, 0x80, 0xC0, 0x20, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x10, 0x10, 0x18, 0x2F, 0xE7, 0x80, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07, 0x00, 0x00 }, /*"3",19*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xB0, 0x88, 0x86, 0x81, 0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x00 }, /*"4",20*/ + { 0x00, 0x00, 0xE0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x10, 0x08, 0x08, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x07, 0x0B, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x0F, 0x03, 0x00, 0x00 }, /*"5",21*/ + { 0x00, 0x00, 0x80, 0xC0, 0x40, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x21, 0x10, 0x08, 0x08, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x00, 0x01, 0x07, 0x0C, 0x18, 0x10, 0x10, 0x10, 0x08, 0x0F, 0x03, 0x00 }, /*"6",22*/ + { 0x00, 0x00, 0xC0, 0xE0, 0x60, 0x60, 0x60, 0x60, 0x60, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xE0, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"7",23*/ + { 0x00, 0x80, 0xC0, 0x60, 0x20, 0x20, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x87, 0xEF, 0x2C, 0x18, 0x18, 0x30, 0x30, 0x68, 0xCF, 0x83, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07, 0x00 }, /*"8",24*/ + { 0x00, 0x00, 0xC0, 0xC0, 0x20, 0x20, 0x20, 0x20, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x60, 0x40, 0x40, 0x40, 0x20, 0x10, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x10, 0x10, 0x10, 0x08, 0x0F, 0x03, 0x00, 0x00 }, /*"9",25*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00 }, /*":",26*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*";",27*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00 }, /*"<",28*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"=",29*/ + { 0x00, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*">",30*/ + { 0x00, 0xC0, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x30, 0xE0, 0xC0, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0xF0, 0x10, 0x08, 0x0C, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"?",31*/ + { 0x00, 0x00, 0x00, 0xC0, 0x40, 0x60, 0x20, 0x20, 0x20, 0x40, 0xC0, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xF0, 0x0E, 0x03, 0xC1, 0xFE, 0x03, 0x80, 0x7F, 0x00, 0x01, 0x07, 0x0E, 0x08, 0x11, 0x11, 0x10, 0x11, 0x09, 0x04, 0x02 }, /*"@",32*/ + { 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x43, 0x40, 0x47, 0x7F, 0xF8, 0x80, 0x00, 0x00, 0x10, 0x18, 0x1F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x1F, 0x1C, 0x10 }, /*"A",33*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x18, 0x2F, 0xE7, 0x80, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07, 0x00 }, /*"B",34*/ + { 0x00, 0x00, 0x80, 0xC0, 0x40, 0x20, 0x20, 0x20, 0x20, 0x60, 0xE0, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x07, 0x0E, 0x18, 0x10, 0x10, 0x10, 0x08, 0x04, 0x03, 0x00 }, /*"C",35*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08, 0x0E, 0x07, 0x01, 0x00 }, /*"D",36*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x06, 0x00 }, /*"E",37*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00, 0x01, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"F",38*/ + { 0x00, 0x00, 0x80, 0xC0, 0x60, 0x20, 0x20, 0x20, 0x40, 0xE0, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x40, 0x40, 0xC0, 0xC1, 0x40, 0x40, 0x00, 0x01, 0x07, 0x0E, 0x18, 0x10, 0x10, 0x10, 0x0F, 0x0F, 0x00, 0x00 }, /*"G",39*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0xE0, 0xE0, 0x20, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10 }, /*"H",40*/ + { 0x00, 0x00, 0x20, 0x20, 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x00, 0x00 }, /*"I",41*/ + { 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE0, 0x80, 0x80, 0x80, 0xC0, 0x7F, 0x3F, 0x00, 0x00, 0x00 }, /*"J",42*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x20, 0xA0, 0x60, 0x20, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x18, 0x7C, 0xE3, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01, 0x13, 0x1F, 0x1C, 0x18, 0x10 }, /*"K",43*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x06, 0x00 }, /*"L",44*/ + { 0x20, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0x20, 0x00, 0xFF, 0x01, 0x3F, 0xFE, 0xC0, 0xE0, 0x1E, 0x01, 0xFF, 0xFF, 0x00, 0x10, 0x1F, 0x10, 0x00, 0x03, 0x1F, 0x03, 0x00, 0x10, 0x1F, 0x1F, 0x10 }, /*"M",45*/ + { 0x20, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xE0, 0x20, 0x00, 0xFF, 0x00, 0x03, 0x07, 0x1C, 0x78, 0xE0, 0x80, 0x00, 0xFF, 0x00, 0x10, 0x1F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x00 }, /*"N",46*/ + { 0x00, 0x00, 0x80, 0xC0, 0x60, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0x07, 0x0E, 0x18, 0x10, 0x10, 0x18, 0x0C, 0x07, 0x01, 0x00 }, /*"O",47*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x1F, 0x0F, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"P",48*/ + { 0x00, 0x00, 0x80, 0xC0, 0x60, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0x07, 0x0E, 0x11, 0x11, 0x13, 0x3C, 0x7C, 0x67, 0x21, 0x00 }, /*"Q",49*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0xC0, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x30, 0xF0, 0xD0, 0x08, 0x0F, 0x07, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1C, 0x10, 0x10 }, /*"R",50*/ + { 0x00, 0x80, 0xC0, 0x60, 0x20, 0x20, 0x20, 0x20, 0x40, 0x40, 0xE0, 0x00, 0x00, 0x07, 0x0F, 0x0C, 0x18, 0x18, 0x30, 0x30, 0x60, 0xE0, 0x81, 0x00, 0x00, 0x1F, 0x0C, 0x08, 0x10, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07, 0x00 }, /*"S",51*/ + { 0x80, 0x60, 0x20, 0x20, 0x20, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00, 0x00 }, /*"T",52*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xE0, 0x20, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x07, 0x00 }, /*"U",53*/ + { 0x20, 0x60, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x20, 0xE0, 0x60, 0x20, 0x00, 0x00, 0x07, 0x7F, 0xF8, 0x80, 0x00, 0x80, 0x7C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1F, 0x1C, 0x07, 0x00, 0x00, 0x00, 0x00 }, /*"V",54*/ + { 0x20, 0xE0, 0xE0, 0x20, 0x00, 0xE0, 0xE0, 0x20, 0x00, 0x20, 0xE0, 0x20, 0x00, 0x07, 0xFF, 0xF8, 0xE0, 0x1F, 0xFF, 0xFC, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1F, 0x03, 0x00, 0x01, 0x1F, 0x03, 0x00, 0x00, 0x00 }, /*"W",55*/ + { 0x00, 0x20, 0x60, 0xE0, 0xA0, 0x00, 0x00, 0x20, 0xE0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8F, 0x7C, 0xF8, 0xC6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x1E, 0x13, 0x00, 0x01, 0x17, 0x1F, 0x18, 0x10, 0x00 }, /*"X",56*/ + { 0x20, 0x60, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x20, 0xE0, 0x60, 0x20, 0x00, 0x00, 0x01, 0x07, 0x3E, 0xF8, 0xE0, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x00, 0x00, 0x00 }, /*"Y",57*/ + { 0x00, 0x80, 0x60, 0x20, 0x20, 0x20, 0x20, 0xA0, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0x3E, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1C, 0x1F, 0x17, 0x10, 0x10, 0x10, 0x10, 0x18, 0x06, 0x00 }, /*"Z",58*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00 }, /*"[",59*/ + { 0x00, 0x00, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1C, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x70, 0x80, 0x00 }, /*"\",60*/ + { 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, 0x00 }, /*"]",61*/ + { 0x00, 0x00, 0x00, 0x10, 0x08, 0x0C, 0x04, 0x0C, 0x08, 0x10, 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 }, /*"^",62*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, /*"_",63*/ + { 0x00, 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 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 }, /*"`",64*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xD8, 0x44, 0x64, 0x24, 0x24, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x18, 0x10, 0x10, 0x10, 0x08, 0x1F, 0x1F, 0x10, 0x18 }, /*"a",65*/ + { 0x00, 0x20, 0xE0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x08, 0x04, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x18, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x03, 0x00 }, /*"b",66*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0x18, 0x04, 0x04, 0x04, 0x3C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x08, 0x06, 0x00, 0x00 }, /*"c",67*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xE0, 0xF0, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0x1C, 0x04, 0x04, 0x04, 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x18, 0x10, 0x10, 0x10, 0x08, 0x1F, 0x0F, 0x08, 0x00 }, /*"d",68*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0x48, 0x44, 0x44, 0x44, 0x4C, 0x78, 0x70, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x0C, 0x18, 0x10, 0x10, 0x10, 0x08, 0x04, 0x00 }, /*"e",69*/ + { 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x00, 0x04, 0x04, 0x04, 0xFF, 0xFF, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00 }, /*"f",70*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xF8, 0x8C, 0x04, 0x04, 0x8C, 0xF8, 0x74, 0x04, 0x0C, 0x00, 0x70, 0x76, 0xCF, 0x8D, 0x8D, 0x8D, 0x89, 0xC8, 0x78, 0x70, 0x00 }, /*"g",71*/ + { 0x00, 0x20, 0xE0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x08, 0x04, 0x04, 0x04, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00 }, /*"h",72*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x00, 0x00 }, /*"i",73*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x80, 0x80, 0xC0, 0x7F, 0x3F, 0x00, 0x00, 0x00 }, /*"j",74*/ + { 0x00, 0x20, 0xE0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0xC0, 0xF4, 0x1C, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x11, 0x00, 0x03, 0x1F, 0x1C, 0x10, 0x10, 0x00 }, /*"k",75*/ + { 0x00, 0x00, 0x20, 0x20, 0x20, 0xE0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x00, 0x00 }, /*"l",76*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x08, 0x04, 0xFC, 0xFC, 0x08, 0x04, 0xFC, 0xFC, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x1F, 0x1F, 0x10, 0x00, 0x1F, 0x1F, 0x10 }, /*"m",77*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x08, 0x08, 0x04, 0x04, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00 }, /*"n",78*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF0, 0x18, 0x0C, 0x04, 0x04, 0x0C, 0x18, 0xF0, 0xE0, 0x00, 0x00, 0x03, 0x0F, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x0F, 0x03, 0x00 }, /*"o",79*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x08, 0x04, 0x04, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x88, 0x90, 0x10, 0x10, 0x1C, 0x0F, 0x03, 0x00 }, /*"p",80*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0x1C, 0x04, 0x04, 0x04, 0x08, 0xF8, 0xFC, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x18, 0x10, 0x10, 0x90, 0x88, 0xFF, 0xFF, 0x80, 0x00 }, /*"q",81*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0xFC, 0xFC, 0x10, 0x08, 0x04, 0x04, 0x0C, 0x0C, 0x00, 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00 }, /*"r",82*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xCC, 0xC4, 0x84, 0x84, 0x84, 0x0C, 0x1C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x10, 0x10, 0x11, 0x19, 0x0F, 0x06, 0x00 }, /*"s",83*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0xFF, 0xFF, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00 }, /*"t",84*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFC, 0xFE, 0x00, 0x00, 0x00, 0x04, 0xFC, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x18, 0x10, 0x10, 0x08, 0x1F, 0x0F, 0x08, 0x00 }, /*"u",85*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0C, 0x3C, 0xFC, 0xC4, 0x00, 0x00, 0xC4, 0x3C, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x1E, 0x0E, 0x01, 0x00, 0x00, 0x00 }, /*"v",86*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3C, 0xFC, 0xC4, 0x00, 0xE4, 0x7C, 0xFC, 0x84, 0x80, 0x7C, 0x04, 0x00, 0x00, 0x07, 0x1F, 0x07, 0x00, 0x00, 0x07, 0x1F, 0x07, 0x00, 0x00 }, /*"w",87*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x1C, 0x7C, 0xE4, 0xC0, 0x34, 0x1C, 0x04, 0x04, 0x00, 0x00, 0x10, 0x10, 0x1C, 0x16, 0x01, 0x13, 0x1F, 0x1C, 0x18, 0x10, 0x00 }, /*"x",88*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0C, 0x3C, 0xFC, 0xC4, 0x00, 0xC4, 0x3C, 0x04, 0x04, 0x00, 0x00, 0x00, 0xC0, 0x80, 0xC1, 0x37, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00 }, /*"y",89*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x04, 0x04, 0xC4, 0xF4, 0x7C, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1C, 0x1F, 0x17, 0x11, 0x10, 0x10, 0x18, 0x0E, 0x00 }, /*"z",90*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x60, 0x40, 0x00, 0x00 }, /*"{",91*/ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"|",92*/ + { 0x00, 0x00, 0x04, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"}",93*/ + { 0x00, 0x18, 0x06, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"~",94*/ +}; + +#endif diff --git a/board/dongshanpi-aict/i2c_test/CMakeLists.txt b/board/dongshanpi-aict/i2c_test/CMakeLists.txt new file mode 100644 index 00000000..03fa1627 --- /dev/null +++ b/board/dongshanpi-aict/i2c_test/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(i2c_test + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/i2c_test/main.c b/board/dongshanpi-aict/i2c_test/main.c new file mode 100644 index 00000000..01a8f131 --- /dev/null +++ b/board/dongshanpi-aict/i2c_test/main.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include + +#include "sys-i2c.h" +#include "sys-uart.h" + +extern sunxi_serial_t uart_dbg; + +sunxi_i2c_t i2c_0 = { + .base = 0x02502000, + .id = 0, + .speed = 4000000, + .gpio_scl = {GPIO_PIN(GPIO_PORTE, 4), GPIO_PERIPH_MUX8}, + .gpio_sda = {GPIO_PIN(GPIO_PORTE, 5), GPIO_PERIPH_MUX8}, +}; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_clk_init(); + + sunxi_i2c_init(&i2c_0); + + printk(LOG_LEVEL_INFO, "Hello World\n"); + + int ret = 0; + + while (1) { + printk(LOG_LEVEL_INFO, "sunxi_i2c_write\n"); + ret = sunxi_i2c_write(&i2c_0, 0x32, 0x11, 0x11); + mdelay(100); + printk(LOG_LEVEL_INFO, "sunxi_i2c_write done, ret = %08x\n", ret); + } + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/init_dram/CMakeLists.txt b/board/dongshanpi-aict/init_dram/CMakeLists.txt new file mode 100644 index 00000000..c02c6d1e --- /dev/null +++ b/board/dongshanpi-aict/init_dram/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(initdram + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/init_dram/main.c b/board/dongshanpi-aict/init_dram/main.c new file mode 100644 index 00000000..7f44711d --- /dev/null +++ b/board/dongshanpi-aict/init_dram/main.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include +#include "sys-dram.h" + +#include + +extern sunxi_serial_t uart_dbg; + +extern dram_para_t dram_para; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + show_banner(); + + sunxi_clk_init(); + + sunxi_dram_init(&dram_para); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/load_e907/CMakeLists.txt b/board/dongshanpi-aict/load_e907/CMakeLists.txt new file mode 100644 index 00000000..457b306a --- /dev/null +++ b/board/dongshanpi-aict/load_e907/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(loade907 + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/load_e907/main.c b/board/dongshanpi-aict/load_e907/main.c new file mode 100644 index 00000000..0aae797b --- /dev/null +++ b/board/dongshanpi-aict/load_e907/main.c @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "sys-dram.h" +#include "sys-sdcard.h" +#include "sys-sid.h" +#include "sys-spi.h" + +#include "elf_loader.h" +#include "ff.h" + +#define CONFIG_RISCV_ELF_FILENAME "e907.elf" +#define CONFIG_RISCV_ELF_LOADADDR (0x41008000) + +#define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) + +extern sunxi_serial_t uart_dbg; + +extern sdhci_t sdhci0; + +extern dram_para_t dram_para; + +#define FILENAME_MAX_LEN 64 +typedef struct { + unsigned int offset; + unsigned int length; + unsigned char *dest; + + char filename[FILENAME_MAX_LEN]; +} image_info_t; + +image_info_t image; + +#define CHUNK_SIZE 0x20000 + +static int fatfs_loadimage(char *filename, BYTE *dest) { + FIL file; + UINT byte_to_read = CHUNK_SIZE; + UINT byte_read; + UINT total_read = 0; + FRESULT fret; + int ret; + uint32_t start, time; + + fret = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, + "FATFS: open, filename: [%s]: error %d\n", filename, + fret); + ret = -1; + goto open_fail; + } + + start = time_ms(); + + do { + byte_read = 0; + fret = f_read(&file, (void *) (dest), byte_to_read, &byte_read); + dest += byte_to_read; + total_read += byte_read; + } while (byte_read >= byte_to_read && fret == FR_OK); + + time = time_ms() - start + 1; + + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: read: error %d\n", fret); + ret = -1; + goto read_fail; + } + ret = 0; + +read_fail: + fret = f_close(&file); + + printk(LOG_LEVEL_DEBUG, "FATFS: read in %ums at %.2fMB/S\n", time, + (f32) (total_read / time) / 1024.0f); + +open_fail: + return ret; +} + +static int load_sdcard(image_info_t *image) { + FATFS fs; + FRESULT fret; + int ret; + uint32_t start; + + uint32_t test_time; + start = time_ms(); + sdmmc_blk_read(&card0, (uint8_t *) (SDRAM_BASE), 0, + CONFIG_SDMMC_SPEED_TEST_SIZE); + test_time = time_ms() - start; + printk(LOG_LEVEL_DEBUG, "SDMMC: speedtest %uKB in %ums at %uKB/S\n", + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / 1024, test_time, + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / test_time); + + start = time_ms(); + + fret = f_mount(&fs, "", 1); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: mount error: %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: mount OK\n"); + } + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->filename, + (unsigned int) image->dest); + ret = fatfs_loadimage(image->filename, image->dest); + if (ret) + return ret; + + /* umount fs */ + fret = f_mount(0, "", 0); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: unmount error %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: unmount OK\n"); + } + printk(LOG_LEVEL_DEBUG, "FATFS: done in %ums\n", time_ms() - start); + + return 0; +} + +int main(void) { + sunxi_serial_init(&uart_dbg); + + show_banner(); + + sunxi_clk_init(); + + sunxi_dram_init(&dram_para); + + sunxi_clk_dump(); + + memset(&image, 0, sizeof(image_info_t)); + + image.dest = (uint8_t *) CONFIG_RISCV_ELF_LOADADDR; + + strcpy(image.filename, CONFIG_RISCV_ELF_FILENAME); + + if (sunxi_sdhci_init(&sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: %s controller init failed\n", sdhci0.name); + return 0; + } else { + printk(LOG_LEVEL_INFO, "SMHC: %s controller v%x initialized\n", sdhci0.name, sdhci0.reg->vers); + } + + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: init failed\n"); + return 0; + } + + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: loading failed\n"); + return 0; + } + + sunxi_e907_clock_reset(); + + uint32_t elf_run_addr = elf32_get_entry_addr((phys_addr_t) image.dest); + printk(LOG_LEVEL_INFO, "RISC-V ELF run addr: 0x%08x\n", elf_run_addr); + + if (load_elf32_image((phys_addr_t) image.dest)) { + printk(LOG_LEVEL_ERROR, "RISC-V ELF load FAIL\n"); + } + + sunxi_e907_clock_init(elf_run_addr); + + dump_e907_clock(); + + printk(LOG_LEVEL_INFO, "RISC-V E907 Core now Running... \n"); + + abort(); + + jmp_to_fel(); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/read_chip_efuse/CMakeLists.txt b/board/dongshanpi-aict/read_chip_efuse/CMakeLists.txt new file mode 100644 index 00000000..b515d278 --- /dev/null +++ b/board/dongshanpi-aict/read_chip_efuse/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(read_chipsid + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/read_chip_efuse/main.c b/board/dongshanpi-aict/read_chip_efuse/main.c new file mode 100644 index 00000000..13130e33 --- /dev/null +++ b/board/dongshanpi-aict/read_chip_efuse/main.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include + +extern sunxi_serial_t uart_dbg; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_clk_init(); + + uint32_t id[4]; + + id[0] = read32(0x03006200 + 0x0); + id[1] = read32(0x03006200 + 0x4); + id[2] = read32(0x03006200 + 0x8); + id[3] = read32(0x03006200 + 0xc); + + printk(LOG_LEVEL_INFO, "Chip ID is: %08x%08x%08x%08x\n", id[0], id[1], + id[2], id[3]); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/read_chipsid/CMakeLists.txt b/board/dongshanpi-aict/read_chipsid/CMakeLists.txt new file mode 100644 index 00000000..7f1611a3 --- /dev/null +++ b/board/dongshanpi-aict/read_chipsid/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(read_chip_efuse + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/read_chipsid/main.c b/board/dongshanpi-aict/read_chipsid/main.c new file mode 100644 index 00000000..accc2444 --- /dev/null +++ b/board/dongshanpi-aict/read_chipsid/main.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include + +#include + +extern sunxi_serial_t uart_dbg; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_clk_init(); + + syter_efuse_dump(); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/spi_lcd/CMakeLists.txt b/board/dongshanpi-aict/spi_lcd/CMakeLists.txt new file mode 100644 index 00000000..d82093cf --- /dev/null +++ b/board/dongshanpi-aict/spi_lcd/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(spi_lcd + main.c + lcd.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/spi_lcd/lcd.c b/board/dongshanpi-aict/spi_lcd/lcd.c new file mode 100644 index 00000000..20280433 --- /dev/null +++ b/board/dongshanpi-aict/spi_lcd/lcd.c @@ -0,0 +1,261 @@ +#include +#include +#include +#include +#include +#include + +#include "lcd.h" +#include "lcd_font.h" +#include "lcd_init.h" + +/****************************************************************************** +函数说明:填充颜色 +入口数据:color 要填充的颜色 +返回值: 无 +******************************************************************************/ +void LCD_Fill_All(uint16_t color) { + uint16_t i, j; + LCD_Address_Set(0, 0, LCD_W - 1, LCD_H - 1);// 设置显示范围 + uint16_t *video_mem = smalloc(LCD_W * LCD_H); + + for (uint32_t i = 0; i < LCD_W * LCD_H; i++) { + video_mem[i] = color; + } + + LCD_Write_Data_Bus(video_mem, LCD_W * LCD_H * (sizeof(uint16_t) / sizeof(uint8_t))); + + sfree(video_mem); +} + +/****************************************************************************** +函数说明:在指定区域填充颜色 +入口数据:xsta,ysta 起始坐标 + xend,yend 终止坐标 + color 要填充的颜色 +返回值: 无 +******************************************************************************/ +void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color) { + uint16_t i, j; + LCD_Address_Set(xsta, ysta, xend - 1, yend - 1);//设置显示范围 + for (i = ysta; i < yend; i++) { + for (j = xsta; j < xend; j++) { + LCD_WR_DATA(color); + } + } +} + +/****************************************************************************** + 函数说明:在指定位置画点 + 入口数据:x,y 画点坐标 + color 点的颜色 + 返回值: 无 +******************************************************************************/ +void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color) { + LCD_Address_Set(x, y, x, y);//设置光标位置 + LCD_WR_DATA(color); +} + + +/****************************************************************************** + 函数说明:画线 + 入口数据:x1,y1 起始坐标 + x2,y2 终止坐标 + color 线的颜色 + 返回值: 无 +******************************************************************************/ +void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { + uint16_t t; + int xerr = 0, yerr = 0, delta_x, delta_y, distance; + int incx, incy, uRow, uCol; + delta_x = x2 - x1;//计算坐标增量 + delta_y = y2 - y1; + uRow = x1;//画线起点坐标 + uCol = y1; + if (delta_x > 0) incx = 1;//设置单步方向 + else if (delta_x == 0) + incx = 0;//垂直线 + else { + incx = -1; + delta_x = -delta_x; + } + if (delta_y > 0) incy = 1; + else if (delta_y == 0) + incy = 0;//水平线 + else { + incy = -1; + delta_y = -delta_y; + } + if (delta_x > delta_y) distance = delta_x;//选取基本增量坐标轴 + else + distance = delta_y; + for (t = 0; t < distance + 1; t++) { + LCD_DrawPoint(uRow, uCol, color);//画点 + xerr += delta_x; + yerr += delta_y; + if (xerr > distance) { + xerr -= distance; + uRow += incx; + } + if (yerr > distance) { + yerr -= distance; + uCol += incy; + } + } +} + + +/****************************************************************************** + 函数说明:画矩形 + 入口数据:x1,y1 起始坐标 + x2,y2 终止坐标 + color 矩形的颜色 + 返回值: 无 +******************************************************************************/ +void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { + LCD_DrawLine(x1, y1, x2, y1, color); + LCD_DrawLine(x1, y1, x1, y2, color); + LCD_DrawLine(x1, y2, x2, y2, color); + LCD_DrawLine(x2, y1, x2, y2, color); +} + + +/****************************************************************************** + 函数说明:画圆 + 入口数据:x0,y0 圆心坐标 + r 半径 + color 圆的颜色 + 返回值: 无 +******************************************************************************/ +void Draw_Circle(uint16_t x0, uint16_t y0, uint8_t r, uint16_t color) { + int a, b; + a = 0; + b = r; + while (a <= b) { + LCD_DrawPoint(x0 - b, y0 - a, color);//3 + LCD_DrawPoint(x0 + b, y0 - a, color);//0 + LCD_DrawPoint(x0 - a, y0 + b, color);//1 + LCD_DrawPoint(x0 - a, y0 - b, color);//2 + LCD_DrawPoint(x0 + b, y0 + a, color);//4 + LCD_DrawPoint(x0 + a, y0 - b, color);//5 + LCD_DrawPoint(x0 + a, y0 + b, color);//6 + LCD_DrawPoint(x0 - b, y0 + a, color);//7 + a++; + if ((a * a + b * b) > (r * r))//判断要画的点是否过远 + { + b--; + } + } +} + +/****************************************************************************** + 函数说明:显示单个字符 + 入口数据:x,y显示坐标 + num 要显示的字符 + fc 字的颜色 + bc 字的背景色 + sizey 字号 + mode: 0非叠加模式 1叠加模式 + 返回值: 无 +******************************************************************************/ +void LCD_ShowChar(uint16_t x, uint16_t y, uint8_t num, uint16_t fc, uint16_t bc, uint8_t sizey, uint8_t mode) { + uint8_t temp, sizex, t, m = 0; + uint16_t i, TypefaceNum;//一个字符所占字节大小 + uint16_t x0 = x; + sizex = sizey / 2; + TypefaceNum = (sizex / 8 + ((sizex % 8) ? 1 : 0)) * sizey; + num = num - ' '; //得到偏移后的值 + LCD_Address_Set(x, y, x + sizex - 1, y + sizey - 1);//设置光标位置 + for (i = 0; i < TypefaceNum; i++) { + if (sizey == 12) temp = ascii_1206[num][i];//调用6x12字体 + else if (sizey == 16) + temp = ascii_1608[num][i];//调用8x16字体 + else if (sizey == 24) + temp = ascii_2412[num][i];//调用12x24字体 + else if (sizey == 32) + temp = ascii_3216[num][i];//调用16x32字体 + else + return; + for (t = 0; t < 8; t++) { + if (!mode)//非叠加模式 + { + if (temp & (0x01 << t)) LCD_WR_DATA(fc); + else + LCD_WR_DATA(bc); + m++; + if (m % sizex == 0) { + m = 0; + break; + } + } else//叠加模式 + { + if (temp & (0x01 << t)) LCD_DrawPoint(x, y, fc);//画一个点 + x++; + if ((x - x0) == sizex) { + x = x0; + y++; + break; + } + } + } + } +} + +/****************************************************************************** + 函数说明:显示字符串 + 入口数据:x,y显示坐标 + *p 要显示的字符串 + fc 字的颜色 + bc 字的背景色 + sizey 字号 + mode: 0非叠加模式 1叠加模式 + 返回值: 无 +******************************************************************************/ +void LCD_ShowString(uint16_t x, uint16_t y, const uint8_t *p, uint16_t fc, uint16_t bc, uint8_t sizey, uint8_t mode) { + printk(LOG_LEVEL_INFO, "LCD: Show String: \"%s\"\n", p); + while (*p != '\0') { + LCD_ShowChar(x, y, *p, fc, bc, sizey, mode); + x += sizey / 2; + p++; + } +} + +/****************************************************************************** + 函数说明:显示数字 + 入口数据:m底数,n指数 + 返回值: 无 +******************************************************************************/ +u32 mypow(uint8_t m, uint8_t n) { + u32 result = 1; + while (n--) result *= m; + return result; +} + + +/****************************************************************************** + 函数说明:显示整数变量 + 入口数据:x,y显示坐标 + num 要显示整数变量 + len 要显示的位数 + fc 字的颜色 + bc 字的背景色 + sizey 字号 + 返回值: 无 +******************************************************************************/ +void LCD_ShowIntNum(uint16_t x, uint16_t y, uint16_t num, uint8_t len, uint16_t fc, uint16_t bc, uint8_t sizey) { + printk(LOG_LEVEL_INFO, "LCD: Show Number: \"%d\"\n", num); + uint8_t t, temp; + uint8_t enshow = 0; + uint8_t sizex = sizey / 2; + for (t = 0; t < len; t++) { + temp = (num / mypow(10, len - t - 1)) % 10; + if (enshow == 0 && t < (len - 1)) { + if (temp == 0) { + LCD_ShowChar(x + t * sizex, y, ' ', fc, bc, sizey, 0); + continue; + } else + enshow = 1; + } + LCD_ShowChar(x + t * sizex, y, temp + 48, fc, bc, sizey, 0); + } +} \ No newline at end of file diff --git a/board/dongshanpi-aict/spi_lcd/lcd.h b/board/dongshanpi-aict/spi_lcd/lcd.h new file mode 100644 index 00000000..33530145 --- /dev/null +++ b/board/dongshanpi-aict/spi_lcd/lcd.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __LCD_H__ +#define __LCD_H__ + +#include +#include +#include +#include + +#define LCD_W 240 +#define LCD_H 240 + +void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color);//指定区域填充颜色 + +void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color);//在指定位置画一个点 + +void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);//在指定位置画一条线 + +void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);//在指定位置画一个矩形 + +void Draw_Circle(uint16_t x0, uint16_t y0, uint8_t r, uint16_t color);//在指定位置画一个圆 + +void LCD_ShowChar(uint16_t x, uint16_t y, uint8_t num, uint16_t fc, uint16_t bc, uint8_t sizey, uint8_t mode);//显示一个字符 + +void LCD_ShowString(uint16_t x, uint16_t y, const uint8_t *p, uint16_t fc, uint16_t bc, uint8_t sizey, uint8_t mode);//显示字符串 + +u32 mypow(uint8_t m, uint8_t n);//求幂 + +void LCD_ShowIntNum(uint16_t x, uint16_t y, uint16_t num, uint8_t len, uint16_t fc, uint16_t bc, uint8_t sizey);//显示整数变量 + +void LCD_ShowPicture(uint16_t x, uint16_t y, uint16_t length, uint16_t width, const uint8_t pic[]);//显示图片 + +//画笔颜色 +#define WHITE 0xFFFF +#define BLACK 0x0000 +#define BLUE 0x001F +#define BRED 0XF81F +#define GRED 0XFFE0 +#define GBLUE 0X07FF +#define RED 0xF800 +#define MAGENTA 0xF81F +#define GREEN 0x07E0 +#define CYAN 0x7FFF +#define YELLOW 0xFFE0 +#define BROWN 0XBC40 //棕色 +#define BRRED 0XFC07 //棕红色 +#define GRAY 0X8430 //灰色 +#define DARKBLUE 0X01CF //深蓝色 +#define LIGHTBLUE 0X7D7C //浅蓝色 +#define GRAYBLUE 0X5458 //灰蓝色 +#define LIGHTGREEN 0X841F//浅绿色 +#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色 +#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色) +#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色) + +#endif//__LCD_H__ \ No newline at end of file diff --git a/board/dongshanpi-aict/spi_lcd/lcd_font.h b/board/dongshanpi-aict/spi_lcd/lcd_font.h new file mode 100644 index 00000000..0f628b4a --- /dev/null +++ b/board/dongshanpi-aict/spi_lcd/lcd_font.h @@ -0,0 +1,397 @@ +#ifndef __LCDFONT_H +#define __LCDFONT_H + +const unsigned char ascii_1206[][12] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*" ",0*/ + {0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00}, /*"!",1*/ + {0x14, 0x14, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*""",2*/ + {0x00, 0x00, 0x0A, 0x0A, 0x1F, 0x0A, 0x0A, 0x1F, 0x0A, 0x0A, 0x00, 0x00}, /*"#",3*/ + {0x00, 0x04, 0x0E, 0x15, 0x05, 0x06, 0x0C, 0x14, 0x15, 0x0E, 0x04, 0x00}, /*"$",4*/ + {0x00, 0x00, 0x12, 0x15, 0x0D, 0x15, 0x2E, 0x2C, 0x2A, 0x12, 0x00, 0x00}, /*"%",5*/ + {0x00, 0x00, 0x04, 0x0A, 0x0A, 0x36, 0x15, 0x15, 0x29, 0x16, 0x00, 0x00}, /*"&",6*/ + {0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"'",7*/ + {0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x00}, /*"(",8*/ + {0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x00}, /*")",9*/ + {0x00, 0x00, 0x00, 0x04, 0x15, 0x0E, 0x0E, 0x15, 0x04, 0x00, 0x00, 0x00}, /*"*",10*/ + {0x00, 0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00}, /*"+",11*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x01, 0x00}, /*",",12*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"-",13*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}, /*".",14*/ + {0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00}, /*"/",15*/ + {0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00}, /*"0",16*/ + {0x00, 0x00, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E, 0x00, 0x00}, /*"1",17*/ + {0x00, 0x00, 0x0E, 0x11, 0x11, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x00, 0x00}, /*"2",18*/ + {0x00, 0x00, 0x0E, 0x11, 0x10, 0x0C, 0x10, 0x10, 0x11, 0x0E, 0x00, 0x00}, /*"3",19*/ + {0x00, 0x00, 0x08, 0x0C, 0x0C, 0x0A, 0x09, 0x1F, 0x08, 0x1C, 0x00, 0x00}, /*"4",20*/ + {0x00, 0x00, 0x1F, 0x01, 0x01, 0x0F, 0x11, 0x10, 0x11, 0x0E, 0x00, 0x00}, /*"5",21*/ + {0x00, 0x00, 0x0C, 0x12, 0x01, 0x0D, 0x13, 0x11, 0x11, 0x0E, 0x00, 0x00}, /*"6",22*/ + {0x00, 0x00, 0x1E, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00}, /*"7",23*/ + {0x00, 0x00, 0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00}, /*"8",24*/ + {0x00, 0x00, 0x0E, 0x11, 0x11, 0x19, 0x16, 0x10, 0x09, 0x06, 0x00, 0x00}, /*"9",25*/ + {0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00}, /*":",26*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00}, /*";",27*/ + {0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00}, /*"<",28*/ + {0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"=",29*/ + {0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, /*">",30*/ + {0x00, 0x00, 0x0E, 0x11, 0x11, 0x08, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00}, /*"?",31*/ + {0x00, 0x00, 0x1C, 0x22, 0x29, 0x2D, 0x2D, 0x1D, 0x22, 0x1C, 0x00, 0x00}, /*"@",32*/ + {0x00, 0x00, 0x04, 0x04, 0x0C, 0x0A, 0x0A, 0x1E, 0x12, 0x33, 0x00, 0x00}, /*"A",33*/ + {0x00, 0x00, 0x0F, 0x12, 0x12, 0x0E, 0x12, 0x12, 0x12, 0x0F, 0x00, 0x00}, /*"B",34*/ + {0x00, 0x00, 0x1E, 0x11, 0x01, 0x01, 0x01, 0x01, 0x11, 0x0E, 0x00, 0x00}, /*"C",35*/ + {0x00, 0x00, 0x0F, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x0F, 0x00, 0x00}, /*"D",36*/ + {0x00, 0x00, 0x1F, 0x12, 0x0A, 0x0E, 0x0A, 0x02, 0x12, 0x1F, 0x00, 0x00}, /*"E",37*/ + {0x00, 0x00, 0x1F, 0x12, 0x0A, 0x0E, 0x0A, 0x02, 0x02, 0x07, 0x00, 0x00}, /*"F",38*/ + {0x00, 0x00, 0x1C, 0x12, 0x01, 0x01, 0x39, 0x11, 0x12, 0x0C, 0x00, 0x00}, /*"G",39*/ + {0x00, 0x00, 0x33, 0x12, 0x12, 0x1E, 0x12, 0x12, 0x12, 0x33, 0x00, 0x00}, /*"H",40*/ + {0x00, 0x00, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F, 0x00, 0x00}, /*"I",41*/ + {0x00, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x07}, /*"J",42*/ + {0x00, 0x00, 0x37, 0x12, 0x0A, 0x06, 0x0A, 0x12, 0x12, 0x37, 0x00, 0x00}, /*"K",43*/ + {0x00, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x02, 0x22, 0x3F, 0x00, 0x00}, /*"L",44*/ + {0x00, 0x00, 0x3B, 0x1B, 0x1B, 0x1B, 0x15, 0x15, 0x15, 0x35, 0x00, 0x00}, /*"M",45*/ + {0x00, 0x00, 0x3B, 0x12, 0x16, 0x16, 0x1A, 0x1A, 0x12, 0x17, 0x00, 0x00}, /*"N",46*/ + {0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00}, /*"O",47*/ + {0x00, 0x00, 0x0F, 0x12, 0x12, 0x0E, 0x02, 0x02, 0x02, 0x07, 0x00, 0x00}, /*"P",48*/ + {0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x17, 0x19, 0x0E, 0x18, 0x00}, /*"Q",49*/ + {0x00, 0x00, 0x0F, 0x12, 0x12, 0x0E, 0x0A, 0x12, 0x12, 0x37, 0x00, 0x00}, /*"R",50*/ + {0x00, 0x00, 0x1E, 0x11, 0x01, 0x06, 0x08, 0x10, 0x11, 0x0F, 0x00, 0x00}, /*"S",51*/ + {0x00, 0x00, 0x1F, 0x15, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E, 0x00, 0x00}, /*"T",52*/ + {0x00, 0x00, 0x33, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x0C, 0x00, 0x00}, /*"U",53*/ + {0x00, 0x00, 0x33, 0x12, 0x12, 0x0A, 0x0A, 0x0C, 0x04, 0x04, 0x00, 0x00}, /*"V",54*/ + {0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x0E, 0x0A, 0x0A, 0x0A, 0x00, 0x00}, /*"W",55*/ + {0x00, 0x00, 0x1B, 0x0A, 0x0A, 0x04, 0x04, 0x0A, 0x0A, 0x1B, 0x00, 0x00}, /*"X",56*/ + {0x00, 0x00, 0x1B, 0x0A, 0x0A, 0x0A, 0x04, 0x04, 0x04, 0x0E, 0x00, 0x00}, /*"Y",57*/ + {0x00, 0x00, 0x1F, 0x09, 0x08, 0x04, 0x04, 0x02, 0x12, 0x1F, 0x00, 0x00}, /*"Z",58*/ + {0x1C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1C, 0x00}, /*"[",59*/ + {0x00, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x00}, /*"\",60*/ + {0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0E, 0x00}, /*"]",61*/ + {0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"^",62*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F}, /*"_",63*/ + {0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"`",64*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x12, 0x1C, 0x12, 0x3C, 0x00, 0x00}, /*"a",65*/ + {0x00, 0x03, 0x02, 0x02, 0x02, 0x0E, 0x12, 0x12, 0x12, 0x0E, 0x00, 0x00}, /*"b",66*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x12, 0x02, 0x12, 0x0C, 0x00, 0x00}, /*"c",67*/ + {0x00, 0x18, 0x10, 0x10, 0x10, 0x1C, 0x12, 0x12, 0x12, 0x3C, 0x00, 0x00}, /*"d",68*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x12, 0x1E, 0x02, 0x1C, 0x00, 0x00}, /*"e",69*/ + {0x00, 0x18, 0x24, 0x04, 0x04, 0x1E, 0x04, 0x04, 0x04, 0x1E, 0x00, 0x00}, /*"f",70*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x12, 0x0C, 0x02, 0x1C, 0x22, 0x1C}, /*"g",71*/ + {0x00, 0x03, 0x02, 0x02, 0x02, 0x0E, 0x12, 0x12, 0x12, 0x37, 0x00, 0x00}, /*"h",72*/ + {0x00, 0x04, 0x04, 0x00, 0x00, 0x06, 0x04, 0x04, 0x04, 0x0E, 0x00, 0x00}, /*"i",73*/ + {0x00, 0x08, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07}, /*"j",74*/ + {0x00, 0x03, 0x02, 0x02, 0x02, 0x1A, 0x0A, 0x06, 0x0A, 0x13, 0x00, 0x00}, /*"k",75*/ + {0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F, 0x00, 0x00}, /*"l",76*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00}, /*"m",77*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x12, 0x12, 0x12, 0x37, 0x00, 0x00}, /*"n",78*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x12, 0x12, 0x12, 0x0C, 0x00, 0x00}, /*"o",79*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x12, 0x12, 0x12, 0x0E, 0x02, 0x07}, /*"p",80*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x12, 0x12, 0x12, 0x1C, 0x10, 0x38}, /*"q",81*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x06, 0x02, 0x02, 0x07, 0x00, 0x00}, /*"r",82*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x02, 0x0C, 0x10, 0x1E, 0x00, 0x00}, /*"s",83*/ + {0x00, 0x00, 0x00, 0x04, 0x04, 0x1E, 0x04, 0x04, 0x04, 0x1C, 0x00, 0x00}, /*"t",84*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x12, 0x12, 0x12, 0x3C, 0x00, 0x00}, /*"u",85*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x0A, 0x0A, 0x04, 0x04, 0x00, 0x00}, /*"v",86*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x0E, 0x0A, 0x0A, 0x00, 0x00}, /*"w",87*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x0A, 0x04, 0x0A, 0x1B, 0x00, 0x00}, /*"x",88*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x12, 0x12, 0x0C, 0x08, 0x04, 0x03}, /*"y",89*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x08, 0x04, 0x04, 0x1E, 0x00, 0x00}, /*"z",90*/ + {0x18, 0x08, 0x08, 0x08, 0x08, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00}, /*"{",91*/ + {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, /*"|",92*/ + {0x06, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x06, 0x00}, /*"}",93*/ + {0x16, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"~",94*/ +}; + +unsigned char ascii_1608[][16] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*" ",0*/ + {0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, /*"!",1*/ + {0x00, 0x48, 0x6C, 0x24, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*""",2*/ + {0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x7F, 0x12, 0x12, 0x12, 0x7F, 0x12, 0x12, 0x12, 0x00, 0x00}, /*"#",3*/ + {0x00, 0x00, 0x08, 0x1C, 0x2A, 0x2A, 0x0A, 0x0C, 0x18, 0x28, 0x28, 0x2A, 0x2A, 0x1C, 0x08, 0x08}, /*"$",4*/ + {0x00, 0x00, 0x00, 0x22, 0x25, 0x15, 0x15, 0x15, 0x2A, 0x58, 0x54, 0x54, 0x54, 0x22, 0x00, 0x00}, /*"%",5*/ + {0x00, 0x00, 0x00, 0x0C, 0x12, 0x12, 0x12, 0x0A, 0x76, 0x25, 0x29, 0x11, 0x91, 0x6E, 0x00, 0x00}, /*"&",6*/ + {0x00, 0x06, 0x06, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"'",7*/ + {0x00, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00}, /*"(",8*/ + {0x00, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x00}, /*")",9*/ + {0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x1C, 0x1C, 0x6B, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00}, /*"*",10*/ + {0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x7F, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00}, /*"+",11*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x04, 0x03}, /*",",12*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"-",13*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, /*".",14*/ + {0x00, 0x00, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00}, /*"/",15*/ + {0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00}, /*"0",16*/ + {0x00, 0x00, 0x00, 0x08, 0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /*"1",17*/ + {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x20, 0x20, 0x10, 0x08, 0x04, 0x42, 0x7E, 0x00, 0x00}, /*"2",18*/ + {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x20, 0x18, 0x20, 0x40, 0x40, 0x42, 0x22, 0x1C, 0x00, 0x00}, /*"3",19*/ + {0x00, 0x00, 0x00, 0x20, 0x30, 0x28, 0x24, 0x24, 0x22, 0x22, 0x7E, 0x20, 0x20, 0x78, 0x00, 0x00}, /*"4",20*/ + {0x00, 0x00, 0x00, 0x7E, 0x02, 0x02, 0x02, 0x1A, 0x26, 0x40, 0x40, 0x42, 0x22, 0x1C, 0x00, 0x00}, /*"5",21*/ + {0x00, 0x00, 0x00, 0x38, 0x24, 0x02, 0x02, 0x1A, 0x26, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00}, /*"6",22*/ + {0x00, 0x00, 0x00, 0x7E, 0x22, 0x22, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /*"7",23*/ + {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00}, /*"8",24*/ + {0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x64, 0x58, 0x40, 0x40, 0x24, 0x1C, 0x00, 0x00}, /*"9",25*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, /*":",26*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04}, /*";",27*/ + {0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00}, /*"<",28*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"=",29*/ + {0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, /*">",30*/ + {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x46, 0x40, 0x20, 0x10, 0x10, 0x00, 0x18, 0x18, 0x00, 0x00}, /*"?",31*/ + {0x00, 0x00, 0x00, 0x1C, 0x22, 0x5A, 0x55, 0x55, 0x55, 0x55, 0x2D, 0x42, 0x22, 0x1C, 0x00, 0x00}, /*"@",32*/ + {0x00, 0x00, 0x00, 0x08, 0x08, 0x18, 0x14, 0x14, 0x24, 0x3C, 0x22, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"A",33*/ + {0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x1E, 0x22, 0x42, 0x42, 0x42, 0x22, 0x1F, 0x00, 0x00}, /*"B",34*/ + {0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x01, 0x01, 0x01, 0x01, 0x01, 0x42, 0x22, 0x1C, 0x00, 0x00}, /*"C",35*/ + {0x00, 0x00, 0x00, 0x1F, 0x22, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x22, 0x1F, 0x00, 0x00}, /*"D",36*/ + {0x00, 0x00, 0x00, 0x3F, 0x42, 0x12, 0x12, 0x1E, 0x12, 0x12, 0x02, 0x42, 0x42, 0x3F, 0x00, 0x00}, /*"E",37*/ + {0x00, 0x00, 0x00, 0x3F, 0x42, 0x12, 0x12, 0x1E, 0x12, 0x12, 0x02, 0x02, 0x02, 0x07, 0x00, 0x00}, /*"F",38*/ + {0x00, 0x00, 0x00, 0x3C, 0x22, 0x22, 0x01, 0x01, 0x01, 0x71, 0x21, 0x22, 0x22, 0x1C, 0x00, 0x00}, /*"G",39*/ + {0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"H",40*/ + {0x00, 0x00, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /*"I",41*/ + {0x00, 0x00, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x0F}, /*"J",42*/ + {0x00, 0x00, 0x00, 0x77, 0x22, 0x12, 0x0A, 0x0E, 0x0A, 0x12, 0x12, 0x22, 0x22, 0x77, 0x00, 0x00}, /*"K",43*/ + {0x00, 0x00, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x7F, 0x00, 0x00}, /*"L",44*/ + {0x00, 0x00, 0x00, 0x77, 0x36, 0x36, 0x36, 0x36, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x6B, 0x00, 0x00}, /*"M",45*/ + {0x00, 0x00, 0x00, 0xE3, 0x46, 0x46, 0x4A, 0x4A, 0x52, 0x52, 0x52, 0x62, 0x62, 0x47, 0x00, 0x00}, /*"N",46*/ + {0x00, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1C, 0x00, 0x00}, /*"O",47*/ + {0x00, 0x00, 0x00, 0x3F, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x00}, /*"P",48*/ + {0x00, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x4D, 0x53, 0x32, 0x1C, 0x60, 0x00}, /*"Q",49*/ + {0x00, 0x00, 0x00, 0x3F, 0x42, 0x42, 0x42, 0x3E, 0x12, 0x12, 0x22, 0x22, 0x42, 0xC7, 0x00, 0x00}, /*"R",50*/ + {0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x02, 0x04, 0x18, 0x20, 0x40, 0x42, 0x42, 0x3E, 0x00, 0x00}, /*"S",51*/ + {0x00, 0x00, 0x00, 0x7F, 0x49, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /*"T",52*/ + {0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00}, /*"U",53*/ + {0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x22, 0x24, 0x24, 0x14, 0x14, 0x18, 0x08, 0x08, 0x00, 0x00}, /*"V",54*/ + {0x00, 0x00, 0x00, 0x6B, 0x49, 0x49, 0x49, 0x49, 0x55, 0x55, 0x36, 0x22, 0x22, 0x22, 0x00, 0x00}, /*"W",55*/ + {0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0xE7, 0x00, 0x00}, /*"X",56*/ + {0x00, 0x00, 0x00, 0x77, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /*"Y",57*/ + {0x00, 0x00, 0x00, 0x7E, 0x21, 0x20, 0x10, 0x10, 0x08, 0x04, 0x04, 0x42, 0x42, 0x3F, 0x00, 0x00}, /*"Z",58*/ + {0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00}, /*"[",59*/ + {0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x20, 0x40, 0x40}, /*"\",60*/ + {0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x00}, /*"]",61*/ + {0x00, 0x38, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"^",62*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, /*"_",63*/ + {0x00, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"`",64*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x78, 0x44, 0x42, 0x42, 0xFC, 0x00, 0x00}, /*"a",65*/ + {0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x02, 0x1A, 0x26, 0x42, 0x42, 0x42, 0x26, 0x1A, 0x00, 0x00}, /*"b",66*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x02, 0x02, 0x02, 0x44, 0x38, 0x00, 0x00}, /*"c",67*/ + {0x00, 0x00, 0x00, 0x60, 0x40, 0x40, 0x40, 0x78, 0x44, 0x42, 0x42, 0x42, 0x64, 0xD8, 0x00, 0x00}, /*"d",68*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x7E, 0x02, 0x02, 0x42, 0x3C, 0x00, 0x00}, /*"e",69*/ + {0x00, 0x00, 0x00, 0xF0, 0x88, 0x08, 0x08, 0x7E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /*"f",70*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x22, 0x22, 0x1C, 0x02, 0x3C, 0x42, 0x42, 0x3C}, /*"g",71*/ + {0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x02, 0x3A, 0x46, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"h",72*/ + {0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /*"i",73*/ + {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1E}, /*"j",74*/ + {0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x02, 0x72, 0x12, 0x0A, 0x16, 0x12, 0x22, 0x77, 0x00, 0x00}, /*"k",75*/ + {0x00, 0x00, 0x00, 0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /*"l",76*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x92, 0x92, 0x92, 0x92, 0x92, 0xB7, 0x00, 0x00}, /*"m",77*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x46, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"n",78*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00}, /*"o",79*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x26, 0x42, 0x42, 0x42, 0x22, 0x1E, 0x02, 0x07}, /*"p",80*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0x78, 0x40, 0xE0}, /*"q",81*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x4C, 0x04, 0x04, 0x04, 0x04, 0x1F, 0x00, 0x00}, /*"r",82*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x42, 0x02, 0x3C, 0x40, 0x42, 0x3E, 0x00, 0x00}, /*"s",83*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00}, /*"t",84*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x42, 0x42, 0x42, 0x42, 0x62, 0xDC, 0x00, 0x00}, /*"u",85*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x14, 0x08, 0x08, 0x00, 0x00}, /*"v",86*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x49, 0x49, 0x55, 0x55, 0x22, 0x22, 0x00, 0x00}, /*"w",87*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x24, 0x18, 0x18, 0x18, 0x24, 0x6E, 0x00, 0x00}, /*"x",88*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x14, 0x18, 0x08, 0x08, 0x07}, /*"y",89*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x22, 0x10, 0x08, 0x08, 0x44, 0x7E, 0x00, 0x00}, /*"z",90*/ + {0x00, 0xC0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xC0, 0x00}, /*"{",91*/ + {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, /*"|",92*/ + {0x00, 0x06, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00}, /*"}",93*/ + {0x0C, 0x32, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"~",94*/ +}; + +const unsigned char ascii_2412[][48] = { + {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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*" ",0*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"!",1*/ + {0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x60, 0x06, 0x30, 0x03, 0x98, 0x01, 0x88, 0x00, 0x44, 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, 0x00}, /*""",2*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0xFE, 0x07, 0xFE, 0x07, 0x08, 0x02, 0x08, 0x01, 0x08, 0x01, 0x08, 0x01, 0x08, 0x01, 0xFE, 0x07, 0xFE, 0x07, 0x04, 0x01, 0x04, 0x01, 0x04, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"#",3*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x58, 0x03, 0x4C, 0x03, 0xCC, 0x03, 0x4C, 0x00, 0x58, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0x40, 0x03, 0x4C, 0x03, 0x5C, 0x03, 0x4C, 0x03, 0x48, 0x01, 0xF0, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00}, /*"$",4*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x0A, 0x01, 0x91, 0x00, 0x91, 0x00, 0x91, 0x00, 0x51, 0x00, 0x51, 0x00, 0x3A, 0x00, 0xAE, 0x03, 0xA0, 0x02, 0x50, 0x04, 0x50, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x84, 0x02, 0x84, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"%",5*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x2C, 0x00, 0x98, 0x07, 0x1C, 0x01, 0x1A, 0x01, 0x33, 0x01, 0x33, 0x01, 0x63, 0x01, 0xE3, 0x00, 0xC3, 0x08, 0xC6, 0x09, 0x3C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"&",6*/ + {0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x1C, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 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, 0x00}, /*"'",7*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00}, /*"(",8*/ + {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00}, /*")",9*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x40, 0x00, 0x46, 0x0C, 0x4E, 0x0F, 0xD0, 0x01, 0xF0, 0x01, 0x5E, 0x0F, 0x46, 0x0C, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"*",10*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xFE, 0x0F, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"+",11*/ + {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, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x1C, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00}, /*",",12*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"-",13*/ + {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, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*".",14*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00}, /*"/",15*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x98, 0x01, 0x0C, 0x03, 0x0C, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0C, 0x03, 0x0C, 0x03, 0x98, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"0",16*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7C, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"1",17*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x01, 0x02, 0x03, 0x06, 0x03, 0x06, 0x03, 0x00, 0x03, 0x00, 0x01, 0x80, 0x01, 0xC0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x02, 0x04, 0x02, 0x06, 0x02, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"2",18*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xC6, 0x00, 0x86, 0x01, 0x86, 0x01, 0x80, 0x01, 0x80, 0x01, 0xC0, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x06, 0x03, 0x06, 0x03, 0x86, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"3",19*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0xC0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0x90, 0x01, 0x88, 0x01, 0x88, 0x01, 0x84, 0x01, 0x82, 0x01, 0xFE, 0x0F, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"4",20*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0xF4, 0x00, 0x8C, 0x01, 0x04, 0x03, 0x00, 0x03, 0x00, 0x03, 0x06, 0x03, 0x06, 0x03, 0x82, 0x01, 0x84, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"5",21*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x18, 0x03, 0x0C, 0x03, 0x0C, 0x00, 0x04, 0x00, 0x06, 0x00, 0xE6, 0x01, 0x16, 0x03, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x0C, 0x02, 0x18, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"6",22*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x0C, 0x06, 0x04, 0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"7",23*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x0C, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0C, 0x02, 0x1C, 0x03, 0xF0, 0x00, 0xC8, 0x01, 0x0C, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0C, 0x03, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"8",24*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x0C, 0x01, 0x0C, 0x03, 0x06, 0x02, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x8C, 0x06, 0x78, 0x06, 0x00, 0x06, 0x00, 0x03, 0x00, 0x03, 0x0C, 0x01, 0x8C, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"9",25*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*":",26*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00}, /*";",27*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"<",28*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"=",29*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*">",30*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x18, 0x06, 0x04, 0x0C, 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x07, 0x80, 0x01, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"?",31*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x18, 0x03, 0x0C, 0x02, 0xCC, 0x05, 0x64, 0x05, 0x66, 0x05, 0xA6, 0x05, 0xB6, 0x04, 0xB6, 0x04, 0xB6, 0x04, 0xB6, 0x04, 0xB6, 0x02, 0xE4, 0x01, 0x0C, 0x04, 0x0C, 0x02, 0x18, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"@",32*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x50, 0x00, 0xD0, 0x00, 0x90, 0x00, 0x90, 0x00, 0x88, 0x00, 0x88, 0x01, 0x08, 0x01, 0xF8, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x02, 0x02, 0x02, 0x02, 0x06, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"A",33*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x8C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x8C, 0x01, 0xFC, 0x00, 0x0C, 0x03, 0x0C, 0x02, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x03, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"B",34*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x18, 0x03, 0x0C, 0x06, 0x0C, 0x04, 0x04, 0x04, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x04, 0x0C, 0x04, 0x0C, 0x02, 0x18, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"C",35*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x8C, 0x01, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x03, 0x0C, 0x03, 0x8C, 0x01, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"D",36*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x06, 0x03, 0x06, 0x04, 0x06, 0x04, 0x06, 0x00, 0x86, 0x00, 0x86, 0x00, 0xFE, 0x00, 0x86, 0x00, 0x86, 0x00, 0x86, 0x00, 0x06, 0x00, 0x06, 0x04, 0x06, 0x04, 0x06, 0x02, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"E",37*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x06, 0x03, 0x06, 0x04, 0x06, 0x04, 0x06, 0x00, 0x86, 0x00, 0x86, 0x00, 0xFE, 0x00, 0x86, 0x00, 0x86, 0x00, 0x86, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"F",38*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x18, 0x01, 0x0C, 0x02, 0x0C, 0x02, 0x04, 0x02, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0xC6, 0x0F, 0x06, 0x03, 0x06, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x18, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"G",39*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xFE, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"H",40*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"I",41*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC6, 0x00, 0x66, 0x00, 0x3C, 0x00}, /*"J",42*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0x03, 0x86, 0x01, 0xC6, 0x00, 0x46, 0x00, 0x26, 0x00, 0x16, 0x00, 0x36, 0x00, 0x2E, 0x00, 0x6E, 0x00, 0x46, 0x00, 0xC6, 0x00, 0x86, 0x00, 0x86, 0x01, 0x06, 0x01, 0x06, 0x03, 0x8F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"K",43*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x04, 0x06, 0x04, 0x06, 0x02, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"L",44*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x86, 0x03, 0x86, 0x03, 0x8E, 0x03, 0x8E, 0x03, 0x4E, 0x03, 0x4E, 0x03, 0x4A, 0x03, 0x5A, 0x03, 0x5A, 0x03, 0x3A, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x12, 0x03, 0x87, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"M",45*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x0F, 0x0C, 0x02, 0x1C, 0x02, 0x1C, 0x02, 0x34, 0x02, 0x34, 0x02, 0x64, 0x02, 0x64, 0x02, 0x44, 0x02, 0xC4, 0x02, 0x84, 0x02, 0x84, 0x03, 0x84, 0x03, 0x04, 0x03, 0x04, 0x03, 0x1F, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"N",46*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x98, 0x01, 0x0C, 0x03, 0x0C, 0x02, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0C, 0x02, 0x0C, 0x03, 0x98, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"O",47*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x06, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0x03, 0xFE, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"P",48*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x98, 0x01, 0x0C, 0x03, 0x0C, 0x02, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x76, 0x06, 0x4C, 0x02, 0xCC, 0x03, 0x98, 0x01, 0xF0, 0x00, 0x80, 0x07, 0x00, 0x03, 0x00, 0x00}, /*"Q",49*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x06, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x03, 0xFE, 0x00, 0x46, 0x00, 0xC6, 0x00, 0x86, 0x00, 0x86, 0x01, 0x06, 0x03, 0x06, 0x03, 0x06, 0x06, 0x0F, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"R",50*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x02, 0x0C, 0x03, 0x06, 0x02, 0x06, 0x02, 0x06, 0x00, 0x0E, 0x00, 0x3C, 0x00, 0xF8, 0x00, 0xE0, 0x03, 0x80, 0x03, 0x00, 0x07, 0x02, 0x06, 0x02, 0x06, 0x06, 0x06, 0x0C, 0x03, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"S",51*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 0x62, 0x04, 0x61, 0x08, 0x61, 0x08, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"T",52*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x07, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x18, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"U",53*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x07, 0x06, 0x02, 0x04, 0x01, 0x04, 0x01, 0x0C, 0x01, 0x0C, 0x01, 0x88, 0x00, 0x88, 0x00, 0x98, 0x00, 0x98, 0x00, 0x50, 0x00, 0x50, 0x00, 0x70, 0x00, 0x30, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"V",54*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0E, 0x62, 0x04, 0x42, 0x04, 0x46, 0x04, 0x46, 0x04, 0x64, 0x02, 0x64, 0x02, 0xE4, 0x02, 0xE4, 0x02, 0x9C, 0x02, 0x9C, 0x01, 0x98, 0x01, 0x98, 0x01, 0x88, 0x01, 0x88, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"W",55*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x07, 0x0C, 0x01, 0x08, 0x01, 0x18, 0x01, 0x90, 0x00, 0xB0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x60, 0x00, 0xD0, 0x00, 0x90, 0x00, 0x88, 0x01, 0x08, 0x01, 0x04, 0x03, 0x8E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"X",56*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x06, 0x04, 0x04, 0x02, 0x0C, 0x02, 0x08, 0x01, 0x18, 0x01, 0xB8, 0x00, 0xB0, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"Y",57*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x07, 0x0C, 0x02, 0x06, 0x03, 0x02, 0x01, 0x80, 0x01, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x18, 0x00, 0x08, 0x04, 0x0C, 0x04, 0x04, 0x02, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"Z",58*/ + {0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x00, 0x00}, /*"[",59*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04}, /*"\",60*/ + {0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x7C, 0x00, 0x00, 0x00}, /*"]",61*/ + {0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"^",62*/ + {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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F}, /*"_",63*/ + {0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"`",64*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x0C, 0x03, 0x0C, 0x03, 0x00, 0x03, 0xE0, 0x03, 0x1C, 0x03, 0x0E, 0x03, 0x06, 0x03, 0x06, 0x03, 0x8E, 0x0B, 0x7C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"a",65*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0xCC, 0x01, 0x3C, 0x03, 0x1C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x02, 0x1C, 0x03, 0xE4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"b",66*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x8C, 0x01, 0x8C, 0x01, 0x86, 0x01, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x02, 0x0C, 0x02, 0x0C, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"c",67*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xC0, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x78, 0x03, 0x8C, 0x03, 0x0C, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x04, 0x03, 0x8C, 0x07, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"d",68*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x18, 0x03, 0x08, 0x02, 0x0C, 0x06, 0x0C, 0x06, 0xFC, 0x07, 0x0C, 0x00, 0x0C, 0x00, 0x18, 0x04, 0x18, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"e",69*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x60, 0x06, 0x30, 0x06, 0x30, 0x00, 0x30, 0x00, 0xFE, 0x01, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"f",70*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0xD8, 0x06, 0x8C, 0x01, 0x8C, 0x01, 0x8C, 0x01, 0x98, 0x01, 0xF8, 0x00, 0x0C, 0x00, 0xFC, 0x00, 0xCC, 0x03, 0x06, 0x03, 0x06, 0x03, 0x8E, 0x03, 0xF8, 0x00}, /*"g",71*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0xEC, 0x01, 0x1C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x9E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"h",72*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7C, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"i",73*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xCC, 0x00, 0x7C, 0x00}, /*"j",74*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x8C, 0x03, 0x8C, 0x00, 0x8C, 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x5C, 0x00, 0x8C, 0x00, 0x8C, 0x01, 0x0C, 0x01, 0x0C, 0x03, 0x9E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"k",75*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7C, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"l",76*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0xEE, 0x06, 0x66, 0x06, 0x66, 0x06, 0x66, 0x06, 0x66, 0x06, 0x66, 0x06, 0x66, 0x06, 0x66, 0x06, 0x66, 0x06, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"m",77*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x01, 0x1C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x9E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"n",78*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x98, 0x01, 0x0C, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0C, 0x03, 0x0C, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"o",79*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x01, 0x1C, 0x03, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x03, 0x1C, 0x03, 0xEC, 0x01, 0x0C, 0x00, 0x0C, 0x00, 0x3E, 0x00}, /*"p",80*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x02, 0x8C, 0x03, 0x0C, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x04, 0x03, 0x8C, 0x03, 0x78, 0x03, 0x00, 0x03, 0x00, 0x03, 0xC0, 0x07}, /*"q",81*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x03, 0x58, 0x06, 0x38, 0x06, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"r",82*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x1C, 0x03, 0x0C, 0x02, 0x0C, 0x02, 0x38, 0x00, 0xF0, 0x00, 0xC0, 0x03, 0x04, 0x03, 0x04, 0x03, 0x8C, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"s",83*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x30, 0x00, 0x30, 0x00, 0xFE, 0x01, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x02, 0x30, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"t",84*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x8E, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x9C, 0x07, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"u",85*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x07, 0x0C, 0x02, 0x08, 0x01, 0x08, 0x01, 0x18, 0x01, 0x90, 0x00, 0xB0, 0x00, 0xB0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"v",86*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0E, 0x62, 0x04, 0x46, 0x04, 0x64, 0x02, 0x64, 0x02, 0xEC, 0x02, 0x9C, 0x01, 0x98, 0x01, 0x98, 0x01, 0x98, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"w",87*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x07, 0x18, 0x01, 0x10, 0x01, 0xB0, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x90, 0x00, 0x08, 0x01, 0x08, 0x03, 0x9E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"x",88*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x07, 0x08, 0x01, 0x08, 0x01, 0x08, 0x01, 0x90, 0x00, 0x90, 0x00, 0xB0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x24, 0x00, 0x1C, 0x00}, /*"y",89*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x84, 0x01, 0xC4, 0x00, 0x44, 0x00, 0x60, 0x00, 0x20, 0x00, 0x30, 0x00, 0x18, 0x02, 0x08, 0x02, 0x0C, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"z",90*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00}, /*"{",91*/ + {0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00}, /*"|",92*/ + {0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00}, /*"}",93*/ + {0x00, 0x00, 0x1C, 0x00, 0x22, 0x04, 0xC2, 0x04, 0x80, 0x03, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"~",94*/ + + +}; + +unsigned char ascii_3216[][64] = { + {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, 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}, /*" ",0*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"!",1*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1C, 0xE0, 0x1C, 0xF0, 0x1E, 0x70, 0x0E, 0x38, 0x07, 0x18, 0x03, 0x08, 0x01, 0x84, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*""",2*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10, 0xFE, 0x7F, 0xFE, 0x7F, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0xFE, 0x7F, 0xFE, 0x7F, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"#",3*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0, 0x07, 0x60, 0x19, 0x10, 0x31, 0x18, 0x31, 0x18, 0x39, 0x18, 0x39, 0x38, 0x01, 0x70, 0x01, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0F, 0x00, 0x1D, 0x00, 0x39, 0x00, 0x31, 0x1C, 0x31, 0x1C, 0x31, 0x0C, 0x31, 0x0C, 0x11, 0x18, 0x0D, 0xE0, 0x07, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, /*"$",4*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x10, 0x36, 0x18, 0x63, 0x08, 0x63, 0x0C, 0x63, 0x04, 0x63, 0x04, 0x63, 0x02, 0x63, 0x02, 0x63, 0x01, 0x36, 0x1D, 0x9C, 0x37, 0x80, 0x22, 0x80, 0x63, 0x40, 0x63, 0x40, 0x63, 0x20, 0x63, 0x20, 0x63, 0x30, 0x63, 0x10, 0x22, 0x18, 0x36, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"%",5*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x98, 0x01, 0x8C, 0x01, 0x8C, 0x01, 0x8C, 0x01, 0x8C, 0x01, 0x8C, 0x00, 0xCC, 0x00, 0x78, 0x00, 0x18, 0x3E, 0x1C, 0x08, 0x36, 0x08, 0x32, 0x08, 0x63, 0x04, 0x63, 0x04, 0xC3, 0x04, 0xC3, 0x03, 0x83, 0x43, 0x06, 0x43, 0x8E, 0x26, 0x78, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"&",6*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x30, 0x00, 0x30, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x06, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"'",7*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x06, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00}, /*"(",8*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x30, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00}, /*")",9*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x80, 0x03, 0x00, 0x01, 0x1C, 0x71, 0x3C, 0x79, 0x78, 0x3D, 0xC0, 0x07, 0x00, 0x01, 0xC0, 0x07, 0x78, 0x3D, 0x3C, 0x79, 0x1C, 0x71, 0x00, 0x01, 0x80, 0x03, 0x80, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"*",10*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFC, 0x7F, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"+",11*/ + {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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x30, 0x00, 0x30, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x06, 0x00}, /*",",12*/ + {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, 0xFE, 0x7F, 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}, /*"-",13*/ + {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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*".",14*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x20, 0x00, 0x30, 0x00, 0x10, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x40, 0x00, 0x60, 0x00, 0x20, 0x00, 0x30, 0x00, 0x10, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"/",15*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x60, 0x0C, 0x30, 0x18, 0x18, 0x30, 0x18, 0x30, 0x18, 0x20, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x18, 0x20, 0x18, 0x30, 0x18, 0x30, 0x30, 0x18, 0x60, 0x0C, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"0",16*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0xF8, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xC0, 0x03, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"1",17*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x10, 0x1C, 0x08, 0x18, 0x04, 0x30, 0x04, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x00, 0x30, 0x00, 0x18, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x80, 0x00, 0x40, 0x00, 0x20, 0x20, 0x10, 0x20, 0x08, 0x20, 0x04, 0x30, 0xFC, 0x1F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"2",18*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x18, 0x0E, 0x0C, 0x0C, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x06, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x10, 0x0C, 0x18, 0x18, 0x0C, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"3",19*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0F, 0x80, 0x0E, 0x80, 0x0E, 0x40, 0x0E, 0x60, 0x0E, 0x20, 0x0E, 0x10, 0x0E, 0x10, 0x0E, 0x08, 0x0E, 0x04, 0x0E, 0x04, 0x0E, 0xFE, 0x7F, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"4",20*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0xF0, 0x3F, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC8, 0x07, 0x28, 0x0C, 0x18, 0x18, 0x08, 0x10, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x04, 0x18, 0x04, 0x18, 0x08, 0x0C, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"5",21*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xC0, 0x10, 0x20, 0x30, 0x10, 0x30, 0x18, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x8C, 0x0F, 0x6C, 0x18, 0x3C, 0x30, 0x1C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x18, 0x60, 0x18, 0x20, 0x30, 0x30, 0x60, 0x18, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"6",22*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xF8, 0x3F, 0x1C, 0x10, 0x0C, 0x08, 0x04, 0x08, 0x04, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"7",23*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x30, 0x0C, 0x18, 0x18, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x1C, 0x30, 0x38, 0x18, 0x70, 0x08, 0xE0, 0x07, 0xB0, 0x07, 0x18, 0x0E, 0x0C, 0x1C, 0x06, 0x38, 0x06, 0x30, 0x06, 0x30, 0x06, 0x30, 0x06, 0x30, 0x0C, 0x18, 0x18, 0x0C, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"8",24*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x18, 0x04, 0x0C, 0x08, 0x0C, 0x18, 0x06, 0x10, 0x06, 0x30, 0x06, 0x30, 0x06, 0x30, 0x06, 0x30, 0x06, 0x38, 0x0C, 0x3C, 0x18, 0x36, 0xF0, 0x31, 0x00, 0x30, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x0C, 0x0C, 0x0C, 0x06, 0x0C, 0x03, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"9",25*/ + {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, 0x80, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*":",26*/ + {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, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00}, /*";",27*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"<",28*/ + {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, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"=",29*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x03, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*">",30*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x30, 0x18, 0x08, 0x30, 0x08, 0x60, 0x0C, 0x60, 0x1C, 0x60, 0x1C, 0x60, 0x1C, 0x60, 0x00, 0x30, 0x00, 0x1C, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"?",31*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x60, 0x18, 0x10, 0x30, 0x18, 0x20, 0x0C, 0x2F, 0x8C, 0x4D, 0x86, 0x4C, 0xC6, 0x4C, 0xC6, 0x4C, 0x66, 0x4C, 0x66, 0x44, 0x66, 0x44, 0x66, 0x26, 0x66, 0x26, 0x66, 0x15, 0xCC, 0x1C, 0x0C, 0x40, 0x08, 0x20, 0x18, 0x30, 0x30, 0x18, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"@",32*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0x40, 0x01, 0x60, 0x03, 0x20, 0x03, 0x20, 0x03, 0x20, 0x03, 0x30, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0xF8, 0x0F, 0x08, 0x0C, 0x08, 0x0C, 0x08, 0x0C, 0x0C, 0x0C, 0x04, 0x18, 0x04, 0x18, 0x06, 0x18, 0x1F, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"A",33*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 0x18, 0x1C, 0x18, 0x38, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x18, 0x18, 0x0C, 0xF8, 0x07, 0x18, 0x18, 0x18, 0x30, 0x18, 0x20, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x18, 0x18, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"B",34*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x27, 0x60, 0x38, 0x10, 0x30, 0x18, 0x20, 0x0C, 0x40, 0x0C, 0x40, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0C, 0x40, 0x0C, 0x40, 0x0C, 0x20, 0x18, 0x30, 0x30, 0x18, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"C",35*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x18, 0x30, 0x18, 0x10, 0x18, 0x18, 0x18, 0x0E, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"D",36*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x18, 0x30, 0x18, 0x20, 0x18, 0x60, 0x18, 0x40, 0x18, 0x00, 0x18, 0x08, 0x18, 0x08, 0x18, 0x0C, 0xF8, 0x0F, 0x18, 0x0C, 0x18, 0x08, 0x18, 0x08, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x40, 0x18, 0x40, 0x18, 0x20, 0x18, 0x30, 0xFE, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"E",37*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x18, 0x70, 0x18, 0x40, 0x18, 0xC0, 0x18, 0x80, 0x18, 0x00, 0x18, 0x10, 0x18, 0x10, 0x18, 0x18, 0xF8, 0x1F, 0x18, 0x18, 0x18, 0x10, 0x18, 0x10, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"F",38*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x13, 0x70, 0x1C, 0x10, 0x10, 0x18, 0x10, 0x0C, 0x20, 0x0C, 0x20, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0xFC, 0x06, 0x30, 0x06, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x08, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"G",39*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7E, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0xFC, 0x1F, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x3F, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"H",40*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"I",41*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x0E, 0x06, 0x0E, 0x03, 0x8E, 0x01, 0xFC, 0x00}, /*"J",42*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7C, 0x18, 0x18, 0x18, 0x08, 0x18, 0x04, 0x18, 0x06, 0x18, 0x02, 0x18, 0x01, 0x98, 0x01, 0x98, 0x01, 0xD8, 0x01, 0xB8, 0x03, 0x38, 0x03, 0x18, 0x07, 0x18, 0x06, 0x18, 0x0E, 0x18, 0x0C, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x30, 0x18, 0x30, 0x7E, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"K",43*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x40, 0x18, 0x40, 0x18, 0x20, 0x18, 0x30, 0xFE, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"L",44*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x3C, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x36, 0x74, 0x32, 0x64, 0x32, 0x64, 0x32, 0x64, 0x32, 0x64, 0x31, 0xC4, 0x31, 0xC4, 0x31, 0xC4, 0x31, 0xC4, 0x30, 0xC4, 0x30, 0x84, 0x30, 0x9F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"M",45*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x7C, 0x1C, 0x10, 0x3C, 0x10, 0x34, 0x10, 0x34, 0x10, 0x74, 0x10, 0x64, 0x10, 0xE4, 0x10, 0xC4, 0x10, 0xC4, 0x11, 0x84, 0x11, 0x84, 0x13, 0x04, 0x13, 0x04, 0x17, 0x04, 0x16, 0x04, 0x1E, 0x04, 0x1C, 0x04, 0x1C, 0x04, 0x1C, 0x04, 0x18, 0x1F, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"N",46*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x30, 0x0C, 0x18, 0x18, 0x08, 0x10, 0x0C, 0x30, 0x0C, 0x30, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x0C, 0x20, 0x0C, 0x30, 0x08, 0x10, 0x18, 0x18, 0x30, 0x0C, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"O",47*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x18, 0x18, 0x18, 0x30, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x18, 0x18, 0xF8, 0x0F, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"P",48*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x30, 0x0C, 0x18, 0x18, 0x0C, 0x10, 0x0C, 0x30, 0x0C, 0x20, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0xE4, 0x61, 0x2C, 0x33, 0x1C, 0x32, 0x18, 0x16, 0x30, 0x0E, 0xC0, 0x07, 0x00, 0x4C, 0x00, 0x7C, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00}, /*"Q",49*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 0x18, 0x1C, 0x18, 0x38, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x18, 0x18, 0x0C, 0xF8, 0x07, 0x98, 0x03, 0x18, 0x03, 0x18, 0x07, 0x18, 0x06, 0x18, 0x06, 0x18, 0x0E, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x1C, 0x18, 0x18, 0x7E, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"R",50*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x27, 0x30, 0x38, 0x18, 0x30, 0x0C, 0x20, 0x0C, 0x20, 0x0C, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x78, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x38, 0x00, 0x70, 0x00, 0x60, 0x04, 0x60, 0x04, 0x60, 0x08, 0x60, 0x18, 0x30, 0x38, 0x18, 0xC8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"S",51*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x8C, 0x21, 0x84, 0x61, 0x82, 0x41, 0x82, 0x41, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"T",52*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7C, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x08, 0x08, 0x38, 0x04, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"U",53*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0xF8, 0x18, 0x20, 0x18, 0x20, 0x18, 0x20, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x60, 0x08, 0x60, 0x08, 0x60, 0x08, 0xE0, 0x0C, 0xC0, 0x04, 0xC0, 0x04, 0xC0, 0x04, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"V",54*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF3, 0x86, 0x61, 0x86, 0x21, 0x86, 0x21, 0x8C, 0x21, 0x0C, 0x21, 0x8C, 0x23, 0x8C, 0x13, 0x8C, 0x13, 0x8C, 0x13, 0x4C, 0x13, 0x58, 0x12, 0x58, 0x16, 0x58, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x30, 0x0C, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"W",55*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x3E, 0x18, 0x08, 0x38, 0x08, 0x30, 0x04, 0x30, 0x04, 0x70, 0x02, 0x60, 0x02, 0xE0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x03, 0x40, 0x03, 0x40, 0x07, 0x20, 0x06, 0x20, 0x06, 0x10, 0x0C, 0x10, 0x0C, 0x08, 0x18, 0x08, 0x18, 0x3E, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"X",56*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7C, 0x1C, 0x10, 0x18, 0x10, 0x18, 0x08, 0x30, 0x08, 0x30, 0x0C, 0x70, 0x04, 0x60, 0x04, 0x60, 0x02, 0xC0, 0x02, 0xC0, 0x02, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"Y",57*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x18, 0x18, 0x08, 0x18, 0x04, 0x0C, 0x04, 0x0E, 0x00, 0x06, 0x00, 0x07, 0x00, 0x03, 0x80, 0x03, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0x70, 0x00, 0x30, 0x00, 0x38, 0x20, 0x18, 0x20, 0x1C, 0x10, 0x0C, 0x18, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"Z",58*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00}, /*"[",59*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0x60, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x06, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x18, 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x00}, /*"\",60*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00}, /*"]",61*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xC0, 0x06, 0x20, 0x08, 0x10, 0x10, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"^",62*/ + {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, 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, 0xFF, 0xFF}, /*"_",63*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xC0, 0x00, 0x00, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"`",64*/ + {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, 0xF0, 0x03, 0x18, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x0C, 0x80, 0x0F, 0x70, 0x0C, 0x1C, 0x0C, 0x0C, 0x0C, 0x06, 0x0C, 0x06, 0x0C, 0x06, 0x4C, 0x0C, 0x4F, 0xF8, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"a",65*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1E, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x0F, 0xD8, 0x18, 0x38, 0x30, 0x38, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x20, 0x38, 0x30, 0x78, 0x18, 0xC8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"b",66*/ + {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, 0xC0, 0x07, 0x70, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x0C, 0x18, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x20, 0x18, 0x20, 0x18, 0x10, 0x30, 0x08, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"c",67*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1E, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0xE0, 0x1B, 0x30, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x08, 0x18, 0x18, 0x1C, 0x30, 0x7A, 0xE0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"d",68*/ + {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, 0xC0, 0x07, 0x30, 0x0C, 0x18, 0x18, 0x08, 0x10, 0x0C, 0x30, 0x0C, 0x30, 0xFC, 0x3F, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x18, 0x20, 0x18, 0x10, 0x70, 0x18, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"e",69*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x80, 0xC3, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xFC, 0x1F, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"f",70*/ + {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, 0xC0, 0x77, 0x30, 0x6C, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x10, 0x18, 0x30, 0x0C, 0xF0, 0x07, 0x18, 0x00, 0x18, 0x00, 0xF0, 0x0F, 0xF0, 0x3F, 0x08, 0x70, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x38, 0x38, 0xE0, 0x0F}, /*"g",71*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1E, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x98, 0x0F, 0xD8, 0x18, 0x38, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x7E, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"h",72*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"i",73*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x1F, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x18, 0x06, 0xF0, 0x03}, /*"j",74*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1E, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x3E, 0x18, 0x0C, 0x18, 0x06, 0x18, 0x03, 0x18, 0x01, 0x98, 0x01, 0xD8, 0x01, 0x38, 0x03, 0x18, 0x07, 0x18, 0x06, 0x18, 0x0C, 0x18, 0x1C, 0x18, 0x18, 0x7E, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"k",75*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"l",76*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xEE, 0x1C, 0x9C, 0x33, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0xDE, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"m",77*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1E, 0x0F, 0xD8, 0x18, 0x38, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x7E, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"n",78*/ + {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, 0xC0, 0x07, 0x70, 0x1C, 0x10, 0x30, 0x18, 0x30, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x18, 0x30, 0x18, 0x30, 0x30, 0x18, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"o",79*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x9E, 0x0F, 0x58, 0x18, 0x38, 0x30, 0x18, 0x20, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x38, 0x30, 0x78, 0x18, 0x98, 0x07, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x7E, 0x00}, /*"p",80*/ + {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, 0xC0, 0x23, 0x30, 0x3C, 0x18, 0x38, 0x18, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x08, 0x30, 0x18, 0x38, 0x30, 0x3C, 0xE0, 0x33, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xFC}, /*"q",81*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x7E, 0x3C, 0x60, 0x66, 0x60, 0x61, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"r",82*/ + {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, 0xE0, 0x27, 0x30, 0x38, 0x18, 0x30, 0x18, 0x20, 0x18, 0x00, 0x70, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x04, 0x30, 0x04, 0x30, 0x0C, 0x30, 0x1C, 0x18, 0xEC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"s",83*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xFC, 0x1F, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x20, 0xC0, 0x20, 0x80, 0x11, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"t",84*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x1E, 0x3C, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x38, 0x30, 0xF4, 0xE0, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"u",85*/ + {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, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x08, 0x38, 0x08, 0x30, 0x04, 0x30, 0x04, 0x70, 0x02, 0x60, 0x02, 0x60, 0x02, 0xE0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"v",86*/ + {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, 0xDF, 0xF7, 0x8E, 0x63, 0x0C, 0x23, 0x8C, 0x23, 0x8C, 0x23, 0x98, 0x13, 0x98, 0x13, 0x58, 0x16, 0x58, 0x16, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x20, 0x04, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"w",87*/ + {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, 0xFC, 0x3E, 0x70, 0x08, 0x70, 0x04, 0xE0, 0x04, 0xC0, 0x02, 0xC0, 0x01, 0x80, 0x03, 0x80, 0x03, 0x40, 0x07, 0x60, 0x06, 0x20, 0x0C, 0x10, 0x0C, 0x18, 0x18, 0x3E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"x",88*/ + {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, 0x7E, 0x7C, 0x18, 0x18, 0x18, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x04, 0x60, 0x04, 0x60, 0x04, 0xC0, 0x02, 0xC0, 0x02, 0xC0, 0x02, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x4C, 0x00, 0x3C, 0x00}, /*"y",89*/ + {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, 0xFC, 0x1F, 0x0C, 0x0C, 0x04, 0x0E, 0x04, 0x06, 0x00, 0x03, 0x80, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x20, 0x30, 0x20, 0x38, 0x30, 0x1C, 0x18, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"z",90*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x30, 0x00, 0x00}, /*"{",91*/ + {0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, /*"|",92*/ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x01, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00}, /*"}",93*/ + {0x00, 0x00, 0x38, 0x00, 0xC4, 0x00, 0x86, 0x40, 0x02, 0x61, 0x00, 0x22, 0x00, 0x1C, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"~",94*/ +}; +#endif \ No newline at end of file diff --git a/board/dongshanpi-aict/spi_lcd/lcd_init.h b/board/dongshanpi-aict/spi_lcd/lcd_init.h new file mode 100644 index 00000000..2896f6da --- /dev/null +++ b/board/dongshanpi-aict/spi_lcd/lcd_init.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __LCD_INIT_H__ +#define __LCD_INIT_H__ + +#include +#include +#include +#include + +void LCD_Write_Data_Bus(void *dat, uint32_t len); + +void LCD_WR_DATA8(uint8_t dat); + +void LCD_WR_REG(uint8_t dat); + +void LCD_WR_DATA(uint16_t dat); + +void LCD_Address_Set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); + +#endif//__LCD_INIT_H__ \ No newline at end of file diff --git a/board/dongshanpi-aict/spi_lcd/main.c b/board/dongshanpi-aict/spi_lcd/main.c new file mode 100644 index 00000000..d7ba91b1 --- /dev/null +++ b/board/dongshanpi-aict/spi_lcd/main.c @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "sys-dram.h" +#include "sys-dma.h" +#include "sys-spi.h" + +#include "lcd.h" +#include "lcd_init.h" + +#define CONFIG_HEAP_BASE (0x40800000) +#define CONFIG_HEAP_SIZE (16 * 1024 * 1024) + +extern sunxi_serial_t uart_dbg; + +extern dram_para_t dram_para; + +sunxi_spi_t sunxi_spi0_lcd = { + .base = 0x04025000, + .id = 0, + .clk_rate = 120 * 1000 * 1000, + .gpio_cs = {GPIO_PIN(GPIO_PORTC, 1), GPIO_PERIPH_MUX4}, + .gpio_sck = {GPIO_PIN(GPIO_PORTC, 0), GPIO_PERIPH_MUX4}, + .gpio_mosi = {GPIO_PIN(GPIO_PORTC, 2), GPIO_PERIPH_MUX4}, + .gpio_miso = {GPIO_PIN(GPIO_PORTC, 3), GPIO_PERIPH_MUX4}, +}; + +static gpio_mux_t lcd_dc_pins = { + .pin = GPIO_PIN(GPIO_PORTC, 4), + .mux = GPIO_OUTPUT, +}; + +static gpio_mux_t lcd_res_pins = { + .pin = GPIO_PIN(GPIO_PORTC, 5), + .mux = GPIO_OUTPUT, +}; + +static void LCD_Set_DC(uint8_t val) { + sunxi_gpio_set_value(lcd_dc_pins.pin, val); +} + +static void LCD_Set_RES(uint8_t val) { + sunxi_gpio_set_value(lcd_res_pins.pin, val); +} + +static void LCD_Write_Bus(uint8_t dat) { + uint8_t tx[1]; /* Transmit buffer */ + int r; /* Return value */ + + tx[0] = dat; + r = sunxi_spi_transfer(&sunxi_spi0_lcd, SPI_IO_SINGLE, tx, 1, 0, 0); /* Perform SPI transfer */ + if (r < 0) + printk(LOG_LEVEL_ERROR, "SPI: SPI Xfer error!\n"); +} + +void LCD_Write_Data_Bus(void *dat, uint32_t len) { + int r = sunxi_spi_transfer(&sunxi_spi0_lcd, SPI_IO_SINGLE, dat, len, 0, 0); /* Perform SPI transfer */ + if (r < 0) + printk(LOG_LEVEL_ERROR, "SPI: SPI Xfer error!\n"); +} + +void LCD_WR_DATA(uint16_t dat) { + LCD_Write_Bus(dat >> 8); + LCD_Write_Bus(dat); +} + +void LCD_Address_Set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { + LCD_WR_REG(0x2a); + LCD_WR_DATA(x1); + LCD_WR_DATA(x2); + LCD_WR_REG(0x2b); + LCD_WR_DATA(y1); + LCD_WR_DATA(y2); + LCD_WR_REG(0x2c); +} + +void LCD_WR_DATA8(uint8_t dat) { + LCD_Write_Bus(dat); +} + +void LCD_WR_REG(uint8_t dat) { + LCD_Set_DC(0); + LCD_Write_Bus(dat); + LCD_Set_DC(1); +} + +static void LCD_Init(void) { + LCD_Set_RES(0);//复位 + mdelay(100); + LCD_Set_RES(1); + mdelay(100); + + LCD_WR_REG(0x11);//Sleep out + mdelay(120); //Delay 120ms + LCD_WR_REG(0x36); + LCD_WR_DATA8(0x00); + + LCD_WR_REG(0x3A); + LCD_WR_DATA8(0x05); + + LCD_WR_REG(0xB2); + LCD_WR_DATA8(0x1F); + LCD_WR_DATA8(0x1F); + LCD_WR_DATA8(0x00); + LCD_WR_DATA8(0x33); + LCD_WR_DATA8(0x33); + + LCD_WR_REG(0xB7); + LCD_WR_DATA8(0x35); + + LCD_WR_REG(0xBB); + LCD_WR_DATA8(0x20);//2b + + LCD_WR_REG(0xC0); + LCD_WR_DATA8(0x2C); + + LCD_WR_REG(0xC2); + LCD_WR_DATA8(0x01); + + LCD_WR_REG(0xC3); + LCD_WR_DATA8(0x01); + + LCD_WR_REG(0xC4); + LCD_WR_DATA8(0x18);//VDV, 0x20:0v + + LCD_WR_REG(0xC6); + LCD_WR_DATA8(0x13);//0x13:60Hz + + LCD_WR_REG(0xD0); + LCD_WR_DATA8(0xA4); + LCD_WR_DATA8(0xA1); + + LCD_WR_REG(0xD6); + LCD_WR_DATA8(0xA1);//sleep in后,gate输出为GND + + LCD_WR_REG(0xE0); + LCD_WR_DATA8(0xF0); + LCD_WR_DATA8(0x04); + LCD_WR_DATA8(0x07); + LCD_WR_DATA8(0x04); + LCD_WR_DATA8(0x04); + LCD_WR_DATA8(0x04); + LCD_WR_DATA8(0x25); + LCD_WR_DATA8(0x33); + LCD_WR_DATA8(0x3C); + LCD_WR_DATA8(0x36); + LCD_WR_DATA8(0x14); + LCD_WR_DATA8(0x12); + LCD_WR_DATA8(0x29); + LCD_WR_DATA8(0x30); + + LCD_WR_REG(0xE1); + LCD_WR_DATA8(0xF0); + LCD_WR_DATA8(0x02); + LCD_WR_DATA8(0x04); + LCD_WR_DATA8(0x05); + LCD_WR_DATA8(0x05); + LCD_WR_DATA8(0x21); + LCD_WR_DATA8(0x25); + LCD_WR_DATA8(0x32); + LCD_WR_DATA8(0x3B); + LCD_WR_DATA8(0x38); + LCD_WR_DATA8(0x12); + LCD_WR_DATA8(0x14); + LCD_WR_DATA8(0x27); + LCD_WR_DATA8(0x31); + + LCD_WR_REG(0xE4); + LCD_WR_DATA8(0x1D);//使用240根gate (N+1)*8 + LCD_WR_DATA8(0x00);//设定gate起点位置 + LCD_WR_DATA8(0x00);//当gate没有用完时,bit4(TMG)设为0 + + LCD_WR_REG(0x21); + + LCD_WR_REG(0x29); +} + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_clk_init(); + + uint64_t dram_size = sunxi_dram_init(&dram_para); + arm32_mmu_enable(SDRAM_BASE, dram_size); + + printk(LOG_LEVEL_DEBUG, "enable mmu ok\n"); + + smalloc_init(CONFIG_HEAP_BASE, CONFIG_HEAP_SIZE); + + printk(LOG_LEVEL_INFO, "Hello World!\n"); + + sunxi_gpio_init(lcd_dc_pins.pin, lcd_dc_pins.mux); + sunxi_gpio_init(lcd_res_pins.pin, lcd_res_pins.mux); + + dma_init(); + + if (sunxi_spi_init(&sunxi_spi0_lcd) != 0) { + printk(LOG_LEVEL_ERROR, "SPI: init failed\n"); + } + + LCD_Init(); + + LCD_Fill_All(WHITE); + + LCD_ShowString(0, 40, "LCD_W:", RED, WHITE, 16, 0); + + LCD_ShowIntNum(48, 40, LCD_W, 3, RED, WHITE, 16); + + LCD_ShowString(80, 40, "LCD_H:", RED, WHITE, 16, 0); + + LCD_ShowIntNum(128, 40, LCD_H, 3, RED, WHITE, 16); + + LCD_ShowString(80, 40, "LCD_H:", RED, WHITE, 16, 0); + + LCD_ShowString(0, 80, "LCD ST7789V2", BLUE, WHITE, 32, 0); + + LCD_ShowString(0, 160, "SyterKit", BLACK, WHITE, 32, 0); + + LCD_ShowString(0, 240, "1.0.2", BLACK, WHITE, 32, 0); + + sunxi_spi_disable(&sunxi_spi0_lcd); + + arm32_mmu_disable(); + + clean_syterkit_data(); + + sunxi_clk_reset(); + + jmp_to_fel(); + + return 0; +} \ No newline at end of file diff --git a/board/dongshanpi-aict/start.S b/board/dongshanpi-aict/start.S new file mode 100644 index 00000000..6b32a13f --- /dev/null +++ b/board/dongshanpi-aict/start.S @@ -0,0 +1,225 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +.macro save_regs + str lr, [sp, #-4] + mrs lr, spsr_all + str lr, [sp, #-8] + str r1, [sp, #-12] + str r0, [sp, #-16] + mov r0, sp + cps #0x13 + ldr r1, [r0, #-4] + str r1, [sp, #-4]! + ldr r1, [r0, #-8] + str r1, [sp, #-(4 * 16)] + ldr r1, [r0, #-12] + ldr r0, [r0, #-16] + stmdb sp, {r0 - r14}^ + sub sp, sp, #(4 * 16) + ldr r4, [sp] + and r0, r4, #0x1f + cmp r0, #0x10 + beq 10f + cmp r0, #0x13 + beq 11f + b . +11: add r1, sp, #(4 * 17) + str r1, [sp, #(4 * 14)] + str lr, [sp, #(4 * 15)] +10: add r1, sp, #(4 * 17) + str r1, [sp, #-4]! + mov r0, sp +.endm + +.macro restore_regs + mov r12, sp + ldr sp, [r12], #4 + ldr r1, [r12], #4 + msr spsr_cxsf, r1 + and r0, r1, #0x1f + cmp r0, #0x10 + beq 20f + cmp r0, #0x13 + beq 21f + b . +20: ldr lr, [r12, #(4 * 15)] + ldmia r12, {r0 - r14}^ + movs pc, lr +21: ldm r12, {r0 - r15}^ + mov r0, r0 +.endm + +#define ARMV7_USR_MODE 0x10 +#define ARMV7_FIQ_MODE 0x11 +#define ARMV7_IRQ_MODE 0x12 +#define ARMV7_SVC_MODE 0x13 +#define ARMV7_MON_MODE 0x16 +#define ARMV7_ABT_MODE 0x17 +#define ARMV7_UND_MODE 0x1b +#define ARMV7_SYSTEM_MODE 0x1f +#define ARMV7_MODE_MASK 0x1f +#define ARMV7_FIQ_MASK 0x40 +#define ARMV7_IRQ_MASK 0x80 + +.arm +.globl _start +.text + +_start: + /* Boot head information for BROM */ + .long 0xea000016 + .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' + .long 0x12345678 /* checksum */ + .long __spl_size /* spl size */ + .long 0x30 /* boot header size */ + .long 0x30303033 /* boot header version */ + .long 0x00020000 /* return value */ + .long 0x00028000 /* run address */ + .long 0x0 /* eGON version */ + .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ + .byte 0x34, 0x2e, 0x30, 0x00 + + .align 5 +_vector: + b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: + .word undefined_instruction +_software_interrupt: + .word software_interrupt +_prefetch_abort: + .word prefetch_abort +_data_abort: + .word data_abort +_not_used: + .word not_used +_irq: + .word irq +_fiq: + .word fiq + +reset: + /* Enter svc mode cleanly and mask interrupts */ + mrs r0, cpsr + bic r0, r0, #ARMV7_MODE_MASK + orr r0, r0, #ARMV7_SVC_MODE + orr r0, r0, #(ARMV7_IRQ_MASK | ARMV7_FIQ_MASK) + bic r0, r0, #(1<<9) @set little-endian + msr cpsr_c, r0 + + /* Set vector base address register */ + ldr r0, =_vector + mcr p15, 0, r0, c12, c0, 0 + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1 << 13) + mcr p15, 0, r0, c1, c0, 0 + + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache + mcr p15, 0, r0, c1, c0, 0 + + /* Enable neon/vfp unit */ + mrc p15, 0, r0, c1, c0, 2 + orr r0, r0, #(0xf << 20) + mcr p15, 0, r0, c1, c0, 2 + isb + mov r0, #0x40000000 + vmsr fpexc, r0 + + /* Set stack pointer */ + ldr sp, =__stack_srv_end + + bl clear_bss + + /* + * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, + * except if in HYP mode already + */ + mrs r0, cpsr + and r1, r0, #0x1f @ mask mode bits + teq r1, #0x1a @ test for HYP mode + bicne r0, r0, #0x1f @ clear all mode bits + orrne r0, r0, #0x13 @ set SVC mode + orr r0, r0, #0xc0 @ disable FIQ and IRQ + msr cpsr,r0 + + @set cntfrq to 24M + ldr r0, =24000000 + mcr p15, 0, r0, c14, c0, 0 + + bl set_timer_count + + bl main + +clear_bss: + ldr r0, =_sbss + ldr r1, =_ebss + mov r2, #0 + +clbss_1: + stmia r0!, {r2} + cmp r0, r1 + blt clbss_1 + + mov pc, lr + + /* + * Exception handlers + */ + .align 5 +undefined_instruction: + sub lr, lr, #4 + save_regs + bl arm32_do_undefined_instruction + restore_regs + + .align 5 +software_interrupt: + sub lr, lr, #4 + save_regs + bl arm32_do_software_interrupt + restore_regs + + .align 5 +prefetch_abort: + sub lr, lr, #4 + save_regs + bl arm32_do_prefetch_abort + restore_regs + + .align 5 +data_abort: + sub lr, lr, #8 + save_regs + bl arm32_do_data_abort + restore_regs + + .align 5 +not_used: + b . + + .align 5 +irq: + sub lr, lr, #4 + save_regs + bl arm32_do_irq + restore_regs + + .align 5 +fiq: + sub lr, lr, #4 + save_regs + bl arm32_do_fiq + restore_regs diff --git a/board/dongshanpi-aict/syter_amp/CMakeLists.txt b/board/dongshanpi-aict/syter_amp/CMakeLists.txt new file mode 100644 index 00000000..317a0987 --- /dev/null +++ b/board/dongshanpi-aict/syter_amp/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(syter_amp + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/syter_amp/main.c b/board/dongshanpi-aict/syter_amp/main.c new file mode 100644 index 00000000..a84259d3 --- /dev/null +++ b/board/dongshanpi-aict/syter_amp/main.c @@ -0,0 +1,289 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "sys-dram.h" +#include "sys-sdcard.h" +#include "sys-sid.h" +#include "sys-spi.h" + +#include "libfdt.h" +#include "ff.h" + +#define CONFIG_KERNEL_FILENAME "zImage" +#define CONFIG_DTB_FILENAME "sunxi.dtb" +#define CONFIG_RISCV_ELF_FILENAME "e907.elf" + +#define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) + +#define CONFIG_RISCV_ELF_LOADADDR (0x40008000) +#define CONFIG_DTB_LOAD_ADDR (0x41008000) +#define CONFIG_KERNEL_LOAD_ADDR (0x41800000) + +// 128KB erase sectors, so place them starting from 2nd sector +#define CONFIG_SPINAND_DTB_ADDR (128 * 2048) +#define CONFIG_SPINAND_KERNEL_ADDR (256 * 2048) + +#define FILENAME_MAX_LEN 64 +typedef struct { + unsigned int offset; + unsigned char *dest; + + unsigned int of_offset; + unsigned char *of_dest; + + unsigned int elf_offset; + unsigned char *elf_dest; + + char filename[FILENAME_MAX_LEN]; + char of_filename[FILENAME_MAX_LEN]; + char elf_filename[FILENAME_MAX_LEN]; +} image_info_t; + +/* Linux zImage Header */ +#define LINUX_ZIMAGE_MAGIC 0x016f2818 +typedef struct { + unsigned int code[9]; + unsigned int magic; + unsigned int start; + unsigned int end; +} linux_zimage_header_t; + +extern sunxi_serial_t uart_dbg; + +extern dram_para_t dram_para; + +sunxi_serial_t uart_e907 = { + .base = 0x02500C00, + .id = 3, + .gpio_tx = {GPIO_PIN(GPIO_PORTE, 0), GPIO_PERIPH_MUX7}, + .gpio_rx = {GPIO_PIN(GPIO_PORTE, 1), GPIO_PERIPH_MUX7}, +}; + +extern sunxi_spi_t sunxi_spi0; + +extern sdhci_t sdhci0; + +image_info_t image; + +unsigned int code[9]; +unsigned int magic; +unsigned int start; +unsigned int end; + +static int boot_image_setup(unsigned char *addr, unsigned int *entry) { + linux_zimage_header_t *zimage_header = (linux_zimage_header_t *) addr; + + printk(LOG_LEVEL_INFO, "Linux zImage->code = 0x"); + for (int i = 0; i < 9; i++) + printk(LOG_LEVEL_MUTE, "%x", code[i]); + + printk(LOG_LEVEL_MUTE, "\n"); + printk(LOG_LEVEL_DEBUG, "Linux zImage->magic = 0x%x\n", zimage_header->magic); + printk(LOG_LEVEL_DEBUG, "Linux zImage->start = 0x%x\n", (unsigned int) addr + zimage_header->start); + printk(LOG_LEVEL_DEBUG, "Linux zImage->end = 0x%x\n", (unsigned int) addr + zimage_header->end); + + if (zimage_header->magic == LINUX_ZIMAGE_MAGIC) { + *entry = ((unsigned int) addr + zimage_header->start); + return 0; + } + + printk(LOG_LEVEL_ERROR, "unsupported kernel image\n"); + + return -1; +} + +#define CHUNK_SIZE 0x20000 + +static int fatfs_loadimage(char *filename, BYTE *dest) { + FIL file; + UINT byte_to_read = CHUNK_SIZE; + UINT byte_read; + UINT total_read = 0; + FRESULT fret; + int ret; + uint32_t start, time; + + fret = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: open, filename: [%s]: error %d\n", filename, fret); + ret = -1; + goto open_fail; + } + + start = time_ms(); + + do { + byte_read = 0; + fret = f_read(&file, (void *) (dest), byte_to_read, &byte_read); + dest += byte_to_read; + total_read += byte_read; + } while (byte_read >= byte_to_read && fret == FR_OK); + + time = time_ms() - start + 1; + + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: read: error %d\n", fret); + ret = -1; + goto read_fail; + } + ret = 0; + +read_fail: + fret = f_close(&file); + + printk(LOG_LEVEL_DEBUG, "FATFS: read in %ums at %.2fMB/S\n", time, (f32) (total_read / time) / 1024.0f); + +open_fail: + return ret; +} + +static int load_sdcard(image_info_t *image) { + FATFS fs; + FRESULT fret; + int ret; + uint32_t start; + + uint32_t test_time; + start = time_ms(); + sdmmc_blk_read(&card0, (uint8_t *) (SDRAM_BASE), 0, + CONFIG_SDMMC_SPEED_TEST_SIZE); + test_time = time_ms() - start; + printk(LOG_LEVEL_DEBUG, "SDMMC: speedtest %uKB in %ums at %uKB/S\n", + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / 1024, test_time, + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / test_time); + + start = time_ms(); + + fret = f_mount(&fs, "", 1); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: mount error: %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: mount OK\n"); + } + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->of_filename, (unsigned int) image->of_dest); + ret = fatfs_loadimage(image->of_filename, image->of_dest); + if (ret) + return ret; + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->filename, (unsigned int) image->dest); + ret = fatfs_loadimage(image->filename, image->dest); + if (ret) + return ret; + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->elf_filename, (unsigned int) image->elf_dest); + ret = fatfs_loadimage(image->elf_filename, image->elf_dest); + if (ret) + return ret; + + /* umount fs */ + fret = f_mount(0, "", 0); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: unmount error %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: unmount OK\n"); + } + printk(LOG_LEVEL_DEBUG, "FATFS: done in %ums\n", time_ms() - start); + + return 0; +} + + + +int main(void) { + sunxi_serial_init(&uart_dbg); + + sunxi_serial_init(&uart_e907); + + show_banner(); + + sunxi_clk_init(); + + sunxi_dram_init(&dram_para); + + unsigned int entry_point = 0; + void (*kernel_entry)(int zero, int arch, unsigned int params); + + sunxi_clk_dump(); + + memset(&image, 0, sizeof(image_info_t)); + + image.of_dest = (uint8_t *) CONFIG_DTB_LOAD_ADDR; + image.dest = (uint8_t *) CONFIG_KERNEL_LOAD_ADDR; + image.elf_dest = (uint8_t *) CONFIG_RISCV_ELF_LOADADDR; + + strcpy(image.filename, CONFIG_KERNEL_FILENAME); + strcpy(image.of_filename, CONFIG_DTB_FILENAME); + strcpy(image.elf_filename, CONFIG_RISCV_ELF_FILENAME); + + if (sunxi_sdhci_init(&sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: %s controller init failed\n", sdhci0.name); + } else { + printk(LOG_LEVEL_INFO, "SMHC: %s controller v%x initialized\n", sdhci0.name, sdhci0.reg->vers); + } + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_WARNING, "SMHC: init failed, back to FEL\n"); + } + + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_WARNING, "SMHC: loading failed, back to FEL\n"); + goto _fel; + } + + sunxi_e907_clock_reset(); + + uint32_t elf_run_addr = elf32_get_entry_addr((phys_addr_t) image.dest); + printk(LOG_LEVEL_INFO, "RISC-V ELF run addr: 0x%08x\n", elf_run_addr); + + if (load_elf32_image((phys_addr_t) image.dest)) { + printk(LOG_LEVEL_ERROR, "RISC-V ELF load FAIL\n"); + } + + sunxi_e907_clock_init(elf_run_addr); + + dump_e907_clock(); + + printk(LOG_LEVEL_INFO, "RISC-V E907 Core now Running... \n"); + + if (boot_image_setup((unsigned char *) image.dest, &entry_point)) { + printk(LOG_LEVEL_ERROR, "boot setup failed\n"); + goto _fel; + } + + printk(LOG_LEVEL_INFO, "booting linux...\n"); + + arm32_mmu_disable(); + printk(LOG_LEVEL_INFO, "disable mmu ok...\n"); + arm32_dcache_disable(); + printk(LOG_LEVEL_INFO, "disable dcache ok...\n"); + arm32_icache_disable(); + printk(LOG_LEVEL_INFO, "disable icache ok...\n"); + arm32_interrupt_disable(); + printk(LOG_LEVEL_INFO, "free interrupt ok...\n"); + enable_kernel_smp(); + printk(LOG_LEVEL_INFO, "enable kernel smp ok...\n"); + + printk(LOG_LEVEL_INFO, "jump to kernel address: 0x%x\n", image.dest); + + kernel_entry = (void (*)(int, int, unsigned int)) entry_point; + kernel_entry(0, ~0, (unsigned int) image.of_dest); + + // if kernel boot not success, jump to fel. +_fel: + jmp_to_fel(); + + return 0; +} diff --git a/board/dongshanpi-aict/syter_boot/CMakeLists.txt b/board/dongshanpi-aict/syter_boot/CMakeLists.txt new file mode 100644 index 00000000..5bfbb5f4 --- /dev/null +++ b/board/dongshanpi-aict/syter_boot/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(syter_boot + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/syter_boot/main.c b/board/dongshanpi-aict/syter_boot/main.c new file mode 100644 index 00000000..31ddf62a --- /dev/null +++ b/board/dongshanpi-aict/syter_boot/main.c @@ -0,0 +1,698 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "sys-dram.h" +#include "sys-rtc.h" +#include "sys-sdcard.h" +#include "sys-sid.h" +#include "sys-spi.h" + +#include "fdt_wrapper.h" +#include "ff.h" +#include "libfdt.h" +#include "uart.h" + +#define CONFIG_KERNEL_FILENAME "zImage" +#define CONFIG_DTB_FILENAME "sunxi.dtb" +#define CONFIG_CONFIG_FILENAME "config.txt" + +#define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) + +#define CONFIG_DTB_LOAD_ADDR (0x41008000) +#define CONFIG_KERNEL_LOAD_ADDR (0x41800000) +#define CONFIG_CONFIG_LOAD_ADDR (0x40008000) +#define CONFIG_HEAP_BASE (0x40800000) +#define CONFIG_HEAP_SIZE (16 * 1024 * 1024) + +#define CONFIG_DEFAULT_BOOTDELAY 5 + +#define FILENAME_MAX_LEN 64 +typedef struct { + uint8_t *dest; + + uint8_t *of_dest; + + uint8_t *config_dest; + uint8_t is_config; + + char filename[FILENAME_MAX_LEN]; + + char of_filename[FILENAME_MAX_LEN]; + + char config_filename[FILENAME_MAX_LEN]; +} image_info_t; + +#define MAX_SECTION_LEN 16 +#define MAX_KEY_LEN 16 +#define MAX_VALUE_LEN 512 +#define CONFIG_MAX_ENTRY 3 + +typedef struct { + char section[MAX_SECTION_LEN]; + char key[MAX_KEY_LEN]; + char value[MAX_VALUE_LEN]; +} IniEntry; + +IniEntry entries[CONFIG_MAX_ENTRY]; + +/* Linux zImage Header */ +#define LINUX_ZIMAGE_MAGIC 0x016f2818 +typedef struct { + uint32_t code[9]; + uint32_t magic; + uint32_t start; + uint32_t end; +} linux_zimage_header_t; + +extern sunxi_serial_t uart_dbg; + +extern sunxi_spi_t sunxi_spi0; + +extern sdhci_t sdhci0; + +extern dram_para_t dram_para; + +image_info_t image; + +uint32_t code[9]; +uint32_t magic; +uint32_t start; +uint32_t end; + +static int boot_image_setup(uint8_t *addr, uint32_t *entry) { + linux_zimage_header_t *zimage_header = (linux_zimage_header_t *) addr; + + printk(LOG_LEVEL_INFO, "Linux zImage->code = 0x"); + for (int i = 0; i < 9; i++) + printk(LOG_LEVEL_MUTE, "%x", code[i]); + + printk(LOG_LEVEL_MUTE, "\n"); + printk(LOG_LEVEL_DEBUG, "Linux zImage->magic = 0x%x\n", + zimage_header->magic); + printk(LOG_LEVEL_DEBUG, "Linux zImage->start = 0x%x\n", + (uint32_t) addr + zimage_header->start); + printk(LOG_LEVEL_DEBUG, "Linux zImage->end = 0x%x\n", + (uint32_t) addr + zimage_header->end); + + if (zimage_header->magic == LINUX_ZIMAGE_MAGIC) { + *entry = ((uint32_t) addr + zimage_header->start); + return 0; + } + + printk(LOG_LEVEL_ERROR, "unsupported kernel image\n"); + + return -1; +} + +#define CHUNK_SIZE 0x20000 + +static int fatfs_loadimage(char *filename, BYTE *dest) { + FIL file; + UINT byte_to_read = CHUNK_SIZE; + UINT byte_read; + UINT total_read = 0; + FRESULT fret; + int ret = 1; + uint32_t start, time; + + fret = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: open, filename: [%s]: error %d\n", filename, fret); + ret = -1; + goto open_fail; + } + + start = time_ms(); + + do { + byte_read = 0; + fret = f_read(&file, (void *) (dest), byte_to_read, &byte_read); + dest += byte_to_read; + total_read += byte_read; + } while (byte_read >= byte_to_read && fret == FR_OK); + + time = time_ms() - start + 1; + + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: read: error %d\n", fret); + ret = -1; + goto read_fail; + } + ret = 0; + +read_fail: + fret = f_close(&file); + + printk(LOG_LEVEL_INFO, "FATFS: read in %ums at %.2fMB/S\n", time, + (f32) (total_read / time) / 1024.0f); + +open_fail: + return ret; +} + +static int load_sdcard(image_info_t *image) { + FATFS fs; + FRESULT fret; + int ret; + uint32_t start; + + uint32_t test_time; + start = time_ms(); + sdmmc_blk_read(&card0, (uint8_t *) (SDRAM_BASE), 0, CONFIG_SDMMC_SPEED_TEST_SIZE); + test_time = time_ms() - start; + printk(LOG_LEVEL_DEBUG, "SDMMC: speedtest %uKB in %ums at %uKB/S\n", + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / 1024, test_time, + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / test_time); + + start = time_ms(); + + fret = f_mount(&fs, "", 1); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: mount error: %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: mount OK\n"); + } + + /* load DTB */ + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->of_filename, (uint32_t) image->of_dest); + ret = fatfs_loadimage(image->of_filename, image->of_dest); + if (ret) + return ret; + + /* load Kernel */ + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->filename, (uint32_t) image->dest); + ret = fatfs_loadimage(image->filename, image->dest); + if (ret) + return ret; + + /* load config */ + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->config_filename, (uint32_t) image->config_dest); + ret = fatfs_loadimage(image->config_filename, image->config_dest); + if (ret) { + printk(LOG_LEVEL_INFO, "CONFIG: Cannot find config file, Using default config.\n"); + image->is_config = 0; + } else { + image->is_config = 1; + } + + /* umount fs */ + fret = f_mount(0, "", 0); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: unmount error %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: unmount OK\n"); + } + printk(LOG_LEVEL_INFO, "FATFS: done in %ums\n", time_ms() - start); + + return 0; +} + +static void trim(char *str) { + int len = strlen(str); + while (len > 0 && (str[len - 1] == ' ' || str[len - 1] == '\n' || str[len - 1] == '\r')) { + str[--len] = '\0'; + } + while (*str && (*str == ' ' || *str == '\n' || *str == '\r')) { + ++str; + --len; + } +} + +static int parse_ini_data(const char *data, size_t size, IniEntry *entries, int max_entries) { + char line[MAX_VALUE_LEN]; + char current_section[MAX_SECTION_LEN] = ""; + int entry_count = 0; + + const char *p = data; + const char *end = data + size; + + while (p < end) { + /* Read a line of data */ + size_t len = 0; + while (p + len < end && *(p + len) != '\n') { + ++len; + } + if (p + len < end && *(p + len) == '\n') { + ++len; + } + if (len > 0) { + strncpy(line, p, len); + line[len] = '\0'; + p += len; + + trim(line); + + /* Ignore empty lines and comments */ + if (line[0] == '\0' || line[0] == ';' || line[0] == '#') { + continue; + } + + /* Parse the section name */ + if (line[0] == '[' && line[strlen(line) - 1] == ']') { + strncpy(current_section, &line[1], strlen(line) - 2); + current_section[strlen(line) - 2] = '\0'; + continue; + } + + /* Parse key-value pairs */ + char *pos = strchr(line, '='); + if (pos != NULL) { + char *key_start = line; + char *value_start = pos + 1; + *pos = '\0'; + trim(key_start); + trim(value_start); + + if (strlen(current_section) > 0 && strlen(key_start) > 0 && strlen(value_start) > 0) { + if (entry_count >= max_entries) { + printk(LOG_LEVEL_ERROR, "INI: Too many entries!\n"); + break; + } + strncpy(entries[entry_count].section, current_section, MAX_SECTION_LEN - 1); + strncpy(entries[entry_count].key, key_start, MAX_KEY_LEN - 1); + strncpy(entries[entry_count].value, value_start, MAX_VALUE_LEN - 1); + ++entry_count; + } + } + } + } + + return entry_count; +} + +static const char *find_entry_value(const IniEntry *entries, int entry_count, const char *section, const char *key) { + for (int i = 0; i < entry_count; ++i) { + if (strcmp(entries[i].section, section) == 0 && strcmp(entries[i].key, key) == 0) { + return entries[i].value; + } + } + return NULL; +} + +static int update_bootargs_from_config(uint64_t dram_size) { + int ret = 0; + char *bootargs_str_config = NULL; + char *mac_addr = NULL; + + /* Check if using config file, get bootargs in the config file */ + if (image.is_config) { + size_t size_a = strlen(image.config_dest); + int entry_count = parse_ini_data(image.config_dest, size_a, entries, CONFIG_MAX_ENTRY); + for (int i = 0; i < entry_count; ++i) { + /* Print parsed INI entries */ + printk(LOG_LEVEL_DEBUG, "INI: [%s] %s = %s\n", entries[i].section, entries[i].key, entries[i].value); + } + bootargs_str_config = find_entry_value(entries, entry_count, "configs", "bootargs"); + mac_addr = find_entry_value(entries, entry_count, "configs", "mac_addr"); + } + + /* Force image.dest to be a pointer to fdt_header structure */ + struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; + + /* Check if DTB header is valid */ + if ((ret = fdt_check_header(dtb_header)) != 0) { + printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(ret)); + return -1; + } + + /* Get the total size of DTB */ + uint32_t size = fdt_totalsize(image.of_dest); + printk(LOG_LEVEL_DEBUG, "%s: FDT Size = %d\n", image.of_filename, size); + + int len = 0; + /* Get the offset of "/chosen" node */ + uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); + + /* Get bootargs string */ + char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); + + /* If config file read fail or not using */ + if (bootargs_str_config == NULL) { + printk(LOG_LEVEL_WARNING, "INI: Cannot parse bootargs, using default bootargs in DTB.\n"); + bootargs_str_config = bootargs_str; + } + + /* update mac address of board */ + if (mac_addr != NULL) { + strcat(bootargs_str_config, " mac_addr="); + strcat(bootargs_str_config, mac_addr); + } + + /* Add dram size to dtb */ + char dram_size_str[8]; + strcat(bootargs_str_config, " mem="); + strcat(bootargs_str_config, ltoa(dram_size, dram_size_str, 10)); + strcat(bootargs_str_config, "M"); + + /* Set bootargs based on the configuration file */ + printk(LOG_LEVEL_DEBUG, "INI: Set bootargs to %s\n", bootargs_str_config); + +_add_dts_size: + /* Modify bootargs string */ + ret = fdt_setprop(image.of_dest, bootargs_node, "bootargs", bootargs_str_config, strlen(bootargs_str_config) + 1); + if (ret == -FDT_ERR_NOSPACE) { + printk(LOG_LEVEL_DEBUG, "FDT: FDT_ERR_NOSPACE, Size = %d, Increase Size = %d\n", size, 512); + ret = fdt_increase_size(image.of_dest, 512); + if (!ret) + goto _add_dts_size; + else + goto _err_size; + } else if (ret < 0) { + printk(LOG_LEVEL_ERROR, "Can't change bootargs node: %s\n", fdt_strerror(ret)); + return -1; + } + + /* Get the total size of DTB */ + printk(LOG_LEVEL_DEBUG, "Modify FDT Size = %d\n", fdt_totalsize(image.of_dest)); + + if (ret < 0) { + printk(LOG_LEVEL_ERROR, "libfdt fdt_setprop() error: %s\n", fdt_strerror(ret)); + return -1; + } + + return 0; +_err_size: + printk(LOG_LEVEL_ERROR, "DTB: Can't increase blob size: %s\n", fdt_strerror(ret)); + return -1; +} + +static int abortboot_single_key(int bootdelay) { + int abort = 0; + unsigned long ts; + + printk(LOG_LEVEL_INFO, "Hit any key to stop autoboot: %2d ", bootdelay); + + /* Check if key already pressed */ + if (tstc()) { /* we got a key press */ + uart_getchar(); /* consume input */ + printk(LOG_LEVEL_MUTE, "\b\b\b%2d", bootdelay); + abort = 1; /* don't auto boot */ + } + + while ((bootdelay > 0) && (!abort)) { + --bootdelay; + /* delay 1000 ms */ + ts = time_ms(); + do { + if (tstc()) { /* we got a key press */ + abort = 1; /* don't auto boot */ + break; + } + udelay(10000); + } while (!abort && time_ms() - ts < 1000); + printk(LOG_LEVEL_MUTE, "\b\b\b%2d ", bootdelay); + } + uart_putchar('\n'); + return abort; +} + +msh_declare_command(bootargs); +msh_define_help(bootargs, "get/set bootargs for kernel", + "Usage: bootargs set \"bootargs\" - set new bootargs for zImage\n" + " bootargs get - get current bootargs\n"); +int cmd_bootargs(int argc, const char **argv) { + int err = 0; + + if (argc < 2) { + uart_puts(cmd_bootargs_usage); + return 0; + } + + if (strncmp(argv[1], "set", 3) == 0) { + if (argc != 3) { + uart_puts(cmd_bootargs_usage); + return 0; + } + /* Force image.of_dest to be a pointer to fdt_header structure */ + struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; + + /* Check if DTB header is valid */ + if ((err = fdt_check_header(dtb_header)) != 0) { + printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); + return 0; + } + + int len = 0; + /* Get the offset of "/chosen" node */ + uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); + + /* Get bootargs string */ + char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_MUTE, "DTB OLD bootargs = \"%s\"\n", bootargs_str); + + /* New bootargs string */ + char *new_bootargs_str = argv[2]; + printk(LOG_LEVEL_MUTE, "Now set bootargs to \"%s\"\n", new_bootargs_str); + + _add_dts_size: + /* Modify bootargs string */ + err = fdt_setprop(image.of_dest, bootargs_node, "bootargs", new_bootargs_str, strlen(new_bootargs_str) + 1); + if (err == -FDT_ERR_NOSPACE) { + printk(LOG_LEVEL_DEBUG, "FDT: FDT_ERR_NOSPACE, Increase Size = %d\n", 512); + err = fdt_increase_size(image.of_dest, 512); + if (!err) + goto _add_dts_size; + else + goto _err_size; + } else if (err < 0) { + printk(LOG_LEVEL_ERROR, "Can't change bootargs node: %s\n", fdt_strerror(err)); + abort(); + } + + /* Get updated bootargs string */ + char *updated_bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_MUTE, "DTB NEW bootargs = \"%s\"\n", updated_bootargs_str); + } else if (strncmp(argv[1], "get", 3) == 0) { + /* Force image.of_dest to be a pointer to fdt_header structure */ + struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; + + int err = 0; + + /* Check if DTB header is valid */ + if ((err = fdt_check_header(dtb_header)) != 0) { + printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); + return 0; + } + + int len = 0; + /* Get the offset of "/chosen" node */ + uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); + + /* Get bootargs string */ + char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_MUTE, "DTB bootargs = \"%s\"\n", bootargs_str); + } else { + uart_puts(cmd_bootargs_usage); + } + return 0; + +_err_size: + printk(LOG_LEVEL_ERROR, "DTB: Can't increase blob size: %s\n", fdt_strerror(err)); + abort(); +} + +msh_declare_command(reload); +msh_define_help(reload, "rescan TF Card and reload DTB, Kernel zImage", "Usage: reload\n"); +int cmd_reload(int argc, const char **argv) { + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: init failed\n"); + return 0; + } + + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: loading failed\n"); + return 0; + } + return 0; +} + +msh_declare_command(print); +msh_define_help(print, "print out env config", "Usage: print\n"); +int cmd_print(int argc, const char **argv) { + if (image.is_config) { + size_t size_a = strlen(image.config_dest); + int entry_count = parse_ini_data(image.config_dest, size_a, entries, CONFIG_MAX_ENTRY); + for (int i = 0; i < entry_count; ++i) { + /* Print parsed INI entries */ + printk(LOG_LEVEL_MUTE, "ENV: [%s] %s = %s\n", entries[i].section, entries[i].key, entries[i].value); + } + } else { + printk(LOG_LEVEL_WARNING, "ENV: Can not find env file\n"); + } + return 0; +} + +msh_declare_command(boot); +msh_define_help(boot, "boot to linux", "Usage: boot\n"); +int cmd_boot(int argc, const char **argv) { + /* Initialize variables for kernel entry point and SD card access. */ + uint32_t entry_point = 0; + void (*kernel_entry)(int zero, int arch, uint32_t params); + + /* Set up boot parameters for the kernel. */ + if (boot_image_setup((uint8_t *) image.dest, &entry_point)) { + printk(LOG_LEVEL_ERROR, "boot setup failed\n"); + abort(); + } + + /* Disable MMU, data cache, instruction cache, interrupts */ + clean_syterkit_data(); + + enable_kernel_smp(); + printk(LOG_LEVEL_INFO, "enable kernel smp ok...\n"); + + /* Debug message to indicate the kernel address that the system is jumping to. */ + printk(LOG_LEVEL_INFO, "jump to kernel address: 0x%x\n\n", image.dest); + + /* Jump to the kernel entry point. */ + kernel_entry = (void (*)(int, int, uint32_t)) entry_point; + kernel_entry(0, ~0, (uint32_t) image.of_dest); + + // if kernel boot not success, jump to fel. + jmp_to_fel(); + return 0; +} + +const msh_command_entry commands[] = { + msh_define_command(bootargs), + msh_define_command(reload), + msh_define_command(boot), + msh_define_command(print), + msh_command_end, +}; + +/* + * main function for the bootloader. Initializes and sets up the system, loads the kernel and device tree binary from + * an SD card, sets boot arguments, and boots the kernel. If the kernel fails to boot, the function jumps to FEL mode. + */ +int main(void) { + /* Initialize the debug serial interface. */ + sunxi_serial_init(&uart_dbg); + + /* Display the bootloader banner. */ + show_banner(); + + /* Initialize the system clock. */ + sunxi_clk_init(); + + /* Check rtc fel flag. if set flag, goto fel */ + if (rtc_probe_fel_flag()) { + printk(LOG_LEVEL_INFO, "RTC: get fel flag, jump to fel mode.\n"); + clean_syterkit_data(); + rtc_clear_fel_flag(); + sunxi_clk_reset(); + mdelay(100); + goto _fel; + } + + /* Initialize the DRAM and enable memory management unit (MMU). */ + uint64_t dram_size = sunxi_dram_init(&dram_para); + arm32_mmu_enable(SDRAM_BASE, dram_size); + + /* Debug message to indicate that MMU is enabled. */ + printk(LOG_LEVEL_DEBUG, "enable mmu ok\n"); + + /* Initialize the small memory allocator. */ + smalloc_init(CONFIG_HEAP_BASE, CONFIG_HEAP_SIZE); + + /* Set up Real-Time Clock (RTC) hardware. */ + rtc_set_vccio_det_spare(); + + /* Check if system voltage is within limits. */ + sys_ldo_check(); + + /* Dump information about the system clocks. */ + sunxi_clk_dump(); + + /* Clear the image_info_t struct. */ + memset(&image, 0, sizeof(image_info_t)); + + /* Set the destination address for the device tree binary (DTB), kernel image, and configuration data. */ + image.of_dest = (uint8_t *) CONFIG_DTB_LOAD_ADDR; + image.dest = (uint8_t *) CONFIG_KERNEL_LOAD_ADDR; + image.config_dest = (uint8_t *) CONFIG_CONFIG_LOAD_ADDR; + image.is_config = 0; + + /* Copy the filenames for the DTB, kernel image, and configuration data. */ + strcpy(image.filename, CONFIG_KERNEL_FILENAME); + strcpy(image.of_filename, CONFIG_DTB_FILENAME); + strcpy(image.config_filename, CONFIG_CONFIG_FILENAME); + + /* Initialize the SD host controller. */ + if (sunxi_sdhci_init(&sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: %s controller init failed\n", sdhci0.name); + goto _shell; + } else { + printk(LOG_LEVEL_INFO, "SMHC: %s controller v%x initialized\n", sdhci0.name, sdhci0.reg->vers); + } + + /* Initialize the SD card and check if initialization is successful. */ + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_WARNING, "SMHC: init failed\n"); + goto _shell; + } + + /* Load the DTB, kernel image, and configuration data from the SD card. */ + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_WARNING, "SMHC: loading failed\n"); + goto _shell; + } + + /* Update boot arguments based on configuration file. */ + if (update_bootargs_from_config(dram_size)) { + goto _shell; + } + + int bootdelay = CONFIG_DEFAULT_BOOTDELAY; + + if (image.is_config) { + size_t size_a = strlen(image.config_dest); + int entry_count = parse_ini_data(image.config_dest, size_a, entries, CONFIG_MAX_ENTRY); + for (int i = 0; i < entry_count; ++i) { + /* Print parsed INI entries */ + printk(LOG_LEVEL_DEBUG, "INI: [%s] %s = %s\n", entries[i].section, entries[i].key, entries[i].value); + } + char *bootdelay_str = find_entry_value(entries, entry_count, "configs", "bootdelay"); + if (bootdelay_str != NULL) { + bootdelay = simple_atoi(bootdelay_str); + } + } + + /* Showing boot delays */ + if (abortboot_single_key(bootdelay)) { + goto _shell; + } + + cmd_boot(0, NULL); + +_shell: + syterkit_shell_attach(commands); + +_fel: + /* If the kernel boot fails, jump to FEL mode. */ + jmp_to_fel(); + + /* Return 0 to indicate successful execution. */ + return 0; +} diff --git a/board/dongshanpi-aict/syter_boot_spi/CMakeLists.txt b/board/dongshanpi-aict/syter_boot_spi/CMakeLists.txt new file mode 100644 index 00000000..7ea44abd --- /dev/null +++ b/board/dongshanpi-aict/syter_boot_spi/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(syter_boot_spi + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/syter_boot_spi/main.c b/board/dongshanpi-aict/syter_boot_spi/main.c new file mode 100644 index 00000000..d2f33dfa --- /dev/null +++ b/board/dongshanpi-aict/syter_boot_spi/main.c @@ -0,0 +1,326 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "sys-dram.h" +#include "sys-rtc.h" +#include "sys-sid.h" +#include "sys-spi.h" +#include "sys-dma.h" +#include "sys-spi-nand.h" + +#include "ff.h" +#include "libfdt.h" +#include "uart.h" + +#define CONFIG_KERNEL_FILENAME "zImage" +#define CONFIG_DTB_FILENAME "sunxi.dtb" + +#define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) + +#define CONFIG_DTB_LOAD_ADDR (0x41008000) +#define CONFIG_KERNEL_LOAD_ADDR (0x41800000) + +// 128KB erase sectors, so place them starting from 2nd sector +#define CONFIG_SPINAND_DTB_ADDR (128 * 2048) +#define CONFIG_SPINAND_KERNEL_ADDR (256 * 2048) + +#define CONFIG_DEFAULT_BOOTDELAY 5 + +#define FILENAME_MAX_LEN 64 +typedef struct { + uint32_t offset; + uint32_t length; + uint8_t *dest; + + uint32_t of_offset; + uint8_t *of_dest; + + char filename[FILENAME_MAX_LEN]; + char of_filename[FILENAME_MAX_LEN]; +} image_info_t; + +/* Linux zImage Header */ +#define LINUX_ZIMAGE_MAGIC 0x016f2818 +typedef struct { + uint32_t code[9]; + uint32_t magic; + uint32_t start; + uint32_t end; +} linux_zimage_header_t; + +extern sunxi_serial_t uart_dbg; + +extern sunxi_spi_t sunxi_spi0; + +extern dram_para_t dram_para; + +image_info_t image; + +uint32_t code[9]; +uint32_t magic; +uint32_t start; +uint32_t end; + +static int boot_image_setup(uint8_t *addr, uint32_t *entry) { + linux_zimage_header_t *zimage_header = (linux_zimage_header_t *) addr; + + printk(LOG_LEVEL_INFO, "Linux zImage->code = 0x"); + for (int i = 0; i < 9; i++) + printk(LOG_LEVEL_MUTE, "%x", code[i]); + + printk(LOG_LEVEL_MUTE, "\n"); + printk(LOG_LEVEL_DEBUG, "Linux zImage->magic = 0x%x\n", + zimage_header->magic); + printk(LOG_LEVEL_DEBUG, "Linux zImage->start = 0x%x\n", + (uint32_t) addr + zimage_header->start); + printk(LOG_LEVEL_DEBUG, "Linux zImage->end = 0x%x\n", + (uint32_t) addr + zimage_header->end); + + if (zimage_header->magic == LINUX_ZIMAGE_MAGIC) { + *entry = ((uint32_t) addr + zimage_header->start); + return 0; + } + + printk(LOG_LEVEL_ERROR, "unsupported kernel image\n"); + + return -1; +} + +int load_spi_nand(sunxi_spi_t *spi, image_info_t *image) { + linux_zimage_header_t *hdr; + unsigned int size; + uint64_t start, time; + + if (spi_nand_detect(spi) != 0) + return -1; + + /* get dtb size and read */ + spi_nand_read(spi, image->of_dest, CONFIG_SPINAND_DTB_ADDR, (uint32_t) sizeof(struct fdt_header)); + if (fdt_check_header(image->of_dest)) { + printk(LOG_LEVEL_ERROR, "SPI-NAND: DTB verification failed\n"); + return -1; + } + + size = fdt_totalsize(image->of_dest); + printk(LOG_LEVEL_DEBUG, + "SPI-NAND: dt blob: Copy from 0x%08x to 0x%08lx size:0x%08x\n", + CONFIG_SPINAND_DTB_ADDR, (uint32_t) image->of_dest, size); + start = time_us(); + spi_nand_read(spi, image->of_dest, CONFIG_SPINAND_DTB_ADDR, + (uint32_t) size); + time = time_us() - start; + printk(LOG_LEVEL_INFO, + "SPI-NAND: read dt blob of size %u at %.2fMB/S\n", size, + (f32) (size / time)); + + /* get kernel size and read */ + spi_nand_read(spi, image->dest, CONFIG_SPINAND_KERNEL_ADDR, + (uint32_t) sizeof(linux_zimage_header_t)); + hdr = (linux_zimage_header_t *) image->dest; + if (hdr->magic != LINUX_ZIMAGE_MAGIC) { + printk(LOG_LEVEL_DEBUG, + "SPI-NAND: zImage verification failed\n"); + return -1; + } + size = hdr->end - hdr->start; + printk(LOG_LEVEL_DEBUG, + "SPI-NAND: Image: Copy from 0x%08x to 0x%08lx size:0x%08x\n", + CONFIG_SPINAND_KERNEL_ADDR, (uint32_t) image->dest, size); + start = time_us(); + spi_nand_read(spi, image->dest, CONFIG_SPINAND_KERNEL_ADDR, + (uint32_t) size); + time = time_us() - start; + printk(LOG_LEVEL_INFO, + "SPI-NAND: read Image of size %u at %.2fMB/S\n", size, + (f32) (size / time)); + + return 0; +} + +static int abortboot_single_key(int bootdelay) { + int abort = 0; + unsigned long ts; + + printk(LOG_LEVEL_INFO, "Hit any key to stop autoboot: %2d ", bootdelay); + + /* Check if key already pressed */ + if (tstc()) { /* we got a key press */ + uart_getchar(); /* consume input */ + printk(LOG_LEVEL_MUTE, "\b\b\b%2d", bootdelay); + abort = 1; /* don't auto boot */ + } + + while ((bootdelay > 0) && (!abort)) { + --bootdelay; + /* delay 1000 ms */ + ts = time_ms(); + do { + if (tstc()) { /* we got a key press */ + abort = 1; /* don't auto boot */ + break; + } + udelay(10000); + } while (!abort && time_ms() - ts < 1000); + printk(LOG_LEVEL_MUTE, "\b\b\b%2d ", bootdelay); + } + uart_putchar('\n'); + return abort; +} + +msh_declare_command(reload); +msh_define_help(reload, "rescan SPI NAND and reload DTB, Kernel zImage", "Usage: reload\n"); +int cmd_reload(int argc, const char **argv) { + if (sunxi_spi_init(&sunxi_spi0) != 0) { + printk(LOG_LEVEL_ERROR, "SPI: init failed\n"); + return 0; + } + + if (load_spi_nand(&sunxi_spi0, &image) != 0) { + printk(LOG_LEVEL_ERROR, "SPI-NAND: loading failed\n"); + return 0; + } + return 0; +} + +msh_declare_command(boot); +msh_define_help(boot, "boot to linux", "Usage: boot\n"); +int cmd_boot(int argc, const char **argv) { + /* Initialize variables for kernel entry point and SD card access. */ + uint32_t entry_point = 0; + void (*kernel_entry)(int zero, int arch, uint32_t params); + + /* Disable SPI controller, clean up and exit the DMA subsystem. */ + sunxi_spi_disable(&sunxi_spi0); + dma_exit(); + + /* Set up boot parameters for the kernel. */ + if (boot_image_setup((uint8_t *) image.dest, &entry_point)) { + printk(LOG_LEVEL_ERROR, "boot setup failed\n"); + abort(); + } + + /* Disable MMU, data cache, instruction cache, interrupts */ + clean_syterkit_data(); + + enable_kernel_smp(); + printk(LOG_LEVEL_INFO, "enable kernel smp ok...\n"); + + /* Debug message to indicate the kernel address that the system is jumping to. */ + printk(LOG_LEVEL_INFO, "jump to kernel address: 0x%x\n\n", image.dest); + + /* Jump to the kernel entry point. */ + kernel_entry = (void (*)(int, int, uint32_t)) entry_point; + kernel_entry(0, ~0, (uint32_t) image.of_dest); + + // if kernel boot not success, jump to fel. + jmp_to_fel(); + return 0; +} + +const msh_command_entry commands[] = { + msh_define_command(reload), + msh_define_command(boot), + msh_command_end, +}; + +int main(void) { + /* Initialize the debug serial interface. */ + sunxi_serial_init(&uart_dbg); + + /* Display the bootloader banner. */ + show_banner(); + + /* Initialize the system clock. */ + sunxi_clk_init(); + + /* Check rtc fel flag. if set flag, goto fel */ + if (rtc_probe_fel_flag()) { + printk(LOG_LEVEL_INFO, "RTC: get fel flag, jump to fel mode.\n"); + clean_syterkit_data(); + rtc_clear_fel_flag(); + sunxi_clk_reset(); + mdelay(100); + goto _fel; + } + + /* Initialize the DRAM and enable memory management unit (MMU). */ + uint64_t dram_size = sunxi_dram_init(&dram_para); + arm32_mmu_enable(SDRAM_BASE, dram_size); + + /* Debug message to indicate that MMU is enabled. */ + printk(LOG_LEVEL_DEBUG, "enable mmu ok\n"); + + /* Set up Real-Time Clock (RTC) hardware. */ + rtc_set_vccio_det_spare(); + + /* Check if system voltage is within limits. */ + sys_ldo_check(); + + /* Dump information about the system clocks. */ + sunxi_clk_dump(); + + /* Clear the image_info_t struct. */ + memset(&image, 0, sizeof(image_info_t)); + + /* Set the destination address for the device tree binary (DTB), kernel image. */ + image.of_dest = (uint8_t *) CONFIG_DTB_LOAD_ADDR; + image.dest = (uint8_t *) CONFIG_KERNEL_LOAD_ADDR; + + /* Copy the filenames for the DTB, kernel image. */ + strcpy(image.filename, CONFIG_KERNEL_FILENAME); + strcpy(image.of_filename, CONFIG_DTB_FILENAME); + + /* Initialize the DMA subsystem and test it */ + dma_init(); + dma_test((uint32_t *) CONFIG_DTB_LOAD_ADDR, + (uint32_t *) CONFIG_KERNEL_LOAD_ADDR); + + /* Initialize the SPI controller. */ + if (sunxi_spi_init(&sunxi_spi0) != 0) { + printk(LOG_LEVEL_ERROR, "SPI: init failed\n"); + goto _shell; + } else { + printk(LOG_LEVEL_INFO, "SPI: spi0 controller initialized\n"); + } + + /* Load the DTB, kernel image from the SPI NAND. */ + if (load_spi_nand(&sunxi_spi0, &image) != 0) { + printk(LOG_LEVEL_ERROR, "SPI-NAND: loading failed\n"); + goto _shell; + } + + int bootdelay = CONFIG_DEFAULT_BOOTDELAY; + + /* Showing boot delays */ + if (abortboot_single_key(bootdelay)) { + goto _shell; + } + + cmd_boot(0, NULL); + +_shell: + syterkit_shell_attach(commands); + +_fel: + /* If the kernel boot fails, jump to FEL mode. */ + jmp_to_fel(); + + /* Return 0 to indicate successful execution. */ + return 0; +} diff --git a/board/dongshanpi-aict/syter_bootargs/CMakeLists.txt b/board/dongshanpi-aict/syter_bootargs/CMakeLists.txt new file mode 100644 index 00000000..ea16d422 --- /dev/null +++ b/board/dongshanpi-aict/syter_bootargs/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(syter_bootargs + main.c +) \ No newline at end of file diff --git a/board/dongshanpi-aict/syter_bootargs/main.c b/board/dongshanpi-aict/syter_bootargs/main.c new file mode 100644 index 00000000..d151c003 --- /dev/null +++ b/board/dongshanpi-aict/syter_bootargs/main.c @@ -0,0 +1,420 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "sys-dram.h" +#include "sys-sdcard.h" +#include "sys-sid.h" +#include "sys-spi.h" + +#include +#include +#include + +#include "ff.h" +#include "libfdt.h" + +#define CONFIG_KERNEL_FILENAME "zImage" +#define CONFIG_DTB_FILENAME "sunxi.dtb" + +#define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) + +#define CONFIG_DTB_LOAD_ADDR (0x41008000) +#define CONFIG_KERNEL_LOAD_ADDR (0x41800000) + +// 128KB erase sectors, so place them starting from 2nd sector +#define CONFIG_SPINAND_DTB_ADDR (128 * 2048) +#define CONFIG_SPINAND_KERNEL_ADDR (256 * 2048) + +#define FILENAME_MAX_LEN 64 +typedef struct { + unsigned int offset; + unsigned int length; + unsigned char *dest; + + unsigned int of_offset; + unsigned char *of_dest; + + char filename[FILENAME_MAX_LEN]; + char of_filename[FILENAME_MAX_LEN]; +} image_info_t; + +/* Linux zImage Header */ +#define LINUX_ZIMAGE_MAGIC 0x016f2818 +typedef struct { + unsigned int code[9]; + unsigned int magic; + unsigned int start; + unsigned int end; +} linux_zimage_header_t; + +extern sunxi_serial_t uart_dbg; + +extern sunxi_spi_t sunxi_spi0; + +extern sdhci_t sdhci0; + +extern dram_para_t dram_para; + +image_info_t image; + +unsigned int code[9]; +unsigned int magic; +unsigned int start; +unsigned int end; + +static int boot_image_setup(unsigned char *addr, unsigned int *entry) { + linux_zimage_header_t *zimage_header = (linux_zimage_header_t *) addr; + + printk(LOG_LEVEL_INFO, "Linux zImage->code = 0x"); + for (int i = 0; i < 9; i++) + printk(LOG_LEVEL_MUTE, "%x", code[i]); + + printk(LOG_LEVEL_MUTE, "\n"); + printk(LOG_LEVEL_DEBUG, "Linux zImage->magic = 0x%x\n", + zimage_header->magic); + printk(LOG_LEVEL_DEBUG, "Linux zImage->start = 0x%x\n", + (unsigned int) addr + zimage_header->start); + printk(LOG_LEVEL_DEBUG, "Linux zImage->end = 0x%x\n", + (unsigned int) addr + zimage_header->end); + + if (zimage_header->magic == LINUX_ZIMAGE_MAGIC) { + *entry = ((unsigned int) addr + zimage_header->start); + return 0; + } + + printk(LOG_LEVEL_ERROR, "unsupported kernel image\n"); + + return -1; +} + +#define CHUNK_SIZE 0x20000 + +static int fatfs_loadimage(char *filename, BYTE *dest) { + FIL file; + UINT byte_to_read = CHUNK_SIZE; + UINT byte_read; + UINT total_read = 0; + FRESULT fret; + int ret; + uint32_t start, time; + + fret = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, + "FATFS: open, filename: [%s]: error %d\n", filename, + fret); + ret = -1; + goto open_fail; + } + + start = time_ms(); + + do { + byte_read = 0; + fret = f_read(&file, (void *) (dest), byte_to_read, &byte_read); + dest += byte_to_read; + total_read += byte_read; + } while (byte_read >= byte_to_read && fret == FR_OK); + + time = time_ms() - start + 1; + + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: read: error %d\n", fret); + ret = -1; + goto read_fail; + } + ret = 0; + +read_fail: + fret = f_close(&file); + + printk(LOG_LEVEL_DEBUG, "FATFS: read in %ums at %.2fMB/S\n", time, + (f32) (total_read / time) / 1024.0f); + +open_fail: + return ret; +} + +static int load_sdcard(image_info_t *image) { + FATFS fs; + FRESULT fret; + int ret; + uint32_t start; + + uint32_t test_time; + start = time_ms(); + sdmmc_blk_read(&card0, (uint8_t *) (SDRAM_BASE), 0, + CONFIG_SDMMC_SPEED_TEST_SIZE); + test_time = time_ms() - start; + printk(LOG_LEVEL_DEBUG, "SDMMC: speedtest %uKB in %ums at %uKB/S\n", + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / 1024, test_time, + (CONFIG_SDMMC_SPEED_TEST_SIZE * 512) / test_time); + + start = time_ms(); + + fret = f_mount(&fs, "", 1); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: mount error: %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: mount OK\n"); + } + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->of_filename, + (unsigned int) image->of_dest); + ret = fatfs_loadimage(image->of_filename, image->of_dest); + if (ret) + return ret; + + printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->filename, + (unsigned int) image->dest); + ret = fatfs_loadimage(image->filename, image->dest); + if (ret) + return ret; + + /* umount fs */ + fret = f_mount(0, "", 0); + if (fret != FR_OK) { + printk(LOG_LEVEL_ERROR, "FATFS: unmount error %d\n", fret); + return -1; + } else { + printk(LOG_LEVEL_DEBUG, "FATFS: unmount OK\n"); + } + printk(LOG_LEVEL_DEBUG, "FATFS: done in %ums\n", time_ms() - start); + + return 0; +} + +int load_spi_nand(sunxi_spi_t *spi, image_info_t *image) { + linux_zimage_header_t *hdr; + unsigned int size; + uint64_t start, time; + + if (spi_nand_detect(spi) != 0) + return -1; + + /* get dtb size and read */ + spi_nand_read(spi, image->of_dest, CONFIG_SPINAND_DTB_ADDR, (uint32_t) sizeof(struct fdt_header)); + if (fdt_check_header(image->of_dest)) { + printk(LOG_LEVEL_ERROR, "SPI-NAND: DTB verification failed\n"); + return -1; + } + + size = fdt_totalsize(image->of_dest); + printk(LOG_LEVEL_DEBUG, + "SPI-NAND: dt blob: Copy from 0x%08x to 0x%08lx size:0x%08x\n", + CONFIG_SPINAND_DTB_ADDR, (uint32_t) image->of_dest, size); + start = time_us(); + spi_nand_read(spi, image->of_dest, CONFIG_SPINAND_DTB_ADDR, + (uint32_t) size); + time = time_us() - start; + printk(LOG_LEVEL_INFO, + "SPI-NAND: read dt blob of size %u at %.2fMB/S\n", size, + (f32) (size / time)); + + /* get kernel size and read */ + spi_nand_read(spi, image->dest, CONFIG_SPINAND_KERNEL_ADDR, + (uint32_t) sizeof(linux_zimage_header_t)); + hdr = (linux_zimage_header_t *) image->dest; + if (hdr->magic != LINUX_ZIMAGE_MAGIC) { + printk(LOG_LEVEL_DEBUG, + "SPI-NAND: zImage verification failed\n"); + return -1; + } + size = hdr->end - hdr->start; + printk(LOG_LEVEL_DEBUG, + "SPI-NAND: Image: Copy from 0x%08x to 0x%08lx size:0x%08x\n", + CONFIG_SPINAND_KERNEL_ADDR, (uint32_t) image->dest, size); + start = time_us(); + spi_nand_read(spi, image->dest, CONFIG_SPINAND_KERNEL_ADDR, + (uint32_t) size); + time = time_us() - start; + printk(LOG_LEVEL_INFO, + "SPI-NAND: read Image of size %u at %.2fMB/S\n", size, + (f32) (size / time)); + + return 0; +} + +msh_declare_command(bootargs); +msh_define_help(bootargs, "get/set bootargs for kernel", + "Usage: bootargs set \"bootargs\" - set new bootargs for zImage\n" + " bootargs get - get current bootargs\n"); +int cmd_bootargs(int argc, const char **argv) { + if (argc < 2) { + uart_puts(cmd_bootargs_usage); + return 0; + } + + if (strncmp(argv[1], "set", 3) == 0) { + if (argc != 3) { + uart_puts(cmd_bootargs_usage); + return 0; + } + /* Force image.of_dest to be a pointer to fdt_header structure */ + struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; + + int err = 0; + + /* Check if DTB header is valid */ + if ((err = fdt_check_header(dtb_header)) != 0) { + printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); + return 0; + } + + int len = 0; + /* Get the offset of "/chosen" node */ + uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); + + /* Get bootargs string */ + char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_MUTE, "DTB OLD bootargs = \"%s\"\n", bootargs_str); + + /* New bootargs string */ + char *new_bootargs_str = argv[2]; + printk(LOG_LEVEL_MUTE, "Now set bootargs to \"%s\"\n", new_bootargs_str); + + /* Modify bootargs string */ + err = fdt_setprop(image.of_dest, bootargs_node, "bootargs", new_bootargs_str, strlen(new_bootargs_str) + 1); + + if (err < 0) { + printk(LOG_LEVEL_ERROR, "libfdt fdt_setprop() error: %s\n", fdt_strerror(err)); + abort(); + } + + /* Get updated bootargs string */ + char *updated_bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_MUTE, "DTB NEW bootargs = \"%s\"\n", updated_bootargs_str); + } else if (strncmp(argv[1], "get", 3) == 0) { + /* Force image.of_dest to be a pointer to fdt_header structure */ + struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; + + int err = 0; + + /* Check if DTB header is valid */ + if ((err = fdt_check_header(dtb_header)) != 0) { + printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); + return 0; + } + + int len = 0; + /* Get the offset of "/chosen" node */ + uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); + + /* Get bootargs string */ + char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); + printk(LOG_LEVEL_MUTE, "DTB bootargs = \"%s\"\n", bootargs_str); + } else { + uart_puts(cmd_bootargs_usage); + } + + return 0; +} + +msh_declare_command(reload); +msh_define_help(reload, "rescan TF Card and reload DTB, Kernel zImage", "Usage: reload\n"); +int cmd_reload(int argc, const char **argv) { + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: init failed\n"); + return 0; + } + + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: loading failed\n"); + return 0; + } + return 0; +} + +msh_declare_command(boot); +msh_define_help(boot, "boot to linux", "Usage: boot\n"); +int cmd_boot(int argc, const char **argv) { + unsigned int entry_point = 0; + void (*kernel_entry)(int zero, int arch, unsigned int params); + + if (boot_image_setup((unsigned char *) image.dest, &entry_point)) { + printk(LOG_LEVEL_ERROR, "boot setup failed\n"); + return 0; + } + + printk(LOG_LEVEL_INFO, "booting linux...\n"); + + arm32_mmu_disable(); + printk(LOG_LEVEL_INFO, "disable mmu ok...\n"); + arm32_dcache_disable(); + printk(LOG_LEVEL_INFO, "disable dcache ok...\n"); + arm32_icache_disable(); + printk(LOG_LEVEL_INFO, "disable icache ok...\n"); + arm32_interrupt_disable(); + printk(LOG_LEVEL_INFO, "free interrupt ok...\n"); + enable_kernel_smp(); + printk(LOG_LEVEL_INFO, "enable kernel smp ok...\n"); + + printk(LOG_LEVEL_INFO, "jump to kernel address: 0x%x\n", image.dest); + + kernel_entry = (void (*)(int, int, unsigned int)) entry_point; + kernel_entry(0, ~0, (unsigned int) image.of_dest); + + // if kernel boot not success, jump to fel. + jmp_to_fel(); + return 0; +} + +const msh_command_entry commands[] = { + msh_define_command(bootargs), + msh_define_command(reload), + msh_define_command(boot), + msh_command_end, +}; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + show_banner(); + + sunxi_clk_init(); + + sunxi_dram_init(&dram_para); + + sunxi_clk_dump(); + + memset(&image, 0, sizeof(image_info_t)); + + image.of_dest = (uint8_t *) CONFIG_DTB_LOAD_ADDR; + image.dest = (uint8_t *) CONFIG_KERNEL_LOAD_ADDR; + + strcpy(image.filename, CONFIG_KERNEL_FILENAME); + strcpy(image.of_filename, CONFIG_DTB_FILENAME); + + if (sunxi_sdhci_init(&sdhci0) != 0) { + printk(LOG_LEVEL_ERROR, "SMHC: %s controller init failed\n", sdhci0.name); + goto _shell; + } else { + printk(LOG_LEVEL_INFO, "SMHC: %s controller v%x initialized\n", sdhci0.name, sdhci0.reg->vers); + } + if (sdmmc_init(&card0, &sdhci0) != 0) { + printk(LOG_LEVEL_WARNING, "SMHC: init failed\n"); + goto _shell; + } + + if (load_sdcard(&image) != 0) { + printk(LOG_LEVEL_WARNING, "SMHC: loading failed\n"); + goto _shell; + } + +_shell: + syterkit_shell_attach(commands); + + return 0; +} diff --git a/cmake/board/dongshanpi-aict.cmake b/cmake/board/dongshanpi-aict.cmake new file mode 100644 index 00000000..b7966b17 --- /dev/null +++ b/cmake/board/dongshanpi-aict.cmake @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(CONFIG_ARCH_ARM32 True) +set(CONFIG_CHIP_SUN8IW21 True) +set(CONFIG_BOARD_DONGSHANPI_AICT True) + +add_definitions(-DCONFIG_CHIP_SUN8IW21) + +# Options + +# By setting ENABLE_HARDFP to ON, it indicates that the project is configured +# to utilize hard floating-point operations when applicable. This can be beneficial +# in scenarios where performance gains from hardware acceleration are desired. +option(ENABLE_HARDFP "Enable hardware floating-point operations" ON) + +# Set the cross-compile toolchain +set(CROSS_COMPILE "arm-none-eabi-") +set(CROSS_COMPILE ${CROSS_COMPILE} CACHE STRING "CROSS_COMPILE Toolchain") + +# Set the C and C++ compilers +set(CMAKE_C_COMPILER "${CROSS_COMPILE}gcc") +set(CMAKE_CXX_COMPILER "${CROSS_COMPILE}g++") + +# Configure compiler flags based on ENABLE_HARDFP option +if(ENABLE_HARDFP) + set(CMAKE_COMMON_FLAGS "-nostdlib -g -ggdb -O3 -mcpu=cortex-a7 -mthumb-interwork -mthumb -mno-unaligned-access -mfpu=neon-vfpv4 -mfloat-abi=hard") +else() + set(CMAKE_COMMON_FLAGS "-nostdlib -g -ggdb -O3 -mcpu=cortex-a7 -mthumb-interwork -mthumb -mno-unaligned-access -mfpu=neon-vfpv4 -mfloat-abi=softfp") +endif() + +# Disable specific warning flags for C and C++ compilers +set(CMAKE_C_DISABLE_WARN_FLAGS "-Wno-int-to-pointer-cast -Wno-implicit-function-declaration -Wno-discarded-qualifiers") +set(CMAKE_CXX_DISABLE_WARN_FLAGS "-Wno-int-to-pointer-cast") + +set(ARCH_BIN_START_ADDRESS "0x00020000") +set(ARCH_BIN_SRAM_LENGTH "128K") + +set(ARCH_FEL_START_ADDRESS "0x00028000") +set(ARCH_FEL_SRAM_LENGTH "100K") \ No newline at end of file diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt index cd42c5f7..79f857e4 100644 --- a/src/drivers/CMakeLists.txt +++ b/src/drivers/CMakeLists.txt @@ -8,6 +8,8 @@ elseif(CONFIG_CHIP_SUN55IW3) add_subdirectory(sun55iw3) elseif(CONFIG_CHIP_SUN8IW8) add_subdirectory(sun8iw8) +elseif(CONFIG_CHIP_SUN50IW10) + add_subdirectory(sun50iw10) endif() set(DRIVER_PMU "") diff --git a/src/drivers/sun8iw20/sys-dram.c b/src/drivers/sun8iw20/sys-dram.c index 776fe4fd..f675b5b4 100644 --- a/src/drivers/sun8iw20/sys-dram.c +++ b/src/drivers/sun8iw20/sys-dram.c @@ -673,48 +673,48 @@ static void mctl_phy_ac_remapping(dram_para_t *para) { return; fuse = (readl(SYS_SID_BASE + SYS_EFUSE_REG) & 0xf00) >> 8; - printk(LOG_LEVEL_DEBUG, "DDR efuse: 0x%x\r\n", fuse); + printk(LOG_LEVEL_DEBUG, "DDR efuse: 0x%x\n", fuse); if (para->dram_type == SUNXI_DRAM_TYPE_DDR2) { /* if fuse is 0xa then D1s -> no remap*/ if (fuse == 0x0a) { - printk(LOG_LEVEL_DEBUG, "D1s no REMAP!!\r\n"); + printk(LOG_LEVEL_DEBUG, "D1s no REMAP!!\n"); return; } if (fuse == 15) return; - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 6 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 6 \n"); cfg = ac_remapping_tables[6]; } else { if (para->dram_tpr13 & 0xc0000) { - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 7 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 7 \n"); cfg = ac_remapping_tables[7]; } else { switch (fuse) { case 8: - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 2 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 2 \n"); cfg = ac_remapping_tables[2]; break; case 9: - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 3 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 3 \n"); cfg = ac_remapping_tables[3]; break; case 10: - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 5 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 5 \n"); cfg = ac_remapping_tables[5]; break; case 11: - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 4 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 4 \n"); cfg = ac_remapping_tables[4]; break; default: case 12: - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 1 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 1 \n"); cfg = ac_remapping_tables[1]; break; case 13: case 14: - printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 0 \r\n"); + printk(LOG_LEVEL_DEBUG, "DDR Using MAP: 0 \n"); cfg = ac_remapping_tables[0]; break; } @@ -734,13 +734,13 @@ static void mctl_phy_ac_remapping(dram_para_t *para) { (cfg[20] << 20) | (cfg[21] << 25); writel(val, (MCTL_COM_BASE + MCTL_COM_REMAP3)); - printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP0 = 0x%x\r\n", + printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP0 = 0x%x\n", readl((MCTL_COM_BASE + MCTL_COM_REMAP0))); - printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP1 = 0x%x\r\n", + printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP1 = 0x%x\n", readl((MCTL_COM_BASE + MCTL_COM_REMAP1))); - printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP2 = 0x%x\r\n", + printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP2 = 0x%x\n", readl((MCTL_COM_BASE + MCTL_COM_REMAP2))); - printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP3 = 0x%x\r\n", + printk(LOG_LEVEL_DEBUG, "MCTL_COM_REMAP3 = 0x%x\n", readl((MCTL_COM_BASE + MCTL_COM_REMAP3))); } @@ -882,7 +882,7 @@ static unsigned int mctl_channel_init(unsigned int ch_index, dram_para_t *para) // Check for training error if (readl((MCTL_PHY_BASE + MCTL_PHY_PGSR0)) & (1 << 20)) { - printk(LOG_LEVEL_ERROR, "ZQ calibration error, check external 240 ohm resistor\r\n"); + printk(LOG_LEVEL_ERROR, "ZQ calibration error, check external 240 ohm resistor\n"); return 0; } @@ -951,7 +951,7 @@ static int dqs_gate_detect(dram_para_t *para) { if ((readl(MCTL_PHY_BASE + MCTL_PHY_PGSR0) & BIT(22)) == 0) { para->dram_para2 = (para->dram_para2 & ~0xf) | BIT(12); - printk(LOG_LEVEL_DEBUG, "dual rank and full DQ\r\n"); + printk(LOG_LEVEL_DEBUG, "dual rank and full DQ\n"); return 1; } @@ -959,7 +959,7 @@ static int dqs_gate_detect(dram_para_t *para) { dx0 = (readl(MCTL_PHY_BASE + MCTL_PHY_DXnGSR0(0)) & 0x3000000) >> 24; if (dx0 == 0) { para->dram_para2 = (para->dram_para2 & ~0xf) | 0x1001; - printk(LOG_LEVEL_DEBUG, "dual rank and half DQ\r\n"); + printk(LOG_LEVEL_DEBUG, "dual rank and half DQ\n"); return 1; } @@ -968,10 +968,10 @@ static int dqs_gate_detect(dram_para_t *para) { dx1 = (readl(MCTL_PHY_BASE + MCTL_PHY_DXnGSR0(1)) & 0x3000000) >> 24; if (dx1 == 2) { para->dram_para2 = para->dram_para2 & ~0xf00f; - printk(LOG_LEVEL_DEBUG, "single rank and full DQ\r\n"); + printk(LOG_LEVEL_DEBUG, "single rank and full DQ\n"); } else { para->dram_para2 = (para->dram_para2 & ~0xf00f) | BIT(0); - printk(LOG_LEVEL_DEBUG, "single rank and half DQ\r\n"); + printk(LOG_LEVEL_DEBUG, "single rank and half DQ\n"); } return 1; @@ -980,8 +980,8 @@ static int dqs_gate_detect(dram_para_t *para) { if ((para->dram_tpr13 & BIT(29)) == 0) return 0; - printk(LOG_LEVEL_DEBUG, "DX0 state: %lu\r\n", dx0); - printk(LOG_LEVEL_DEBUG, "DX1 state: %lu\r\n", dx1); + printk(LOG_LEVEL_DEBUG, "DX0 state: %lu\n", dx0); + printk(LOG_LEVEL_DEBUG, "DX1 state: %lu\n", dx1); return 0; } @@ -1003,20 +1003,20 @@ static int dramc_simple_wr_test(unsigned int mem_mb, int len) { v1 = readl((unsigned long) (addr + i)); v2 = patt1 + i; if (v1 != v2) { - printk(LOG_LEVEL_ERROR, "DRAM: simple test FAIL\r\n"); - printk(LOG_LEVEL_ERROR, "%x != %x at address %p\r\n", v1, v2, addr + i); + printk(LOG_LEVEL_ERROR, "DRAM: simple test FAIL\n"); + printk(LOG_LEVEL_ERROR, "%x != %x at address %p\n", v1, v2, addr + i); return 1; } v1 = readl((unsigned long) (addr + offs + i)); v2 = patt2 + i; if (v1 != v2) { - printk(LOG_LEVEL_ERROR, "DRAM: simple test FAIL\r\n"); - printk(LOG_LEVEL_ERROR, "%x != %x at address %p\r\n", v1, v2, addr + offs + i); + printk(LOG_LEVEL_ERROR, "DRAM: simple test FAIL\n"); + printk(LOG_LEVEL_ERROR, "%x != %x at address %p\n", v1, v2, addr + offs + i); return 1; } } - printk(LOG_LEVEL_DEBUG, "DRAM: simple test OK\r\n"); + printk(LOG_LEVEL_DEBUG, "DRAM: simple test OK\n"); return 0; } @@ -1072,7 +1072,7 @@ static int auto_scan_dram_size(dram_para_t *para) { // init core if (mctl_core_init(para) == 0) { - printk(LOG_LEVEL_DEBUG, "DRAM initial error : 0!\r\n"); + printk(LOG_LEVEL_DEBUG, "DRAM initial error : 0!\n"); return 0; } @@ -1118,7 +1118,7 @@ static int auto_scan_dram_size(dram_para_t *para) { i = 16; addr_line += i; - printk(LOG_LEVEL_DEBUG, "rank %lu row = %lu \r\n", current_rank, i); + printk(LOG_LEVEL_DEBUG, "rank %lu row = %lu \n", current_rank, i); /* Store rows in para 1 */ para->dram_para1 &= ~(0xffU << (16 * current_rank + 4)); @@ -1149,7 +1149,7 @@ static int auto_scan_dram_size(dram_para_t *para) { } addr_line += i + 2; - printk(LOG_LEVEL_DEBUG, "rank %lu bank = %lu \r\n", current_rank, (4 + i * 4)); + printk(LOG_LEVEL_DEBUG, "rank %lu bank = %lu \n", current_rank, (4 + i * 4)); /* Store bank in para 1 */ para->dram_para1 &= ~(0xfU << (16 * current_rank + 12)); @@ -1194,7 +1194,7 @@ static int auto_scan_dram_size(dram_para_t *para) { i = (0x1U << (i - 10)); } - printk(LOG_LEVEL_DEBUG, "rank %lu page size = %lu KB \r\n", current_rank, i); + printk(LOG_LEVEL_DEBUG, "rank %lu page size = %lu KB \n", current_rank, i); /* Store page in para 1 */ para->dram_para1 &= ~(0xfU << (16 * current_rank)); @@ -1205,10 +1205,10 @@ static int auto_scan_dram_size(dram_para_t *para) { if (rank_count == 2) { para->dram_para2 &= 0xfffff0ff; if ((para->dram_para1 & 0xffff) == (para->dram_para1 >> 16)) { - printk(LOG_LEVEL_DEBUG, "rank1 config same as rank0\r\n"); + printk(LOG_LEVEL_DEBUG, "rank1 config same as rank0\n"); } else { para->dram_para2 |= 0x1 << 8; - printk(LOG_LEVEL_DEBUG, "rank1 config different from rank0\r\n"); + printk(LOG_LEVEL_DEBUG, "rank1 config different from rank0\n"); } } return 1; @@ -1252,12 +1252,12 @@ static int auto_scan_dram_rank_width(dram_para_t *para) { */ static int auto_scan_dram_config(dram_para_t *para) { if (((para->dram_tpr13 & BIT(14)) == 0) && (auto_scan_dram_rank_width(para) == 0)) { - printk(LOG_LEVEL_ERROR, "ERROR: auto scan dram rank & width failed\r\n"); + printk(LOG_LEVEL_ERROR, "ERROR: auto scan dram rank & width failed\n"); return 0; } if (((para->dram_tpr13 & BIT(0)) == 0) && (auto_scan_dram_size(para) == 0)) { - printk(LOG_LEVEL_ERROR, "ERROR: auto scan dram size failed\r\n"); + printk(LOG_LEVEL_ERROR, "ERROR: auto scan dram size failed\n"); return 0; } @@ -1270,17 +1270,17 @@ static int auto_scan_dram_config(dram_para_t *para) { int init_DRAM(int type, dram_para_t *para) { u32 rc, mem_size_mb; - printk(LOG_LEVEL_DEBUG, "DRAM BOOT DRIVE INFO: %s\r\n", "V0.24"); - printk(LOG_LEVEL_DEBUG, "DRAM CLK = %d MHz\r\n", para->dram_clk); - printk(LOG_LEVEL_DEBUG, "DRAM Type = %d (2:DDR2,3:DDR3)\r\n", para->dram_type); + printk(LOG_LEVEL_DEBUG, "DRAM BOOT DRIVE INFO: %s\n", "V0.24"); + printk(LOG_LEVEL_DEBUG, "DRAM CLK = %d MHz\n", para->dram_clk); + printk(LOG_LEVEL_DEBUG, "DRAM Type = %d (2:DDR2,3:DDR3)\n", para->dram_type); if ((para->dram_odt_en & 0x1) == 0) - printk(LOG_LEVEL_DEBUG, "DRAMC read ODT off\r\n"); + printk(LOG_LEVEL_DEBUG, "DRAMC read ODT off\n"); else - printk(LOG_LEVEL_DEBUG, "DRAMC ZQ value: 0x%x\r\n", para->dram_zq); + printk(LOG_LEVEL_DEBUG, "DRAMC ZQ value: 0x%x\n", para->dram_zq); /* Test ZQ status */ if (para->dram_tpr13 & (1 << 16)) { - printk(LOG_LEVEL_DEBUG, "DRAM only have internal ZQ\r\n"); + printk(LOG_LEVEL_DEBUG, "DRAM only have internal ZQ\n"); setbits_le32((SYS_CONTROL_REG_BASE + ZQ_CAL_CTRL_REG), (1 << 8)); writel(0, (SYS_CONTROL_REG_BASE + ZQ_RES_CTRL_REG)); udelay(10); @@ -1292,7 +1292,7 @@ int init_DRAM(int type, dram_para_t *para) { udelay(10); setbits_le32((SYS_CONTROL_REG_BASE + ZQ_CAL_CTRL_REG), (1 << 0)); udelay(20); - printk(LOG_LEVEL_DEBUG, "ZQ value = 0x%" PRIx32 "\r\n", readl((SYS_CONTROL_REG_BASE + ZQ_RES_STATUS_REG))); + printk(LOG_LEVEL_DEBUG, "ZQ value = 0x%" PRIx32 "\n", readl((SYS_CONTROL_REG_BASE + ZQ_RES_STATUS_REG))); } dram_voltage_set(para); @@ -1300,7 +1300,7 @@ int init_DRAM(int type, dram_para_t *para) { /* Set SDRAM controller auto config */ if ((para->dram_tpr13 & (1 << 0)) == 0) { if (auto_scan_dram_config(para) == 0) { - printk(LOG_LEVEL_ERROR, "auto_scan_dram_config() FAILED\r\n"); + printk(LOG_LEVEL_ERROR, "auto_scan_dram_config() FAILED\n"); return 0; } } @@ -1308,13 +1308,13 @@ int init_DRAM(int type, dram_para_t *para) { /* report ODT */ rc = para->dram_mr1; if ((rc & 0x44) == 0) - printk(LOG_LEVEL_DEBUG, "DRAM ODT off\r\n"); + printk(LOG_LEVEL_DEBUG, "DRAM ODT off\n"); else - printk(LOG_LEVEL_DEBUG, "DRAM ODT value: 0x%" PRIx32 "\r\n", rc); + printk(LOG_LEVEL_DEBUG, "DRAM ODT value: 0x%" PRIx32 "\n", rc); /* Init core, final run */ if (mctl_core_init(para) == 0) { - printk(LOG_LEVEL_DEBUG, "DRAM initialisation error: 1\r\n"); + printk(LOG_LEVEL_DEBUG, "DRAM initialisation error: 1\n"); return 0; } @@ -1326,7 +1326,7 @@ int init_DRAM(int type, dram_para_t *para) { rc = (rc >> 16) & ~(1 << 15); } else { rc = DRAMC_get_dram_size(); - printk(LOG_LEVEL_INFO, "DRAM: size = %uMB\r\n", rc); + printk(LOG_LEVEL_INFO, "DRAM: size = %uMB\n", rc); para->dram_para2 = (para->dram_para2 & 0xffffU) | rc << 16; } mem_size_mb = rc; @@ -1339,7 +1339,7 @@ int init_DRAM(int type, dram_para_t *para) { writel(rc, (MCTL_PHY_BASE + MCTL_PHY_ASRTC)); writel(0x40a, (MCTL_PHY_BASE + MCTL_PHY_ASRC)); setbits_le32((MCTL_PHY_BASE + MCTL_PHY_PWRCTL), (1 << 0)); - printk(LOG_LEVEL_DEBUG, "Enable Auto SR\r\n"); + printk(LOG_LEVEL_DEBUG, "Enable Auto SR\n"); } else { clrbits_le32((MCTL_PHY_BASE + MCTL_PHY_ASRTC), 0xffff); clrbits_le32((MCTL_PHY_BASE + MCTL_PHY_PWRCTL), 0x1);