├── .gitignore ├── README.md ├── boot.py └── odroid_go ├── __init__.py ├── examples ├── README.md ├── battery │ └── battery.py ├── button │ └── button.py ├── hello_world │ └── hello_world.py ├── led │ └── led.py ├── led_pwm │ └── led_pwm.py └── speaker │ └── speaker.py ├── odroid_go.py └── utils ├── __init__.py ├── battery ├── __init__.py └── battery.py ├── button ├── __init__.py └── button.py ├── go_consts.py ├── lcd ├── LICENSE ├── README.md ├── __init__.py ├── colors.py ├── font_to_py.py ├── fonts.py ├── glcdfont.py ├── ili934xnew.py ├── m5stack.py ├── main.py ├── tt14.py ├── tt24.py └── tt32.py └── speaker ├── __init__.py └── speaker.py /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ project files 2 | *.iml 3 | *.iws 4 | *.ipr 5 | .idea/ 6 | 7 | # prevent from adding some test codes 8 | odroid_go/test 9 | odroid_go/test/* 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ODROID-GO 2 | 3 |
4 |
5 |
6 | 7 | > To celebrate ODROID’s 10th anniversary, we present to you the ODROID-GO Game Kit! With a special anniversary board and with all the parts to put together your own game kit and see the workings behind such a device, it is not only a fun assembly project, it can be an educational tool to learn about all the hardware and software that goes into building such a device. 8 | 9 |
10 | 11 | ## Specifications 12 | |Component |Description | 13 | |---------------------|-----------------------------------------| 14 | | MCU | Custom ESP32-WROVER(16 MB Flash Memory) | 15 | | CPU & RAM | 80MHz - 240MHz(Adjustable), 4MB PSRAM | 16 | | Wi-Fi | 802.11 b/g/n 2.4GHz - 2.5GHz | 17 | | Bluetooth | Bluetooth v4.2 BR/EDR, BLE | 18 | | Display | 2.4inch 320x240 TFT LCD (SPI interface) | 19 | | Battery | Li-Polymer 3.7V/1200mAh, Up to 10 hours of continuous game playing time | 20 | | Speaker | 0.5Watt 8Ω Mono | 21 | | Micro SD card slot | 20Mhz SPI interface | 22 | | Micro USB port | Battery charging(500mA) and USB-UART data communication | 23 | | Expansion Port | 10Pin port(I2C, GPIO, IRQ at 3.3Volt) | 24 | | Input Buttons | Menu, Volume, Select, Start, A, B, Direction Pad | 25 | 26 | ## References 27 | - [Product page](https://www.hardkernel.com/main/products/prdt_info.php?g_code=G152875062626) 28 | - [Store](https://www.hardkernel.com/main/shop/good_list.php?lang=en) 29 | - [Wiki](https://wiki.odroid.com/odroid_go/odroid_go) 30 | - [Game Emulator](https://wiki.odroid.com/odroid_go/odroid_go#gbc_nes_and_sms_emulators) 31 | - [Arduino Coding Camp](https://wiki.odroid.com/odroid_go/odroid_go#arduino) 32 | - [MicroPython Coding Camp](https://wiki.odroid.com/odroid_go/odroid_go#micropython) 33 | - [Forum](https://forum.odroid.com/viewforum.php?f=157&sid=e9409529c1d6c81b654b7dd32c9a5140) 34 | 35 | -------------------------------------------------------------------------------- /boot.py: -------------------------------------------------------------------------------- 1 | """ 2 | An example boot.py for ODROID-GO module 3 | """ 4 | 5 | from odroid_go import GO 6 | 7 | print("\033[1;32mGO: ODROID-GO module loaded\033[1;m") 8 | print("\033[1;32mGO: Enter \"hello()\" to see a message on the screen.\033[1;m") 9 | 10 | 11 | def hello(): 12 | GO.lcd.fill(color=GO.lcd.colors.BLACK) 13 | GO.lcd.set_font(GO.lcd.fonts.TT32) 14 | GO.lcd.set_color(fg=GO.lcd.colors.GREEN, bg=GO.lcd.colors.BLACK) 15 | GO.lcd.print("Hello, ODROID-GO!") 16 | -------------------------------------------------------------------------------- /odroid_go/__init__.py: -------------------------------------------------------------------------------- 1 | from .odroid_go import GO 2 | -------------------------------------------------------------------------------- /odroid_go/examples/README.md: -------------------------------------------------------------------------------- 1 | MicroPython Examples for ODROID-GO 2 | ===== 3 | 4 | These examples are not provided as a module. 5 | 6 | Copy and paste an example code to try. -------------------------------------------------------------------------------- /odroid_go/examples/battery/battery.py: -------------------------------------------------------------------------------- 1 | from odroid_go import GO 2 | import time 3 | 4 | GO.lcd.set_font(GO.lcd.fonts.TT24) 5 | 6 | 7 | def show_battery_voltage(): 8 | GO.lcd.erase() 9 | GO.lcd.set_pos(0, 0) 10 | 11 | GO.lcd.print("Current Voltage: " + str(GO.battery.get_voltage())) 12 | 13 | 14 | while True: 15 | show_battery_voltage() 16 | 17 | time.sleep(1) 18 | -------------------------------------------------------------------------------- /odroid_go/examples/button/button.py: -------------------------------------------------------------------------------- 1 | from odroid_go import GO 2 | import time 3 | 4 | GO.lcd.set_font(GO.lcd.fonts.TT14) 5 | 6 | 7 | def display_buttons(): 8 | GO.lcd.erase() 9 | GO.lcd.set_pos(0, 0) 10 | 11 | GO.lcd.print("/* Direction Pad */") 12 | GO.lcd.print("Joy-Y-Up: " + ("Pressed" if GO.btn_joy_y.is_axis_pressed() == 2 else "")) 13 | GO.lcd.print("Joy-Y-Down: " + ("Pressed" if GO.btn_joy_y.is_axis_pressed() == 1 else "")) 14 | GO.lcd.print("Joy-X-Left: " + ("Pressed" if GO.btn_joy_x.is_axis_pressed() == 2 else "")) 15 | GO.lcd.print("Joy-X-Right: " + ("Pressed" if GO.btn_joy_x.is_axis_pressed() == 1 else "")) 16 | GO.lcd.print("") 17 | GO.lcd.print("/* Function Key */") 18 | GO.lcd.print("Menu: " + ("Pressed" if GO.btn_menu.is_pressed() == 1 else "")) 19 | GO.lcd.print("Volume: " + ("Pressed" if GO.btn_volume.is_pressed() == 1 else "")) 20 | GO.lcd.print("Select: " + ("Pressed" if GO.btn_select.is_pressed() == 1 else "")) 21 | GO.lcd.print("Start: " + ("Pressed" if GO.btn_start.is_pressed() == 1 else "")) 22 | GO.lcd.print("") 23 | GO.lcd.print("/* Actions */") 24 | GO.lcd.print("B: " + ("Pressed" if GO.btn_b.is_pressed() == 1 else "")) 25 | GO.lcd.print("A: " + ("Pressed" if GO.btn_a.is_pressed() == 1 else "")) 26 | 27 | 28 | while True: 29 | GO.update() 30 | display_buttons() 31 | 32 | time.sleep(1) 33 | -------------------------------------------------------------------------------- /odroid_go/examples/hello_world/hello_world.py: -------------------------------------------------------------------------------- 1 | from odroid_go import GO 2 | 3 | GO.lcd.set_font(GO.lcd.fonts.TT24) 4 | GO.lcd.set_color(GO.lcd.colors.GREEN, GO.lcd.colors.BLACK) 5 | GO.lcd.print("Hello, ODROID-GO") 6 | -------------------------------------------------------------------------------- /odroid_go/examples/led/led.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from micropython import const 3 | 4 | import time 5 | 6 | LED_PIN = const(2) 7 | led = Pin(LED_PIN, Pin.OUT) 8 | 9 | while True: 10 | led.value(1) 11 | time.sleep(0.5) 12 | led.value(0) 13 | time.sleep(0.5) 14 | -------------------------------------------------------------------------------- /odroid_go/examples/led_pwm/led_pwm.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | from micropython import const 3 | 4 | import time 5 | 6 | LED_PIN = const(2) 7 | led = Pin(LED_PIN, Pin.OUT) 8 | pwm1 = PWM(led, freq=1000, duty=0) 9 | 10 | while True: 11 | for dValue in range(0, 1023, 100): 12 | pwm1.duty(dValue) 13 | time.sleep(0.1) 14 | 15 | for dValue in range(1023, 0, -100): 16 | pwm1.duty(dValue) 17 | time.sleep(0.1) 18 | -------------------------------------------------------------------------------- /odroid_go/examples/speaker/speaker.py: -------------------------------------------------------------------------------- 1 | from odroid_go import GO 2 | 3 | GO.lcd.set_font(GO.lcd.fonts.TT24) 4 | GO.lcd.print("ODROID-GO speaker test:") 5 | 6 | GO.speaker.set_volume(3) 7 | 8 | 9 | while True: 10 | GO.update() 11 | 12 | if GO.btn_a.was_pressed(): 13 | GO.lcd.print("was_pressed: A") 14 | GO.speaker.beep() 15 | 16 | if GO.btn_b.was_pressed(): 17 | GO.lcd.print("was_pressed: B") 18 | GO.speaker.tone(3000, 2) 19 | -------------------------------------------------------------------------------- /odroid_go/odroid_go.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, SPI, ADC 2 | from .utils import * 3 | 4 | 5 | class ODROID_GO: 6 | """ 7 | Class for helping to code with ODROID-GO. 8 | """ 9 | 10 | def __init__(self): 11 | self._init_lcd() 12 | self._init_buttons() 13 | self._init_speaker() 14 | self._init_battery() 15 | 16 | def _init_lcd(self): 17 | self.lcd = ILI9341(SPI(2, baudrate=40000000, 18 | miso=Pin(TFT_MISO_PIN, Pin.IN), 19 | mosi=Pin(TFT_MOSI_PIN, Pin.OUT), 20 | sck=Pin(TFT_SCLK_PIN, Pin.OUT)), 21 | cs=Pin(TFT_CS_PIN, Pin.OUT), 22 | dc=Pin(TFT_DC_PIN, Pin.OUT)) 23 | 24 | def _init_buttons(self): 25 | self.btn_joy_x = Button(BUTTON_JOY_X_PIN, True, BUTTON_DEBOUNCE_MS) 26 | self.btn_joy_y = Button(BUTTON_JOY_Y_PIN, True, BUTTON_DEBOUNCE_MS) 27 | self.btn_menu = Button(BUTTON_MENU_PIN, True, BUTTON_DEBOUNCE_MS) 28 | self.btn_volume = Button(BUTTON_VOLUME_PIN, True, BUTTON_DEBOUNCE_MS) 29 | self.btn_select = Button(BUTTON_SELECT_PIN, True, BUTTON_DEBOUNCE_MS) 30 | self.btn_start = Button(BUTTON_START_PIN, True, BUTTON_DEBOUNCE_MS) 31 | self.btn_a = Button(BUTTON_A_PIN, True, BUTTON_DEBOUNCE_MS) 32 | self.btn_b = Button(BUTTON_B_PIN, True, BUTTON_DEBOUNCE_MS) 33 | 34 | def _init_speaker(self): 35 | self.speaker = Speaker(SPEAKER_PIN, SPEAKER_DAC_PIN) 36 | 37 | def _init_battery(self): 38 | self.battery = Battery(BATTERY_PIN, BATTERY_RESISTANCE_NUM, 39 | ADC.WIDTH_12BIT, ADC.ATTN_11DB) 40 | 41 | def begin(self): 42 | # LCD 43 | self.lcd.erase() 44 | self.lcd.fill(colors.BLACK) 45 | self.lcd.set_pos(0, 0) 46 | self.lcd.colors = colors 47 | self.lcd.fonts = fonts 48 | Pin(TFT_LED_PIN, Pin.OUT).value(1) 49 | 50 | # Buttons 51 | Pin(BUTTON_JOY_X_PIN, Pin.IN, Pin.PULL_UP) 52 | Pin(BUTTON_JOY_Y_PIN, Pin.IN, Pin.PULL_UP) 53 | Pin(BUTTON_MENU_PIN, Pin.IN, Pin.PULL_UP) 54 | Pin(BUTTON_VOLUME_PIN, Pin.IN, Pin.PULL_UP) 55 | Pin(BUTTON_SELECT_PIN, Pin.IN, Pin.PULL_UP) 56 | Pin(BUTTON_START_PIN, Pin.IN, Pin.PULL_UP) 57 | Pin(BUTTON_A_PIN, Pin.IN, Pin.PULL_UP) 58 | Pin(BUTTON_B_PIN, Pin.IN, Pin.PULL_UP) 59 | 60 | # Speaker 61 | self.speaker.set_volume(0.1) 62 | self.speaker.set_beep(262, 1) 63 | 64 | def update(self): 65 | self.btn_joy_x.read_axis() 66 | self.btn_joy_y.read_axis() 67 | self.btn_menu.read() 68 | self.btn_volume.read() 69 | self.btn_select.read() 70 | self.btn_start.read() 71 | self.btn_a.read() 72 | self.btn_b.read() 73 | 74 | 75 | GO = ODROID_GO() 76 | GO.begin() 77 | -------------------------------------------------------------------------------- /odroid_go/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .go_consts import * 2 | from .lcd import ILI9341, colors, fonts 3 | from .button import Button 4 | from .speaker import Speaker 5 | from .battery import Battery 6 | -------------------------------------------------------------------------------- /odroid_go/utils/battery/__init__.py: -------------------------------------------------------------------------------- 1 | from .battery import Battery -------------------------------------------------------------------------------- /odroid_go/utils/battery/battery.py: -------------------------------------------------------------------------------- 1 | """ 2 | A simple battery module for Micropython, only for ODROID-GO (ESP32). 3 | 4 | Created on: 2018. 7. 13 5 | Author: Joshua Yang (joshua.yang@hardkernel.com) 6 | """ 7 | 8 | from machine import Pin, ADC 9 | 10 | 11 | class Battery: 12 | """ 13 | TODO: Have to calibrate the results voltage using Vref on efuse. 14 | But the necessary functions seem not to be implemented to MicroPython yet. 15 | * esp_adc_cal_characterize() 16 | * esp_adc_cal_raw_to_voltage() 17 | 18 | This module calculate current battery voltage roughly for now. 19 | """ 20 | 21 | _adc1_pin = object() 22 | _sampling_count = 64 23 | _battery_resistance_num = 0 24 | 25 | def __init__(self, pin, resistance_num, width, atten): 26 | self._adc1_pin = ADC(Pin(pin)) 27 | self._adc1_pin.width(width) 28 | self._adc1_pin.atten(atten) 29 | 30 | self._battery_resistance_num = resistance_num 31 | 32 | def get_voltage(self): 33 | reading = 0 34 | for i in range(0, self._sampling_count): 35 | reading += self._adc1_pin.read() 36 | 37 | reading /= self._sampling_count 38 | 39 | return reading * self._battery_resistance_num / 1000 40 | -------------------------------------------------------------------------------- /odroid_go/utils/button/__init__.py: -------------------------------------------------------------------------------- 1 | from .button import Button 2 | -------------------------------------------------------------------------------- /odroid_go/utils/button/button.py: -------------------------------------------------------------------------------- 1 | """ 2 | A Micropython port of Arduino Button Library. 3 | 4 | Created on: 2018. 7. 6 5 | Author: Joshua Yang (joshua.yang@hardkernel.com) 6 | 7 | /*----------------------------------------------------------------------* 8 | * Arduino Button Library v1.0 * 9 | * Jack Christensen May 2011, published Mar 2012 * 10 | * * 11 | * Library for reading momentary contact switches like tactile button * 12 | * switches. Intended for use in state machine constructs. * 13 | * Use the read() function to read all buttons in the main loop, * 14 | * which should execute as fast as possible. * 15 | * * 16 | * This work is licensed under the Creative Commons Attribution- * 17 | * ShareAlike 3.0 Unported License. To view a copy of this license, * 18 | * visit http://creativecommons.org/licenses/by-sa/3.0/ or send a * 19 | * letter to Creative Commons, 171 Second Street, Suite 300, * 20 | * San Francisco, California, 94105, USA. * 21 | *----------------------------------------------------------------------*/ 22 | """ 23 | 24 | from machine import Pin, ADC 25 | import utime 26 | 27 | 28 | class Button: 29 | _pin = object() 30 | _invert = 0 31 | _state = 0 32 | _last_state = 0 33 | _changed = 0 34 | _axis = 0 35 | _time = 0 36 | _last_time = 0 37 | _last_change = 0 38 | _db_time = 0 39 | 40 | _debug_mode = False 41 | 42 | def __init__(self, pin, invert, db_time): 43 | self._pin = Pin(pin, Pin.IN, Pin.PULL_UP) 44 | self._invert = invert 45 | self._db_time = db_time 46 | 47 | self._state = self._pin.value() 48 | if self._invert != 0: 49 | self._state = not self._state 50 | self._time = utime.ticks_ms() 51 | self._last_state = self._state 52 | self._last_time = self._time 53 | self._last_change = self._time 54 | 55 | # self._debug_mode = True 56 | 57 | def _debug_message(self, results): 58 | if self._debug_mode: 59 | print(results) 60 | 61 | def read(self): 62 | ms = utime.ticks_ms() 63 | pin_val = self._pin.value() 64 | 65 | if self._invert != 0: 66 | pin_val = not pin_val 67 | 68 | if ms - self._last_change < self._db_time: 69 | self._last_time = self._time 70 | self._time = ms 71 | self._changed = 0 72 | 73 | return self._state 74 | else: 75 | self._last_time = self._time 76 | self._last_state = self._state 77 | self._state = pin_val 78 | self._time = ms 79 | 80 | if self._state != self._last_state: 81 | self._last_change = ms 82 | self._changed = 1 83 | else: 84 | self._changed = 0 85 | 86 | return self._state 87 | 88 | def read_axis(self): 89 | apin = ADC(self._pin) 90 | apin.atten(ADC.ATTN_11DB) 91 | val = apin.read() 92 | 93 | ms = utime.ticks_ms() 94 | pin_val = 0 95 | 96 | self._debug_message("val: " + str(val)) 97 | 98 | if val > 3900: 99 | pin_val = 1 100 | self._axis = 2 101 | elif 1500 < val < 2000: 102 | pin_val = 1 103 | self._axis = 1 104 | else: 105 | pin_val = 0 106 | self._axis = 0 107 | 108 | if self._invert == 0: 109 | pin_val = not pin_val 110 | 111 | if ms - self._last_change < self._db_time: 112 | self._last_time = self._time 113 | self._time = ms 114 | self._changed = 0 115 | else: 116 | self._last_time = self._time 117 | self._last_state = self._state 118 | self._state = pin_val 119 | self._time = ms 120 | 121 | if self._state != self._last_state: 122 | self._last_state = ms 123 | self._changed = 1 124 | else: 125 | self._changed = 0 126 | 127 | return self._state 128 | 129 | def is_pressed(self): 130 | return 0 if self._state == 0 else 1 131 | 132 | def is_axis_pressed(self): 133 | return self._axis if self._state else 0 134 | 135 | def is_released(self): 136 | return 1 if self._state == 0 else 0 137 | 138 | def was_pressed(self): 139 | return self._state and self._changed 140 | 141 | def was_axis_pressed(self): 142 | return self._axis if self._state and self._changed else 0 143 | 144 | def was_released(self): 145 | return (not self._state) and self._changed 146 | 147 | def pressed_for(self, ms): 148 | return 1 if (self._state == 1 and self._time - self._last_change >= ms) else 0 149 | 150 | def released_for(self, ms): 151 | return 1 if (self._state == 0 and self._time - self._last_change >= ms) else 0 152 | 153 | def last_change(self): 154 | return self._last_change 155 | -------------------------------------------------------------------------------- /odroid_go/utils/go_consts.py: -------------------------------------------------------------------------------- 1 | from micropython import const 2 | 3 | 4 | TFT_DC_PIN = const(21) 5 | TFT_CS_PIN = const(5) 6 | TFT_LED_PIN = const(14) 7 | TFT_MOSI_PIN = const(23) 8 | TFT_MISO_PIN = const(19) 9 | TFT_SCLK_PIN = const(18) 10 | 11 | BUTTON_A_PIN = const(32) 12 | BUTTON_B_PIN = const(33) 13 | BUTTON_MENU_PIN = const(13) 14 | BUTTON_SELECT_PIN = const(27) 15 | BUTTON_VOLUME_PIN = const(0) 16 | BUTTON_START_PIN = const(39) 17 | BUTTON_JOY_Y_PIN = const(35) 18 | BUTTON_JOY_X_PIN = const(34) 19 | BUTTON_DEBOUNCE_MS = const(5) 20 | 21 | SPEAKER_PIN = const(26) 22 | SPEAKER_DAC_PIN = const(25) 23 | SPEAKER_TONE_CHANNEL = const(0) 24 | 25 | BATTERY_PIN = const(36) 26 | BATTERY_RESISTANCE_NUM = const(2) 27 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jeffrey N. Magee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /odroid_go/utils/lcd/README.md: -------------------------------------------------------------------------------- 1 | # Micropython Driver for ILI9341 display 2 | 3 | 4 | This has been tested on an M5Stack module using the standard esp32 micropython port. The default font is the Adafruit glcdfont and additional fonts can be generated by a very slightly modified version of Peter Hinch's font-to-py program which includes a function in font file to return the pixel width of a string of characters. 5 | 6 | ![m5stack](image/m5stack.jpg) 7 | 8 | 9 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/__init__.py: -------------------------------------------------------------------------------- 1 | from .ili934xnew import ILI9341 2 | from .colors import * 3 | from .fonts import GLCDFONT, TT14, TT24, TT32 4 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/colors.py: -------------------------------------------------------------------------------- 1 | RED = const(0xF800) 2 | GREEN = const(0x07E0) 3 | BLUE = const(0x001F) 4 | BLACK = const(0x0000) 5 | WHITE = const(0xFFFF) -------------------------------------------------------------------------------- /odroid_go/utils/lcd/font_to_py.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | # Needs freetype-py>=1.0 4 | 5 | # Implements multi-pass solution to setting an exact font height 6 | 7 | # Some code adapted from Daniel Bader's work at the following URL 8 | # http://dbader.org/blog/monochrome-font-rendering-with-freetype-and-python 9 | 10 | # The MIT License (MIT) 11 | # 12 | # Copyright (c) 2016 Peter Hinch 13 | # 14 | # Permission is hereby granted, free of charge, to any person obtaining a copy 15 | # of this software and associated documentation files (the "Software"), to deal 16 | # in the Software without restriction, including without limitation the rights 17 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | # copies of the Software, and to permit persons to whom the Software is 19 | # furnished to do so, subject to the following conditions: 20 | # 21 | # The above copyright notice and this permission notice shall be included in 22 | # all copies or substantial portions of the Software. 23 | # 24 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | # THE SOFTWARE. 31 | 32 | import argparse 33 | import sys 34 | import os 35 | import freetype 36 | 37 | # UTILITIES FOR WRITING PYTHON SOURCECODE TO A FILE 38 | 39 | # ByteWriter takes as input a variable name and data values and writes 40 | # Python source to an output stream of the form 41 | # my_variable = b'\x01\x02\x03\x04\x05\x06\x07\x08'\ 42 | 43 | # Lines are broken with \ for readability. 44 | 45 | 46 | class ByteWriter(object): 47 | bytes_per_line = 16 48 | 49 | def __init__(self, stream, varname): 50 | self.stream = stream 51 | self.stream.write('{} =\\\n'.format(varname)) 52 | self.bytecount = 0 # For line breaks 53 | 54 | def _eol(self): 55 | self.stream.write("'\\\n") 56 | 57 | def _eot(self): 58 | self.stream.write("'\n") 59 | 60 | def _bol(self): 61 | self.stream.write("b'") 62 | 63 | # Output a single byte 64 | def obyte(self, data): 65 | if not self.bytecount: 66 | self._bol() 67 | self.stream.write('\\x{:02x}'.format(data)) 68 | self.bytecount += 1 69 | self.bytecount %= self.bytes_per_line 70 | if not self.bytecount: 71 | self._eol() 72 | 73 | # Output from a sequence 74 | def odata(self, bytelist): 75 | for byt in bytelist: 76 | self.obyte(byt) 77 | 78 | # ensure a correct final line 79 | def eot(self): # User force EOL if one hasn't occurred 80 | if self.bytecount: 81 | self._eot() 82 | self.stream.write('\n') 83 | 84 | 85 | # Define a global 86 | def var_write(stream, name, value): 87 | stream.write('{} = {}\n'.format(name, value)) 88 | 89 | # FONT HANDLING 90 | 91 | 92 | class Bitmap(object): 93 | """ 94 | A 2D bitmap image represented as a list of byte values. Each byte indicates 95 | the state of a single pixel in the bitmap. A value of 0 indicates that the 96 | pixel is `off` and any other value indicates that it is `on`. 97 | """ 98 | def __init__(self, width, height, pixels=None): 99 | self.width = width 100 | self.height = height 101 | self.pixels = pixels or bytearray(width * height) 102 | 103 | def display(self): 104 | """Print the bitmap's pixels.""" 105 | for row in range(self.height): 106 | for col in range(self.width): 107 | char = '#' if self.pixels[row * self.width + col] else '.' 108 | print(char, end='') 109 | print() 110 | print() 111 | 112 | def bitblt(self, src, row): 113 | """Copy all pixels from `src` into this bitmap""" 114 | srcpixel = 0 115 | dstpixel = row * self.width 116 | row_offset = self.width - src.width 117 | 118 | for _ in range(src.height): 119 | for _ in range(src.width): 120 | self.pixels[dstpixel] = src.pixels[srcpixel] 121 | srcpixel += 1 122 | dstpixel += 1 123 | dstpixel += row_offset 124 | 125 | # Horizontal mapping generator function 126 | def get_hbyte(self, reverse): 127 | for row in range(self.height): 128 | col = 0 129 | while True: 130 | bit = col % 8 131 | if bit == 0: 132 | if col >= self.width: 133 | break 134 | byte = 0 135 | if col < self.width: 136 | if reverse: 137 | byte |= self.pixels[row * self.width + col] << bit 138 | else: 139 | # Normal map MSB of byte 0 is (0, 0) 140 | byte |= self.pixels[row * self.width + col] << (7 - bit) 141 | if bit == 7: 142 | yield byte 143 | col += 1 144 | 145 | # Vertical mapping 146 | def get_vbyte(self, reverse): 147 | for col in range(self.width): 148 | row = 0 149 | while True: 150 | bit = row % 8 151 | if bit == 0: 152 | if row >= self.height: 153 | break 154 | byte = 0 155 | if row < self.height: 156 | if reverse: 157 | byte |= self.pixels[row * self.width + col] << (7 - bit) 158 | else: 159 | # Normal map MSB of byte 0 is (0, 7) 160 | byte |= self.pixels[row * self.width + col] << bit 161 | if bit == 7: 162 | yield byte 163 | row += 1 164 | 165 | 166 | class Glyph(object): 167 | def __init__(self, pixels, width, height, top, advance_width): 168 | self.bitmap = Bitmap(width, height, pixels) 169 | 170 | # The glyph bitmap's top-side bearing, i.e. the vertical distance from 171 | # the baseline to the bitmap's top-most scanline. 172 | self.top = top 173 | 174 | # Ascent and descent determine how many pixels the glyph extends 175 | # above or below the baseline. 176 | self.descent = max(0, self.height - self.top) 177 | self.ascent = max(0, max(self.top, self.height) - self.descent) 178 | 179 | # The advance width determines where to place the next character 180 | # horizontally, that is, how many pixels we move to the right to 181 | # draw the next glyph. 182 | self.advance_width = advance_width 183 | 184 | @property 185 | def width(self): 186 | return self.bitmap.width 187 | 188 | @property 189 | def height(self): 190 | return self.bitmap.height 191 | 192 | @staticmethod 193 | def from_glyphslot(slot): 194 | """Construct and return a Glyph object from a FreeType GlyphSlot.""" 195 | pixels = Glyph.unpack_mono_bitmap(slot.bitmap) 196 | width, height = slot.bitmap.width, slot.bitmap.rows 197 | top = slot.bitmap_top 198 | 199 | # The advance width is given in FreeType's 26.6 fixed point format, 200 | # which means that the pixel values are multiples of 64. 201 | advance_width = slot.advance.x / 64 202 | 203 | return Glyph(pixels, width, height, top, advance_width) 204 | 205 | @staticmethod 206 | def unpack_mono_bitmap(bitmap): 207 | """ 208 | Unpack a freetype FT_LOAD_TARGET_MONO glyph bitmap into a bytearray 209 | where each pixel is represented by a single byte. 210 | """ 211 | # Allocate a bytearray of sufficient size to hold the glyph bitmap. 212 | data = bytearray(bitmap.rows * bitmap.width) 213 | 214 | # Iterate over every byte in the glyph bitmap. Note that we're not 215 | # iterating over every pixel in the resulting unpacked bitmap -- 216 | # we're iterating over the packed bytes in the input bitmap. 217 | for row in range(bitmap.rows): 218 | for byte_index in range(bitmap.pitch): 219 | 220 | # Read the byte that contains the packed pixel data. 221 | byte_value = bitmap.buffer[row * bitmap.pitch + byte_index] 222 | 223 | # We've processed this many bits (=pixels) so far. This 224 | # determines where we'll read the next batch of pixels from. 225 | num_bits_done = byte_index * 8 226 | 227 | # Pre-compute where to write the pixels that we're going 228 | # to unpack from the current byte in the glyph bitmap. 229 | rowstart = row * bitmap.width + byte_index * 8 230 | 231 | # Iterate over every bit (=pixel) that's still a part of the 232 | # output bitmap. Sometimes we're only unpacking a fraction of 233 | # a byte because glyphs may not always fit on a byte boundary. 234 | # So we make sure to stop if we unpack past the current row 235 | # of pixels. 236 | for bit_index in range(min(8, bitmap.width - num_bits_done)): 237 | 238 | # Unpack the next pixel from the current glyph byte. 239 | bit = byte_value & (1 << (7 - bit_index)) 240 | 241 | # Write the pixel to the output bytearray. We ensure that 242 | # `off` pixels have a value of 0 and `on` pixels have a 243 | # value of 1. 244 | data[rowstart + bit_index] = 1 if bit else 0 245 | 246 | return data 247 | 248 | 249 | # A Font object is a dictionary of ASCII chars indexed by a character e.g. 250 | # myfont['a'] 251 | # Each entry comprises a list 252 | # [0] A Bitmap instance containing the character 253 | # [1] The width of the character data including advance (actual data stored) 254 | # Public attributes: 255 | # height (in pixels) of all characters 256 | # width (in pixels) for monospaced output (advance width of widest char) 257 | class Font(dict): 258 | def __init__(self, filename, size, minchar, maxchar, monospaced, defchar): 259 | super().__init__() 260 | self._face = freetype.Face(filename) 261 | if defchar is None: # Binary font 262 | self.charset = [chr(char) for char in range(minchar, maxchar + 1)] 263 | else: 264 | self.charset = [chr(defchar)] + [chr(char) for char in range(minchar, maxchar + 1)] 265 | self.max_width = self.get_dimensions(size) 266 | self.width = self.max_width if monospaced else 0 267 | for char in self.charset: # Populate dictionary 268 | self._render_char(char) 269 | 270 | # n-pass solution to setting a precise height. 271 | def get_dimensions(self, required_height): 272 | error = 0 273 | height = required_height 274 | for npass in range(10): 275 | height += error 276 | self._face.set_pixel_sizes(0, height) 277 | max_descent = 0 278 | 279 | # For each character in the charset string we get the glyph 280 | # and update the overall dimensions of the resulting bitmap. 281 | max_width = 0 282 | max_ascent = 0 283 | for char in self.charset: 284 | glyph = self._glyph_for_character(char) 285 | max_ascent = max(max_ascent, glyph.ascent) 286 | max_descent = max(max_descent, glyph.descent) 287 | # for a few chars e.g. _ glyph.width > glyph.advance_width 288 | max_width = int(max(max_width, glyph.advance_width, 289 | glyph.width)) 290 | 291 | new_error = required_height - (max_ascent + max_descent) 292 | if (new_error == 0) or (abs(new_error) - abs(error) == 0): 293 | break 294 | error = new_error 295 | self.height = int(max_ascent + max_descent) 296 | st = 'Height set in {} passes. Actual height {} pixels.\nMax character width {} pixels.' 297 | print(st.format(npass + 1, self.height, max_width)) 298 | self._max_descent = int(max_descent) 299 | return max_width 300 | 301 | 302 | def _glyph_for_character(self, char): 303 | # Let FreeType load the glyph for the given character and tell it to 304 | # render a monochromatic bitmap representation. 305 | self._face.load_char(char, freetype.FT_LOAD_RENDER | 306 | freetype.FT_LOAD_TARGET_MONO) 307 | return Glyph.from_glyphslot(self._face.glyph) 308 | 309 | def _render_char(self, char): 310 | glyph = self._glyph_for_character(char) 311 | char_width = int(max(glyph.width, glyph.advance_width)) # Actual width 312 | width = self.width if self.width else char_width # Space required if monospaced 313 | outbuffer = Bitmap(width, self.height) 314 | 315 | # The vertical drawing position should place the glyph 316 | # on the baseline as intended. 317 | row = self.height - int(glyph.ascent) - self._max_descent 318 | outbuffer.bitblt(glyph.bitmap, row) 319 | self[char] = [outbuffer, width, char_width] 320 | 321 | def stream_char(self, char, hmap, reverse): 322 | outbuffer, _, _ = self[char] 323 | if hmap: 324 | gen = outbuffer.get_hbyte(reverse) 325 | else: 326 | gen = outbuffer.get_vbyte(reverse) 327 | yield from gen 328 | 329 | def build_arrays(self, hmap, reverse): 330 | data = bytearray() 331 | index = bytearray((0, 0)) 332 | for char in self.charset: 333 | width = self[char][1] 334 | data += (width).to_bytes(2, byteorder='little') 335 | data += bytearray(self.stream_char(char, hmap, reverse)) 336 | index += (len(data)).to_bytes(2, byteorder='little') 337 | return data, index 338 | 339 | def build_binary_array(self, hmap, reverse, sig): 340 | data = bytearray((0x3f + sig, 0xe7, self.max_width, self.height)) 341 | for char in self.charset: 342 | width = self[char][2] 343 | data += bytes((width,)) 344 | data += bytearray(self.stream_char(char, hmap, reverse)) 345 | return data 346 | 347 | # PYTHON FILE WRITING 348 | 349 | STR01 = """# Code generated by font-to-py.py. 350 | # Font: {} 351 | version = '0.2' 352 | """ 353 | 354 | STR02 = """_mvfont = memoryview(_font) 355 | 356 | def _chr_addr(ordch): 357 | offset = 2 * (ordch - {}) 358 | return int.from_bytes(_index[offset:offset + 2], 'little') 359 | 360 | def get_width(s): 361 | width = 0 362 | for ch in s: 363 | ordch = ord(ch) 364 | ordch = ordch + 1 if ordch >= {} and ordch <= {} else 32 365 | offset = _chr_addr(ordch) 366 | width += int.from_bytes(_font[offset:offset + 2], 'little') 367 | return width 368 | 369 | def get_ch(ch): 370 | ordch = ord(ch) 371 | ordch = ordch + 1 if ordch >= {} and ordch <= {} else {} 372 | offset = _chr_addr(ordch) 373 | width = int.from_bytes(_font[offset:offset + 2], 'little') 374 | next_offs = _chr_addr(ordch +1) 375 | return _mvfont[offset + 2:next_offs], width 376 | 377 | """ 378 | 379 | def write_func(stream, name, arg): 380 | stream.write('def {}():\n return {}\n\n'.format(name, arg)) 381 | 382 | # filename, size, minchar=32, maxchar=126, monospaced=False, defchar=ord('?'): 383 | 384 | def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar, maxchar, defchar): 385 | try: 386 | fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar) 387 | except freetype.ft_errors.FT_Exception: 388 | print("Can't open", font_path) 389 | return False 390 | try: 391 | with open(op_path, 'w') as stream: 392 | write_data(stream, fnt, font_path, monospaced, hmap, reverse, minchar, maxchar) 393 | except OSError: 394 | print("Can't open", op_path, 'for writing') 395 | return False 396 | return True 397 | 398 | 399 | def write_data(stream, fnt, font_path, monospaced, hmap, reverse, minchar, maxchar): 400 | height = fnt.height # Actual height, not target height 401 | stream.write(STR01.format(os.path.split(font_path)[1])) 402 | stream.write('\n') 403 | write_func(stream, 'height', height) 404 | write_func(stream, 'max_width', fnt.max_width) 405 | write_func(stream, 'hmap', hmap) 406 | write_func(stream, 'reverse', reverse) 407 | write_func(stream, 'monospaced', monospaced) 408 | write_func(stream, 'min_ch', minchar) 409 | write_func(stream, 'max_ch', maxchar) 410 | data, index = fnt.build_arrays(hmap, reverse) 411 | bw_font = ByteWriter(stream, '_font') 412 | bw_font.odata(data) 413 | bw_font.eot() 414 | bw_index = ByteWriter(stream, '_index') 415 | bw_index.odata(index) 416 | bw_index.eot() 417 | stream.write(STR02.format(minchar, minchar, maxchar, minchar, maxchar, minchar)) 418 | 419 | # BINARY OUTPUT 420 | # hmap reverse magic bytes 421 | # 0 0 0x3f 0xe7 422 | # 1 0 0x40 0xe7 423 | # 0 1 0x41 0xe7 424 | # 1 1 0x42 0xe7 425 | def write_binary_font(op_path, font_path, height, hmap, reverse): 426 | try: 427 | fnt = Font(font_path, height, 32, 126, True, None) # All chars have same width 428 | except freetype.ft_errors.FT_Exception: 429 | print("Can't open", font_path) 430 | return False 431 | sig = 1 if hmap else 0 432 | if reverse: 433 | sig += 2 434 | try: 435 | with open(op_path, 'wb') as stream: 436 | data = fnt.build_binary_array(hmap, reverse, sig) 437 | stream.write(data) 438 | except OSError: 439 | print("Can't open", op_path, 'for writing') 440 | return False 441 | return True 442 | 443 | # PARSE COMMAND LINE ARGUMENTS 444 | 445 | def quit(msg): 446 | print(msg) 447 | sys.exit(1) 448 | 449 | DESC = """font_to_py.py 450 | Utility to convert ttf or otf font files to Python source. 451 | Sample usage: 452 | font_to_py.py FreeSans.ttf 23 freesans.py 453 | 454 | This creates a font with nominal height 23 pixels with these defaults: 455 | Mapping is vertical, pitch variable, character set 32-126 inclusive. 456 | Illegal characters will be rendered as "?". 457 | 458 | To specify monospaced rendering issue: 459 | font_to_py.py FreeSans.ttf 23 --fixed freesans.py 460 | """ 461 | 462 | BINARY = """Invalid arguments. Binary (random access) font files support the standard ASCII 463 | character set (from 32 to 126 inclusive). This range cannot be overridden. 464 | Random access font files don't support an error character. 465 | """ 466 | 467 | if __name__ == "__main__": 468 | parser = argparse.ArgumentParser(__file__, description=DESC, 469 | formatter_class=argparse.RawDescriptionHelpFormatter) 470 | parser.add_argument('infile', type=str, help='Input file path') 471 | parser.add_argument('height', type=int, help='Font height in pixels') 472 | parser.add_argument('outfile', type=str, 473 | help='Path and name of output file') 474 | 475 | parser.add_argument('-x', '--xmap', action='store_true', 476 | help='Horizontal (x) mapping') 477 | parser.add_argument('-r', '--reverse', action='store_true', 478 | help='Bit reversal') 479 | parser.add_argument('-f', '--fixed', action='store_true', 480 | help='Fixed width (monospaced) font') 481 | parser.add_argument('-b', '--binary', action='store_true', 482 | help='Produce binary (random access) font file.') 483 | 484 | parser.add_argument('-s', '--smallest', 485 | type = int, 486 | default = 32, 487 | help = 'Ordinal value of smallest character default %(default)i') 488 | 489 | parser.add_argument('-l', '--largest', 490 | type = int, 491 | help = 'Ordinal value of largest character default %(default)i', 492 | default = 126) 493 | 494 | parser.add_argument('-e', '--errchar', 495 | type = int, 496 | help = 'Ordinal value of error character default %(default)i ("?")', 497 | default = 63) 498 | 499 | args = parser.parse_args() 500 | if not args.infile[0].isalpha(): 501 | quit('Font filenames must be valid Python variable names.') 502 | 503 | if not os.path.isfile(args.infile): 504 | quit("Font filename does not exist") 505 | 506 | if not os.path.splitext(args.infile)[1].upper() in ('.TTF', '.OTF'): 507 | quit("Font file should be a ttf or otf file.") 508 | 509 | if args.binary: 510 | if os.path.splitext(args.outfile)[1].upper() == '.PY': 511 | quit('Binary file must not have a .py extension.') 512 | 513 | if args.smallest != 32 or args.largest != 126 or args.errchar != ord('?'): 514 | quit(BINARY) 515 | 516 | print('Writing binary font file.') 517 | if not write_binary_font(args.outfile, args.infile, args.height, 518 | args.xmap, args.reverse): 519 | sys.exit(1) 520 | else: 521 | if not os.path.splitext(args.outfile)[1].upper() == '.PY': 522 | quit('Output filename must have a .py extension.') 523 | 524 | if args.smallest < 0: 525 | quit('--smallest must be >= 0') 526 | 527 | if args.largest > 255: 528 | quit('--largest must be < 256') 529 | 530 | if args.errchar < 0 or args.errchar > 255: 531 | quit('--errchar must be between 0 and 255') 532 | 533 | print('Writing Python font file.') 534 | if not write_font(args.outfile, args.infile, args.height, args.fixed, 535 | args.xmap, args.reverse, args.smallest, args.largest, 536 | args.errchar): 537 | sys.exit(1) 538 | 539 | print(args.outfile, 'written successfully.') 540 | 541 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/fonts.py: -------------------------------------------------------------------------------- 1 | from . import glcdfont 2 | from . import tt14, tt24, tt32 3 | 4 | GLCDFONT = glcdfont 5 | TT14 = tt14 6 | TT24 = tt24 7 | TT32 = tt32 8 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/glcdfont.py: -------------------------------------------------------------------------------- 1 | # Original Adafruit_GFX 5x7 font 2 | 3 | def height(): 4 | return 8 5 | 6 | def max_width(): 7 | return 6 8 | 9 | def hmap(): 10 | return False 11 | 12 | def reverse(): 13 | return False 14 | 15 | def monospaced(): 16 | return True 17 | 18 | def min_ch(): 19 | return 0 20 | 21 | def max_ch(): 22 | return 255 23 | 24 | 25 | _font = \ 26 | b'\x00\x00\x00\x00\x00'\ 27 | b'\x3E\x5B\x4F\x5B\x3E'\ 28 | b'\x3E\x6B\x4F\x6B\x3E'\ 29 | b'\x1C\x3E\x7C\x3E\x1C'\ 30 | b'\x18\x3C\x7E\x3C\x18'\ 31 | b'\x1C\x57\x7D\x57\x1C'\ 32 | b'\x1C\x5E\x7F\x5E\x1C'\ 33 | b'\x00\x18\x3C\x18\x00'\ 34 | b'\xFF\xE7\xC3\xE7\xFF'\ 35 | b'\x00\x18\x24\x18\x00'\ 36 | b'\xFF\xE7\xDB\xE7\xFF'\ 37 | b'\x30\x48\x3A\x06\x0E'\ 38 | b'\x26\x29\x79\x29\x26'\ 39 | b'\x40\x7F\x05\x05\x07'\ 40 | b'\x40\x7F\x05\x25\x3F'\ 41 | b'\x5A\x3C\xE7\x3C\x5A'\ 42 | b'\x7F\x3E\x1C\x1C\x08'\ 43 | b'\x08\x1C\x1C\x3E\x7F'\ 44 | b'\x14\x22\x7F\x22\x14'\ 45 | b'\x5F\x5F\x00\x5F\x5F'\ 46 | b'\x06\x09\x7F\x01\x7F'\ 47 | b'\x00\x66\x89\x95\x6A'\ 48 | b'\x60\x60\x60\x60\x60'\ 49 | b'\x94\xA2\xFF\xA2\x94'\ 50 | b'\x08\x04\x7E\x04\x08'\ 51 | b'\x10\x20\x7E\x20\x10'\ 52 | b'\x08\x08\x2A\x1C\x08'\ 53 | b'\x08\x1C\x2A\x08\x08'\ 54 | b'\x1E\x10\x10\x10\x10'\ 55 | b'\x0C\x1E\x0C\x1E\x0C'\ 56 | b'\x30\x38\x3E\x38\x30'\ 57 | b'\x06\x0E\x3E\x0E\x06'\ 58 | b'\x00\x00\x00\x00\x00'\ 59 | b'\x00\x00\x5F\x00\x00'\ 60 | b'\x00\x07\x00\x07\x00'\ 61 | b'\x14\x7F\x14\x7F\x14'\ 62 | b'\x24\x2A\x7F\x2A\x12'\ 63 | b'\x23\x13\x08\x64\x62'\ 64 | b'\x36\x49\x56\x20\x50'\ 65 | b'\x00\x08\x07\x03\x00'\ 66 | b'\x00\x1C\x22\x41\x00'\ 67 | b'\x00\x41\x22\x1C\x00'\ 68 | b'\x2A\x1C\x7F\x1C\x2A'\ 69 | b'\x08\x08\x3E\x08\x08'\ 70 | b'\x00\x80\x70\x30\x00'\ 71 | b'\x08\x08\x08\x08\x08'\ 72 | b'\x00\x00\x60\x60\x00'\ 73 | b'\x20\x10\x08\x04\x02'\ 74 | b'\x3E\x51\x49\x45\x3E'\ 75 | b'\x00\x42\x7F\x40\x00'\ 76 | b'\x72\x49\x49\x49\x46'\ 77 | b'\x21\x41\x49\x4D\x33'\ 78 | b'\x18\x14\x12\x7F\x10'\ 79 | b'\x27\x45\x45\x45\x39'\ 80 | b'\x3C\x4A\x49\x49\x31'\ 81 | b'\x41\x21\x11\x09\x07'\ 82 | b'\x36\x49\x49\x49\x36'\ 83 | b'\x46\x49\x49\x29\x1E'\ 84 | b'\x00\x00\x14\x00\x00'\ 85 | b'\x00\x40\x34\x00\x00'\ 86 | b'\x00\x08\x14\x22\x41'\ 87 | b'\x14\x14\x14\x14\x14'\ 88 | b'\x00\x41\x22\x14\x08'\ 89 | b'\x02\x01\x59\x09\x06'\ 90 | b'\x3E\x41\x5D\x59\x4E'\ 91 | b'\x7C\x12\x11\x12\x7C'\ 92 | b'\x7F\x49\x49\x49\x36'\ 93 | b'\x3E\x41\x41\x41\x22'\ 94 | b'\x7F\x41\x41\x41\x3E'\ 95 | b'\x7F\x49\x49\x49\x41'\ 96 | b'\x7F\x09\x09\x09\x01'\ 97 | b'\x3E\x41\x41\x51\x73'\ 98 | b'\x7F\x08\x08\x08\x7F'\ 99 | b'\x00\x41\x7F\x41\x00'\ 100 | b'\x20\x40\x41\x3F\x01'\ 101 | b'\x7F\x08\x14\x22\x41'\ 102 | b'\x7F\x40\x40\x40\x40'\ 103 | b'\x7F\x02\x1C\x02\x7F'\ 104 | b'\x7F\x04\x08\x10\x7F'\ 105 | b'\x3E\x41\x41\x41\x3E'\ 106 | b'\x7F\x09\x09\x09\x06'\ 107 | b'\x3E\x41\x51\x21\x5E'\ 108 | b'\x7F\x09\x19\x29\x46'\ 109 | b'\x26\x49\x49\x49\x32'\ 110 | b'\x03\x01\x7F\x01\x03'\ 111 | b'\x3F\x40\x40\x40\x3F'\ 112 | b'\x1F\x20\x40\x20\x1F'\ 113 | b'\x3F\x40\x38\x40\x3F'\ 114 | b'\x63\x14\x08\x14\x63'\ 115 | b'\x03\x04\x78\x04\x03'\ 116 | b'\x61\x59\x49\x4D\x43'\ 117 | b'\x00\x7F\x41\x41\x41'\ 118 | b'\x02\x04\x08\x10\x20'\ 119 | b'\x00\x41\x41\x41\x7F'\ 120 | b'\x04\x02\x01\x02\x04'\ 121 | b'\x40\x40\x40\x40\x40'\ 122 | b'\x00\x03\x07\x08\x00'\ 123 | b'\x20\x54\x54\x78\x40'\ 124 | b'\x7F\x28\x44\x44\x38'\ 125 | b'\x38\x44\x44\x44\x28'\ 126 | b'\x38\x44\x44\x28\x7F'\ 127 | b'\x38\x54\x54\x54\x18'\ 128 | b'\x00\x08\x7E\x09\x02'\ 129 | b'\x18\xA4\xA4\x9C\x78'\ 130 | b'\x7F\x08\x04\x04\x78'\ 131 | b'\x00\x44\x7D\x40\x00'\ 132 | b'\x20\x40\x40\x3D\x00'\ 133 | b'\x7F\x10\x28\x44\x00'\ 134 | b'\x00\x41\x7F\x40\x00'\ 135 | b'\x7C\x04\x78\x04\x78'\ 136 | b'\x7C\x08\x04\x04\x78'\ 137 | b'\x38\x44\x44\x44\x38'\ 138 | b'\xFC\x18\x24\x24\x18'\ 139 | b'\x18\x24\x24\x18\xFC'\ 140 | b'\x7C\x08\x04\x04\x08'\ 141 | b'\x48\x54\x54\x54\x24'\ 142 | b'\x04\x04\x3F\x44\x24'\ 143 | b'\x3C\x40\x40\x20\x7C'\ 144 | b'\x1C\x20\x40\x20\x1C'\ 145 | b'\x3C\x40\x30\x40\x3C'\ 146 | b'\x44\x28\x10\x28\x44'\ 147 | b'\x4C\x90\x90\x90\x7C'\ 148 | b'\x44\x64\x54\x4C\x44'\ 149 | b'\x00\x08\x36\x41\x00'\ 150 | b'\x00\x00\x77\x00\x00'\ 151 | b'\x00\x41\x36\x08\x00'\ 152 | b'\x02\x01\x02\x04\x02'\ 153 | b'\x3C\x26\x23\x26\x3C'\ 154 | b'\x1E\xA1\xA1\x61\x12'\ 155 | b'\x3A\x40\x40\x20\x7A'\ 156 | b'\x38\x54\x54\x55\x59'\ 157 | b'\x21\x55\x55\x79\x41'\ 158 | b'\x21\x54\x54\x78\x41'\ 159 | b'\x21\x55\x54\x78\x40'\ 160 | b'\x20\x54\x55\x79\x40'\ 161 | b'\x0C\x1E\x52\x72\x12'\ 162 | b'\x39\x55\x55\x55\x59'\ 163 | b'\x39\x54\x54\x54\x59'\ 164 | b'\x39\x55\x54\x54\x58'\ 165 | b'\x00\x00\x45\x7C\x41'\ 166 | b'\x00\x02\x45\x7D\x42'\ 167 | b'\x00\x01\x45\x7C\x40'\ 168 | b'\xF0\x29\x24\x29\xF0'\ 169 | b'\xF0\x28\x25\x28\xF0'\ 170 | b'\x7C\x54\x55\x45\x00'\ 171 | b'\x20\x54\x54\x7C\x54'\ 172 | b'\x7C\x0A\x09\x7F\x49'\ 173 | b'\x32\x49\x49\x49\x32'\ 174 | b'\x32\x48\x48\x48\x32'\ 175 | b'\x32\x4A\x48\x48\x30'\ 176 | b'\x3A\x41\x41\x21\x7A'\ 177 | b'\x3A\x42\x40\x20\x78'\ 178 | b'\x00\x9D\xA0\xA0\x7D'\ 179 | b'\x39\x44\x44\x44\x39'\ 180 | b'\x3D\x40\x40\x40\x3D'\ 181 | b'\x3C\x24\xFF\x24\x24'\ 182 | b'\x48\x7E\x49\x43\x66'\ 183 | b'\x2B\x2F\xFC\x2F\x2B'\ 184 | b'\xFF\x09\x29\xF6\x20'\ 185 | b'\xC0\x88\x7E\x09\x03'\ 186 | b'\x20\x54\x54\x79\x41'\ 187 | b'\x00\x00\x44\x7D\x41'\ 188 | b'\x30\x48\x48\x4A\x32'\ 189 | b'\x38\x40\x40\x22\x7A'\ 190 | b'\x00\x7A\x0A\x0A\x72'\ 191 | b'\x7D\x0D\x19\x31\x7D'\ 192 | b'\x26\x29\x29\x2F\x28'\ 193 | b'\x26\x29\x29\x29\x26'\ 194 | b'\x30\x48\x4D\x40\x20'\ 195 | b'\x38\x08\x08\x08\x08'\ 196 | b'\x08\x08\x08\x08\x38'\ 197 | b'\x2F\x10\xC8\xAC\xBA'\ 198 | b'\x2F\x10\x28\x34\xFA'\ 199 | b'\x00\x00\x7B\x00\x00'\ 200 | b'\x08\x14\x2A\x14\x22'\ 201 | b'\x22\x14\x2A\x14\x08'\ 202 | b'\xAA\x00\x55\x00\xAA'\ 203 | b'\xAA\x55\xAA\x55\xAA'\ 204 | b'\x00\x00\x00\xFF\x00'\ 205 | b'\x10\x10\x10\xFF\x00'\ 206 | b'\x14\x14\x14\xFF\x00'\ 207 | b'\x10\x10\xFF\x00\xFF'\ 208 | b'\x10\x10\xF0\x10\xF0'\ 209 | b'\x14\x14\x14\xFC\x00'\ 210 | b'\x14\x14\xF7\x00\xFF'\ 211 | b'\x00\x00\xFF\x00\xFF'\ 212 | b'\x14\x14\xF4\x04\xFC'\ 213 | b'\x14\x14\x17\x10\x1F'\ 214 | b'\x10\x10\x1F\x10\x1F'\ 215 | b'\x14\x14\x14\x1F\x00'\ 216 | b'\x10\x10\x10\xF0\x00'\ 217 | b'\x00\x00\x00\x1F\x10'\ 218 | b'\x10\x10\x10\x1F\x10'\ 219 | b'\x10\x10\x10\xF0\x10'\ 220 | b'\x00\x00\x00\xFF\x10'\ 221 | b'\x10\x10\x10\x10\x10'\ 222 | b'\x10\x10\x10\xFF\x10'\ 223 | b'\x00\x00\x00\xFF\x14'\ 224 | b'\x00\x00\xFF\x00\xFF'\ 225 | b'\x00\x00\x1F\x10\x17'\ 226 | b'\x00\x00\xFC\x04\xF4'\ 227 | b'\x14\x14\x17\x10\x17'\ 228 | b'\x14\x14\xF4\x04\xF4'\ 229 | b'\x00\x00\xFF\x00\xF7'\ 230 | b'\x14\x14\x14\x14\x14'\ 231 | b'\x14\x14\xF7\x00\xF7'\ 232 | b'\x14\x14\x14\x17\x14'\ 233 | b'\x10\x10\x1F\x10\x1F'\ 234 | b'\x14\x14\x14\xF4\x14'\ 235 | b'\x10\x10\xF0\x10\xF0'\ 236 | b'\x00\x00\x1F\x10\x1F'\ 237 | b'\x00\x00\x00\x1F\x14'\ 238 | b'\x00\x00\x00\xFC\x14'\ 239 | b'\x00\x00\xF0\x10\xF0'\ 240 | b'\x10\x10\xFF\x10\xFF'\ 241 | b'\x14\x14\x14\xFF\x14'\ 242 | b'\x10\x10\x10\x1F\x00'\ 243 | b'\x00\x00\x00\xF0\x10'\ 244 | b'\xFF\xFF\xFF\xFF\xFF'\ 245 | b'\xF0\xF0\xF0\xF0\xF0'\ 246 | b'\xFF\xFF\xFF\x00\x00'\ 247 | b'\x00\x00\x00\xFF\xFF'\ 248 | b'\x0F\x0F\x0F\x0F\x0F'\ 249 | b'\x38\x44\x44\x38\x44'\ 250 | b'\x7C\x2A\x2A\x3E\x14'\ 251 | b'\x7E\x02\x02\x06\x06'\ 252 | b'\x02\x7E\x02\x7E\x02'\ 253 | b'\x63\x55\x49\x41\x63'\ 254 | b'\x38\x44\x44\x3C\x04'\ 255 | b'\x40\x7E\x20\x1E\x20'\ 256 | b'\x06\x02\x7E\x02\x02'\ 257 | b'\x99\xA5\xE7\xA5\x99'\ 258 | b'\x1C\x2A\x49\x2A\x1C'\ 259 | b'\x4C\x72\x01\x72\x4C'\ 260 | b'\x30\x4A\x4D\x4D\x30'\ 261 | b'\x30\x48\x78\x48\x30'\ 262 | b'\xBC\x62\x5A\x46\x3D'\ 263 | b'\x3E\x49\x49\x49\x00'\ 264 | b'\x7E\x01\x01\x01\x7E'\ 265 | b'\x2A\x2A\x2A\x2A\x2A'\ 266 | b'\x44\x44\x5F\x44\x44'\ 267 | b'\x40\x51\x4A\x44\x40'\ 268 | b'\x40\x44\x4A\x51\x40'\ 269 | b'\x00\x00\xFF\x01\x03'\ 270 | b'\xE0\x80\xFF\x00\x00'\ 271 | b'\x08\x08\x6B\x6B\x08'\ 272 | b'\x36\x12\x36\x24\x36'\ 273 | b'\x06\x0F\x09\x0F\x06'\ 274 | b'\x00\x00\x18\x18\x00'\ 275 | b'\x00\x00\x10\x10\x00'\ 276 | b'\x30\x40\xFF\x01\x01'\ 277 | b'\x00\x1F\x01\x01\x1E'\ 278 | b'\x00\x19\x1D\x17\x12'\ 279 | b'\x00\x3C\x3C\x3C\x3C'\ 280 | b'\x00\x00\x00\x00\x00' 281 | 282 | _mvfont = memoryview(_font) 283 | 284 | def get_width(s): 285 | return len(s)*6 286 | 287 | def get_ch(ch): 288 | ordch = ord(ch) 289 | offset = ordch*5 290 | buf = bytearray(6) 291 | buf[0] = 0 292 | buf[1:]=_mvfont[offset:offset+5] 293 | return buf, 6 294 | 295 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/ili934xnew.py: -------------------------------------------------------------------------------- 1 | # This is an adapted version of the ILI934X driver as below. 2 | # It works with multiple fonts and also works with the esp32 H/W SPI implementation 3 | # Also includes a word wrap print function 4 | # Proportional fonts are generated by Peter Hinch's Font-to-py 5 | # MIT License; Copyright (c) 2017 Jeffrey N. Magee 6 | 7 | # This file is part of MicroPython ILI934X driver 8 | # Copyright (c) 2016 - 2017 Radomir Dopieralski, Mika Tuupola 9 | # 10 | # Licensed under the MIT license: 11 | # http://www.opensource.org/licenses/mit-license.php 12 | # 13 | # Project home: 14 | # https://github.com/tuupola/micropython-ili934x 15 | 16 | import time 17 | import ustruct 18 | import framebuf 19 | from .fonts import GLCDFONT 20 | from micropython import const 21 | 22 | _RDDSDR = const(0x0f) # Read Display Self-Diagnostic Result 23 | _SLPOUT = const(0x11) # Sleep Out 24 | _GAMSET = const(0x26) # Gamma Set 25 | _DISPOFF = const(0x28) # Display Off 26 | _DISPON = const(0x29) # Display On 27 | _CASET = const(0x2a) # Column Address Set 28 | _PASET = const(0x2b) # Page Address Set 29 | _RAMWR = const(0x2c) # Memory Write 30 | _RAMRD = const(0x2e) # Memory Read 31 | _MADCTL = const(0x36) # Memory Access Control 32 | _VSCRSADD = const(0x37) # Vertical Scrolling Start Address 33 | _PIXSET = const(0x3a) # Pixel Format Set 34 | _PWCTRLA = const(0xcb) # Power Control A 35 | _PWCRTLB = const(0xcf) # Power Control B 36 | _DTCTRLA = const(0xe8) # Driver Timing Control A 37 | _DTCTRLB = const(0xea) # Driver Timing Control B 38 | _PWRONCTRL = const(0xed) # Power on Sequence Control 39 | _PRCTRL = const(0xf7) # Pump Ratio Control 40 | _PWCTRL1 = const(0xc0) # Power Control 1 41 | _PWCTRL2 = const(0xc1) # Power Control 2 42 | _VMCTRL1 = const(0xc5) # VCOM Control 1 43 | _VMCTRL2 = const(0xc7) # VCOM Control 2 44 | _FRMCTR1 = const(0xb1) # Frame Rate Control 1 45 | _DISCTRL = const(0xb6) # Display Function Control 46 | _INTFACE = const(0xf6) # Interface 47 | _ENA3G = const(0xf2) # Enable 3G 48 | _PGAMCTRL = const(0xe0) # Positive Gamma Control 49 | _NGAMCTRL = const(0xe1) # Negative Gamma Control 50 | 51 | _CHUNK = const(1024) #maximum number of pixels per spi write 52 | 53 | def color565(r, g, b): 54 | return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3 55 | 56 | class ILI9341: 57 | 58 | width = 320 59 | height = 240 60 | 61 | def __init__(self, spi, cs, dc, rst=None): 62 | self.spi = spi 63 | self.cs = cs 64 | self.dc = dc 65 | # self.rst = rst 66 | self.cs.init(self.cs.OUT, value=1) 67 | self.dc.init(self.dc.OUT, value=0) 68 | # self.rst.init(self.rst.OUT, value=0) 69 | # self.reset() 70 | self.init() 71 | self._scroll = 0 72 | self._buf = bytearray(_CHUNK * 2) 73 | self._colormap = bytearray(b'\x00\x00\xFF\xFF') #default white foregraound, black background 74 | self._x = 0 75 | self._y = 0 76 | self._font = GLCDFONT 77 | self.scrolling = False 78 | 79 | def set_color(self,fg,bg): 80 | self._colormap[0] = bg>>8 81 | self._colormap[1] = bg & 255 82 | self._colormap[2] = fg>>8 83 | self._colormap[3] = fg & 255 84 | 85 | def set_pos(self,x,y): 86 | self._x = x 87 | self._y = y 88 | 89 | def reset_scroll(self): 90 | self.scrolling = False 91 | self._scroll = 0 92 | self.scroll(0) 93 | 94 | def set_font(self, font): 95 | self._font = font 96 | 97 | def init(self): 98 | for command, data in ( 99 | (_RDDSDR, b"\x03\x80\x02"), 100 | (_PWCRTLB, b"\x00\xcf\x30"), 101 | (_PWRONCTRL, b"\x64\x03\x12\x81"), 102 | (_DTCTRLA, b"\x85\x00\x78"), 103 | (_PWCTRLA, b"\x39\x2c\x00\x34\x02"), 104 | (_PRCTRL, b"\x20"), 105 | (_DTCTRLB, b"\x00\x00"), 106 | (_PWCTRL1, b"\x1b"), 107 | (_PWCTRL2, b"\x12"), 108 | (_VMCTRL1, b"\x3e\x3c"), 109 | (_VMCTRL2, b"\x91"), 110 | (_MADCTL, b"\xa8"), 111 | (_PIXSET, b"\x55"), 112 | (_FRMCTR1, b"\x00\x1b"), 113 | (_DISCTRL, b"\x0a\xa2\x27"), 114 | (_INTFACE, b"\x01\x30"), 115 | (_ENA3G, b"\x00"), 116 | (_GAMSET, b"\x01"), 117 | (_PGAMCTRL, b"\x0f\x31\x2b\x0c\x0e\x08\x4e\xf1\x37\x07\x10\x03\x0e\x09\x00"), 118 | (_NGAMCTRL, b"\x00\x0e\x14\x03\x11\x07\x31\xc1\x48\x08\x0f\x0c\x31\x36\x0f")): 119 | self._write(command, data) 120 | self._write(_SLPOUT) 121 | time.sleep_ms(120) 122 | self._write(_DISPON) 123 | 124 | # def reset(self): 125 | # self.rst(0) 126 | # time.sleep_ms(50) 127 | # self.rst(1) 128 | # time.sleep_ms(50) 129 | 130 | def _write(self, command, data=None): 131 | self.dc(0) 132 | self.cs(0) 133 | self.spi.write(bytearray([command])) 134 | self.cs(1) 135 | if data is not None: 136 | self._data(data) 137 | 138 | def _data(self, data): 139 | self.dc(1) 140 | self.cs(0) 141 | self.spi.write(data) 142 | self.cs(1) 143 | 144 | def _writeblock(self, x0, y0, x1, y1, data=None): 145 | self._write(_CASET, ustruct.pack(">HH", x0, x1)) 146 | self._write(_PASET, ustruct.pack(">HH", y0, y1)) 147 | self._write(_RAMWR, data) 148 | 149 | def _readblock(self, x0, y0, x1, y1): 150 | self._write(_CASET, ustruct.pack(">HH", x0, x1)) 151 | self._write(_PASET, ustruct.pack(">HH", y0, y1)) 152 | if data is None: 153 | return self._read(_RAMRD, (x1 - x0 + 1) * (y1 - y0 + 1) * 3) 154 | 155 | def _read(self, command, count): 156 | self.dc(0) 157 | self.cs(0) 158 | self.spi.write(bytearray([command])) 159 | data = self.spi.read(count) 160 | self.cs(1) 161 | return data 162 | 163 | def pixel(self, x, y, color=None): 164 | if color is None: 165 | r, b, g = self._readblock(x, y, x, y) 166 | return color565(r, g, b) 167 | if not 0 <= x < self.width or not 0 <= y < self.height: 168 | return 169 | self._writeblock(x, y, x, y, ustruct.pack(">H", color)) 170 | 171 | def fill_rectangle(self, x, y, w, h, color=None): 172 | x = min(self.width - 1, max(0, x)) 173 | y = min(self.height - 1, max(0, y)) 174 | w = min(self.width - x, max(1, w)) 175 | h = min(self.height - y, max(1, h)) 176 | if color: 177 | color = ustruct.pack(">H", color) 178 | else: 179 | color = self._colormap[0:2] #background 180 | for i in range(_CHUNK): 181 | self._buf[2*i]=color[0]; self._buf[2*i+1]=color[1] 182 | chunks, rest = divmod(w * h, _CHUNK) 183 | self._writeblock(x, y, x + w - 1, y + h - 1, None) 184 | if chunks: 185 | for count in range(chunks): 186 | self._data(self._buf) 187 | if rest != 0: 188 | mv = memoryview(self._buf) 189 | self._data(mv[:rest*2]) 190 | 191 | def fill(self, color): 192 | self.fill_rectangle(0, 0, self.width, self.height, color) 193 | 194 | def erase(self): 195 | self.fill_rectangle(0, 0, self.width, self.height) 196 | 197 | def blit(self, bitbuff, x, y, w, h): 198 | x = min(self.width - 1, max(0, x)) 199 | y = min(self.height - 1, max(0, y)) 200 | w = min(self.width - x, max(1, w)) 201 | h = min(self.height - y, max(1, h)) 202 | chunks, rest = divmod(w * h, _CHUNK) 203 | self._writeblock(x, y, x + w - 1, y + h - 1, None) 204 | written = 0 205 | for iy in range(h): 206 | for ix in range(w): 207 | index = ix+iy*w - written 208 | if index >=_CHUNK: 209 | self._data(self._buf) 210 | written += _CHUNK 211 | index -= _CHUNK 212 | c = bitbuff.pixel(ix,iy) 213 | self._buf[index*2] = self._colormap[c*2] 214 | self._buf[index*2+1] = self._colormap[c*2+1] 215 | rest = w*h - written 216 | if rest != 0: 217 | mv = memoryview(self._buf) 218 | self._data(mv[:rest*2]) 219 | 220 | def chars(self, str, x, y): 221 | str_w = self._font.get_width(str) 222 | div, rem = divmod(self._font.height(),8) 223 | nbytes = div+1 if rem else div 224 | buf = bytearray(str_w * nbytes) 225 | pos = 0 226 | for ch in str: 227 | glyph, char_w = self._font.get_ch(ch) 228 | for row in range(nbytes): 229 | index = row*str_w + pos 230 | for i in range(char_w): 231 | buf[index+i] = glyph[nbytes*i+row] 232 | pos += char_w 233 | fb = framebuf.FrameBuffer(buf,str_w, self._font.height(), framebuf.MONO_VLSB) 234 | self.blit(fb,x,y,str_w,self._font.height()) 235 | return x+str_w 236 | 237 | def scroll(self, dy): 238 | self._scroll = (self._scroll + dy) % self.height 239 | self._write(_VSCRSADD, ustruct.pack(">H", self._scroll)) 240 | 241 | def next_line(self, cury, char_h): 242 | global scrolling 243 | if not self.scrolling: 244 | res = cury + char_h 245 | self.scrolling = (res >= self.height) 246 | if self.scrolling: 247 | self.scroll(char_h) 248 | res = (self.height - char_h + self._scroll)%self.height 249 | self.fill_rectangle(0, res, self.width, self._font.height()) 250 | return res 251 | 252 | def write(self, text): #does character wrap, compatible with stream output 253 | curx = self._x; cury = self._y 254 | char_h = self._font.height() 255 | width = 0 256 | written = 0 257 | for pos, ch in enumerate(text): 258 | if ch == '\n': 259 | if pos>0: 260 | self.chars(text[written:pos],curx,cury) 261 | curx = 0; written = pos+1; width = 0 262 | cury = self.next_line(cury,char_h) 263 | else: 264 | char_w = self._font.get_width(ch) 265 | if curx + width + char_w >= self.width: 266 | self.chars(text[written:pos], curx,cury) 267 | curx = 0 ; written = pos; width = char_h 268 | cury = self.next_line(cury,char_h) 269 | else: 270 | width += char_w 271 | if written= self.width: 285 | curx = self._x; cury = self.next_line(cury,char_h) 286 | while self._font.get_width(word) > self.width: 287 | self.chars(word[:self.width//char_w],curx,cury) 288 | word = word[self.width//char_w:] 289 | cury = self.next_line(cury,char_h) 290 | if len(word)>0: 291 | curx = self.chars(word+' ', curx,cury) 292 | curx = self._x; cury = self.next_line(cury,char_h) 293 | self._y = cury 294 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/m5stack.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of MicroPython M5Stack package 3 | # Copyright (c) 2017 Mika Tuupola 4 | # 5 | # Licensed under the MIT license: 6 | # http://www.opensource.org/licenses/mit-license.php 7 | # 8 | # Project home: 9 | # https://github.com/tuupola/micropython-m5stacj 10 | 11 | from micropython import const 12 | 13 | BUTTON_A_PIN = const(39) 14 | BUTTON_B_PIN = const(38) 15 | BUTTON_C_PIN = const(37) 16 | SPEAKER_PIN = const(25) 17 | 18 | TFT_LED_PIN = const(32) 19 | TFT_DC_PIN = const(27) 20 | TFT_CS_PIN = const(14) 21 | TFT_MOSI_PIN = const(23) 22 | TFT_CLK_PIN = const(18) 23 | TFT_RST_PIN = const(33) 24 | TFT_MISO_PIN = const(19) 25 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/main.py: -------------------------------------------------------------------------------- 1 | # test of printing multiple fonts to the ILI9341 on an M5Stack using H/W SP 2 | # MIT License; Copyright (c) 2017 Jeffrey N. Magee 3 | 4 | from ili934xnew import ILI9341, color565 5 | from machine import Pin, SPI 6 | import m5stack 7 | import tt14 8 | import glcdfont 9 | import tt14 10 | import tt24 11 | import tt32 12 | 13 | fonts = [glcdfont,tt14,tt24,tt32] 14 | 15 | text = 'Now is the time for all good men to come to the aid of the party.' 16 | 17 | power = Pin(m5stack.TFT_LED_PIN, Pin.OUT) 18 | power.value(1) 19 | 20 | spi = SPI( 21 | 2, 22 | baudrate=40000000, 23 | miso=Pin(m5stack.TFT_MISO_PIN), 24 | mosi=Pin(m5stack.TFT_MOSI_PIN), 25 | sck=Pin(m5stack.TFT_CLK_PIN)) 26 | 27 | display = ILI9341( 28 | spi, 29 | cs=Pin(m5stack.TFT_CS_PIN), 30 | dc=Pin(m5stack.TFT_DC_PIN), 31 | rst=Pin(m5stack.TFT_RST_PIN)) 32 | display.erase() 33 | display.set_pos(0,0) 34 | for ff in fonts: 35 | display.set_font(ff) 36 | display.print(text) 37 | 38 | 39 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/tt14.py: -------------------------------------------------------------------------------- 1 | # Code generated by font-to-py.py. 2 | # Font: CM Sans Serif 2012.ttf 3 | version = '0.2' 4 | 5 | def height(): 6 | return 15 7 | 8 | def max_width(): 9 | return 12 10 | 11 | def hmap(): 12 | return False 13 | 14 | def reverse(): 15 | return False 16 | 17 | def monospaced(): 18 | return False 19 | 20 | def min_ch(): 21 | return 32 22 | 23 | def max_ch(): 24 | return 126 25 | 26 | _font =\ 27 | b'\x08\x00\x08\x00\x0c\x00\x8c\x07\xcc\x07\xcc\x00\x7c\x00\x38\x00'\ 28 | b'\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\xfc\x06'\ 29 | b'\xfc\x06\x00\x00\x05\x00\x1c\x00\x3c\x00\x00\x00\x3c\x00\x00\x00'\ 30 | b'\x07\x00\x40\x03\xf0\x03\xf0\x03\x30\x03\xf0\x03\x30\x03\x30\x00'\ 31 | b'\x07\x00\x30\x00\x78\x03\x6c\x02\xfc\x07\xd8\x03\x90\x03\x00\x00'\ 32 | b'\x0b\x00\x18\x00\x3c\x00\x3c\x04\x3c\x03\xd8\x01\xf0\x03\xd8\x07'\ 33 | b'\xc4\x06\xc0\x07\x80\x03\x00\x00\x09\x00\x80\x03\xf8\x07\x7c\x06'\ 34 | b'\x4c\x06\xfc\x06\x98\x07\xc0\x07\xc0\x05\x00\x04\x02\x00\x1c\x00'\ 35 | b'\x3c\x00\x04\x00\xf0\x03\xfc\x0f\x0e\x1c\x02\x10\x05\x00\x02\x10'\ 36 | b'\x0e\x1c\xfc\x0f\xf0\x03\x00\x00\x05\x00\x0c\x00\x3c\x00\x18\x00'\ 37 | b'\x2c\x00\x0c\x00\x07\x00\xc0\x00\xc0\x00\xf0\x03\xf0\x03\xc0\x00'\ 38 | b'\xc0\x00\x00\x00\x03\x00\x00\x16\x00\x0e\x00\x00\x04\x00\xc0\x00'\ 39 | b'\xc0\x00\xc0\x00\xc0\x00\x03\x00\x00\x06\x00\x06\x00\x00\x04\x00'\ 40 | b'\x00\x06\xe0\x07\xfc\x00\x0e\x00\x08\x00\xf0\x01\xf8\x03\x1c\x07'\ 41 | b'\x0c\x06\x1c\x07\xf8\x03\xf0\x01\x00\x00\x04\x00\x18\x00\xfc\x07'\ 42 | b'\xfc\x07\x00\x00\x08\x00\x18\x04\x1c\x07\x8c\x06\x8c\x06\x4c\x06'\ 43 | b'\x7c\x06\x38\x06\x00\x00\x07\x00\x08\x02\x0c\x06\x0c\x06\x6c\x06'\ 44 | b'\x6c\x06\xfc\x07\xd8\x03\x07\x00\x80\x01\xe0\x01\xb0\x01\x9c\x01'\ 45 | b'\xfc\x07\xfc\x07\x80\x01\x07\x00\x00\x02\xfc\x06\x6c\x06\x6c\x06'\ 46 | b'\x6c\x06\xcc\x03\xc0\x03\x08\x00\xf0\x01\xf8\x03\x6c\x06\x6c\x06'\ 47 | b'\x6c\x06\xe8\x07\xc0\x03\x00\x00\x06\x00\x0c\x00\x0c\x07\xcc\x07'\ 48 | b'\xfc\x00\x1c\x00\x0c\x00\x07\x00\x98\x03\xfc\x07\x6c\x06\x6c\x06'\ 49 | b'\x6c\x06\xfc\x07\x98\x03\x08\x00\x78\x02\xfc\x06\xcc\x06\xcc\x06'\ 50 | b'\xcc\x06\xf8\x03\xf0\x01\x00\x00\x03\x00\x30\x06\x30\x06\x00\x00'\ 51 | b'\x03\x00\x30\x16\x30\x0e\x00\x00\x06\x00\xc0\x01\xc0\x01\x60\x03'\ 52 | b'\x60\x03\x30\x06\x00\x00\x06\x00\x60\x03\x60\x03\x60\x03\x60\x03'\ 53 | b'\x60\x03\x60\x03\x06\x00\x30\x06\x60\x03\x60\x03\x40\x01\xc0\x01'\ 54 | b'\x00\x00\x08\x00\x08\x00\x0c\x00\x8c\x07\xcc\x07\xcc\x00\x7c\x00'\ 55 | b'\x38\x00\x00\x00\x0b\x00\xe0\x00\xf8\x01\x18\x03\xec\x07\xbc\x07'\ 56 | b'\xfc\x06\xfc\x07\x9c\x03\xf8\x01\xf0\x00\x00\x00\x08\x00\x00\x06'\ 57 | b'\x80\x07\xf0\x01\x9c\x01\x8c\x01\xf8\x01\xc0\x07\x00\x07\x08\x00'\ 58 | b'\xfc\x07\xfc\x07\x6c\x06\x6c\x06\x6c\x06\xfc\x07\xd8\x03\x00\x00'\ 59 | b'\x09\x00\xe0\x00\xf8\x03\x18\x03\x0c\x06\x0c\x06\x0c\x06\x1c\x07'\ 60 | b'\x18\x03\x20\x01\x09\x00\xfc\x07\xfc\x07\x0c\x06\x0c\x06\x1c\x07'\ 61 | b'\xf8\x03\xf0\x01\x00\x00\x00\x00\x08\x00\xfc\x07\xfc\x07\x6c\x06'\ 62 | b'\x6c\x06\x6c\x06\x6c\x06\x0c\x06\x00\x00\x07\x00\xfc\x07\xfc\x07'\ 63 | b'\xcc\x00\xcc\x00\xcc\x00\xcc\x00\x0c\x00\x0a\x00\xe0\x01\xf8\x03'\ 64 | b'\x18\x07\x0c\x06\x0c\x06\xcc\x06\xdc\x02\xd8\x07\xe0\x07\x00\x00'\ 65 | b'\x09\x00\xfc\x07\xfc\x07\x60\x00\x60\x00\x60\x00\xfc\x07\xfc\x07'\ 66 | b'\x00\x00\x00\x00\x03\x00\xfc\x07\xfc\x07\x00\x00\x07\x00\x80\x03'\ 67 | b'\x80\x07\x00\x06\x00\x06\xfc\x07\xfc\x03\x00\x00\x08\x00\xfc\x07'\ 68 | b'\xfc\x07\x60\x00\xf0\x00\xd8\x01\x0c\x07\x04\x06\x04\x04\x07\x00'\ 69 | b'\xfc\x07\xfc\x07\x00\x06\x00\x06\x00\x06\x00\x06\x00\x00\x0b\x00'\ 70 | b'\xfc\x07\xfc\x07\x3c\x00\xe0\x03\x00\x06\xe0\x03\x3c\x00\xfc\x07'\ 71 | b'\xfc\x07\x00\x00\x00\x00\x09\x00\xfc\x07\xfc\x07\x38\x00\xe0\x00'\ 72 | b'\x80\x03\xfc\x07\xfc\x07\x00\x00\x00\x00\x0a\x00\xf0\x01\xf8\x03'\ 73 | b'\x1c\x07\x0c\x06\x0c\x06\x0c\x06\x1c\x07\xf8\x03\xf0\x01\x00\x00'\ 74 | b'\x09\x00\xfc\x07\xfc\x07\xcc\x00\xcc\x00\xcc\x00\xfc\x00\x78\x00'\ 75 | b'\x00\x00\x00\x00\x0a\x00\xf0\x01\xf8\x03\x1c\x07\x0c\x06\x8c\x06'\ 76 | b'\x8c\x07\x1c\x07\xf8\x07\xf0\x05\x00\x00\x09\x00\xfc\x07\xfc\x07'\ 77 | b'\xcc\x00\xcc\x00\xcc\x03\x7c\x07\x78\x04\x00\x00\x00\x00\x09\x00'\ 78 | b'\x38\x01\x3c\x03\x4c\x06\x4c\x06\x4c\x06\x4c\x06\x98\x07\x90\x03'\ 79 | b'\x00\x00\x07\x00\x0c\x00\x0c\x00\xfc\x07\xfc\x07\x0c\x00\x0c\x00'\ 80 | b'\x00\x00\x09\x00\xfc\x03\xfc\x07\x00\x06\x00\x06\x00\x06\xfc\x07'\ 81 | b'\xfc\x01\x00\x00\x00\x00\x08\x00\x0c\x00\x7c\x00\xe0\x03\x00\x07'\ 82 | b'\x80\x07\xf8\x01\x3c\x00\x04\x00\x0b\x00\x0c\x00\xfc\x00\xe0\x07'\ 83 | b'\x80\x07\xf8\x03\x1c\x00\xfc\x00\xc0\x07\x80\x07\xfc\x01\x1c\x00'\ 84 | b'\x08\x00\x04\x04\x0c\x07\xb8\x03\xf0\x00\xf0\x01\x9c\x07\x0c\x06'\ 85 | b'\x04\x04\x08\x00\x04\x00\x1c\x00\x78\x00\xe0\x07\xe0\x07\x78\x00'\ 86 | b'\x1c\x00\x04\x00\x07\x00\x0c\x06\x0c\x07\x8c\x07\xcc\x06\x2c\x06'\ 87 | b'\x1c\x06\x0c\x06\x04\x00\xff\x1f\xff\x1f\x03\x18\x00\x00\x04\x00'\ 88 | b'\x0e\x00\xfe\x00\xe0\x07\x00\x07\x04\x00\x03\x18\xff\x1f\xff\x1f'\ 89 | b'\x00\x00\x07\x00\x80\x00\xe0\x00\x7c\x00\x0c\x00\x7c\x00\xe0\x00'\ 90 | b'\x80\x00\x0a\x00\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18'\ 91 | b'\x00\x18\x00\x18\x00\x18\x00\x18\x05\x00\x04\x00\x0c\x00\x08\x00'\ 92 | b'\x00\x00\x00\x00\x08\x00\x00\x03\xe0\x07\xb0\x06\xb0\x06\xb0\x02'\ 93 | b'\xf0\x07\xe0\x07\x00\x00\x09\x00\xfe\x07\xfe\x07\x30\x02\x30\x06'\ 94 | b'\x30\x06\xe0\x07\xc0\x01\x00\x00\x00\x00\x07\x00\xc0\x01\xe0\x03'\ 95 | b'\x30\x06\x30\x06\x30\x06\x60\x03\x40\x01\x08\x00\xc0\x01\xf0\x07'\ 96 | b'\x30\x06\x30\x06\x30\x06\xfe\x07\xfe\x07\x00\x00\x07\x00\xc0\x01'\ 97 | b'\xe0\x03\xb0\x07\xb0\x07\xb0\x07\xe0\x03\xc0\x01\x04\x00\x20\x00'\ 98 | b'\xfc\x07\xfe\x07\x00\x00\x08\x00\xc0\x11\xf0\x1f\x30\x36\x30\x36'\ 99 | b'\x20\x36\xf0\x1f\xf0\x0f\x00\x00\x08\x00\xfe\x07\xfe\x07\x30\x00'\ 100 | b'\x30\x00\xf0\x07\xe0\x07\x00\x00\x00\x00\x03\x00\xfc\x07\xfc\x07'\ 101 | b'\x00\x00\x03\x00\xec\x7f\xec\x3f\x00\x00\x07\x00\xfe\x07\xfe\x07'\ 102 | b'\xc0\x00\xe0\x01\xb0\x07\x10\x06\x10\x04\x03\x00\xfe\x07\xfe\x07'\ 103 | b'\x00\x00\x0c\x00\xf0\x07\xf0\x07\x30\x00\x30\x00\xf0\x07\xe0\x07'\ 104 | b'\x30\x00\x30\x00\xf0\x07\xe0\x07\x00\x00\x00\x00\x08\x00\xf0\x07'\ 105 | b'\xf0\x07\x30\x00\x30\x00\xf0\x07\xe0\x07\x00\x00\x00\x00\x08\x00'\ 106 | b'\xc0\x01\xe0\x03\x30\x06\x30\x06\x30\x06\xe0\x03\xc0\x01\x00\x00'\ 107 | b'\x09\x00\xf0\x3f\xf0\x3f\x30\x06\x30\x06\x30\x06\xf0\x07\xc0\x01'\ 108 | b'\x00\x00\x00\x00\x08\x00\xc0\x01\xf0\x07\x30\x06\x30\x06\x30\x06'\ 109 | b'\xf0\x3f\xf0\x3f\x00\x00\x04\x00\xf0\x07\xf0\x07\x30\x00\x30\x00'\ 110 | b'\x08\x00\x60\x00\x70\x03\xb0\x07\xf0\x06\xb0\x06\xa0\x07\x00\x03'\ 111 | b'\x00\x00\x04\x00\x30\x00\xfe\x03\xfe\x07\x00\x00\x08\x00\xf0\x03'\ 112 | b'\xf0\x07\x00\x06\x00\x06\xf0\x07\xf0\x07\x00\x00\x00\x00\x07\x00'\ 113 | b'\x30\x00\xf0\x00\x80\x07\x00\x06\xc0\x03\xf0\x00\x10\x00\x0a\x00'\ 114 | b'\x30\x00\xf0\x01\x80\x07\xc0\x07\xf0\x00\xf0\x00\x80\x07\x80\x07'\ 115 | b'\xf0\x01\x30\x00\x07\x00\x10\x04\x30\x07\xe0\x03\xc0\x01\x70\x07'\ 116 | b'\x10\x06\x00\x04\x07\x00\x30\x00\xf0\x30\xc0\x3f\x00\x1f\xe0\x03'\ 117 | b'\x70\x00\x10\x00\x06\x00\x30\x06\x30\x07\xb0\x07\xf0\x06\x70\x06'\ 118 | b'\x30\x06\x05\x00\x40\x00\xbe\x0f\xbe\x0f\x00\x00\x00\x00\x04\x00'\ 119 | b'\xfe\x07\xfe\x07\x00\x00\x00\x00\x04\x00\xbe\x0f\xbe\x0f\x40\x00'\ 120 | b'\x00\x00\x05\x00\x04\x00\x04\x00\x04\x00\x06\x00\x04\x00' 121 | 122 | _index =\ 123 | b'\x00\x00\x12\x00\x1c\x00\x24\x00\x30\x00\x40\x00\x50\x00\x68\x00'\ 124 | b'\x7c\x00\x82\x00\x8c\x00\x98\x00\xa4\x00\xb4\x00\xbc\x00\xc6\x00'\ 125 | b'\xce\x00\xd8\x00\xea\x00\xf4\x00\x06\x01\x16\x01\x26\x01\x36\x01'\ 126 | b'\x48\x01\x56\x01\x66\x01\x78\x01\x80\x01\x88\x01\x96\x01\xa4\x01'\ 127 | b'\xb2\x01\xc4\x01\xdc\x01\xee\x01\x00\x02\x14\x02\x28\x02\x3a\x02'\ 128 | b'\x4a\x02\x60\x02\x74\x02\x7c\x02\x8c\x02\x9e\x02\xae\x02\xc6\x02'\ 129 | b'\xda\x02\xf0\x02\x04\x03\x1a\x03\x2e\x03\x42\x03\x52\x03\x66\x03'\ 130 | b'\x78\x03\x90\x03\xa2\x03\xb4\x03\xc4\x03\xce\x03\xd8\x03\xe2\x03'\ 131 | b'\xf2\x03\x08\x04\x14\x04\x26\x04\x3a\x04\x4a\x04\x5c\x04\x6c\x04'\ 132 | b'\x76\x04\x88\x04\x9a\x04\xa2\x04\xaa\x04\xba\x04\xc2\x04\xdc\x04'\ 133 | b'\xee\x04\x00\x05\x14\x05\x26\x05\x30\x05\x42\x05\x4c\x05\x5e\x05'\ 134 | b'\x6e\x05\x84\x05\x94\x05\xa4\x05\xb2\x05\xbe\x05\xc8\x05\xd2\x05'\ 135 | b'\xde\x05' 136 | 137 | _mvfont = memoryview(_font) 138 | 139 | def _chr_addr(ordch): 140 | offset = 2 * (ordch - 32) 141 | return int.from_bytes(_index[offset:offset + 2], 'little') 142 | 143 | def get_width(s): 144 | width = 0 145 | for ch in s: 146 | ordch = ord(ch) 147 | ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 148 | offset = _chr_addr(ordch) 149 | width += int.from_bytes(_font[offset:offset + 2], 'little') 150 | return width 151 | 152 | def get_ch(ch): 153 | ordch = ord(ch) 154 | ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 155 | offset = _chr_addr(ordch) 156 | width = int.from_bytes(_font[offset:offset + 2], 'little') 157 | next_offs = _chr_addr(ordch +1) 158 | return _mvfont[offset + 2:next_offs], width 159 | 160 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/tt24.py: -------------------------------------------------------------------------------- 1 | # Code generated by font-to-py.py. 2 | # Font: CM Sans Serif 2012.ttf 3 | version = '0.2' 4 | 5 | def height(): 6 | return 24 7 | 8 | def max_width(): 9 | return 20 10 | 11 | def hmap(): 12 | return False 13 | 14 | def reverse(): 15 | return False 16 | 17 | def monospaced(): 18 | return False 19 | 20 | def min_ch(): 21 | return 32 22 | 23 | def max_ch(): 24 | return 126 25 | 26 | _font =\ 27 | b'\x0c\x00\xc0\x00\x00\xf0\x00\x00\xf0\x00\x00\x78\x70\x07\x38\x78'\ 28 | b'\x07\x38\x7c\x07\x78\x1e\x00\xf0\x0f\x00\xf0\x07\x00\xc0\x03\x00'\ 29 | b'\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 30 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00'\ 31 | b'\x00\x02\xf8\x3f\x07\xf8\x3f\x07\xf8\x3f\x02\x00\x00\x00\x00\x00'\ 32 | b'\x00\x08\x00\xf8\x03\x00\xf8\x03\x00\x08\x00\x00\x00\x00\x00\xf8'\ 33 | b'\x03\x00\xf8\x03\x00\x08\x00\x00\x00\x00\x00\x0c\x00\x00\xe0\x00'\ 34 | b'\x80\xe3\x00\x80\xf3\x03\xe0\xff\x03\xe0\xff\x00\xe0\xe3\x00\x80'\ 35 | b'\xe3\x03\x80\xff\x03\xe0\xff\x01\xe0\xe7\x00\x80\xe3\x00\x80\x03'\ 36 | b'\x00\x0b\x00\x00\xe0\x00\xc0\xe3\x01\xe0\xc7\x01\x70\x8e\x03\xf8'\ 37 | b'\xef\x07\xf8\xff\x07\x70\x8c\x03\xe0\x9d\x01\xc0\xf9\x01\x00\xf0'\ 38 | b'\x00\x00\x00\x00\x12\x00\xe0\x01\x00\xf0\x03\x00\x38\x07\x00\x38'\ 39 | b'\x07\x04\x38\x07\x07\x38\xc7\x07\xf0\xf3\x01\xe0\x79\x00\x00\x1e'\ 40 | b'\x00\x80\x07\x00\xe0\xe3\x01\xf8\xf0\x03\x38\x38\x07\x08\x38\x07'\ 41 | b'\x00\x38\x07\x00\xf0\x03\x00\xe0\x01\x00\x00\x00\x0f\x00\x00\xf0'\ 42 | b'\x00\x00\xf8\x01\xe0\xfd\x03\xf0\x8f\x07\xf8\x07\x07\x38\x0e\x07'\ 43 | b'\x38\x1f\x07\xf8\x3f\x07\xf0\xfb\x07\xe0\xf0\x07\x00\xe0\x03\x00'\ 44 | b'\xf8\x07\x00\xf8\x07\x00\x78\x06\x00\x00\x04\x04\x00\xf8\x03\x00'\ 45 | b'\xf8\x03\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x7f\x00\xe0\xff'\ 46 | b'\x03\xf8\xff\x0f\x7c\x00\x1f\x0e\x00\x38\x02\x00\x20\x02\x00\x20'\ 47 | b'\x07\x00\x02\x00\x20\x0e\x00\x38\x7c\x00\x1f\xf8\xff\x0f\xe0\xff'\ 48 | b'\x03\x00\x7f\x00\x00\x00\x00\x09\x00\x60\x00\x00\x60\x00\x00\x78'\ 49 | b'\x03\x00\xf0\x01\x00\xe0\x00\x00\xf8\x03\x00\x68\x01\x00\x60\x00'\ 50 | b'\x00\x00\x00\x00\x0c\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ 51 | b'\x38\x00\x80\xff\x03\x80\xff\x03\x80\xff\x03\x00\x38\x00\x00\x38'\ 52 | b'\x00\x00\x38\x00\x00\x38\x00\x00\x00\x00\x05\x00\x00\x00\x37\x00'\ 53 | b'\x00\x3f\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x07\x00\x00\x38\x00'\ 54 | b'\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ 55 | b'\x38\x00\x05\x00\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00\x00'\ 56 | b'\x00\x00\x00\x08\x00\x00\x00\x06\x00\xe0\x07\x00\xfc\x07\xc0\xff'\ 57 | b'\x01\xf8\x3f\x00\xfc\x03\x00\x7c\x00\x00\x04\x00\x00\x0d\x00\x80'\ 58 | b'\x7f\x00\xe0\xff\x01\xf0\xff\x03\xf8\xc0\x07\x38\x00\x07\x38\x00'\ 59 | b'\x07\x38\x00\x07\xf8\xc0\x07\xf0\xff\x03\xe0\xff\x01\x80\x7f\x00'\ 60 | b'\x00\x00\x00\x00\x00\x00\x08\x00\xc0\x01\x00\xc0\x01\x00\xe0\x01'\ 61 | b'\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00\x00'\ 62 | b'\x0d\x00\xc0\x81\x07\xe0\xe1\x07\xf0\xe1\x07\x78\x70\x07\x38\x38'\ 63 | b'\x07\x38\x38\x07\x38\x1c\x07\x78\x1e\x07\xf0\x0f\x07\xf0\x07\x07'\ 64 | b'\xc0\x03\x07\x00\x00\x00\x00\x00\x00\x0c\x00\xc0\xc0\x00\xf0\xc0'\ 65 | b'\x03\xf0\xc0\x03\x78\x80\x07\x38\x00\x07\x38\x0e\x07\x38\x0e\x07'\ 66 | b'\x78\x9e\x07\xf0\xff\x03\xf0\xff\x03\xe0\xf1\x00\x00\x00\x00\x0c'\ 67 | b'\x00\x00\xf0\x00\x00\xf8\x00\x00\xfe\x00\x00\xef\x00\xc0\xe7\x00'\ 68 | b'\xf0\xe1\x00\xf8\xe0\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00'\ 69 | b'\xe0\x00\x00\xe0\x00\x0c\x00\x00\xce\x00\xf8\xcf\x03\xf8\xcf\x03'\ 70 | b'\x38\x8e\x07\x38\x07\x07\x38\x07\x07\x38\x07\x07\x38\x8f\x07\x38'\ 71 | b'\xfe\x03\x38\xfc\x01\x00\xf8\x00\x00\x00\x00\x0d\x00\x00\x7f\x00'\ 72 | b'\xe0\xff\x01\xf0\xff\x03\x78\x8e\x07\x38\x07\x07\x38\x07\x07\x38'\ 73 | b'\x07\x07\x78\x8f\x07\xf0\xfe\x03\xe0\xfc\x01\xc0\xf8\x00\x00\x00'\ 74 | b'\x00\x00\x00\x00\x0b\x00\x38\x00\x00\x38\x00\x00\x38\xc0\x07\x38'\ 75 | b'\xf8\x07\x38\xfe\x07\xb8\x3f\x00\xf8\x07\x00\xf8\x01\x00\xf8\x00'\ 76 | b'\x00\x78\x00\x00\x38\x00\x00\x0c\x00\x00\xf0\x00\xe0\xf9\x01\xf0'\ 77 | b'\xff\x03\xf0\x9f\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e'\ 78 | b'\x07\xf0\x9f\x07\xf0\xff\x03\xe0\xf9\x01\x00\xf0\x00\x0d\x00\xc0'\ 79 | b'\x07\x00\xe0\x0f\x01\xf0\x1f\x03\x78\x3c\x07\x38\x38\x07\x38\x38'\ 80 | b'\x07\x38\x38\x07\x38\x38\x07\x70\x9c\x07\xf0\xff\x03\xe0\xff\x01'\ 81 | b'\x80\x7f\x00\x00\x00\x00\x05\x00\x00\x07\x07\x00\x07\x07\x00\x07'\ 82 | b'\x07\x00\x00\x00\x00\x00\x00\x05\x00\x00\x07\x37\x00\x07\x3f\x00'\ 83 | b'\x07\x1f\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x38\x00\x00\x38\x00'\ 84 | b'\x00\x7c\x00\x00\x6c\x00\x00\xee\x00\x00\xee\x00\x00\xc7\x01\x00'\ 85 | b'\xc7\x01\x80\x83\x03\x00\x00\x00\x0b\x00\x00\xce\x01\x00\xce\x01'\ 86 | b'\x00\xce\x01\x00\xce\x01\x00\xce\x01\x00\xce\x01\x00\xce\x01\x00'\ 87 | b'\xce\x01\x00\xce\x01\x00\xce\x01\x00\x00\x00\x0a\x00\x80\x83\x03'\ 88 | b'\x80\x83\x03\x00\xc7\x01\x00\xc7\x01\x00\xee\x00\x00\xee\x00\x00'\ 89 | b'\x7c\x00\x00\x7c\x00\x00\x38\x00\x00\x00\x00\x0c\x00\xc0\x00\x00'\ 90 | b'\xf0\x00\x00\xf0\x00\x00\x78\x70\x07\x38\x78\x07\x38\x7c\x07\x78'\ 91 | b'\x1e\x00\xf0\x0f\x00\xf0\x07\x00\xc0\x03\x00\x00\x00\x00\x00\x00'\ 92 | b'\x00\x11\x00\x00\x3f\x00\xc0\xff\x00\xe0\xe1\x01\xf0\xc0\x03\x70'\ 93 | b'\xbc\x03\x78\x7e\x07\x38\x7f\x07\xb8\x73\x07\xb8\x33\x07\xb8\x3f'\ 94 | b'\x07\x38\x7f\x07\x70\xf3\x03\x70\x70\x03\xe0\x38\x02\xe0\x3f\x00'\ 95 | b'\x80\x0f\x00\x00\x00\x00\x0f\x00\x00\x00\x06\x00\xc0\x07\x00\xf0'\ 96 | b'\x07\x00\xfe\x03\xc0\xff\x00\xf8\xef\x00\xf8\xe1\x00\x78\xe0\x00'\ 97 | b'\xf8\xe3\x00\xf0\xff\x00\xc0\xff\x00\x00\xfe\x07\x00\xf0\x07\x00'\ 98 | b'\x80\x07\x00\x00\x04\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07'\ 99 | b'\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38'\ 100 | b'\x9e\x07\xf8\xff\x07\xf0\xff\x03\xe0\xf1\x01\x00\x00\x00\x00\x00'\ 101 | b'\x00\x00\x00\x00\x10\x00\x00\x3f\x00\xc0\xff\x00\xe0\xff\x01\xf0'\ 102 | b'\xe1\x03\x70\x80\x03\x78\x80\x07\x38\x00\x07\x38\x00\x07\x38\x00'\ 103 | b'\x07\x38\x00\x07\x78\x80\x03\xf0\xc0\x03\xe0\xc0\x01\xc0\xc0\x00'\ 104 | b'\x80\x40\x00\x00\x00\x00\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff'\ 105 | b'\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07'\ 106 | b'\x78\x80\x07\xf0\xc0\x03\xe0\xff\x01\xc0\xff\x00\x00\x3f\x00\x00'\ 107 | b'\x00\x00\x00\x00\x00\x0e\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07'\ 108 | b'\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38'\ 109 | b'\x0e\x07\x38\x0e\x07\x38\x00\x07\x38\x00\x07\x00\x00\x00\x00\x00'\ 110 | b'\x00\x0d\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x38\x1c\x00\x38'\ 111 | b'\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c'\ 112 | b'\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x3f\x00\xc0'\ 113 | b'\xff\x00\xe0\xff\x01\xf0\xe1\x03\x70\x80\x03\x78\x80\x07\x38\x00'\ 114 | b'\x07\x38\x00\x07\x38\x1c\x07\x38\x1c\x07\x78\x9c\x03\xf0\xdc\x01'\ 115 | b'\xe0\xfc\x07\xc0\xfc\x07\x80\xfc\x07\x00\x00\x00\x00\x00\x00\x0f'\ 116 | b'\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x0e\x00\x00\x0e\x00'\ 117 | b'\x00\x0e\x00\x00\x0e\x00\x00\x0e\x00\x00\x0e\x00\x00\x0e\x00\xf8'\ 118 | b'\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00\x00\x06\x00'\ 119 | b'\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00\x00\x00'\ 120 | b'\x00\x00\x0c\x00\x00\xe0\x00\x00\xe0\x01\x00\xe0\x03\x00\x80\x07'\ 121 | b'\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x80\x07\xf8\xff\x03\xf8'\ 122 | b'\xff\x03\xf8\xff\x00\x00\x00\x00\x0e\x00\xf8\xff\x07\xf8\xff\x07'\ 123 | b'\xf8\xff\x07\x00\x1e\x00\x00\x0f\x00\x80\x1f\x00\xc0\x7f\x00\xe0'\ 124 | b'\xf9\x00\xf0\xf0\x03\x78\xc0\x07\x38\x80\x07\x18\x00\x07\x08\x00'\ 125 | b'\x04\x00\x00\x00\x0c\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00'\ 126 | b'\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00'\ 127 | b'\x07\x00\x00\x07\x00\x00\x07\x00\x00\x00\x12\x00\xf8\xff\x07\xf8'\ 128 | b'\xff\x07\xf8\xff\x07\xf8\x01\x00\xf8\x1f\x00\xc0\xff\x00\x00\xfc'\ 129 | b'\x07\x00\xe0\x07\x00\xe0\x07\x00\xfc\x07\xc0\xff\x00\xf8\x1f\x00'\ 130 | b'\xf8\x01\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00'\ 131 | b'\x00\x00\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\xf8\x00\x00'\ 132 | b'\xe0\x03\x00\xc0\x0f\x00\x00\x3f\x00\x00\xfc\x00\x00\xf0\x01\x00'\ 133 | b'\xe0\x07\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00'\ 134 | b'\x00\x11\x00\x00\x3f\x00\xc0\xff\x00\xe0\xff\x01\xf0\xe1\x03\x70'\ 135 | b'\x80\x03\x78\x80\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07\x78\x80'\ 136 | b'\x07\x70\x80\x03\xf0\xe1\x03\xe0\xff\x01\xc0\xff\x00\x00\x3f\x00'\ 137 | b'\x00\x00\x00\x00\x00\x00\x0e\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff'\ 138 | b'\x07\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00'\ 139 | b'\x78\x1e\x00\xf0\x0f\x00\xf0\x0f\x00\xc0\x03\x00\x00\x00\x00\x00'\ 140 | b'\x00\x00\x11\x00\x00\x3f\x00\xc0\xff\x00\xe0\xff\x01\xf0\xe1\x03'\ 141 | b'\x70\x80\x03\x78\x80\x07\x38\x00\x07\x38\x10\x07\x38\x38\x07\x38'\ 142 | b'\x70\x07\x78\xf0\x07\x70\xe0\x03\xf0\xe1\x03\xe0\xff\x07\xc0\xff'\ 143 | b'\x03\x00\x3f\x02\x00\x00\x00\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8'\ 144 | b'\xff\x07\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x3c\x00\x38\xfc'\ 145 | b'\x00\x38\xfc\x03\x78\xfe\x07\xf0\x9f\x07\xf0\x0f\x07\xc0\x07\x04'\ 146 | b'\x00\x00\x00\x00\x00\x00\x0e\x00\x00\xc0\x00\xe0\xc1\x01\xf0\xe3'\ 147 | b'\x03\xf0\x87\x03\x78\x06\x07\x38\x0e\x07\x38\x0e\x07\x38\x0c\x07'\ 148 | b'\x38\x0c\x07\x78\x9c\x07\xf0\xf8\x03\xe0\xf8\x03\xc0\xf0\x00\x00'\ 149 | b'\x00\x00\x0c\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ 150 | b'\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x38\x00\x00\x38\x00\x00\x38'\ 151 | b'\x00\x00\x38\x00\x00\x00\x00\x00\x0e\x00\xf8\xff\x00\xf8\xff\x01'\ 152 | b'\xf8\xff\x03\x00\x80\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00'\ 153 | b'\x00\x07\x00\x80\x07\xf8\xff\x03\xf8\xff\x01\xf8\xff\x00\x00\x00'\ 154 | b'\x00\x00\x00\x00\x0e\x00\x18\x00\x00\xf8\x00\x00\xf8\x07\x00\xf0'\ 155 | b'\x3f\x00\x00\xff\x01\x00\xf8\x07\x00\x80\x07\x00\xe0\x07\x00\xfe'\ 156 | b'\x07\xc0\x7f\x00\xf8\x0f\x00\xf8\x01\x00\x38\x00\x00\x08\x00\x00'\ 157 | b'\x14\x00\x18\x00\x00\xf8\x01\x00\xf8\x1f\x00\xe0\xff\x00\x00\xfe'\ 158 | b'\x07\x00\xe0\x07\x00\xf8\x07\xc0\xff\x07\xf8\x3f\x00\xf8\x03\x00'\ 159 | b'\xf8\x01\x00\xf8\x3f\x00\xc0\xff\x07\x00\xf8\x07\x00\xc0\x07\x00'\ 160 | b'\xfe\x07\xe0\xff\x01\xf8\x1f\x00\xf8\x01\x00\x38\x00\x00\x0e\x00'\ 161 | b'\x08\x00\x04\x18\x00\x07\x78\x80\x07\xf8\xe0\x07\xf0\xf3\x01\xc0'\ 162 | b'\xff\x00\x00\x3f\x00\x80\x7f\x00\xe0\xff\x00\xf0\xf1\x03\xf8\xc0'\ 163 | b'\x07\x38\x80\x07\x18\x00\x06\x08\x00\x04\x0d\x00\x18\x00\x00\x38'\ 164 | b'\x00\x00\xf8\x00\x00\xf0\x03\x00\xc0\x0f\x00\x00\xff\x07\x00\xfc'\ 165 | b'\x07\x00\xff\x07\xc0\x0f\x00\xf0\x03\x00\xf8\x00\x00\x38\x00\x00'\ 166 | b'\x18\x00\x00\x0d\x00\x00\x00\x07\x38\x80\x07\x38\xc0\x07\x38\xe0'\ 167 | b'\x07\x38\x78\x07\x38\x3c\x07\x38\x1e\x07\x38\x0f\x07\xf8\x07\x07'\ 168 | b'\xf8\x01\x07\xf8\x00\x07\x78\x00\x07\x38\x00\x07\x07\x00\xff\xff'\ 169 | b'\x3f\xff\xff\x3f\xff\xff\x3f\x07\x00\x38\x07\x00\x38\x07\x00\x38'\ 170 | b'\x00\x00\x00\x08\x00\x04\x00\x00\x3c\x00\x00\xfc\x01\x00\xfc\x1f'\ 171 | b'\x00\xe0\xff\x00\x00\xfe\x07\x00\xf0\x07\x00\x00\x07\x07\x00\x07'\ 172 | b'\x00\x38\x07\x00\x38\x07\x00\x38\xff\xff\x3f\xff\xff\x3f\xff\xff'\ 173 | b'\x3f\x00\x00\x00\x0c\x00\x00\x18\x00\x00\x1f\x00\xc0\x1f\x00\xf8'\ 174 | b'\x03\x00\xf8\x00\x00\x78\x00\x00\xf8\x03\x00\xe0\x0f\x00\x00\x1f'\ 175 | b'\x00\x00\x1c\x00\x00\x10\x00\x00\x00\x00\x12\x00\x00\x00\x38\x00'\ 176 | b'\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ 177 | b'\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38'\ 178 | b'\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00'\ 179 | b'\x00\x38\x09\x00\x04\x00\x00\x04\x00\x00\x0c\x00\x00\x1c\x00\x00'\ 180 | b'\x18\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d'\ 181 | b'\x00\x00\xc0\x01\x00\xe4\x03\x00\xe6\x07\x00\x37\x07\x80\x37\x07'\ 182 | b'\x80\x33\x07\x80\x33\x07\x80\x33\x07\x80\x93\x03\x80\xff\x07\x00'\ 183 | b'\xff\x07\x00\xfe\x07\x00\x00\x00\x0e\x00\xfc\xff\x07\xfc\xff\x07'\ 184 | b'\xfc\xff\x07\x00\x87\x03\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80'\ 185 | b'\x03\x07\x80\x87\x07\x00\xff\x03\x00\xfe\x01\x00\xf8\x00\x00\x00'\ 186 | b'\x00\x00\x00\x00\x0d\x00\x00\x78\x00\x00\xfe\x01\x00\xff\x03\x00'\ 187 | b'\x87\x03\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x87'\ 188 | b'\x07\x00\x87\x03\x00\x86\x01\x00\x88\x00\x00\x00\x00\x0e\x00\x00'\ 189 | b'\x78\x00\x00\xfe\x01\x00\xff\x03\x00\x87\x03\x80\x87\x07\x80\x03'\ 190 | b'\x07\x80\x03\x07\x80\x03\x07\x80\x87\x07\x00\x87\x03\xfc\xff\x07'\ 191 | b'\xfc\xff\x07\xfc\xff\x07\x00\x00\x00\x0d\x00\x00\x30\x00\x00\xfc'\ 192 | b'\x00\x00\xfe\x01\x00\xff\x03\x80\x77\x07\x80\x73\x07\x80\x73\x07'\ 193 | b'\x80\x73\x07\x80\xf7\x07\x00\xff\x03\x00\x7e\x03\x00\x7c\x00\x00'\ 194 | b'\x60\x00\x07\x00\x80\x03\x00\xf0\xff\x07\xfc\xff\x07\xfc\xff\x07'\ 195 | b'\x9e\x03\x00\x8e\x03\x00\x00\x00\x00\x0e\x00\x00\x78\x00\x00\xfe'\ 196 | b'\x01\x00\xff\x23\x00\x87\x73\x80\x87\xf7\x80\x03\xe7\x80\x03\xe7'\ 197 | b'\x80\x03\xe7\x00\x87\xe7\x00\x87\xf3\x80\xff\x7f\x80\xff\x3f\x80'\ 198 | b'\xff\x1f\x00\x00\x00\x0d\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff\x07'\ 199 | b'\x00\x07\x00\x80\x03\x00\x80\x03\x00\x80\x03\x00\x80\x07\x00\x00'\ 200 | b'\xff\x07\x00\xff\x07\x00\xfc\x07\x00\x00\x00\x00\x00\x00\x05\x00'\ 201 | b'\xb8\xff\x07\xb8\xff\x07\xb8\xff\x07\x00\x00\x00\x00\x00\x00\x05'\ 202 | b'\x00\x00\x00\xe0\x00\x00\xe0\xb8\xff\xff\xb8\xff\xff\xb8\xff\x7f'\ 203 | b'\x0c\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff\x07\x00\x78\x00\x00\x3c'\ 204 | b'\x00\x00\xfe\x00\x80\xff\x01\x80\xe7\x07\x80\x83\x07\x80\x01\x07'\ 205 | b'\x80\x00\x04\x00\x00\x00\x05\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff'\ 206 | b'\x07\x00\x00\x00\x00\x00\x00\x14\x00\x80\xff\x07\x80\xff\x07\x80'\ 207 | b'\xff\x07\x00\x07\x00\x80\x03\x00\x80\x03\x00\x80\x03\x00\x80\x07'\ 208 | b'\x00\x00\xff\x07\x00\xfe\x07\x00\xff\x07\x80\x07\x00\x80\x03\x00'\ 209 | b'\x80\x03\x00\x80\x07\x00\x00\xff\x07\x00\xff\x07\x00\xfc\x07\x00'\ 210 | b'\x00\x00\x00\x00\x00\x0d\x00\x80\xff\x07\x80\xff\x07\x80\xff\x07'\ 211 | b'\x00\x07\x00\x80\x03\x00\x80\x03\x00\x80\x03\x00\x80\x07\x00\x00'\ 212 | b'\xff\x07\x00\xff\x07\x00\xfc\x07\x00\x00\x00\x00\x00\x00\x0d\x00'\ 213 | b'\x00\x78\x00\x00\xfe\x01\x00\xff\x03\x00\x87\x03\x80\x03\x07\x80'\ 214 | b'\x03\x07\x80\x03\x07\x80\x03\x07\x00\x87\x03\x00\xff\x03\x00\xfe'\ 215 | b'\x01\x00\x78\x00\x00\x00\x00\x0e\x00\x80\xff\xff\x80\xff\xff\x80'\ 216 | b'\xff\xff\x00\x87\x03\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x03'\ 217 | b'\x07\x80\x87\x07\x00\xff\x03\x00\xfe\x01\x00\x7c\x00\x00\x00\x00'\ 218 | b'\x00\x00\x00\x0e\x00\x00\x78\x00\x00\xfe\x01\x00\xff\x03\x00\x87'\ 219 | b'\x03\x80\x87\x07\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x87\x07'\ 220 | b'\x00\x87\x03\x80\xff\xff\x80\xff\xff\x80\xff\xff\x00\x00\x00\x08'\ 221 | b'\x00\x80\xff\x07\x80\xff\x07\x80\xff\x07\x00\x07\x00\x80\x03\x00'\ 222 | b'\x80\x03\x00\x80\x03\x00\x00\x00\x00\x0c\x00\x00\x80\x00\x00\x8e'\ 223 | b'\x01\x00\x9f\x03\x80\x9f\x07\x80\x3b\x07\x80\x33\x07\x80\x33\x07'\ 224 | b'\x80\x33\x07\x00\xf7\x07\x00\xe7\x03\x00\xc6\x01\x00\x00\x00\x07'\ 225 | b'\x00\x80\x03\x00\xfc\xff\x00\xfc\xff\x03\xfc\xff\x07\x80\x03\x07'\ 226 | b'\x80\x03\x07\x00\x00\x00\x0d\x00\x80\xff\x00\x80\xff\x03\x80\xff'\ 227 | b'\x03\x00\x80\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x80\x03'\ 228 | b'\x80\xff\x07\x80\xff\x07\x80\xff\x07\x00\x00\x00\x00\x00\x00\x0c'\ 229 | b'\x00\x80\x01\x00\x80\x0f\x00\x80\x3f\x00\x00\xfe\x01\x00\xf0\x07'\ 230 | b'\x00\x80\x07\x00\xc0\x07\x00\xf8\x07\x00\xff\x00\x80\x3f\x00\x80'\ 231 | b'\x07\x00\x80\x00\x00\x12\x00\x80\x01\x00\x80\x0f\x00\x80\xff\x00'\ 232 | b'\x00\xfe\x07\x00\xe0\x07\x00\xc0\x07\x00\xfc\x07\x80\xff\x00\x80'\ 233 | b'\x0f\x00\x80\x3f\x00\x00\xff\x01\x00\xf0\x07\x00\x80\x07\x00\xf8'\ 234 | b'\x07\x80\xff\x03\x80\x3f\x00\x80\x07\x00\x80\x00\x00\x0c\x00\x80'\ 235 | b'\x00\x04\x80\x01\x07\x80\x87\x07\x80\xef\x07\x00\xfe\x01\x00\x7c'\ 236 | b'\x00\x00\xfe\x00\x00\xff\x03\x80\xc7\x07\x80\x03\x07\x80\x00\x06'\ 237 | b'\x00\x00\x04\x0c\x00\x80\x01\x00\x80\x07\xe0\x80\x3f\xe0\x00\xff'\ 238 | b'\xf0\x00\xf8\xff\x00\xc0\x7f\x00\xc0\x1f\x00\xf8\x07\x00\xff\x00'\ 239 | b'\x80\x1f\x00\x80\x07\x00\x80\x00\x00\x0b\x00\x80\x03\x07\x80\x83'\ 240 | b'\x07\x80\xc3\x07\x80\xe3\x07\x80\xf3\x07\x80\x7b\x07\x80\x3f\x07'\ 241 | b'\x80\x1f\x07\x80\x0f\x07\x80\x07\x07\x00\x00\x07\x08\x00\x00\x0c'\ 242 | b'\x00\x00\x1e\x00\xfc\xff\x0f\xfe\xff\x1f\xfe\xf3\x1f\x06\x00\x38'\ 243 | b'\x06\x00\x38\x00\x00\x00\x05\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff'\ 244 | b'\x07\x00\x00\x00\x00\x00\x00\x07\x00\x06\x00\x38\xfe\xf3\x1f\xfe'\ 245 | b'\xff\x1f\xfc\xff\x0f\x00\x1e\x00\x00\x0c\x00\x00\x00\x00\x09\x00'\ 246 | b'\x18\x00\x00\x0c\x00\x00\x0c\x00\x00\x0c\x00\x00\x18\x00\x00\x18'\ 247 | b'\x00\x00\x1c\x00\x00\x04\x00\x00\x00\x00\x00' 248 | 249 | _index =\ 250 | b'\x00\x00\x26\x00\x3d\x00\x51\x00\x6b\x00\x91\x00\xb4\x00\xec\x00'\ 251 | b'\x1b\x01\x29\x01\x40\x01\x57\x01\x74\x01\x9a\x01\xab\x01\xc2\x01'\ 252 | b'\xd3\x01\xed\x01\x16\x02\x30\x02\x59\x02\x7f\x02\xa5\x02\xcb\x02'\ 253 | b'\xf4\x02\x17\x03\x3d\x03\x66\x03\x77\x03\x88\x03\xa8\x03\xcb\x03'\ 254 | b'\xeb\x03\x11\x04\x46\x04\x75\x04\xa4\x04\xd6\x04\x05\x05\x31\x05'\ 255 | b'\x5a\x05\x8f\x05\xbe\x05\xd2\x05\xf8\x05\x24\x06\x4a\x06\x82\x06'\ 256 | b'\xb1\x06\xe6\x06\x12\x07\x47\x07\x76\x07\xa2\x07\xc8\x07\xf4\x07'\ 257 | b'\x20\x08\x5e\x08\x8a\x08\xb3\x08\xdc\x08\xf3\x08\x0d\x09\x24\x09'\ 258 | b'\x4a\x09\x82\x09\x9f\x09\xc8\x09\xf4\x09\x1d\x0a\x49\x0a\x72\x0a'\ 259 | b'\x89\x0a\xb5\x0a\xde\x0a\xef\x0a\x00\x0b\x26\x0b\x37\x0b\x75\x0b'\ 260 | b'\x9e\x0b\xc7\x0b\xf3\x0b\x1f\x0c\x39\x0c\x5f\x0c\x76\x0c\x9f\x0c'\ 261 | b'\xc5\x0c\xfd\x0c\x23\x0d\x49\x0d\x6c\x0d\x86\x0d\x97\x0d\xae\x0d'\ 262 | b'\xcb\x0d' 263 | 264 | _mvfont = memoryview(_font) 265 | 266 | def _chr_addr(ordch): 267 | offset = 2 * (ordch - 32) 268 | return int.from_bytes(_index[offset:offset + 2], 'little') 269 | 270 | def get_width(s): 271 | width = 0 272 | for ch in s: 273 | ordch = ord(ch) 274 | ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 275 | offset = _chr_addr(ordch) 276 | width += int.from_bytes(_font[offset:offset + 2], 'little') 277 | return width 278 | 279 | def get_ch(ch): 280 | ordch = ord(ch) 281 | ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 282 | offset = _chr_addr(ordch) 283 | width = int.from_bytes(_font[offset:offset + 2], 'little') 284 | next_offs = _chr_addr(ordch +1) 285 | return _mvfont[offset + 2:next_offs], width 286 | 287 | -------------------------------------------------------------------------------- /odroid_go/utils/lcd/tt32.py: -------------------------------------------------------------------------------- 1 | # Code generated by font-to-py.py. 2 | # Font: CM Sans Serif 2012.ttf 3 | version = '0.2' 4 | 5 | def height(): 6 | return 31 7 | 8 | def max_width(): 9 | return 26 10 | 11 | def hmap(): 12 | return False 13 | 14 | def reverse(): 15 | return False 16 | 17 | def monospaced(): 18 | return False 19 | 20 | def min_ch(): 21 | return 32 22 | 23 | def max_ch(): 24 | return 126 25 | 26 | _font =\ 27 | b'\x0f\x00\x00\x07\x00\x00\xc0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07'\ 28 | b'\x00\x00\xf0\x01\x67\x00\xf0\xc0\xf7\x00\xf0\xe0\xf7\x00\xf0\xe0'\ 29 | b'\x67\x00\xf0\xf1\x01\x00\xe0\xff\x00\x00\xe0\x7f\x00\x00\xc0\x3f'\ 30 | b'\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00'\ 31 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 32 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 33 | b'\x00\x00\x00\x00\x08\x00\xf0\xff\xf3\x00\xf0\xff\xf3\x00\xf0\xff'\ 34 | b'\xf3\x00\xf0\xff\x63\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 35 | b'\x00\x00\x00\x00\x00\x00\x0a\x00\xf0\x0f\x00\x00\xf0\x0f\x00\x00'\ 36 | b'\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\x00\x00'\ 37 | b'\xf0\x0f\x00\x00\xf0\x0f\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00'\ 38 | b'\x0f\x00\x00\x00\x0e\x00\x00\x0e\x0e\x00\x00\x0e\x7e\x00\x00\xfe'\ 39 | b'\x7f\x00\xe0\xff\x7f\x00\xe0\xff\x0f\x00\xe0\x0f\x0e\x00\x00\x0e'\ 40 | b'\x0e\x00\x00\x0e\x7f\x00\x00\xfe\x7f\x00\xe0\xff\x7f\x00\xe0\xff'\ 41 | b'\x0f\x00\xe0\x0f\x0e\x00\x00\x0e\x0e\x00\x00\x0e\x00\x00\x0e\x00'\ 42 | b'\x00\x1f\x0e\x00\x80\x3f\x1e\x00\xc0\x3f\x3e\x00\xc0\x79\x3c\x00'\ 43 | b'\xc0\x71\x38\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xc0\xe1\x38\x00'\ 44 | b'\xc0\xe3\x38\x00\xc0\xe7\x3f\x00\x80\xc7\x1f\x00\x00\x86\x0f\x00'\ 45 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x80\x07\x00\x00\xc0\x0f'\ 46 | b'\x00\x00\xe0\x1f\x00\x00\xf0\x3c\x00\x00\x70\x38\x80\x00\x70\x38'\ 47 | b'\xe0\x00\x70\x38\xf8\x00\xf0\x3c\x7e\x00\xe0\x1f\x1f\x00\xc0\xcf'\ 48 | b'\x0f\x00\x80\xf7\x03\x00\x00\xfc\x00\x00\x00\x3f\x1e\x00\x80\x8f'\ 49 | b'\x7f\x00\xe0\x87\x7f\x00\xf0\xc1\xf3\x00\x70\xc0\xe1\x00\x10\xc0'\ 50 | b'\xe1\x00\x00\xc0\xf3\x00\x00\x80\x7f\x00\x00\x80\x7f\x00\x00\x00'\ 51 | b'\x1e\x00\x00\x00\x00\x00\x13\x00\x00\x00\x0f\x00\x00\x80\x3f\x00'\ 52 | b'\x00\xc0\x3f\x00\x80\xe7\x7f\x00\xe0\x7f\xf8\x00\xe0\x3f\xf8\x00'\ 53 | b'\xf0\x3f\xf0\x00\xf0\x78\xf0\x00\xf0\xf8\xf0\x00\xf0\xff\xf3\x00'\ 54 | b'\xe0\xdf\xff\x00\xe0\x8f\xff\x00\x80\x07\x7e\x00\x00\xc0\xff\x00'\ 55 | b'\x00\xc0\xff\x00\x00\xc0\xff\x00\x00\xc0\xc3\x00\x00\x00\x80\x00'\ 56 | b'\x00\x00\x00\x00\x05\x00\xf0\x0f\x00\x00\xf0\x0f\x00\x00\xf0\x0f'\ 57 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\xfc\x03\x00'\ 58 | b'\x80\xff\x1f\x00\xe0\xff\x7f\x00\xf8\xff\xff\x01\xfc\x01\xf8\x03'\ 59 | b'\x3e\x00\xc0\x07\x0e\x00\x00\x07\x02\x00\x00\x04\x00\x00\x00\x00'\ 60 | b'\x09\x00\x02\x00\x00\x04\x0e\x00\x00\x07\x3e\x00\xc0\x07\xfc\x01'\ 61 | b'\xf8\x03\xf8\xff\xff\x01\xe0\xff\x7f\x00\x80\xff\x1f\x00\x00\xfc'\ 62 | b'\x03\x00\x00\x00\x00\x00\x0b\x00\x80\x01\x00\x00\xa0\x09\x00\x00'\ 63 | b'\xf0\x1f\x00\x00\xe0\x0f\x00\x00\xc0\x07\x00\x00\xe0\x0f\x00\x00'\ 64 | b'\xf0\x1d\x00\x00\xa0\x09\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00'\ 65 | b'\x00\x00\x00\x00\x0f\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0'\ 66 | b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xfe\x7f\x00\x00\xfe'\ 67 | b'\x7f\x00\x00\xfe\x7f\x00\x00\xfe\x7f\x00\x00\xc0\x03\x00\x00\xc0'\ 68 | b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\x00'\ 69 | b'\x00\x00\x06\x00\x00\x00\x60\x0c\x00\x00\xf0\x0c\x00\x00\xf0\x07'\ 70 | b'\x00\x00\xe0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\xc0'\ 71 | b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0'\ 72 | b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\x00\x00\x00\x00\x00'\ 73 | b'\x00\x00\x06\x00\x00\x00\x60\x00\x00\x00\xf0\x00\x00\x00\xf0\x00'\ 74 | b'\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00'\ 75 | b'\xe0\x00\x00\x00\xfc\x00\x00\xc0\xff\x00\x00\xf8\xff\x00\x80\xff'\ 76 | b'\x1f\x00\xf8\xff\x03\x00\xfc\x3f\x00\x00\xfc\x07\x00\x00\x7c\x00'\ 77 | b'\x00\x00\x04\x00\x00\x00\x11\x00\x00\xfc\x03\x00\x80\xff\x1f\x00'\ 78 | b'\xc0\xff\x3f\x00\xe0\xff\x7f\x00\xe0\x07\x7e\x00\xf0\x01\xf8\x00'\ 79 | b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x01\xf8\x00'\ 80 | b'\xe0\x07\x7e\x00\xe0\xff\x7f\x00\xc0\xff\x3f\x00\x80\xff\x1f\x00'\ 81 | b'\x00\xfc\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x80\x03'\ 82 | b'\x00\x00\x80\x03\x00\x00\xc0\x03\x00\x00\xe0\xff\xff\x00\xf0\xff'\ 83 | b'\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00'\ 84 | b'\x00\x00\x10\x00\x00\x07\xf8\x00\xc0\x07\xfc\x00\xc0\x07\xfe\x00'\ 85 | b'\xe0\x07\xff\x00\xf0\x81\xf7\x00\xf0\x80\xf3\x00\xf0\xc0\xf1\x00'\ 86 | b'\xf0\xe0\xf1\x00\xf0\xe0\xf0\x00\xf0\xf1\xf0\x00\xe0\x7f\xf0\x00'\ 87 | b'\xe0\x7f\xf0\x00\xc0\x3f\xf0\x00\x00\x0f\xf0\x00\x00\x00\x00\x00'\ 88 | b'\x00\x00\x00\x00\x10\x00\x00\x00\x0e\x00\x00\x07\x3e\x00\xc0\x07'\ 89 | b'\x3e\x00\xe0\x07\x7e\x00\xe0\x07\xf8\x00\xf0\x01\xf0\x00\xf0\xf0'\ 90 | b'\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf9\xf0\x00\xf0\xff'\ 91 | b'\xf9\x00\xe0\xff\x7f\x00\xc0\xdf\x7f\x00\x80\x8f\x3f\x00\x00\x00'\ 92 | b'\x0f\x00\x00\x00\x00\x00\x10\x00\x00\x00\x0f\x00\x00\x80\x0f\x00'\ 93 | b'\x00\xe0\x0f\x00\x00\xf8\x0f\x00\x00\x7c\x0f\x00\x00\x3f\x0f\x00'\ 94 | b'\x80\x0f\x0f\x00\xe0\x07\x0f\x00\xf0\x01\x0f\x00\xf0\xff\xff\x00'\ 95 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x0f\x00'\ 96 | b'\x00\x00\x0f\x00\x00\x00\x00\x00\x0f\x00\x00\x70\x1c\x00\xf0\x7f'\ 97 | b'\x3c\x00\xf0\x7f\x7c\x00\xf0\xff\x7c\x00\xf0\x78\xf8\x00\xf0\x3c'\ 98 | b'\xf0\x00\xf0\x3c\xf0\x00\xf0\x3c\xf0\x00\xf0\x3c\xf0\x00\xf0\x7c'\ 99 | b'\x78\x00\xf0\xf8\x7f\x00\xf0\xf0\x3f\x00\xf0\xe0\x1f\x00\x00\xc0'\ 100 | b'\x0f\x00\x00\x00\x00\x00\x10\x00\x00\xfc\x07\x00\x00\xff\x1f\x00'\ 101 | b'\xc0\xff\x3f\x00\xe0\xff\x7f\x00\xe0\xf3\x78\x00\xf0\x79\xf0\x00'\ 102 | b'\xf0\x78\xf0\x00\xf0\x78\xf0\x00\xf0\x78\xf0\x00\xf0\xf9\xf8\x00'\ 103 | b'\xe0\xf3\x7f\x00\xe0\xf3\x7f\x00\xc0\xe3\x3f\x00\x00\x83\x0f\x00'\ 104 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xf0\x00\x00\x00\xf0\x00'\ 105 | b'\x00\x00\xf0\x00\x00\x00\xf0\x00\xf8\x00\xf0\x80\xff\x00\xf0\xe0'\ 106 | b'\xff\x00\xf0\xf8\xff\x00\xf0\xfc\x07\x00\xf0\x7e\x00\x00\xf0\x1f'\ 107 | b'\x00\x00\xf0\x07\x00\x00\xf0\x03\x00\x00\xf0\x01\x00\x00\xf0\x00'\ 108 | b'\x00\x00\x10\x00\x00\x00\x0f\x00\x80\xc7\x3f\x00\xc0\xef\x7f\x00'\ 109 | b'\xe0\xff\x7f\x00\xe0\xff\xf8\x00\xf0\x7d\xf0\x00\xf0\x78\xf0\x00'\ 110 | b'\xf0\x78\xf0\x00\xf0\x78\xf0\x00\xf0\x7d\xf0\x00\xe0\xff\xf8\x00'\ 111 | b'\xe0\xff\x7f\x00\xc0\xef\x7f\x00\x80\xc7\x3f\x00\x00\x00\x0f\x00'\ 112 | b'\x00\x00\x00\x00\x10\x00\x00\x3f\x00\x00\x80\xff\x30\x00\xc0\xff'\ 113 | b'\x71\x00\xe0\xff\x71\x00\xf0\xe1\xf3\x00\xf0\xc1\xf3\x00\xf0\xc0'\ 114 | b'\xf3\x00\xf0\xc0\xf3\x00\xf0\xc0\xf3\x00\xf0\xc1\xf9\x00\xe0\xe1'\ 115 | b'\x7d\x00\xe0\xff\x7f\x00\xc0\xff\x3f\x00\x80\xff\x1f\x00\x00\xfc'\ 116 | b'\x03\x00\x00\x00\x00\x00\x06\x00\x00\x18\x60\x00\x00\x3c\xf0\x00'\ 117 | b'\x00\x3c\xf0\x00\x00\x18\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 118 | b'\x06\x00\x00\x18\x60\x0c\x00\x3c\xf0\x0c\x00\x3c\xf0\x07\x00\x18'\ 119 | b'\xe0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\xc0\x03\x00'\ 120 | b'\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xf0\x0f\x00\x00\xf0\x0f\x00'\ 121 | b'\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x38\x1c\x00\x00\x3c\x3c\x00'\ 122 | b'\x00\x1c\x38\x00\x00\x1e\x78\x00\x00\x00\x00\x00\x0e\x00\x00\x78'\ 123 | b'\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78'\ 124 | b'\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78'\ 125 | b'\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x00'\ 126 | b'\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x1e\x78\x00\x00\x3c\x3c\x00'\ 127 | b'\x00\x3c\x3c\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x70\x0e\x00'\ 128 | b'\x00\xf0\x0f\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xc0\x07\x00'\ 129 | b'\x00\xc0\x03\x00\x00\x00\x00\x00\x0f\x00\x00\x07\x00\x00\xc0\x07'\ 130 | b'\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xf0\x01\x67\x00\xf0\xc0'\ 131 | b'\xf7\x00\xf0\xe0\xf7\x00\xf0\xe0\x67\x00\xf0\xf1\x01\x00\xe0\xff'\ 132 | b'\x00\x00\xe0\x7f\x00\x00\xc0\x3f\x00\x00\x00\x1f\x00\x00\x00\x00'\ 133 | b'\x00\x00\x00\x00\x00\x00\x16\x00\x00\xf8\x01\x00\x00\xfe\x07\x00'\ 134 | b'\x80\xff\x1f\x00\xc0\x0f\x1e\x00\xc0\x03\x3c\x00\xe0\xe1\x79\x00'\ 135 | b'\xe0\xf8\x73\x00\xf0\xfc\xf7\x00\x70\x1c\xe7\x00\x70\x0e\xe7\x00'\ 136 | b'\x70\x8e\xe3\x00\x70\xfe\xe1\x00\x70\xfc\xe3\x00\xf0\xfc\xe7\x00'\ 137 | b'\xe0\x0c\x77\x00\xe0\x01\x77\x00\xc0\xc3\x23\x00\xc0\xff\x43\x00'\ 138 | b'\x00\xff\x01\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 139 | b'\x13\x00\x00\x00\xc0\x00\x00\x00\xf8\x00\x00\x00\xfe\x00\x00\xc0'\ 140 | b'\xff\x00\x00\xf8\x3f\x00\x00\xff\x0f\x00\xe0\xff\x0f\x00\xf0\x1f'\ 141 | b'\x0f\x00\xf0\x03\x0f\x00\xf0\x00\x0f\x00\xf0\x07\x0f\x00\xf0\x3f'\ 142 | b'\x0f\x00\xc0\xff\x0f\x00\x00\xfe\x0f\x00\x00\xf0\x7f\x00\x00\x80'\ 143 | b'\xff\x00\x00\x00\xfc\x00\x00\x00\xf0\x00\x00\x00\x80\x00\x12\x00'\ 144 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 145 | b'\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00'\ 146 | b'\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf9\xf0\x00'\ 147 | b'\xf0\xff\xf9\x00\xe0\xff\x7f\x00\xc0\xdf\x7f\x00\x80\x8f\x3f\x00'\ 148 | b'\x00\x00\x1f\x00\x00\x00\x00\x00\x14\x00\x00\xf8\x01\x00\x00\xfe'\ 149 | b'\x07\x00\x80\xff\x1f\x00\xc0\xff\x3f\x00\xc0\x0f\x3f\x00\xe0\x03'\ 150 | b'\x7c\x00\xe0\x01\x78\x00\xf0\x01\xf8\x00\xf0\x00\xf0\x00\xf0\x00'\ 151 | b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x01\xf8\x00\xe0\x01'\ 152 | b'\x78\x00\xe0\x07\x7e\x00\xc0\x07\x3e\x00\x80\x07\x1e\x00\x00\x03'\ 153 | b'\x0c\x00\x00\x04\x04\x00\x00\x00\x00\x00\x13\x00\xf0\xff\xff\x00'\ 154 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\x00\xf0\x00'\ 155 | b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00'\ 156 | b'\xf0\x00\xf8\x00\xe0\x01\x78\x00\xe0\x07\x7e\x00\xc0\xff\x3f\x00'\ 157 | b'\x80\xff\x1f\x00\x00\xff\x0f\x00\x00\xfc\x03\x00\x00\x00\x00\x00'\ 158 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\xf0\xff\xff\x00\xf0\xff'\ 159 | b'\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xf0\xf0\x00\xf0\xf0'\ 160 | b'\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0'\ 161 | b'\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\x00'\ 162 | b'\xf0\x00\xf0\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'\ 163 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 164 | b'\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00'\ 165 | b'\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00'\ 166 | b'\xf0\xf0\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00'\ 167 | b'\x15\x00\x00\xf8\x01\x00\x00\xfe\x0f\x00\x80\xff\x1f\x00\xc0\xff'\ 168 | b'\x3f\x00\xc0\x0f\x7f\x00\xe0\x03\x7c\x00\xe0\x01\xf8\x00\xf0\x01'\ 169 | b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\xe0\xf1\x00\xf0\xe0'\ 170 | b'\xf1\x00\xf0\xe1\x79\x00\xe0\xe1\x79\x00\xe0\xe3\x3d\x00\xc0\xe7'\ 171 | b'\xff\x00\x80\xe7\xff\x00\x00\xe3\xff\x00\x00\xe4\xff\x00\x00\x00'\ 172 | b'\x00\x00\x00\x00\x00\x00\x14\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 173 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\xf0\x00\x00\x00\xf0\x00\x00'\ 174 | b'\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00'\ 175 | b'\x00\xf0\x00\x00\x00\xf0\x00\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 176 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 177 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\xf0\xff\xff\x00\xf0\xff'\ 178 | b'\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00'\ 179 | b'\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x3f\x00'\ 180 | b'\x00\x00\x7f\x00\x00\x00\x7f\x00\x00\x00\xf8\x00\x00\x00\xf0\x00'\ 181 | b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf8\x00'\ 182 | b'\xf0\xff\x7f\x00\xf0\xff\x7f\x00\xf0\xff\x3f\x00\xf0\xff\x0f\x00'\ 183 | b'\x00\x00\x00\x00\x12\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff'\ 184 | b'\xff\x00\xf0\xff\xff\x00\x00\xf0\x01\x00\x00\xfc\x00\x00\x00\xfe'\ 185 | b'\x00\x00\x00\xff\x01\x00\x80\xff\x07\x00\xc0\xef\x0f\x00\xe0\x87'\ 186 | b'\x3f\x00\xf0\x01\x7f\x00\xf0\x00\xfc\x00\x70\x00\xf8\x00\x30\x00'\ 187 | b'\xf0\x00\x10\x00\xc0\x00\x10\x00\x80\x00\x00\x00\x00\x00\x10\x00'\ 188 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 189 | b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00'\ 190 | b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00'\ 191 | b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 192 | b'\x18\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff'\ 193 | b'\xff\x00\xf0\x07\x00\x00\xf0\x7f\x00\x00\x80\xff\x07\x00\x00\xfc'\ 194 | b'\x3f\x00\x00\xc0\xff\x00\x00\x00\xfe\x00\x00\x00\xfe\x00\x00\xc0'\ 195 | b'\xff\x00\x00\xfc\x3f\x00\x80\xff\x07\x00\xf0\x7f\x00\x00\xf0\x07'\ 196 | b'\x00\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff'\ 197 | b'\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 198 | b'\x00\x00\x14\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 199 | b'\xf0\xff\xff\x00\xf0\x07\x00\x00\xc0\x1f\x00\x00\x00\x3f\x00\x00'\ 200 | b'\x00\xfc\x00\x00\x00\xf0\x03\x00\x00\xc0\x0f\x00\x00\x80\x3f\x00'\ 201 | b'\x00\x00\xfe\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 202 | b'\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 203 | b'\x00\x00\x00\x00\x16\x00\x00\xf8\x01\x00\x00\xfe\x07\x00\x80\xff'\ 204 | b'\x1f\x00\xc0\xff\x3f\x00\xc0\x0f\x3f\x00\xe0\x03\x7c\x00\xe0\x01'\ 205 | b'\x78\x00\xf0\x01\xf8\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00'\ 206 | b'\xf0\x00\xf0\x00\xf0\x00\xf0\x01\xf8\x00\xe0\x01\x78\x00\xe0\x03'\ 207 | b'\x7c\x00\xc0\x0f\x3f\x00\xc0\xff\x3f\x00\x80\xff\x1f\x00\x00\xfe'\ 208 | b'\x07\x00\x00\xf8\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00'\ 209 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 210 | b'\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x01\x00'\ 211 | b'\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xf1\x01\x00\xe0\xff\x00\x00'\ 212 | b'\xe0\xff\x00\x00\xc0\x7f\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00'\ 213 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\xf8\x01\x00\x00\xff'\ 214 | b'\x0f\x00\x80\xff\x1f\x00\xc0\xff\x3f\x00\xe0\x0f\x7e\x00\xe0\x03'\ 215 | b'\x7c\x00\xf0\x01\xf8\x00\xf0\x00\xf0\x00\xf0\x00\xf1\x00\xf0\x80'\ 216 | b'\xf3\x00\xf0\xc0\xf7\x00\xf0\x80\xff\x00\xf0\x01\xff\x00\xe0\x03'\ 217 | b'\x7e\x00\xe0\x0f\x7e\x00\xc0\xff\x7f\x00\x80\xff\xff\x00\x00\xfe'\ 218 | b'\x77\x00\x00\xf8\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00'\ 219 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 220 | b'\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x03\x00'\ 221 | b'\xf0\xe0\x0f\x00\xf0\xe0\x3f\x00\xf0\xf1\x7f\x00\xe0\xff\xfc\x00'\ 222 | b'\xe0\xff\xf0\x00\xc0\x7f\xe0\x00\x00\x1f\x80\x00\x00\x00\x00\x00'\ 223 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x04\x00\x80\x0f'\ 224 | b'\x1e\x00\xc0\x1f\x3e\x00\xe0\x3f\x7e\x00\xe0\x3f\x7c\x00\xf0\x39'\ 225 | b'\xf8\x00\xf0\x70\xf0\x00\xf0\x70\xf0\x00\xf0\x70\xf0\x00\xf0\x70'\ 226 | b'\xf0\x00\xf0\x60\xf0\x00\xf0\xe1\xf8\x00\xe0\xe3\x78\x00\xe0\xc7'\ 227 | b'\x7f\x00\xc0\xc3\x7f\x00\x80\x83\x3f\x00\x00\x02\x0f\x00\x00\x00'\ 228 | b'\x00\x00\x0f\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00'\ 229 | b'\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ 230 | b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\x00\x00\x00\xf0\x00\x00\x00'\ 231 | b'\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00'\ 232 | b'\x12\x00\xf0\xff\x07\x00\xf0\xff\x1f\x00\xf0\xff\x3f\x00\xf0\xff'\ 233 | b'\x7f\x00\x00\x00\x7c\x00\x00\x00\xf8\x00\x00\x00\xf0\x00\x00\x00'\ 234 | b'\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf8\x00\x00\x00'\ 235 | b'\x7c\x00\xf0\xff\x7f\x00\xf0\xff\x3f\x00\xf0\xff\x1f\x00\xf0\xff'\ 236 | b'\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x30\x00\x00\x00'\ 237 | b'\xf0\x01\x00\x00\xf0\x0f\x00\x00\xf0\x7f\x00\x00\xc0\xff\x03\x00'\ 238 | b'\x00\xfe\x1f\x00\x00\xe0\xff\x00\x00\x00\xff\x00\x00\x00\xf8\x00'\ 239 | b'\x00\x00\xff\x00\x00\xe0\xff\x00\x00\xfe\x1f\x00\xc0\xff\x03\x00'\ 240 | b'\xf0\x7f\x00\x00\xf0\x0f\x00\x00\xf0\x01\x00\x00\x30\x00\x00\x00'\ 241 | b'\x19\x00\x70\x00\x00\x00\xf0\x03\x00\x00\xf0\x3f\x00\x00\xf0\xff'\ 242 | b'\x01\x00\x80\xff\x1f\x00\x00\xf8\xff\x00\x00\x80\xff\x00\x00\x00'\ 243 | b'\xfc\x00\x00\xe0\xff\x00\x00\xff\xff\x00\xf0\xff\x07\x00\xf0\x3f'\ 244 | b'\x00\x00\xf0\x03\x00\x00\xf0\x1f\x00\x00\xf0\xff\x03\x00\x80\xff'\ 245 | b'\x7f\x00\x00\xf8\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\xf0'\ 246 | b'\xff\x00\x00\xff\x3f\x00\xf0\xff\x07\x00\xf0\x7f\x00\x00\xf0\x07'\ 247 | b'\x00\x00\xf0\x00\x00\x00\x11\x00\x10\x00\x80\x00\x30\x00\xe0\x00'\ 248 | b'\xf0\x00\xf0\x00\xf0\x01\xfc\x00\xf0\x07\xfe\x00\xc0\x9f\x3f\x00'\ 249 | b'\x80\xff\x0f\x00\x00\xfe\x07\x00\x00\xfc\x01\x00\x00\xfe\x07\x00'\ 250 | b'\x80\xff\x0f\x00\xc0\x9f\x3f\x00\xf0\x07\x7f\x00\xf0\x03\xfc\x00'\ 251 | b'\xf0\x00\xf8\x00\x70\x00\xe0\x00\x10\x00\x80\x00\x12\x00\x10\x00'\ 252 | b'\x00\x00\x30\x00\x00\x00\xf0\x00\x00\x00\xf0\x03\x00\x00\xf0\x0f'\ 253 | b'\x00\x00\xc0\x3f\x00\x00\x00\x7f\x00\x00\x00\xfc\xff\x00\x00\xf0'\ 254 | b'\xff\x00\x00\xf0\xff\x00\x00\xfc\xff\x00\x00\x7f\x00\x00\xc0\x3f'\ 255 | b'\x00\x00\xf0\x0f\x00\x00\xf0\x03\x00\x00\xf0\x00\x00\x00\x30\x00'\ 256 | b'\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\xe0\x00\xf0\x00\xf8\x00'\ 257 | b'\xf0\x00\xfc\x00\xf0\x00\xfe\x00\xf0\x00\xff\x00\xf0\x80\xff\x00'\ 258 | b'\xf0\xc0\xf3\x00\xf0\xf0\xf1\x00\xf0\xf8\xf0\x00\xf0\x7c\xf0\x00'\ 259 | b'\xf0\x3e\xf0\x00\xf0\x0f\xf0\x00\xf0\x07\xf0\x00\xf0\x03\xf0\x00'\ 260 | b'\xf0\x01\xf0\x00\xf0\x00\xf0\x00\x00\x00\x00\x00\x09\x00\xff\xff'\ 261 | b'\xff\x0f\xff\xff\xff\x0f\xff\xff\xff\x0f\xff\xff\xff\x0f\x0f\x00'\ 262 | b'\x00\x0f\x0f\x00\x00\x0f\x0f\x00\x00\x0f\x00\x00\x00\x00\x00\x00'\ 263 | b'\x00\x00\x0a\x00\x04\x00\x00\x00\x3c\x00\x00\x00\xfc\x03\x00\x00'\ 264 | b'\xfc\x1f\x00\x00\xf8\xff\x01\x00\xc0\xff\x1f\x00\x00\xfc\xff\x00'\ 265 | b'\x00\xe0\xff\x00\x00\x00\xfe\x00\x00\x00\xe0\x00\x09\x00\x0f\x00'\ 266 | b'\x00\x0f\x0f\x00\x00\x0f\x0f\x00\x00\x0f\xff\xff\xff\x0f\xff\xff'\ 267 | b'\xff\x0f\xff\xff\xff\x0f\xff\xff\xff\x0f\x00\x00\x00\x00\x00\x00'\ 268 | b'\x00\x00\x0f\x00\x00\x80\x01\x00\x00\xf0\x01\x00\x00\xfc\x01\x00'\ 269 | b'\x80\xff\x01\x00\xe0\x3f\x00\x00\xf0\x07\x00\x00\xf0\x01\x00\x00'\ 270 | b'\xf0\x03\x00\x00\xf0\x1f\x00\x00\xc0\xff\x00\x00\x00\xfe\x01\x00'\ 271 | b'\x00\xf8\x01\x00\x00\xc0\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00'\ 272 | b'\x17\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ 273 | b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ 274 | b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ 275 | b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ 276 | b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ 277 | b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x0c\x00'\ 278 | b'\x08\x00\x00\x00\x18\x00\x00\x00\x38\x00\x00\x00\x78\x00\x00\x00'\ 279 | b'\x70\x00\x00\x00\x60\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00'\ 280 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 281 | b'\x11\x00\x00\x40\x3c\x00\x00\x30\x7e\x00\x00\x38\x7f\x00\x00\x7c'\ 282 | b'\xff\x00\x00\x3e\xf3\x00\x00\x1e\xf3\x00\x00\x1e\xf3\x00\x00\x1e'\ 283 | b'\xf1\x00\x00\x9e\x71\x00\x00\xbe\x79\x00\x00\xfc\xff\x00\x00\xfc'\ 284 | b'\xff\x00\x00\xf8\xff\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\x00'\ 285 | b'\x00\x00\x00\x00\x00\x00\x12\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ 286 | b'\xfc\xff\xff\x00\xfc\xff\xff\x00\x00\x7c\x3c\x00\x00\x3c\x78\x00'\ 287 | b'\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00'\ 288 | b'\x00\x3e\xf8\x00\x00\x7c\x7c\x00\x00\xfc\x7f\x00\x00\xf8\x3f\x00'\ 289 | b'\x00\xf0\x1f\x00\x00\xc0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 290 | b'\x10\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc'\ 291 | b'\x7f\x00\x00\x7c\x7c\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00\x00\x1e'\ 292 | b'\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x3c\xf8\x00\x00\x7c'\ 293 | b'\x7c\x00\x00\x78\x38\x00\x00\x30\x18\x00\x00\x20\x08\x00\x00\x00'\ 294 | b'\x00\x00\x12\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00'\ 295 | b'\x00\xfc\x7f\x00\x00\x7e\xfc\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00'\ 296 | b'\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x3c\x78\x00\x00\x7c\x7c\x00'\ 297 | b'\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ 298 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\xe0'\ 299 | b'\x0f\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc\x7f\x00\x00\xdc'\ 300 | b'\x7b\x00\x00\xde\xf3\x00\x00\xde\xf3\x00\x00\xde\xf3\x00\x00\xde'\ 301 | b'\xf3\x00\x00\xde\xfb\x00\x00\xfc\x7b\x00\x00\xfc\x7b\x00\x00\xf8'\ 302 | b'\x33\x00\x00\xf0\x03\x00\x00\x80\x03\x00\x00\x00\x00\x00\x09\x00'\ 303 | b'\x00\x1c\x00\x00\x00\x1c\x00\x00\xc0\xff\xff\x00\xf0\xff\xff\x00'\ 304 | b'\xf0\xff\xff\x00\xf8\xff\xff\x00\x78\x1c\x00\x00\x3c\x1c\x00\x00'\ 305 | b'\x3c\x1c\x00\x00\x11\x00\x00\xc0\x07\x08\x00\xf0\x1f\x1c\x00\xf8'\ 306 | b'\x3f\x3c\x00\xfc\x7f\x3c\x00\x7e\xfc\x7c\x00\x3e\xf8\x78\x00\x1e'\ 307 | b'\xf0\x78\x00\x1e\xf0\x78\x00\x1e\xf0\x78\x00\x3c\x78\x7c\x00\x78'\ 308 | b'\x7c\x3e\x00\xfe\xff\x3f\x00\xfe\xff\x1f\x00\xfe\xff\x0f\x00\xfe'\ 309 | b'\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xfc\xff\xff\x00'\ 310 | b'\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\x00\x3c\x00\x00'\ 311 | b'\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00'\ 312 | b'\x00\x3e\x00\x00\x00\xfc\xff\x00\x00\xfc\xff\x00\x00\xf8\xff\x00'\ 313 | b'\x00\xe0\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x60\xfe'\ 314 | b'\xff\x00\xf0\xfe\xff\x00\xf0\xfe\xff\x00\x60\xfe\xff\x00\x00\x00'\ 315 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x78'\ 316 | b'\x00\x00\x00\x78\x60\xfe\xff\x7f\xf0\xfe\xff\x3f\xf0\xfe\xff\x3f'\ 317 | b'\x60\xfe\xff\x0f\x10\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff'\ 318 | b'\xff\x00\xfc\xff\xff\x00\x00\xc0\x07\x00\x00\xe0\x03\x00\x00\xf0'\ 319 | b'\x07\x00\x00\xfc\x0f\x00\x00\xfe\x3f\x00\x00\x3e\xff\x00\x00\x1e'\ 320 | b'\xfc\x00\x00\x0e\xf8\x00\x00\x06\xe0\x00\x00\x02\xc0\x00\x00\x00'\ 321 | b'\x80\x00\x00\x00\x00\x00\x07\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ 322 | b'\xfc\xff\xff\x00\xfc\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 323 | b'\x00\x00\x00\x00\x1a\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe'\ 324 | b'\xff\x00\x00\xfe\xff\x00\x00\x3c\x00\x00\x00\x1e\x00\x00\x00\x1e'\ 325 | b'\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x3e\x00\x00\x00\xfc'\ 326 | b'\xff\x00\x00\xfc\xff\x00\x00\xf8\xff\x00\x00\xfc\xff\x00\x00\x3e'\ 327 | b'\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x3e'\ 328 | b'\x00\x00\x00\xfc\xff\x00\x00\xfc\xff\x00\x00\xf8\xff\x00\x00\xe0'\ 329 | b'\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'\ 330 | b'\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00'\ 331 | b'\x00\x3c\x00\x00\x00\x1c\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00'\ 332 | b'\x00\x1e\x00\x00\x00\x3e\x00\x00\x00\xfc\xff\x00\x00\xfc\xff\x00'\ 333 | b'\x00\xf8\xff\x00\x00\xe0\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 334 | b'\x11\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc'\ 335 | b'\x7f\x00\x00\x7c\x7c\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00\x00\x1e'\ 336 | b'\xf0\x00\x00\x1e\xf0\x00\x00\x3e\xf8\x00\x00\x7c\x7c\x00\x00\xfc'\ 337 | b'\x7f\x00\x00\xf8\x3f\x00\x00\xf0\x1f\x00\x00\xc0\x07\x00\x00\x00'\ 338 | b'\x00\x00\x00\x00\x00\x00\x12\x00\x00\xfe\xff\x7f\x00\xfe\xff\x7f'\ 339 | b'\x00\xfe\xff\x7f\x00\xfe\xff\x7f\x00\x7c\x7c\x00\x00\x3c\x78\x00'\ 340 | b'\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00'\ 341 | b'\x00\x3e\xf8\x00\x00\x7c\x7c\x00\x00\xfc\x7f\x00\x00\xf8\x3f\x00'\ 342 | b'\x00\xf0\x1f\x00\x00\xc0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 343 | b'\x11\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc'\ 344 | b'\x7f\x00\x00\x7e\xfc\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00\x00\x1e'\ 345 | b'\xf0\x00\x00\x1e\xf0\x00\x00\x3c\x78\x00\x00\x7c\x7c\x00\x00\xfe'\ 346 | b'\xff\x7f\x00\xfe\xff\x7f\x00\xfe\xff\x7f\x00\xfe\xff\x7f\x00\x00'\ 347 | b'\x00\x00\x00\x00\x00\x00\x0a\x00\x00\xfe\xff\x00\x00\xfe\xff\x00'\ 348 | b'\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\x3c\x00\x00\x00\x1e\x00\x00'\ 349 | b'\x00\x1e\x00\x00\x00\x0e\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00'\ 350 | b'\x0f\x00\x00\x00\x08\x00\x00\x70\x18\x00\x00\xfc\x38\x00\x00\xfc'\ 351 | b'\x7d\x00\x00\xfe\xf9\x00\x00\x9e\xf1\x00\x00\x9e\xf1\x00\x00\x9e'\ 352 | b'\xf1\x00\x00\x9e\xf3\x00\x00\x3e\xf3\x00\x00\x3c\x7f\x00\x00\x3c'\ 353 | b'\x7f\x00\x00\x38\x3e\x00\x00\x20\x1c\x00\x00\x00\x00\x00\x09\x00'\ 354 | b'\x00\x0e\x00\x00\x00\x0e\x00\x00\xfc\xff\x1f\x00\xfc\xff\x3f\x00'\ 355 | b'\xfc\xff\x7f\x00\xfc\xff\xff\x00\x00\x0e\xf0\x00\x00\x0e\xf0\x00'\ 356 | b'\x00\x0e\xf0\x00\x10\x00\x00\xfe\x0f\x00\x00\xfe\x3f\x00\x00\xfe'\ 357 | b'\x7f\x00\x00\xfe\x7f\x00\x00\x00\xf8\x00\x00\x00\xf0\x00\x00\x00'\ 358 | b'\xf0\x00\x00\x00\xf0\x00\x00\x00\x70\x00\x00\x00\x78\x00\x00\xfe'\ 359 | b'\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\x00'\ 360 | b'\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x06\x00\x00\x00\x3e\x00\x00'\ 361 | b'\x00\xfe\x00\x00\x00\xfe\x07\x00\x00\xf8\x3f\x00\x00\xc0\xff\x00'\ 362 | b'\x00\x00\xfe\x00\x00\x00\xf0\x00\x00\x00\xfe\x00\x00\xc0\xff\x00'\ 363 | b'\x00\xf8\x1f\x00\x00\xfe\x07\x00\x00\xfe\x00\x00\x00\x1e\x00\x00'\ 364 | b'\x00\x06\x00\x00\x16\x00\x00\x06\x00\x00\x00\x7e\x00\x00\x00\xfe'\ 365 | b'\x03\x00\x00\xfe\x1f\x00\x00\xf0\xff\x00\x00\x00\xff\x00\x00\x00'\ 366 | b'\xf8\x00\x00\x80\xff\x00\x00\xf8\xff\x00\x00\xfe\x0f\x00\x00\xfe'\ 367 | b'\x00\x00\x00\xfe\x00\x00\x00\xfe\x07\x00\x00\xf8\x7f\x00\x00\x80'\ 368 | b'\xff\x00\x00\x00\xf8\x00\x00\x00\xff\x00\x00\xf0\xff\x00\x00\xfe'\ 369 | b'\x3f\x00\x00\xfe\x03\x00\x00\x7e\x00\x00\x00\x0e\x00\x00\x0f\x00'\ 370 | b'\x00\x02\x80\x00\x00\x06\xe0\x00\x00\x1e\xf0\x00\x00\x3e\xfc\x00'\ 371 | b'\x00\xfe\x7e\x00\x00\xf8\x3f\x00\x00\xe0\x0f\x00\x00\xe0\x07\x00'\ 372 | b'\x00\xf8\x1f\x00\x00\xfc\x7f\x00\x00\x7e\xfc\x00\x00\x1e\xf8\x00'\ 373 | b'\x00\x0e\xe0\x00\x00\x02\xc0\x00\x00\x00\x80\x00\x0f\x00\x00\x06'\ 374 | b'\x00\x00\x00\x3e\x00\x00\x00\xfe\x00\x78\x00\xfe\x07\x78\x00\xf8'\ 375 | b'\x1f\x7c\x00\xc0\xff\x7f\x00\x00\xfe\x3f\x00\x00\xf0\x1f\x00\x00'\ 376 | b'\xfe\x07\x00\xc0\xff\x00\x00\xf8\x1f\x00\x00\xfe\x07\x00\x00\xfe'\ 377 | b'\x00\x00\x00\x1e\x00\x00\x00\x06\x00\x00\x0e\x00\x00\x00\xe0\x00'\ 378 | b'\x00\x1e\xf0\x00\x00\x1e\xf8\x00\x00\x1e\xfc\x00\x00\x1e\xfe\x00'\ 379 | b'\x00\x1e\xff\x00\x00\x9e\xf7\x00\x00\xde\xf3\x00\x00\xfe\xf1\x00'\ 380 | b'\x00\xfe\xf0\x00\x00\x7e\xf0\x00\x00\x3e\xf0\x00\x00\x1e\xf0\x00'\ 381 | b'\x00\x00\x00\x00\x0a\x00\x00\x60\x00\x00\x00\xf0\x00\x00\x00\xf0'\ 382 | b'\x00\x00\xf8\xff\xff\x01\xfc\xff\xff\x03\xfe\x9f\xff\x07\xfe\x0f'\ 383 | b'\xff\x07\x0e\x00\x00\x07\x0e\x00\x00\x07\x00\x00\x00\x00\x08\x00'\ 384 | b'\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ 385 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 386 | b'\x09\x00\x0e\x00\x00\x07\x0e\x00\x00\x07\xfe\x0f\xff\x07\xfe\x9f'\ 387 | b'\xff\x07\xfc\xff\xff\x03\xf8\xff\xff\x01\x00\xf0\x00\x00\x00\xf0'\ 388 | b'\x00\x00\x00\x60\x00\x00\x0c\x00\x30\x00\x00\x00\x38\x00\x00\x00'\ 389 | b'\x18\x00\x00\x00\x18\x00\x00\x00\x18\x00\x00\x00\x30\x00\x00\x00'\ 390 | b'\x30\x00\x00\x00\x30\x00\x00\x00\x38\x00\x00\x00\x18\x00\x00\x00'\ 391 | b'\x00\x00\x00\x00\x00\x00\x00\x00' 392 | 393 | _index =\ 394 | b'\x00\x00\x3e\x00\x64\x00\x86\x00\xb0\x00\xee\x00\x28\x01\x86\x01'\ 395 | b'\xd4\x01\xea\x01\x10\x02\x36\x02\x64\x02\xa2\x02\xbc\x02\xe2\x02'\ 396 | b'\xfc\x02\x26\x03\x6c\x03\x92\x03\xd4\x03\x16\x04\x58\x04\x96\x04'\ 397 | b'\xd8\x04\x12\x05\x54\x05\x96\x05\xb0\x05\xca\x05\xfc\x05\x36\x06'\ 398 | b'\x68\x06\xa6\x06\x00\x07\x4e\x07\x98\x07\xea\x07\x38\x08\x7e\x08'\ 399 | b'\xc0\x08\x16\x09\x68\x09\x86\x09\xc4\x09\x0e\x0a\x50\x0a\xb2\x0a'\ 400 | b'\x04\x0b\x5e\x0b\xa8\x0b\xfe\x0b\x48\x0c\x92\x0c\xd0\x0c\x1a\x0d'\ 401 | b'\x60\x0d\xc6\x0d\x0c\x0e\x56\x0e\x9c\x0e\xc2\x0e\xec\x0e\x12\x0f'\ 402 | b'\x50\x0f\xae\x0f\xe0\x0f\x26\x10\x70\x10\xb2\x10\xfc\x10\x3e\x11'\ 403 | b'\x64\x11\xaa\x11\xec\x11\x0a\x12\x24\x12\x66\x12\x84\x12\xee\x12'\ 404 | b'\x30\x13\x76\x13\xc0\x13\x06\x14\x30\x14\x6e\x14\x94\x14\xd6\x14'\ 405 | b'\x14\x15\x6e\x15\xac\x15\xea\x15\x24\x16\x4e\x16\x70\x16\x96\x16'\ 406 | b'\xc8\x16' 407 | 408 | _mvfont = memoryview(_font) 409 | 410 | def _chr_addr(ordch): 411 | offset = 2 * (ordch - 32) 412 | return int.from_bytes(_index[offset:offset + 2], 'little') 413 | 414 | def get_width(s): 415 | width = 0 416 | for ch in s: 417 | ordch = ord(ch) 418 | ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 419 | offset = _chr_addr(ordch) 420 | width += int.from_bytes(_font[offset:offset + 2], 'little') 421 | return width 422 | 423 | def get_ch(ch): 424 | ordch = ord(ch) 425 | ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 426 | offset = _chr_addr(ordch) 427 | width = int.from_bytes(_font[offset:offset + 2], 'little') 428 | next_offs = _chr_addr(ordch +1) 429 | return _mvfont[offset + 2:next_offs], width 430 | 431 | -------------------------------------------------------------------------------- /odroid_go/utils/speaker/__init__.py: -------------------------------------------------------------------------------- 1 | from .speaker import Speaker -------------------------------------------------------------------------------- /odroid_go/utils/speaker/speaker.py: -------------------------------------------------------------------------------- 1 | """ 2 | A simple speaker module for Micropython (ESP32). 3 | 4 | Created on: 2018. 7. 10 5 | Author: Joshua Yang (joshua.yang@hardkernel.com) 6 | """ 7 | 8 | from machine import PWM, Pin 9 | import utime 10 | 11 | 12 | class Speaker: 13 | _speaker_pin = object() 14 | _speaker_pwm = object() 15 | _dac_pin = object() 16 | _beep_duration = 0 17 | _beep_frequency = 0 18 | _volume_duty = 0 19 | 20 | def __init__(self, pin, dac_pin, frequency=262, duration=0, volume=1): 21 | self._speaker_pin = Pin(pin, Pin.OUT, value=1) 22 | self._speaker_pwm = PWM(self._speaker_pin, duty=0) 23 | self._dac_pin = Pin(dac_pin, Pin.OUT, value=1) 24 | 25 | self.set_beep(frequency, duration) 26 | self.set_volume(volume) 27 | 28 | def _dac_switch(self, switch=None): 29 | if switch is None: 30 | self._dac_pin.value(1 if self._dac_pin.value() == 0 else 0) 31 | else: 32 | self._dac_pin.value(switch) 33 | 34 | # TODO: It should run as in non-blocking way (async, thread, ...) 35 | def _play_tone(self, frequency=None, duration=None): 36 | self._speaker_pwm.freq(self._beep_frequency if frequency is None else frequency) 37 | self._speaker_pwm.duty(self._volume_duty) 38 | 39 | utime.sleep(self._beep_duration if duration is None else duration) 40 | self._speaker_pwm.duty(0) 41 | 42 | def tone(self, frequency=None, duration=None): 43 | self._play_tone(frequency, duration) 44 | 45 | def beep(self): 46 | self.tone() 47 | 48 | def mute(self): 49 | self._dac_switch(0) 50 | 51 | def toggle_mute(self, switch=None): 52 | self._dac_switch(switch) 53 | 54 | def set_volume(self, volume=None): 55 | if volume is None: 56 | print(str(self._volume_duty) + "/" + str(self._volume_duty / 1023 * 100) + " %") 57 | elif not 0 <= volume <= 10: 58 | print("Volume value must be from 0 to 10") 59 | else: 60 | self._dac_switch(1) 61 | self._volume_duty = round(volume * 10 * 10.23) 62 | 63 | def set_beep(self, frequency=None, duration=None): 64 | if frequency is None and duration is None: 65 | print(str(self._beep_frequency) + "/" + str(self._beep_duration)) 66 | else: 67 | self._beep_frequency = self._beep_frequency if frequency is None else frequency 68 | self._beep_duration = self._beep_duration if duration is None else duration 69 | 70 | # TODO: Not implemented yet 71 | def play_music(self, music_data, sample_rate): 72 | pass 73 | --------------------------------------------------------------------------------