├── .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 | 
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 |
--------------------------------------------------------------------------------