├── .gitignore ├── LICENSE ├── README.md ├── docs ├── astrol.svg ├── cyrilc.svg ├── gotheng.svg ├── gothger.svg ├── gothita.svg ├── greekc.svg ├── greekcs.svg ├── greekp.svg ├── greeks.svg ├── italicc.svg ├── italiccs.svg ├── italict.svg ├── japan.svg ├── lowmat.svg ├── marker.svg ├── meteo.svg ├── misc.svg ├── music.svg ├── romanc.svg ├── romancs.svg ├── romand.svg ├── romanp.svg ├── romans.svg ├── romant.svg ├── scriptc.svg ├── scripts.svg ├── symbol.svg ├── uppmat.svg ├── vga1_16x16.png ├── vga1_16x32.png ├── vga1_8x16.png ├── vga1_8x8.png ├── vga1_bold_16x16.png ├── vga1_bold_16x32.png ├── vga2_16x16.png ├── vga2_16x32.png ├── vga2_8x16.png ├── vga2_8x8.png ├── vga2_bold_16x16.png ├── vga2_bold_16x32.png └── wt32-sc01.png ├── examples ├── README.md ├── bitarray.py ├── bitmap_fonts.py ├── blit_tests │ ├── blit_bounce.py │ └── logo-64x64.jpg ├── chango │ ├── chango.py │ ├── chango_16.mpy │ ├── chango_16.py │ ├── chango_32.mpy │ ├── chango_32.py │ ├── chango_64.mpy │ ├── chango_64.py │ └── make_fonts_py.sh ├── color_test.py ├── configs │ ├── bpi-centi-s3 │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── esp32_s3_box │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── m5stack-atom-s3 │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── m5stack-cores3 │ │ ├── m5cores3.py │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── t-display-s3 │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── t-dongle-s3 │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── t-embed │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── t-hmi │ │ ├── tft_buttons.py │ │ └── tft_config.py │ ├── t-qt-pro │ │ ├── tft_buttons.py │ │ └── tft_config.py │ └── wt32-sc01-plus │ │ ├── tft_buttons.py │ │ └── tft_config.py ├── feathers.py ├── font_decode.py ├── hello.py ├── hershey.py ├── jpg_tests │ ├── Micropython-logo.svg │ ├── conv-logo.sh │ ├── jpg_bounce.py │ ├── jpg_logo.py │ ├── jpg_tests.py │ ├── logo-128x128.jpg │ ├── logo-160x128.jpg │ ├── logo-160x80.jpg │ ├── logo-240x135.jpg │ ├── logo-240x240.jpg │ ├── logo-240x320.jpg │ ├── logo-320x170.jpg │ ├── logo-320x240.jpg │ ├── logo-480x320.jpg │ ├── logo-64x64.jpg │ └── logo-80x160.jpg ├── mono_fonts │ ├── inconsolata_16.mpy │ ├── inconsolata_16.py │ ├── inconsolata_32.mpy │ ├── inconsolata_32.py │ ├── inconsolata_64.mpy │ ├── inconsolata_64.py │ └── mono_fonts.py ├── nasa │ ├── OFL.txt │ ├── Pacifico-Regular.ttf │ ├── make_fonts │ ├── nasa_128x128 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ ├── nasa_160x80 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ ├── nasa_170x320 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ ├── nasa_240x320 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ ├── nasa_320x170 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ ├── nasa_320x240 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ ├── nasa_480x320 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ ├── nasa_clock.py │ ├── nasa_images.py │ ├── pacifico100.mpy │ ├── pacifico100.py │ ├── pacifico150.mpy │ ├── pacifico150.py │ ├── pacifico45.mpy │ ├── pacifico45.py │ ├── pacifico80.mpy │ └── pacifico80.py ├── noto_fonts.py ├── pinball.py ├── png_tests │ ├── alien.png │ ├── alien.py │ ├── png_bounce.py │ └── png_write.py ├── proverbs │ ├── NotoSansSC-Regular.otf │ ├── make_font │ ├── notosanssc20.mpy │ ├── notosanssc20.py │ ├── notosanssc45.mpy │ ├── notosanssc45.py │ └── proverbs.py ├── roids.py ├── scroll.py ├── test_examples ├── tiny_hello.py ├── tiny_toasters │ ├── tiny_toasters.py │ ├── ttoast_bitmaps.mpy │ ├── ttoast_bitmaps.py │ └── ttoasters.bmp ├── toasters │ ├── maketoast │ ├── t1.png │ ├── t1.py │ ├── t2.png │ ├── t2.py │ ├── t3.png │ ├── t3.py │ ├── t4.png │ ├── t4.py │ ├── t5.png │ ├── t5.py │ ├── toast_bitmaps.mpy │ ├── toast_bitmaps.py │ ├── toasters.bmp │ └── toasters.py ├── toasters_jpg │ ├── toaster.jpg │ └── toasters_jpg.py ├── upload-examples.sh └── watch │ ├── LibreBaskerville-Regular.ttf │ ├── create_face.py │ ├── create_faces │ ├── face_128x128.jpg │ ├── face_160x80.jpg │ ├── face_240x320.jpg │ ├── face_320x170.jpg │ ├── face_320x240.jpg │ ├── face_480x320.jpg │ └── watch.py ├── firmware ├── GENERIC_S3_16M │ └── firmware.bin ├── GENERIC_S3_32M │ └── firmware.bin ├── GENERIC_S3_4M │ └── firmware.bin ├── GENERIC_S3_8M │ └── firmware.bin ├── GENERIC_S3_OCT_16M │ └── firmware.bin ├── GENERIC_S3_OCT_32M │ └── firmware.bin ├── GENERIC_S3_OCT_4M │ └── firmware.bin ├── GENERIC_S3_OCT_8M │ └── firmware.bin ├── LICENSE ├── README.md ├── UM_FEATHERS3 │ └── firmware.bin ├── UM_NANOS3 │ └── firmware.bin ├── UM_PROS3 │ └── firmware.bin ├── UM_TINYS3 │ └── firmware.bin └── UM_TINYWATCHS3 │ └── firmware.bin ├── fonts ├── bitmap │ ├── README.md │ ├── vga1_16x16.py │ ├── vga1_16x32.py │ ├── vga1_8x16.py │ ├── vga1_8x8.py │ ├── vga1_bold_16x16.py │ ├── vga1_bold_16x32.py │ ├── vga2_16x16.py │ ├── vga2_16x32.py │ ├── vga2_8x16.py │ ├── vga2_8x8.py │ ├── vga2_bold_16x16.py │ ├── vga2_bold_16x32.py │ ├── vga_8x16.bin │ └── vga_8x8.bin ├── truetype │ ├── Chango-Regular.ttf │ ├── LICENSE_OFL.txt │ ├── NotoSans-Regular.ttf │ ├── NotoSansMono-Regular.ttf │ ├── NotoSansMono_32.py │ ├── NotoSans_32.py │ ├── NotoSerif-Regular.ttf │ ├── NotoSerif_32.py │ ├── README.md │ └── inconsolata-700.ttf └── vector │ ├── README.md │ ├── astrol.py │ ├── cyrilc.py │ ├── gotheng.py │ ├── gothger.py │ ├── gothita.py │ ├── greekc.py │ ├── greekcs.py │ ├── greekp.py │ ├── greeks.py │ ├── italicc.py │ ├── italiccs.py │ ├── italict.py │ ├── lowmat.py │ ├── marker.py │ ├── meteo.py │ ├── music.py │ ├── romanc.py │ ├── romancs.py │ ├── romand.py │ ├── romanp.py │ ├── romans.py │ ├── romant.py │ ├── scriptc.py │ ├── scripts.py │ ├── symbol.py │ └── uppmat.py ├── manifest.py ├── modules ├── NotoSansMono_32.py ├── NotoSans_32.py ├── NotoSerif_32.py ├── axp202c.py ├── df.py ├── focaltouch.py ├── greekc.py ├── greekcs.py ├── greekp.py ├── greeks.py ├── inconsolata_16.py ├── inconsolata_32.py ├── italicc.py ├── italiccs.py ├── italict.py ├── marker.py ├── meteo.py ├── mf.py ├── music.py ├── romanc.py ├── romancs.py ├── romand.py ├── romanp.py ├── romans.py ├── romant.py ├── scriptc.py ├── scripts.py ├── sdcard.py ├── symbol.py ├── vga1_16x16.py ├── vga1_16x32.py ├── vga1_8x16.py ├── vga1_8x8.py ├── vga1_bold_16x16.py ├── vga1_bold_16x32.py ├── vga2_16x16.py ├── vga2_8x16.py ├── vga2_8x8.py ├── vga2_bold_16x16.py └── vga2_bold_16x32.py ├── src ├── jpg │ ├── tjpgd565.c │ └── tjpgd565.h ├── micropython.cmake ├── mpfile.c ├── mpfile.h ├── png │ ├── miniz.c │ ├── miniz.h │ ├── pngle.c │ └── pngle.h ├── pngenc │ ├── adler32.c │ ├── crc32.c │ ├── crc32.h │ ├── deflate.c │ ├── deflate.h │ ├── gzguts.h │ ├── pngenc.c │ ├── pngenc.h │ ├── trees.c │ ├── trees.h │ ├── zconf.h │ ├── zlib.h │ ├── zutil.c │ └── zutil.h ├── s3lcd.c ├── s3lcd.h ├── s3lcd_i80_bus.c ├── s3lcd_i80_bus.h ├── s3lcd_spi_bus.c └── s3lcd_spi_bus.h ├── uncrustify.cfg └── utils ├── font2bitmap.py ├── font_from_romfont.py ├── howto-convert-to-jpg ├── imgtobitmap.py ├── monofont2bitmap.py ├── png_from_font.py ├── requirements.txt ├── sprites2bitmap.py └── wi-alien.svg /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | __pycache__ 4 | sphinx/build 5 | *~ 6 | *.pyc 7 | *.o 8 | *.P 9 | .DS_Store 10 | .history 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2020, 2021, 2022 Russ Hughes 3 | 4 | These files incorporate work covered by the following copyright and 5 | permission notice and are licensed under the same terms: 6 | 7 | The MIT License (MIT) 8 | 9 | Copyright (c) 2019 Ivan Belokobylskiy 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | 29 | -------------------------------------------------------------------------------- /docs/vga1_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga1_16x16.png -------------------------------------------------------------------------------- /docs/vga1_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga1_16x32.png -------------------------------------------------------------------------------- /docs/vga1_8x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga1_8x16.png -------------------------------------------------------------------------------- /docs/vga1_8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga1_8x8.png -------------------------------------------------------------------------------- /docs/vga1_bold_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga1_bold_16x16.png -------------------------------------------------------------------------------- /docs/vga1_bold_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga1_bold_16x32.png -------------------------------------------------------------------------------- /docs/vga2_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga2_16x16.png -------------------------------------------------------------------------------- /docs/vga2_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga2_16x32.png -------------------------------------------------------------------------------- /docs/vga2_8x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga2_8x16.png -------------------------------------------------------------------------------- /docs/vga2_8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga2_8x8.png -------------------------------------------------------------------------------- /docs/vga2_bold_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga2_bold_16x16.png -------------------------------------------------------------------------------- /docs/vga2_bold_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/vga2_bold_16x32.png -------------------------------------------------------------------------------- /docs/wt32-sc01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/docs/wt32-sc01.png -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Example Programs 2 | 3 | 4 | ## bitarray.py 5 | 6 | An example using map_bitarray_to_rgb565 to draw sprites 7 | 8 | 9 | ## bitmap_fonts.py 10 | 11 | Cycles through all characters of four bitmap fonts on the display 12 | 13 | ## chango.py 14 | 15 | Proportional font test for font2bitmap converter. 16 | 17 | 18 | ## clock.py 19 | 20 | Displays a clock over a background image on the display. 21 | 22 | The buttons on the module can be used to set the time. 23 | 24 | Background images courtesy of the NASA image and video gallery available at 25 | https://images.nasa.gov/ 26 | 27 | The Font is Copyright 2018 The Pacifico Project Authors (https://github.com/googlefonts/Pacifico) 28 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 29 | This license is copied below, and is also available with a FAQ at: 30 | http://scripts.sil.org/OFL 31 | 32 | 33 | ## feathers.py 34 | 35 | Smoothly scroll rainbow-colored mirrored random curves across the display. 36 | 37 | 38 | ## hello.py 39 | 40 | Writes "Hello!" in random colors at random locations on the display. 41 | 42 | 43 | ## hershey.py 44 | 45 | Demo program that draws greetings on display cycling thru hershey fonts and colors. 46 | 47 | ## jpg.py 48 | 49 | Draw a full screen jpg using the slower but less memory intensive method of blitting 50 | each Minimum Coded Unit (MCU) block. Usually 8×8pixels but can be other multiples of 8. 51 | 52 | bigbuckbunny.jpg (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org 53 | 54 | 55 | ### mono_fonts.py 56 | mono_fonts.py test for monofont2bitmap converter and bitmap method. This is the older method of 57 | converting monofonts to bitmaps. See the newer method in prop_fonts/chango.py that works with 58 | mono and proportional fonts using the write method. 59 | 60 | 61 | ## noto_fonts.py 62 | 63 | Writes the names of three Noto fonts centered on the display 64 | using the font. The fonts were converted from True Type fonts using 65 | the font2bitmap utility. 66 | 67 | 68 | ## proverbs.py 69 | 70 | Displays what I hope are chinese proverbs in simplified chinese to test UTF-8 font support. 71 | 72 | 73 | ## roids.py 74 | 75 | Asteroids style game demo using polygons. 76 | 77 | 78 | ## scroll.py 79 | 80 | Smoothly scroll all characters of a font up the display. 81 | Fonts heights must be even multiples of the screen height (i.e. 8 or 16 pixels high). 82 | 83 | 84 | ## tiny_toasters.py 85 | 86 | Flying Tiny Toasters for smaller displays (like the ST7735) 87 | 88 | Uses spritesheet from CircuitPython_Flying_Toasters pendant project 89 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 90 | 91 | Convert spritesheet bmp to tft.bitmap() method compatible python module using: 92 | python3 ./sprites2bitmap.py ttoasters.bmp 32 32 4 > ttoast_bitmaps.py 93 | 94 | 95 | ## toasters.py 96 | 97 | Flying Toasters 98 | 99 | Uses spritesheet from CircuitPython_Flying_Toasters pendant project 100 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 101 | 102 | Convert spritesheet bmp to tft.bitmap() method compatible python module using: 103 | python3 ./sprites2bitmap.py toasters.bmp 64 64 4 > toast_bitmaps.py 104 | 105 | 106 | ## toasters_jpg.py 107 | 108 | An example using a jpg sprite map to draw sprites on T-Display. This is an older version of the 109 | toasters.py and tiny_toasters example. It uses the jpg_decode() method to grab a bitmap of each 110 | sprite from the toaster.jpg sprite sheet. 111 | 112 | Youtube video: https://youtu.be/0uWsjKQmCpU 113 | 114 | spritesheet from CircuitPython_Flying_Toasters 115 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 116 | 117 | 118 | ## watch.py 119 | 120 | Analog Watch Display using jpg for the face and filled polygons for the hands 121 | Requires face_{width}x{height}.jpg in the same directory as this script. See the create_face.py 122 | script for creating a face image for a given sized display. 123 | 124 | Previous version video: https://youtu.be/NItKb6umMc4 125 | -------------------------------------------------------------------------------- /examples/bitmap_fonts.py: -------------------------------------------------------------------------------- 1 | """ 2 | fonts.py 3 | 4 | Cycles through all characters of four bitmap fonts on the display 5 | 6 | """ 7 | 8 | import utime 9 | import s3lcd 10 | import tft_config 11 | import vga1_8x8 as font1 12 | import vga1_8x16 as font2 13 | import vga1_bold_16x16 as font3 14 | import vga1_bold_16x32 as font4 15 | 16 | 17 | tft = tft_config.config(tft_config.WIDE) 18 | 19 | 20 | def main(): 21 | 22 | try: 23 | tft.init() 24 | 25 | while True: 26 | for font in (font1, font2, font3, font4): 27 | tft.fill(s3lcd.BLUE) 28 | line = 0 29 | col = 0 30 | for char in range(font.FIRST, font.LAST): 31 | tft.text(font, chr(char), col, line, s3lcd.WHITE, s3lcd.BLUE) 32 | tft.show() 33 | col += font.WIDTH 34 | if col > tft.width() - font.WIDTH: 35 | col = 0 36 | line += font.HEIGHT 37 | 38 | if line > tft.height() - font.HEIGHT: 39 | utime.sleep(3) 40 | tft.fill(s3lcd.BLUE) 41 | line = 0 42 | col = 0 43 | 44 | utime.sleep(3) 45 | 46 | finally: 47 | tft.deinit() 48 | 49 | 50 | main() 51 | -------------------------------------------------------------------------------- /examples/blit_tests/blit_bounce.py: -------------------------------------------------------------------------------- 1 | """ 2 | blit_bounce.py 3 | 4 | Bounce a blitable buffer around the display to test visibility clipping. 5 | 6 | """ 7 | 8 | import gc 9 | import random 10 | import time 11 | import tft_config 12 | import s3lcd 13 | 14 | gc.enable() 15 | gc.collect() 16 | 17 | LOGO_WIDTH = 64 18 | LOGO_HEIGHT = 64 19 | 20 | 21 | def main(): 22 | """ 23 | Decode and draw jpg on display using various methods 24 | """ 25 | 26 | try: 27 | tft = tft_config.config(tft_config.WIDE) 28 | 29 | # enable display and clear screen 30 | tft.init() 31 | width = tft.width() 32 | height = tft.height() 33 | col = width // 2 - LOGO_WIDTH // 2 34 | row = height // 2 - LOGO_HEIGHT // 2 35 | xd = 1 36 | yd = 2 37 | 38 | bitmap, bitmap_width, bitmap_height = tft.jpg_decode("logo-64x64.jpg") 39 | ticks = 1000 // 45 40 | 41 | while True: 42 | last = time.ticks_ms() 43 | tft.clear(0) 44 | tft.blit_buffer(bitmap, col, row, bitmap_width, bitmap_height) 45 | tft.show() 46 | 47 | # Update the position to bounce the bitmap around the screen 48 | col += xd 49 | if col <= -LOGO_WIDTH - 1 or col > width: 50 | xd = -xd 51 | 52 | row += yd 53 | if row <= -LOGO_HEIGHT - 1 or row > height: 54 | yd = -yd 55 | 56 | if time.ticks_ms() - last < ticks: 57 | time.sleep_ms(ticks - (time.ticks_ms() - last)) 58 | 59 | finally: 60 | tft.deinit() 61 | 62 | 63 | main() 64 | -------------------------------------------------------------------------------- /examples/blit_tests/logo-64x64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/blit_tests/logo-64x64.jpg -------------------------------------------------------------------------------- /examples/chango/chango.py: -------------------------------------------------------------------------------- 1 | """ 2 | chango.py proportional font test for font2bitmap converter. 3 | """ 4 | 5 | import time 6 | import gc 7 | import s3lcd 8 | import tft_config 9 | 10 | tft = tft_config.config(tft_config.WIDE) 11 | 12 | # 13 | # Large fonts take a lot of memory, they should be frozen in the 14 | # firmware or cross-compiled using the mpy-cross compiler. 15 | # 16 | 17 | import chango_16 as font_16 18 | import chango_32 as font_32 19 | import chango_64 as font_64 20 | 21 | gc.collect() 22 | 23 | 24 | def display_font(font): 25 | 26 | tft.fill(s3lcd.BLUE) # clear the screen 27 | column = 0 # first column 28 | row = 0 # first row 29 | 30 | for char in font.MAP: # for each character in the font map 31 | width = tft.write_len(font, char) # get the width of the character 32 | 33 | if ( 34 | column + width > tft.width() 35 | ): # if the character will not fit on the current line 36 | row += font.HEIGHT # move to the next row 37 | column = 0 # reset the column 38 | 39 | if ( 40 | row + font.HEIGHT > tft.height() 41 | ): # if the row will not fit on the screen 42 | time.sleep(1) # pause for a second 43 | tft.fill(s3lcd.BLUE) # clear the screen 44 | row = 0 # reset the row 45 | 46 | tft.write( # write to the screen 47 | font, # in this font 48 | char, # the character 49 | column, # at this column 50 | row, # on this row 51 | s3lcd.WHITE, # in white 52 | s3lcd.BLUE, 53 | ) # with blue background 54 | 55 | tft.show() # show the screen 56 | column += width # move the column past the character 57 | 58 | 59 | def main(): 60 | try: 61 | tft.init() 62 | tft.fill(s3lcd.BLUE) 63 | 64 | for font in [font_16, font_32, font_64]: # for each font 65 | display_font(font) # display the font characters 66 | time.sleep(1) # pause for a second 67 | 68 | finally: 69 | tft.deinit() 70 | 71 | 72 | main() 73 | -------------------------------------------------------------------------------- /examples/chango/chango_16.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/chango/chango_16.mpy -------------------------------------------------------------------------------- /examples/chango/chango_32.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/chango/chango_32.mpy -------------------------------------------------------------------------------- /examples/chango/chango_64.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/chango/chango_64.mpy -------------------------------------------------------------------------------- /examples/chango/make_fonts_py.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../utils/font2bitmap.py ../../fonts/truetype/Chango-Regular.ttf 16 -c 0x20-0x7f > chango_16.py 4 | ../../utils/font2bitmap.py ../../fonts/truetype/Chango-Regular.ttf 32 -c 0x20-0x7f > chango_32.py 5 | ../../utils/font2bitmap.py ../../fonts/truetype/Chango-Regular.ttf 64 -c 0x20-0x7f > chango_64.py 6 | 7 | mpy-cross chango_16.py 8 | mpy-cross chango_32.py 9 | mpy-cross chango_64.py 10 | 11 | -------------------------------------------------------------------------------- /examples/color_test.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | import vga1_bold_16x32 as font 5 | import tft_config 6 | import s3lcd 7 | 8 | 9 | def center(text, fg=s3lcd.WHITE, bg=s3lcd.BLACK): 10 | """ 11 | Centers the given text on the display. 12 | """ 13 | length = len(text) 14 | tft.text( 15 | font, 16 | text, 17 | tft.width() // 2 - length // 2 * font.WIDTH, 18 | tft.height() // 2 - font.HEIGHT // 2, 19 | fg, 20 | bg, 21 | ) 22 | 23 | 24 | try: 25 | tft = tft_config.config(tft_config.WIDE) 26 | tft.init() 27 | 28 | for name, background in ( 29 | ("Red", s3lcd.RED), 30 | ("Green", s3lcd.GREEN), 31 | ("Blue", s3lcd.BLUE), 32 | ("Cyan", s3lcd.CYAN), 33 | ("Magenta", s3lcd.MAGENTA), 34 | ("Yellow", s3lcd.YELLOW), 35 | ("White", s3lcd.WHITE), 36 | ("Black", s3lcd.BLACK), 37 | ): 38 | 39 | color = ( 40 | s3lcd.WHITE 41 | if background not in (s3lcd.WHITE, s3lcd.YELLOW) 42 | else s3lcd.BLACK 43 | ) 44 | 45 | tft.fill(background) 46 | tft.rect(0, 0, tft.width(), tft.height(), color) 47 | 48 | center(name, color, background) 49 | tft.show() 50 | time.sleep(2) 51 | 52 | finally: 53 | tft.deinit() 54 | -------------------------------------------------------------------------------- /examples/configs/bpi-centi-s3/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for buttons: you will need to change these to match your wiring 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "bpi-centi-s3" 9 | self.boot = Pin(0, Pin.IN) 10 | self.button = Pin(35, Pin.IN) 11 | 12 | # need more buttons for roids.py 13 | self.fire = 0 14 | self.thrust = 0 15 | self.hyper = 0 16 | 17 | -------------------------------------------------------------------------------- /examples/configs/bpi-centi-s3/tft_config.py: -------------------------------------------------------------------------------- 1 | """ BPI-Centi-S3 170x320 ST7789 display """ 2 | 3 | import s3lcd 4 | from machine import freq, Pin 5 | 6 | freq(240_000_000) # Set esp32s3 cpu frequency to 240MHz 7 | BACKLIGHT = Pin(2, Pin.OUT) 8 | RD = Pin(7, Pin.OUT) 9 | 10 | TFA = 0 11 | BFA = 0 12 | WIDE = 1 13 | TALL = 0 14 | 15 | 16 | def config(rotation=0, options=0): 17 | BACKLIGHT.value(1) 18 | RD.value(1) 19 | bus = s3lcd.I80_BUS( 20 | (8, 9, 10, 11, 12, 13, 14, 15), 21 | dc=5, 22 | wr=6, 23 | rd=7, 24 | cs=4, 25 | # pclk=16_000_000, 26 | swap_color_bytes=True, 27 | reverse_color_bits=False, 28 | pclk_active_neg=False, 29 | pclk_idle_low=True, 30 | ) 31 | 32 | return s3lcd.ESPLCD( 33 | bus, 34 | 170, 35 | 320, 36 | inversion_mode=True, 37 | color_space=s3lcd.RGB, 38 | reset=3, 39 | rotation=rotation, 40 | dma_rows=32, 41 | options=options, 42 | ) 43 | 44 | 45 | def deinit(tft, display_off=False): 46 | """Take an ESPLCD instance and Deinitialize the display.""" 47 | tft.deinit() 48 | if display_off: 49 | BACKLIGHT.value(0) 50 | RD.value(0) 51 | -------------------------------------------------------------------------------- /examples/configs/esp32_s3_box/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # esp32_s3_box 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "esp32-s3-box" 9 | self.left = 0 10 | self.right = 0 11 | self.hyper = 0 12 | self.thrust = 0 13 | self.fire = 0 14 | -------------------------------------------------------------------------------- /examples/configs/esp32_s3_box/tft_config.py: -------------------------------------------------------------------------------- 1 | """ESP32 Box or Box Lite with ili9342c 320x240 display""" 2 | 3 | from machine import Pin, SPI, freq 4 | import s3lcd 5 | 6 | TFA = 0 7 | BFA = 0 8 | WIDE = 0 9 | TALL = 1 10 | 11 | BACKLIGHT = Pin(45, Pin.OUT) 12 | 13 | # Set clock to 240MHz 14 | freq(240000000) 15 | 16 | 17 | def config(rotation=0, options=0): 18 | """Configure the display and return an ESPLCD instance.""" 19 | custom_init = [ 20 | (b"\x01", 150), # soft reset 21 | (b"\x11", 255), # exit sleep 22 | (b"\xCB\x39\x2C\x00\x34\x02",), # power control A 23 | (b"\xCF\x00\xC1\x30",), # power control B 24 | (b"\xE8\x85\x00\x78",), # driver timing control A 25 | (b"\xEA\x00\x00",), # driver timing control B 26 | (b"\xED\x64\x03\x12\x81",), # power on sequence control 27 | (b"\xF7\x20",), # pump ratio control 28 | (b"\xC0\x23",), # power control,VRH[5:0] 29 | (b"\xC1\x10",), # Power control,SAP[2:0];BT[3:0] 30 | (b"\xC5\x3E\x28",), # vcm control 31 | (b"\xC7\x86",), # vcm control 2 32 | (b"\x3A\x55",), # pixel format 33 | (b"\x36\x08",), # madctl 34 | (b"\xB1\x00\x18",), # frameration control,normal mode full colours 35 | (b"\xB6\x08\x82\x27",), # display function control 36 | (b"\xF2\x00",), # 3gamma function disable 37 | (b"\x26\x01",), # gamma curve selected 38 | # set positive gamma correction 39 | (b"\xE0\x0F\x31\x2B\x0C\x0E\x08\x4E\xF1\x37\x07\x10\x03\x0E\x09\x00",), 40 | # set negative gamma correction 41 | (b"\xE1\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F",), 42 | (b"\x29", 100), # display on 43 | ] 44 | 45 | # rotated 180 degrees -- scrolling demos need to be modified to 46 | # to scroll in the opposite direction. 47 | custom_rotations = ( 48 | (320, 240, 0, 0, False, True, True), 49 | (240, 320, 0, 0, True, False, True), 50 | (320, 240, 0, 0, False, False, False), 51 | (240, 320, 0, 0, True, True, False), 52 | (240, 320, 0, 0, True, False, True), 53 | ) 54 | 55 | # # upside down -- scrolling demos are scrolled in the correct direction. 56 | # custom_rotations = ( 57 | # (320, 240, 0, 0, False, False, False), 58 | # (240, 320, 0, 0, True, True, False), 59 | # (320, 240, 0, 0, False, True, True), 60 | # (240, 320, 0, 0, True, False, True), 61 | # ) 62 | 63 | BACKLIGHT.value(1) 64 | 65 | # To use baudrates above 26.6MHz you must use my firmware or modify the micropython 66 | # source code to increase the SPI baudrate limit by adding SPI_DEVICE_NO_DUMMY to the 67 | # .flag member of the spi_device_interface_config_t struct in the machine_hw_spi_init_internal.c 68 | # file. Not doing so will cause the ESP32 to crash if you use a baudrate that is too high. 69 | 70 | bus = s3lcd.SPI_BUS( 71 | 1, 72 | mosi=6, 73 | sck=7, 74 | dc=4, 75 | cs=5, 76 | pclk=60_000_000, 77 | swap_color_bytes=True, 78 | ) 79 | 80 | return s3lcd.ESPLCD( 81 | bus, 82 | 240, 83 | 320, 84 | inversion_mode=False, 85 | color_space=s3lcd.BGR, 86 | reset=48, 87 | rotations=custom_rotations, 88 | rotation=rotation, 89 | custom_init=custom_init, 90 | options=options, 91 | ) 92 | 93 | 94 | def deinit(tft, display_off=False): 95 | """Take an ESPLCD instance and Deinitialize the display.""" 96 | tft.deinit() 97 | if display_off: 98 | BACKLIGHT.value(0) 99 | -------------------------------------------------------------------------------- /examples/configs/m5stack-atom-s3/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # esp32_s3_box 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "atom-s3" 9 | self.left = Pin(1, Pin.IN, Pin.PULL_UP) # PORT A 10 | self.right = Pin(2, Pin.IN, Pin.PULL_UP) # PORT A 11 | self.hyper = 0 12 | self.thrust = 0 13 | self.fire = 0 14 | -------------------------------------------------------------------------------- /examples/configs/m5stack-atom-s3/tft_config.py: -------------------------------------------------------------------------------- 1 | """ M5STACK ATOM-S3 128x128 display """ 2 | 3 | from machine import Pin, freq 4 | import s3lcd 5 | 6 | BL = Pin(16, Pin.OUT) 7 | 8 | TFA = 1 9 | BFA = 1 10 | WIDE = 1 11 | TALL = 0 12 | 13 | freq(240_000_000) 14 | 15 | 16 | def config(rotation=0, options=0): 17 | """Configure the display and return an ESPLCD instance.""" 18 | 19 | BL.value(1) 20 | 21 | custom_rotations = ( 22 | (128, 128, 2, 1, False, False, False), 23 | (128, 128, 1, 2, True, True, False), 24 | (128, 128, 2, 1, False, True, True), 25 | (128, 128, 1, 2, True, False, True), 26 | ) 27 | 28 | bus = s3lcd.SPI_BUS( 29 | 2, mosi=21, sck=17, dc=33, cs=15, pclk=27000000, swap_color_bytes=True 30 | ) 31 | 32 | return s3lcd.ESPLCD( 33 | bus, 34 | 128, 35 | 128, 36 | inversion_mode=True, 37 | color_space=s3lcd.BGR, 38 | reset=34, 39 | rotations=custom_rotations, 40 | rotation=rotation, 41 | dma_rows=32, 42 | options=options, 43 | ) 44 | 45 | 46 | def deinit(tft, display_off=False): 47 | """Take an ESPLCD instance and Deinitialize the display.""" 48 | tft.deinit() 49 | if display_off: 50 | BL.value(0) 51 | -------------------------------------------------------------------------------- /examples/configs/m5stack-cores3/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # M5STACK CORES3 2 | # - Not working with DUAL BUTTON unit 3 | 4 | # DIN Base 5 | # Port A 1, 2 6 | # Port B 8, 9 7 | # Port C 18, 17 8 | 9 | from machine import Pin 10 | 11 | class Buttons: 12 | def __init__(self): 13 | self.name = "m5cores3" 14 | self.left = Pin(1, Pin.IN, Pin.PULL_UP) # PORT A 15 | self.right = Pin(2, Pin.IN, Pin.PULL_UP) # PORT A 16 | self.hyper = 0 17 | self.thrust = 0 18 | self.fire = 0 19 | -------------------------------------------------------------------------------- /examples/configs/m5stack-cores3/tft_config.py: -------------------------------------------------------------------------------- 1 | """M5STACK CORES3 with ili9342c 320x240 display""" 2 | 3 | from machine import freq 4 | import m5cores3 5 | import s3lcd 6 | 7 | 8 | TFA = 0 9 | BFA = 0 10 | WIDE = 0 11 | TALL = 1 12 | 13 | # Set clock to 240MHz 14 | freq(240000000) 15 | 16 | def config(rotation=0, options=0): 17 | """Configure the display and return an ESPLCD instance.""" 18 | custom_init = [ 19 | (b"\x01", 150), # soft reset 20 | (b"\x11", 255), # exit sleep 21 | (b"\xCB\x39\x2C\x00\x34\x02",), # power control A 22 | (b"\xCF\x00\xC1\x30",), # power control B 23 | (b"\xE8\x85\x00\x78",), # driver timing control A 24 | (b"\xEA\x00\x00",), # driver timing control B 25 | (b"\xED\x64\x03\x12\x81",), # power on sequence control 26 | (b"\xF7\x20",), # pump ratio control 27 | (b"\xC0\x23",), # power control,VRH[5:0] 28 | (b"\xC1\x10",), # Power control,SAP[2:0];BT[3:0] 29 | (b"\xC5\x3E\x28",), # vcm control 30 | (b"\xC7\x86",), # vcm control 2 31 | (b"\x3A\x55",), # pixel format 32 | (b"\x36\x08",), # madctl 33 | (b"\xB1\x00\x18",), # frameration control,normal mode full colours 34 | (b"\xB6\x08\x82\x27",), # display function control 35 | (b"\xF2\x00",), # 3gamma function disable 36 | (b"\x26\x01",), # gamma curve selected 37 | # set positive gamma correction 38 | (b"\xE0\x0F\x31\x2B\x0C\x0E\x08\x4E\xF1\x37\x07\x10\x03\x0E\x09\x00",), 39 | # set negative gamma correction 40 | (b"\xE1\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F",), 41 | (b"\x29", 100), # display on 42 | ] 43 | 44 | custom_rotations = ( 45 | (320, 240, 0, 0, False, False, False), 46 | (240, 320, 0, 0, True, True, False), 47 | (320, 240, 0, 0, False, True, True), 48 | (240, 320, 0, 0, True, False, True), 49 | ) 50 | 51 | # To use baudrates above 26.6MHz you must use my firmware or modify the micropython 52 | # source code to increase the SPI baudrate limit by adding SPI_DEVICE_NO_DUMMY to 53 | # the .flag member of the spi_device_interface_config_t struct in the 54 | # machine_hw_spi_init_internal.c file. Not doing so will cause the ESP32 to crash 55 | # if you use a baudrate that is too high. 56 | 57 | bus = s3lcd.SPI_BUS( 58 | 1, 59 | mosi=37, 60 | sck=36, 61 | dc=35, 62 | cs=3, 63 | pclk=60_000_000, 64 | swap_color_bytes=True, 65 | ) 66 | 67 | return s3lcd.ESPLCD( 68 | bus, 69 | 240, 70 | 320, 71 | inversion_mode=True, 72 | color_space=s3lcd.BGR, 73 | rotations=custom_rotations, 74 | rotation=rotation, 75 | custom_init=custom_init, 76 | options=options, 77 | ) 78 | 79 | 80 | def deinit(tft, display_off=False): 81 | """Take an ESPLCD instance and Deinitialize the display.""" 82 | tft.deinit() 83 | -------------------------------------------------------------------------------- /examples/configs/t-display-s3/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for buttons: you will need to change these to match your wiring 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "t-display-s3" 9 | self.left = Pin(0, Pin.IN) 10 | self.right = Pin(14, Pin.IN) 11 | 12 | # need more buttons for roids.py 13 | self.fire = 0 14 | self.thrust = 0 15 | self.hyper = 0 16 | -------------------------------------------------------------------------------- /examples/configs/t-display-s3/tft_config.py: -------------------------------------------------------------------------------- 1 | """ LilyGo T-DISPLAY-S3 170x320 ST7789 display """ 2 | 3 | from machine import Pin, freq 4 | import s3lcd 5 | 6 | 7 | LCD_POWER = Pin(15, Pin.OUT) 8 | RD = Pin(9, Pin.OUT) 9 | BACKLIGHT = Pin(38, Pin.OUT) 10 | 11 | TFA = 0 12 | BFA = 0 13 | WIDE = 1 14 | TALL = 0 15 | 16 | freq(240_000_000) 17 | 18 | 19 | def config(rotation=0, options=0): 20 | """Configure the display and return an ESPLCD instance.""" 21 | LCD_POWER.value(1) 22 | RD.value(1) 23 | BACKLIGHT.value(1) 24 | 25 | bus = s3lcd.I80_BUS( 26 | (39, 40, 41, 42, 45, 46, 47, 48), 27 | dc=7, 28 | wr=8, 29 | cs=6, 30 | pclk=20_000_000, 31 | swap_color_bytes=True, 32 | reverse_color_bits=False, 33 | ) 34 | 35 | return s3lcd.ESPLCD( 36 | bus, 37 | 170, 38 | 320, 39 | inversion_mode=True, 40 | color_space=s3lcd.RGB, 41 | reset=5, 42 | rotation=rotation, 43 | options=options, 44 | ) 45 | 46 | 47 | def deinit(tft, display_off=False): 48 | """Take an ESPLCD instance and Deinitialize the display.""" 49 | tft.deinit() 50 | if display_off: 51 | BACKLIGHT.value(0) 52 | RD.value(0) 53 | LCD_POWER.value(0) 54 | -------------------------------------------------------------------------------- /examples/configs/t-dongle-s3/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for esp32 T-Dongle-S3 module 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "t-dongle-s3" 9 | self.button = Pin(0, Pin.IN) 10 | self.left = self.button 11 | self.right = self.button 12 | 13 | # need more buttons for roids.py 14 | self.fire = 0 15 | self.thrust = 0 16 | self.hyper = 0 17 | -------------------------------------------------------------------------------- /examples/configs/t-dongle-s3/tft_config.py: -------------------------------------------------------------------------------- 1 | """ LilyGo T-Dongle-S3 80x160 ST7735 display """ 2 | 3 | from machine import Pin, freq 4 | import s3lcd 5 | 6 | BL = Pin(37, Pin.OUT) 7 | 8 | TFA = 1 9 | BFA = 1 10 | WIDE = 1 11 | TALL = 0 12 | 13 | freq(240_000_000) 14 | 15 | 16 | def config(rotation=0, options=0): 17 | """Configure the display and return an ESPLCD instance.""" 18 | 19 | BL.value(1) 20 | 21 | bus = s3lcd.SPI_BUS( 22 | 2, mosi=3, sck=5, dc=2, cs=4, pclk=50000000, swap_color_bytes=True 23 | ) 24 | 25 | return s3lcd.ESPLCD( 26 | bus, 27 | 80, 28 | 160, 29 | inversion_mode=True, 30 | color_space=s3lcd.BGR, 31 | reset=1, 32 | rotation=rotation, 33 | dma_rows=32, 34 | options=options, 35 | ) 36 | 37 | 38 | def deinit(tft, display_off=False): 39 | """Take an ESPLCD instance and Deinitialize the display.""" 40 | tft.deinit() 41 | if display_off: 42 | BL.value(0) 43 | -------------------------------------------------------------------------------- /examples/configs/t-embed/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for buttons: you will need to change these to match your wiring 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "t-embed" 9 | self.left = Pin(17, Pin.IN, Pin.PULL_UP) # middle GROVE connector 10 | self.right = Pin(18, Pin.IN, Pin.PULL_UP) 11 | 12 | # need more buttons for roids.py 13 | self.fire = 0 14 | self.thrust = 0 15 | self.hyper = 0 16 | -------------------------------------------------------------------------------- /examples/configs/t-embed/tft_config.py: -------------------------------------------------------------------------------- 1 | """ LilyGo T-embed 170x320 ST7789 display """ 2 | 3 | from machine import Pin, freq 4 | import s3lcd 5 | 6 | 7 | BL = Pin(15, Pin.OUT) 8 | POWER = Pin(46, Pin.OUT) 9 | 10 | TFA = 0 11 | BFA = 0 12 | WIDE = 1 13 | TALL = 0 14 | 15 | freq(240_000_000) 16 | 17 | 18 | def config(rotation=0, options=0): 19 | """Configure the display and return an ESPLCD instance.""" 20 | 21 | POWER.value(1) 22 | BL.value(1) 23 | 24 | bus = s3lcd.SPI_BUS( 25 | 1, 26 | mosi=11, 27 | sck=12, 28 | dc=13, 29 | cs=10, 30 | pclk=60_000_000, 31 | swap_color_bytes=True, 32 | ) 33 | 34 | return s3lcd.ESPLCD( 35 | bus, 36 | 170, 37 | 320, 38 | inversion_mode=True, 39 | color_space=s3lcd.RGB, 40 | reset=9, 41 | rotation=rotation, 42 | options=options, 43 | ) 44 | 45 | 46 | def deinit(tft, display_off=False): 47 | """Take an ESPLCD instance and Deinitialize the display.""" 48 | tft.deinit() 49 | if display_off: 50 | BL.value(0) 51 | POWER.value(0) 52 | -------------------------------------------------------------------------------- /examples/configs/t-hmi/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for buttons: you will need to change these to match your wiring 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "t-hmi" 9 | 10 | # Middle GROVE connector 11 | self.left = Pin(17, Pin.IN) 12 | self.right = Pin(18, Pin.IN) 13 | 14 | # Right GROVE connector 15 | self.fire = Pin(15, Pin.IN) 16 | self.thrust = Pin(16, Pin.IN) 17 | self.hyper = 0 18 | 19 | # Buttons above the display 20 | self.ONOFF = Pin(21, Pin.IN) # Sends 1 when pressed 21 | self.BOT = Pin(0, Pin.IN) # Sends 0 when pressed 22 | -------------------------------------------------------------------------------- /examples/configs/t-hmi/tft_config.py: -------------------------------------------------------------------------------- 1 | """ LilyGo T-HMI 240x320 ST7789 display """ 2 | 3 | from machine import freq, Pin 4 | import s3lcd 5 | 6 | LCD_POWER = Pin(10, Pin.OUT) 7 | BL = Pin(38, Pin.OUT) 8 | 9 | TFA = 0 10 | BFA = 0 11 | WIDE = 1 12 | TALL = 0 13 | 14 | freq(240_000_000) 15 | 16 | 17 | def config(rotation=0, options=0): 18 | """Configure the display and return an ESPLCD instance.""" 19 | i80_bus = s3lcd.I80_BUS( 20 | (48, 47, 39, 40, 41, 42, 45, 46), 21 | dc=7, 22 | wr=8, 23 | cs=6, 24 | swap_color_bytes=True, 25 | reverse_color_bits=False, 26 | ) 27 | 28 | LCD_POWER.value(1) 29 | BL.value(1) 30 | 31 | return s3lcd.ESPLCD( 32 | i80_bus, 33 | 240, 34 | 320, 35 | color_space=s3lcd.RGB, 36 | inversion_mode=False, 37 | rotation=rotation, 38 | dma_rows=32, 39 | options=options, 40 | ) 41 | 42 | 43 | def deinit(tft, display_off=False): 44 | """Take an ESPLCD instance and Deinitialize the display.""" 45 | tft.deinit() 46 | if display_off: 47 | BL.value(0) 48 | LCD_POWER.value(0) 49 | -------------------------------------------------------------------------------- /examples/configs/t-qt-pro/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for buttons: you will need to change these to match your wiring 2 | 3 | from machine import Pin 4 | 5 | 6 | class Buttons: 7 | def __init__(self): 8 | self.name = "t-qt-pro" 9 | self.left = Pin(0, Pin.IN) 10 | self.right = Pin(47, Pin.IN) 11 | 12 | # need more buttons for roids.py 13 | self.fire = 0 14 | self.thrust = 0 15 | self.hyper = 0 16 | -------------------------------------------------------------------------------- /examples/configs/t-qt-pro/tft_config.py: -------------------------------------------------------------------------------- 1 | """LILYGO T-QT Pro GC9107 128x128 display""" 2 | 3 | from machine import Pin, SPI, freq 4 | import s3lcd 5 | 6 | TFA = 0 7 | BFA = 0 8 | WIDE = 0 9 | TALL = 0 10 | 11 | BACKLIGHT = Pin(10, Pin.OUT) 12 | 13 | # Set clock to 240MHz 14 | freq(240000000) 15 | 16 | 17 | def config(rotation=0, options=0): 18 | """Configure the display and return an ESPLCD instance.""" 19 | 20 | # Same as GC9A01 21 | custom_init = ( 22 | (b"\xEF",), 23 | (b"\xEB\x14",), 24 | (b"\xFE",), 25 | (b"\xEF",), 26 | (b"\xEB\x14",), 27 | (b"\x84\x40",), 28 | (b"\x85\xFF",), 29 | (b"\x86\xFF",), 30 | (b"\x87\xFF",), 31 | (b"\x88\x0A",), 32 | (b"\x89\x21",), 33 | (b"\x8A\x00",), 34 | (b"\x8B\x80",), 35 | (b"\x8C\x01",), 36 | (b"\x8D\x01",), 37 | (b"\x8E\xFF",), 38 | (b"\x8F\xFF",), 39 | (b"\xB6\x00\x20",), 40 | (b"\x3A\x05",), 41 | (b"\x90\x08\x08\x08\x08",), 42 | (b"\xBD\x06",), 43 | (b"\xBC\x00",), 44 | (b"\xFF\x60\x01\x04",), 45 | (b"\xC3\x13",), 46 | (b"\xC4\x13",), 47 | (b"\xC9\x22",), 48 | (b"\xBE\x11",), 49 | (b"\xE1\x10\x0E",), 50 | (b"\xDF\x21\x0c\x02",), 51 | (b"\xF0\x45\x09\x08\x08\x26\x2A",), 52 | (b"\xF1\x43\x70\x72\x36\x37\x6F",), 53 | (b"\xF2\x45\x09\x08\x08\x26\x2A",), 54 | (b"\xF3\x43\x70\x72\x36\x37\x6F",), 55 | (b"\xED\x1B\x0B",), 56 | (b"\xAE\x77",), 57 | (b"\xCD\x63",), 58 | (b"\x70\x07\x07\x04\x0E\x0F\x09\x07\x08\x03",), 59 | (b"\xE8\x34",), 60 | (b"\x62\x18\x0D\x71\xED\x70\x70\x18\x0F\x71\xEF\x70\x70",), 61 | (b"\x63\x18\x11\x71\xF1\x70\x70\x18\x13\x71\xF3\x70\x70",), 62 | (b"\x64\x28\x29\xF1\x01\xF1\x00\x07",), 63 | (b"\x66\x3C\x00\xCD\x67\x45\x45\x10\x00\x00\x00",), 64 | (b"\x67\x00\x3C\x00\x00\x00\x01\x54\x10\x32\x98",), 65 | (b"\x74\x10\x85\x80\x00\x00\x4E\x00",), 66 | (b"\x98\x3e\x07",), 67 | (b"\x35",), 68 | (b"\x21",), 69 | (b"\x11", 120), 70 | (b"\x29", 20), 71 | ) 72 | 73 | custom_rotations = ( 74 | (128, 128, 2, 1, False, True, True), 75 | (128, 128, 1, 2, True, False, True), 76 | (128, 128, 2, 1, False, False, False), 77 | (128, 128, 1, 2, True, True, False), 78 | ) 79 | 80 | # To use baudrates above 26.6MHz you must use my firmware or modify the micropython 81 | # source code to increase the SPI baudrate limit by adding SPI_DEVICE_NO_DUMMY to the 82 | # .flag member of the spi_device_interface_config_t struct in the machine_hw_spi_init_internal.c 83 | # file. Not doing so will cause the ESP32 to crash if you use a baudrate that is too high. 84 | 85 | bus = s3lcd.SPI_BUS( 86 | 1, 87 | mosi=2, 88 | sck=3, 89 | dc=6, 90 | cs=5, 91 | pclk=60_000_000, 92 | swap_color_bytes=True, 93 | ) 94 | 95 | tft = s3lcd.ESPLCD( 96 | bus, 97 | 128, 98 | 128, 99 | inversion_mode=True, 100 | color_space=s3lcd.BGR, 101 | reset=1, 102 | rotations=custom_rotations, 103 | rotation=rotation, 104 | custom_init=custom_init, 105 | options=options, 106 | ) 107 | 108 | BACKLIGHT.value(0) 109 | return tft 110 | 111 | 112 | def deinit(tft, display_off=False): 113 | """Take an ESPLCD instance and Deinitialize the display.""" 114 | tft.deinit() 115 | if display_off: 116 | BACKLIGHT.value(1) 117 | -------------------------------------------------------------------------------- /examples/configs/wt32-sc01-plus/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for buttons: you will need to change these to match your wiring 2 | 3 | from machine import Pin 4 | 5 | class Buttons: 6 | def __init__(self): 7 | self.name = "wt32-sc01-plus" 8 | self.left = Pin(0, Pin.IN) 9 | self.right = Pin(14, Pin.IN) 10 | 11 | # need more buttons for roids.py 12 | self.fire = 0 13 | self.thrust = 0 14 | self.hyper = 0 15 | -------------------------------------------------------------------------------- /examples/configs/wt32-sc01-plus/tft_config.py: -------------------------------------------------------------------------------- 1 | """ WT32-SC01 Plus 320x480 ST7796 display """ 2 | 3 | from machine import Pin, freq 4 | import s3lcd 5 | 6 | 7 | BL = Pin(45, Pin.OUT) 8 | 9 | TFA = 0 10 | BFA = 0 11 | WIDE = 1 12 | TALL = 0 13 | 14 | freq(240_000_000) 15 | 16 | 17 | def config(rotation=0, options=0): 18 | """Configure the display and return an ESPLCD instance.""" 19 | 20 | custom_init = ( 21 | (b"\x01", 120), 22 | (b"\x11", 120), 23 | (b"\xF0\xC3",), 24 | (b"\xF0\x96",), 25 | (b"\x36\x48",), 26 | (b"\x3A\x55",), 27 | (b"\xB4\x01",), 28 | (b"\xB6\x80\x02\x3B",), 29 | (b"\xE8\x40\x8A\x00\x00\x29\x19\xA5\x33",), 30 | (b"\xC1\x06",), 31 | (b"\xC2\xA7",), 32 | (b"\xC5\x18", 120), 33 | (b"\xE0\xF0\x09\x0B\x06\x04\x15\x2F\x54\x42\x3C\x17\x14\x18\x1B",), 34 | (b"\xE1\xE0\x09\x0B\x06\x04\x03\x2B\x43\x42\x3B\x16\x14\x17\x1B", 120), 35 | (b"\xF0\x3C",), 36 | (b"\xF0\x69",), 37 | (b"\x29",), 38 | ) 39 | 40 | BL.value(1) 41 | 42 | bus = s3lcd.I80_BUS( 43 | (9, 46, 3, 8, 18, 17, 16, 15), 44 | dc=0, 45 | wr=47, 46 | cs=6, 47 | pclk=20_000_000, 48 | swap_color_bytes=True, 49 | reverse_color_bits=False, 50 | ) 51 | 52 | return s3lcd.ESPLCD( 53 | bus, 54 | 320, 55 | 480, 56 | inversion_mode=True, 57 | color_space=s3lcd.BGR, 58 | reset=4, 59 | rotation=rotation, 60 | custom_init=custom_init, 61 | options=options, 62 | ) 63 | 64 | 65 | def deinit(tft, display_off=False): 66 | """Take an ESPLCD instance and Deinitialize the display.""" 67 | tft.deinit() 68 | if display_off: 69 | BL.value(0) 70 | -------------------------------------------------------------------------------- /examples/feathers.py: -------------------------------------------------------------------------------- 1 | """ 2 | feathers.py 3 | Smoothly scroll rainbow-colored mirrored random curves across the display. 4 | """ 5 | 6 | import random 7 | import math 8 | import utime 9 | import s3lcd 10 | import tft_config 11 | 12 | 13 | def between(left, right, along): 14 | """returns a point along the curve from left to right""" 15 | dist = (1 - math.cos(along * math.pi)) / 2 16 | return left * (1 - dist) + right * dist 17 | 18 | 19 | def color_wheel(position): 20 | """returns a 565 color from the given position of the color wheel""" 21 | position = (255 - position) % 255 22 | 23 | if position < 85: 24 | return s3lcd.color565(255 - position * 3, 0, position * 3) 25 | 26 | if position < 170: 27 | position -= 85 28 | return s3lcd.color565(0, position * 3, 255 - position * 3) 29 | 30 | position -= 170 31 | return s3lcd.color565(position * 3, 255 - position * 3, 0) 32 | 33 | 34 | def main(): 35 | """ 36 | The big show! 37 | """ 38 | try: 39 | tft = tft_config.config(tft_config.WIDE) 40 | tft.init() # initialize display 41 | 42 | height = tft.height() # height of display in pixels 43 | width = tft.width() # width if display in pixels 44 | 45 | wheel = 0 # color wheel position 46 | 47 | tft.fill(s3lcd.BLACK) # clear screen 48 | tft.show() # show the cleared screen 49 | half = (height >> 1) - 1 # half the height of the display 50 | interval = 0 # steps between new points 51 | increment = 0 # increment per step 52 | counter = 1 # step counter, overflow to start 53 | current_y = 0 # current_y value (right point) 54 | last_y = 0 # last_y value (left point) 55 | segments = 0 # number of segments to draw 56 | x_offsets = [] # x offsets for each segment 57 | 58 | tween = 0 # tween value between last_y and current_y 59 | last_tween = 0 # last tween value 60 | wheel = 0 # color wheel position 61 | 62 | while True: 63 | 64 | # when the counter exceeds the interval, save current_y to last_y, 65 | # choose a new random value for current_y between 0 and 1/2 the 66 | # height of the display, choose a new random interval then reset 67 | # the counter to 0 and randmonize the number of segments to draw 68 | 69 | if counter > interval: 70 | last_y = current_y 71 | 72 | current_y = random.randint(0, half) 73 | counter = 0 74 | 75 | interval = random.randint(10, 100) 76 | increment = 1 / interval 77 | 78 | segments = random.randint(5, 10) 79 | offsets = width // segments 80 | x_offsets = [ 81 | x * offsets - offsets +1 for x in range(1, segments + 1) 82 | ] 83 | 84 | # get the next point between last_y and current_y 85 | last_tween = tween 86 | tween = int(between(last_y, current_y, counter * increment)) 87 | 88 | # draw mirrored pixels across the display at the offsets using the color_wheel effect 89 | 90 | color = color_wheel((wheel)) 91 | for x_offset in x_offsets: 92 | col = x_offset % width 93 | tft.pixel(col, half + last_tween, color) 94 | tft.pixel(col, half - last_tween, color) 95 | 96 | # update the display 97 | tft.scroll(1, 0) 98 | tft.show() 99 | 100 | # increment scroll, counter, and wheel 101 | wheel = (wheel + 1) % 256 102 | counter += 1 103 | 104 | finally: 105 | tft.deinit() 106 | 107 | 108 | main() 109 | -------------------------------------------------------------------------------- /examples/font_decode.py: -------------------------------------------------------------------------------- 1 | """Example showing how to deocode glyph bitmaps from a font module""" 2 | 3 | import proverbs_font as font 4 | 5 | text = "师父领进门,修行在个人" 6 | 7 | 8 | def get_bitmap_offset(index): 9 | """Return the bitmap bit offset for the glyph at `index`""" 10 | offset_first = index * font.OFFSET_WIDTH 11 | offset = 0 12 | for offset_byte in range(font.OFFSET_WIDTH): 13 | offset = (offset << 8) + font.OFFSETS[offset_first + offset_byte] 14 | return offset 15 | 16 | 17 | def get_pixel_color(bit): 18 | """Return the color of the pixel starting at `bit` comprised of `font.BPP` bits""" 19 | pixel_color = 0 20 | for _ in range(font.BPP): 21 | pixel_color = (pixel_color << 1) | font.BITMAPS[bit // 8] & 1 << (7 - (bit % 8)) 22 | bit += 1 23 | 24 | return pixel_color 25 | 26 | 27 | # Draw the string `text` one glyph at a time 28 | for glyph in text: 29 | print({glyph}) 30 | glyph_index = font.MAP.index(glyph) 31 | glyph_width = font.WIDTHS[glyph_index] 32 | glyph_bitmap_data = get_bitmap_offset(glyph_index) 33 | for _ in range(font.HEIGHT): 34 | for _ in range(glyph_width): 35 | color = get_pixel_color(glyph_bitmap_data) 36 | print("#" if color else " ", end="") 37 | glyph_bitmap_data += font.BPP 38 | print() 39 | print("\n") 40 | -------------------------------------------------------------------------------- /examples/hello.py: -------------------------------------------------------------------------------- 1 | """ 2 | hello.py 3 | 4 | Writes "Hello!" in random colors at random locations on the display. 5 | """ 6 | 7 | import random 8 | import time 9 | 10 | import vga2_bold_16x32 as big 11 | import vga1_8x8 as small 12 | import tft_config 13 | import s3lcd 14 | 15 | tft = tft_config.config(tft_config.WIDE) 16 | 17 | 18 | def complementary_color(color565): 19 | """returns the complementary color of the given 565 color""" 20 | inverted_color = ~color565 21 | return ( 22 | ((inverted_color & 0x001F) << 11) 23 | | (inverted_color & 0x07E0) 24 | | ((inverted_color & 0xF800) >> 11) 25 | ) 26 | 27 | 28 | def color_wheel(position): 29 | """returns a 565 color from the given position of the color wheel""" 30 | if position < 85: 31 | return s3lcd.color565(255 - position * 3, 0, position * 3) 32 | 33 | if position < 170: 34 | position -= 85 35 | return s3lcd.color565(0, position * 3, 255 - position * 3) 36 | 37 | position -= 170 38 | return s3lcd.color565(position * 3, 255 - position * 3, 0) 39 | 40 | 41 | def center(using_font, text, fg=s3lcd.WHITE, bg=s3lcd.BLACK): 42 | """ 43 | Centers the given text on the display. 44 | """ 45 | length = 1 if isinstance(text, int) else len(text) 46 | tft.text( 47 | using_font, 48 | text, 49 | tft.width() // 2 - length // 2 * using_font.WIDTH, 50 | tft.height() // 2 - using_font.HEIGHT // 2, 51 | fg, 52 | bg, 53 | ) 54 | 55 | 56 | def main(): 57 | """ 58 | The big show! 59 | """ 60 | try: 61 | tft.init() 62 | font = small if tft.height() < 96 else big 63 | for color in [s3lcd.RED, s3lcd.GREEN, s3lcd.BLUE]: 64 | tft.fill(color) 65 | tft.rect(0, 0, tft.width(), tft.height(), complementary_color(color)) 66 | center(font, 'Hello', s3lcd.WHITE, color) 67 | tft.show() 68 | time.sleep(1) 69 | 70 | wheel = 0 71 | 72 | while True: 73 | tft.fill(s3lcd.BLACK) 74 | for rot in range(4): 75 | tft.rotation(rot) 76 | tft.fill(s3lcd.BLACK) 77 | col_max = tft.width() - font.WIDTH * 6 78 | row_max = tft.height() - font.HEIGHT 79 | 80 | now = time.ticks_ms() 81 | for i in range(50): 82 | wheel = (wheel + 43) % 255 83 | opacity = i * 255 // 10 84 | 85 | tft.text( 86 | font, 87 | "Hello!", 88 | random.randint(0, col_max), 89 | random.randint(0, row_max), 90 | color_wheel(wheel), 91 | s3lcd.TRANSPARENT, 92 | opacity, 93 | ) 94 | 95 | tft.show() 96 | 97 | # print(time.ticks_ms() - now, "ms") 98 | 99 | finally: 100 | tft_config.deinit(tft) 101 | 102 | 103 | main() 104 | -------------------------------------------------------------------------------- /examples/hershey.py: -------------------------------------------------------------------------------- 1 | """ 2 | hershey.py 3 | 4 | Demo program that draws greetings on display cycling thru hershey fonts and colors. 5 | 6 | """ 7 | 8 | import time 9 | import s3lcd 10 | import tft_config 11 | 12 | # Load several frozen fonts from flash 13 | 14 | import greeks 15 | import italicc 16 | import italiccs 17 | import meteo 18 | import romanc 19 | import romancs 20 | import romand 21 | import romanp 22 | import romans 23 | import scriptc 24 | import scripts 25 | 26 | tft = tft_config.config(tft_config.TALL, options=s3lcd.WRAP_V) 27 | 28 | 29 | def cycle(p): 30 | """return the next item in a list""" 31 | try: 32 | len(p) 33 | except TypeError: 34 | cache = [] 35 | for i in p: 36 | yield i 37 | cache.append(i) 38 | 39 | p = cache 40 | while p: 41 | yield from p 42 | 43 | 44 | COLORS = ( 45 | s3lcd.RED, 46 | s3lcd.GREEN, 47 | s3lcd.BLUE, 48 | s3lcd.CYAN, 49 | s3lcd.MAGENTA, 50 | s3lcd.YELLOW, 51 | s3lcd.WHITE, 52 | ) 53 | 54 | COLOR = cycle(COLORS) 55 | 56 | # List Hershey fonts 57 | FONTS = ( 58 | greeks, 59 | italicc, 60 | italiccs, 61 | meteo, 62 | romanc, 63 | romancs, 64 | romand, 65 | romanp, 66 | romans, 67 | scriptc, 68 | scripts, 69 | ) 70 | 71 | # Create a cycle of tuples consisting of a FONT[] and the HEIGHT of the next FONT[] in the cycle 72 | FONT = cycle( 73 | [(font, FONTS[(i + 1) % len(FONTS)].HEIGHT) for i, font in enumerate(FONTS)] 74 | ) 75 | 76 | # Greetings 77 | GREETINGS = ( 78 | "Ahoy", 79 | "Bonjour", 80 | "Bonsoir", 81 | "Buenos Dias", 82 | "Buenas tardes", 83 | "Buenas Noches", 84 | "Ciao", 85 | "Dude", 86 | "Good Morning", 87 | "Good Day", 88 | "Good Evening", 89 | "Hello", 90 | "Hey", 91 | "Hi", 92 | "Hiya", 93 | "Hola", 94 | "How Are You", 95 | "How Goes It", 96 | "Howdy", 97 | "How you doing", 98 | "Konnichiwa", 99 | "Salut", 100 | "Shalom", 101 | "Welcome", 102 | "What's Up", 103 | "Yo!", 104 | ) 105 | 106 | # Create a cycle of tuples consisting of a list of words from a GREETING, the number of spaces+1 107 | # in the that GREETING, and the number of spaces+1 in the next GREETING of the cycle 108 | GREETING = cycle( 109 | [ 110 | ( 111 | greeting.split(), 112 | greeting.count(" ") + 1, 113 | GREETINGS[(i + 1) % len(GREETINGS)].count(" ") + 1, 114 | ) 115 | for i, greeting in enumerate(GREETINGS) 116 | ] 117 | ) 118 | 119 | 120 | def main(): 121 | """Scroll greetings on the display cycling thru Hershey fonts and colors""" 122 | 123 | try: 124 | tft.init() 125 | tft.fill(s3lcd.BLACK) 126 | 127 | height = tft.height() 128 | width = tft.width() 129 | 130 | if width > 240: 131 | size = 1.5 132 | elif width > 80: 133 | size = 1 134 | else: 135 | size = 0.5 136 | 137 | to_scroll = 0 138 | wheel = 0 139 | ticks = 1000 // 45 140 | 141 | while True: 142 | last = time.ticks_ms() 143 | # if we have scrolled high enough for the next greeting 144 | if to_scroll == 0: 145 | font = next(FONT) # get the next font 146 | greeting = next(GREETING) # get the next greeting 147 | wheel = (wheel + 29) % 255 # update the color wheel 148 | color = next(COLOR) # get the next color 149 | lines = greeting[2] # number of lines in the greeting 150 | to_scroll = lines * font[1] + 4 * size # number of rows to scroll 151 | 152 | # draw each line of the greeting 153 | for i, word in enumerate(greeting[0][::-1]): 154 | word_len = tft.draw_len(font[0], word, size) # width in pixels 155 | col = ( 156 | 0 if word_len > width else (width // 2 - word_len // 2) 157 | ) # column to center 158 | row = height - ((i + 1) * font[0].HEIGHT) % height # row to draw 159 | tft.draw(font[0], word, col, row, color, size) # draw the word 160 | 161 | tft.show() # show the display 162 | tft.scroll(0, -1) # scroll the display 163 | to_scroll -= 1 # update rows left to scroll 164 | 165 | if time.ticks_ms() - last < ticks: 166 | time.sleep_ms(ticks - (time.ticks_ms() - last)) 167 | 168 | finally: 169 | tft.deinit() 170 | 171 | 172 | main() 173 | -------------------------------------------------------------------------------- /examples/jpg_tests/conv-logo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for size in 64x64 80x160 128x128 160x128 160x80 240x135 240x240 240x320 320x170 320x240 480x320; do 4 | convert Micropython-logo.svg -resize "$size" -gravity center -extent "$size" +repage -background white "logo-$size.jpg" 5 | done 6 | -------------------------------------------------------------------------------- /examples/jpg_tests/jpg_bounce.py: -------------------------------------------------------------------------------- 1 | """ 2 | bounce_jpg.py 3 | 4 | Bounce a jpg around the display to test visibility clipping. 5 | 6 | """ 7 | 8 | import gc 9 | import random 10 | import time 11 | import tft_config 12 | import s3lcd 13 | 14 | gc.enable() 15 | gc.collect() 16 | 17 | LOGO_WIDTH = 64 18 | LOGO_HEIGHT = 64 19 | 20 | 21 | def main(): 22 | """ 23 | Bounce a jpg around the display. 24 | """ 25 | 26 | try: 27 | tft = tft_config.config(tft_config.WIDE) 28 | 29 | # enable display and clear screen 30 | tft.init() 31 | width = tft.width() 32 | height = tft.height() 33 | col = width // 2 - LOGO_WIDTH // 2 34 | row = height // 2 - LOGO_HEIGHT // 2 35 | xd = 3 36 | yd = 2 37 | 38 | ticks = 1000 // 45 39 | 40 | with open(f'logo-{LOGO_WIDTH}x{LOGO_HEIGHT}.jpg', "rb") as file: 41 | jpg_logo = file.read() 42 | 43 | while True: 44 | last = time.ticks_ms() 45 | 46 | tft.jpg(jpg_logo, col, row) 47 | tft.show() 48 | tft.clear(0) 49 | 50 | # Update the position to bounce the bitmap around the screen 51 | col += xd 52 | if col <= -LOGO_WIDTH - 1 or col > width: 53 | xd = -xd 54 | 55 | row += yd 56 | if row <= -LOGO_HEIGHT - 1 or row > height: 57 | yd = -yd 58 | 59 | if time.ticks_ms() - last < ticks: 60 | time.sleep_ms(ticks - (time.ticks_ms() - last)) 61 | 62 | 63 | finally: 64 | tft.deinit() 65 | 66 | 67 | main() 68 | -------------------------------------------------------------------------------- /examples/jpg_tests/jpg_logo.py: -------------------------------------------------------------------------------- 1 | """ 2 | logo.py 3 | 4 | Draw the MicroPython Logo. 5 | 6 | """ 7 | 8 | import random 9 | import tft_config 10 | 11 | tft = tft_config.config(tft_config.WIDE) 12 | 13 | 14 | def main(): 15 | """ 16 | Decode and draw jpg on display 17 | """ 18 | 19 | try: 20 | tft.init() 21 | width=tft.width() 22 | height=tft.height() 23 | 24 | image = f'logo-{width}x{height}.jpg' 25 | print(f"Loading {image}") 26 | tft.jpg(image, 0, 0) 27 | tft.show() 28 | 29 | finally: 30 | tft.deinit() 31 | 32 | 33 | main() 34 | -------------------------------------------------------------------------------- /examples/jpg_tests/jpg_tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | jpg_tests.py 3 | 4 | Randomly draw MicroPython logo on the display using various methods. 5 | 6 | """ 7 | 8 | import gc 9 | import random 10 | import time 11 | import tft_config 12 | import s3lcd 13 | 14 | gc.enable() 15 | gc.collect() 16 | 17 | 18 | def main(): 19 | """ 20 | Decode and draw jpg on display using various methods 21 | """ 22 | 23 | try: 24 | tft = tft_config.config(tft_config.WIDE) 25 | 26 | # enable display and clear screen 27 | tft.init() 28 | 29 | # read jpg file into buffer without decoding 30 | with open("logo-64x64.jpg", "rb") as file: 31 | alien = file.read() 32 | 33 | # read and decode png file into a tuple containing (image, width, height) 34 | decoded_bitmap = tft.jpg_decode("logo-64x64.jpg") 35 | bitmap_width = decoded_bitmap[1] 36 | bitmap_height = decoded_bitmap[2] 37 | 38 | draw_count = 100 39 | 40 | # display png in random locations 41 | while True: 42 | print(f"Drawing {draw_count} jpg's from a file", end=" ") 43 | tft.clear(0) 44 | # decode and draw jpg from a file 45 | start = time.ticks_ms() 46 | for _ in range(draw_count): 47 | tft.jpg( 48 | "logo-64x64.jpg", 49 | random.randint(0, tft.width() - bitmap_width), 50 | random.randint(0, tft.height() - bitmap_height), 51 | True, 52 | ) 53 | print(f"took {time.ticks_ms() - start} ms.") 54 | 55 | tft.show() 56 | time.sleep(2) 57 | 58 | print(f"Drawing {draw_count} jpg's from a buffer", end=" ") 59 | tft.clear(0) 60 | # decode and draw jpg from a buffer 61 | start = time.ticks_ms() 62 | for _ in range(draw_count): 63 | tft.jpg( 64 | alien, 65 | random.randint(0, tft.width() - bitmap_width), 66 | random.randint(0, tft.height() - bitmap_height), 67 | True, 68 | ) 69 | 70 | print(f"took {time.ticks_ms() - start} ms.") 71 | tft.show() 72 | time.sleep(2) 73 | 74 | print(f"Drawing {draw_count} jpg's from a decoded buffer", end=" ") 75 | tft.clear(0) 76 | # draw decoded bitmap from a tuple created by jpg_decode() 77 | start = time.ticks_ms() 78 | for _ in range(draw_count): 79 | tft.blit_buffer( 80 | decoded_bitmap[0], 81 | random.randint(0, tft.width() - bitmap_width), 82 | random.randint(0, tft.height() - bitmap_height), 83 | decoded_bitmap[1], 84 | decoded_bitmap[2], 85 | ) 86 | 87 | print(f"took {time.ticks_ms() - start} ms.\n") 88 | tft.show() 89 | time.sleep(2) 90 | 91 | finally: 92 | tft.deinit() 93 | 94 | 95 | main() 96 | -------------------------------------------------------------------------------- /examples/jpg_tests/logo-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-128x128.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-160x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-160x128.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-160x80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-160x80.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-240x135.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-240x135.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-240x240.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-240x240.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-240x320.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-240x320.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-320x170.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-320x170.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-320x240.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-320x240.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-480x320.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-480x320.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-64x64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-64x64.jpg -------------------------------------------------------------------------------- /examples/jpg_tests/logo-80x160.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/jpg_tests/logo-80x160.jpg -------------------------------------------------------------------------------- /examples/mono_fonts/inconsolata_16.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/mono_fonts/inconsolata_16.mpy -------------------------------------------------------------------------------- /examples/mono_fonts/inconsolata_32.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/mono_fonts/inconsolata_32.mpy -------------------------------------------------------------------------------- /examples/mono_fonts/inconsolata_64.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/mono_fonts/inconsolata_64.mpy -------------------------------------------------------------------------------- /examples/mono_fonts/mono_fonts.py: -------------------------------------------------------------------------------- 1 | """ 2 | mono_fonts.py test for monofont2bitmap converter and bitmap method. This is the older method of 3 | converting monofonts to bitmaps. See the newer method in prop_fonts/chango.py that works with 4 | mono and proportional fonts using the write method. 5 | """ 6 | 7 | import time 8 | import s3lcd 9 | import tft_config 10 | 11 | import inconsolata_16 as font_16 12 | import inconsolata_32 as font_32 13 | import inconsolata_64 as font_64 14 | 15 | tft = tft_config.config(tft_config.WIDE) 16 | 17 | 18 | def display_font(font, fast): 19 | tft.fill(s3lcd.BLUE) 20 | column = 0 21 | row = 0 22 | for char in font.MAP: 23 | tft.bitmap(font, column, row, font.MAP.index(char)) 24 | tft.show() 25 | column += font.WIDTH 26 | if column >= tft.width() - font.WIDTH: 27 | row += font.HEIGHT 28 | column = 0 29 | 30 | if row > tft.height() - font.HEIGHT: 31 | row = 0 32 | 33 | if not fast: 34 | time.sleep(0.05) 35 | 36 | 37 | def main(): 38 | fast = False 39 | 40 | try: 41 | tft.init() 42 | 43 | while True: 44 | for font in [font_16, font_32, font_64]: 45 | display_font(font, fast) 46 | 47 | fast = not fast 48 | 49 | finally: 50 | tft.deinit() 51 | 52 | 53 | main() 54 | -------------------------------------------------------------------------------- /examples/nasa/Pacifico-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/Pacifico-Regular.ttf -------------------------------------------------------------------------------- /examples/nasa/make_fonts: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # usage make_font 4 | 5 | function font() { 6 | ../../utils/font2bitmap.py -s '0123456789:. ' Pacifico-Regular.ttf "$1" > "pacifico$1.py" 7 | } 8 | 9 | font 45 10 | font 80 11 | font 100 12 | font 150 13 | -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa01.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa02.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa03.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa04.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa05.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa06.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa07.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa08.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa09.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa10.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa11.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa12.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa13.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa14.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa15.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa16.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa17.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa18.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa19.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa20.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa21.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa22.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa23.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa24.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_128x128/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_128x128/nasa25.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa01.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa02.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa03.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa04.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa05.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa06.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa07.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa08.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa09.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa10.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa11.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa12.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa13.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa14.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa15.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa16.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa17.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa18.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa19.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa20.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa21.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa22.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa23.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa24.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_160x80/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_160x80/nasa25.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa01.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa02.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa03.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa04.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa05.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa06.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa07.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa08.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa09.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa10.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa11.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa12.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa13.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa14.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa15.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa16.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa17.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa18.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa19.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa20.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa21.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa22.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa23.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa24.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_170x320/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_170x320/nasa25.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa01.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa02.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa03.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa04.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa05.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa06.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa07.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa08.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa09.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa10.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa11.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa12.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa13.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa14.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa15.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa16.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa17.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa18.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa19.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa20.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa21.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa22.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa23.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa24.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_240x320/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_240x320/nasa25.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa01.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa02.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa03.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa04.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa05.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa06.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa07.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa08.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa09.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa10.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa11.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa12.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa13.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa14.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa15.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa16.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa17.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa18.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa19.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa20.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa21.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa22.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa23.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa24.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x170/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x170/nasa25.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa01.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa02.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa03.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa04.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa05.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa06.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa07.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa08.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa09.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa10.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa11.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa12.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa13.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa14.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa15.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa16.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa17.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa18.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa19.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa20.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa21.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa22.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa23.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa24.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_320x240/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_320x240/nasa25.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa01.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa02.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa03.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa04.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa05.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa06.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa07.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa08.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa09.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa10.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa11.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa12.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa13.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa14.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa15.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa16.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa17.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa18.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa19.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa20.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa21.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa22.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa23.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa24.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_480x320/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/nasa_480x320/nasa25.jpg -------------------------------------------------------------------------------- /examples/nasa/nasa_images.py: -------------------------------------------------------------------------------- 1 | """ 2 | nasa_images.py - Display a series of NASA images on the display from the 3 | nasa_480x320/ folder. 4 | 5 | Images courtesy of the NASA image and video gallery available at 6 | https://images.nasa.gov/ 7 | """ 8 | 9 | import random 10 | import time 11 | import s3lcd 12 | import tft_config 13 | from machine import freq 14 | 15 | tft = tft_config.config(tft_config.WIDE) 16 | 17 | 18 | def main(): 19 | 20 | """ 21 | Decode and draw jpg on display 22 | """ 23 | try: 24 | tft.init() 25 | width = tft.width() 26 | height = tft.height() 27 | 28 | while True: 29 | for image in range(1, 25): 30 | filename = f"nasa_{width}x{height}/nasa{image:02d}.jpg" 31 | tft.jpg(filename, 0, 0) # Draw full screen jpg 32 | tft.show() # Show the framebuffer and wait for it to finish 33 | time.sleep(5) # Wait a second 34 | 35 | finally: 36 | tft.deinit() # Deinitialize the display or it will cause a crash on the next run 37 | 38 | 39 | main() 40 | -------------------------------------------------------------------------------- /examples/nasa/pacifico100.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/pacifico100.mpy -------------------------------------------------------------------------------- /examples/nasa/pacifico150.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/pacifico150.mpy -------------------------------------------------------------------------------- /examples/nasa/pacifico45.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/pacifico45.mpy -------------------------------------------------------------------------------- /examples/nasa/pacifico80.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/nasa/pacifico80.mpy -------------------------------------------------------------------------------- /examples/noto_fonts.py: -------------------------------------------------------------------------------- 1 | """ 2 | noto_fonts Writes the names of three Noto fonts centered on the display 3 | using the font. The fonts were converted from True Type fonts using 4 | the font2bitmap utility. 5 | """ 6 | import time 7 | import s3lcd 8 | import tft_config 9 | import NotoSans_32 as noto_sans 10 | import NotoSerif_32 as noto_serif 11 | import NotoSansMono_32 as noto_mono 12 | 13 | 14 | tft = tft_config.config(tft_config.WIDE) 15 | 16 | 17 | def center(font, s, row, color=s3lcd.WHITE): 18 | screen = tft.width() # get screen width 19 | width = tft.write_len(font, s) # get the width of the string 20 | col = tft.width() // 2 - width // 2 if width and width < screen else 0 21 | tft.write(font, s, col, row, color) # and write the string 22 | 23 | 24 | def main(): 25 | try: 26 | # init display 27 | tft.init() 28 | tft.fill(s3lcd.BLACK) 29 | 30 | # center the name of the first font, using the font 31 | row = 16 32 | center(noto_sans, "NotoSans", row, s3lcd.RED) 33 | row += noto_sans.HEIGHT 34 | 35 | # center the name of the second font, using the font 36 | center(noto_serif, "NotoSerif", row, s3lcd.GREEN) 37 | row += noto_serif.HEIGHT 38 | 39 | # center the name of the third font, using the font 40 | center(noto_mono, "NotoSansMono", row, s3lcd.BLUE) 41 | row += noto_mono.HEIGHT 42 | 43 | tft.show() 44 | time.sleep(5) 45 | finally: 46 | tft.deinit() 47 | 48 | 49 | main() 50 | -------------------------------------------------------------------------------- /examples/png_tests/alien.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/png_tests/alien.png -------------------------------------------------------------------------------- /examples/png_tests/alien.py: -------------------------------------------------------------------------------- 1 | """ 2 | alien.py 3 | 4 | Randomly draw alien.png to test alpha-channel masking 5 | 6 | The alien.png is from the Erik Flowers Weather Icons available from 7 | https://github.com/erikflowers/weather-icons and is licensed under 8 | SIL OFL 1.1 9 | 10 | """ 11 | 12 | import gc 13 | import random 14 | import time 15 | import tft_config 16 | import s3lcd 17 | 18 | gc.enable() 19 | gc.collect() 20 | 21 | 22 | def main(): 23 | """ 24 | Decode and draw png on display 25 | """ 26 | 27 | try: 28 | tft = tft_config.config(tft_config.WIDE) 29 | tft.init() 30 | width = tft.width() 31 | height = tft.height() 32 | 33 | # display png in random locations 34 | while True: 35 | x = random.randint(0, width - 32) 36 | y = random.randint(0, height - 32) 37 | tft.png("alien.png", x, y) 38 | tft.show() 39 | 40 | finally: 41 | tft.deinit() 42 | 43 | 44 | main() 45 | -------------------------------------------------------------------------------- /examples/png_tests/png_bounce.py: -------------------------------------------------------------------------------- 1 | """ 2 | png_bounce.py 3 | 4 | Bounce a png around the display to test visibility clipping. 5 | 6 | """ 7 | 8 | import gc 9 | import random 10 | import time 11 | import tft_config 12 | import s3lcd 13 | 14 | gc.enable() 15 | gc.collect() 16 | 17 | LOGO_WIDTH = 30 18 | LOGO_HEIGHT = 30 19 | 20 | 21 | def main(): 22 | """ 23 | Bounce a png around the display. 24 | """ 25 | 26 | try: 27 | tft = tft_config.config(tft_config.WIDE) 28 | 29 | # enable display and clear screen 30 | tft.init() 31 | width = tft.width() 32 | height = tft.height() 33 | col = width // 2 - LOGO_WIDTH // 2 34 | row = height // 2 - LOGO_HEIGHT // 2 35 | xd = 3 36 | yd = 2 37 | 38 | ticks = 1000 // 45 39 | 40 | # read jpg file into buffer without decoding 41 | with open("alien.png", "rb") as file: 42 | alien = file.read() 43 | 44 | while True: 45 | last = time.ticks_ms() 46 | tft.png(alien, col, row) 47 | tft.show() 48 | tft.clear(0) 49 | 50 | # Update the position to bounce the bitmap around the screen 51 | col += xd 52 | if col <= -LOGO_WIDTH - 1 or col > width: 53 | xd = -xd 54 | 55 | row += yd 56 | if row <= -LOGO_HEIGHT - 1 or row > height: 57 | yd = -yd 58 | 59 | if time.ticks_ms() - last < ticks: 60 | time.sleep_ms(ticks - (time.ticks_ms() - last)) 61 | 62 | finally: 63 | tft.deinit() 64 | 65 | 66 | main() 67 | -------------------------------------------------------------------------------- /examples/png_tests/png_write.py: -------------------------------------------------------------------------------- 1 | """ 2 | png_write.py 3 | 4 | Writes "Hello!" in the center of the display and saves the framebuffer to a png file. 5 | 6 | """ 7 | 8 | import random 9 | import time 10 | 11 | import tft_config 12 | import vga1_8x8 as small 13 | import vga2_bold_16x32 as big 14 | 15 | import s3lcd 16 | 17 | tft = tft_config.config(tft_config.WIDE) 18 | 19 | 20 | def center(using_font, text, fg=s3lcd.WHITE, bg=s3lcd.BLACK): 21 | """ 22 | Centers the given text on the display. 23 | """ 24 | length = 1 if isinstance(text, int) else len(text) 25 | 26 | col = (tft.width() // 2 - length // 2 * using_font.WIDTH) 27 | row = (tft.height() // 2 - using_font.HEIGHT // 2) 28 | width = length * using_font.WIDTH 29 | height = using_font.HEIGHT 30 | tft.text(using_font, text, col, row, fg, bg) 31 | return (col, row, width, height) 32 | 33 | 34 | def main(): 35 | """ 36 | The big show! 37 | """ 38 | try: 39 | tft.init() 40 | font = small if tft.height() < 96 else big 41 | tft.fill(s3lcd.RED) 42 | tft.rect(0, 0, tft.width(), tft.height(), s3lcd.WHITE) 43 | (x, y, w, h) = center(font, b"\xAEHello\xAF", s3lcd.WHITE, s3lcd.RED) 44 | tft.show() 45 | tft.png_write("hello.png", x+1, y, w, h) 46 | 47 | finally: 48 | tft_config.deinit(tft) 49 | 50 | 51 | main() 52 | -------------------------------------------------------------------------------- /examples/proverbs/NotoSansSC-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/proverbs/NotoSansSC-Regular.otf -------------------------------------------------------------------------------- /examples/proverbs/make_font: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Convert the font to a bitmap 4 | # usage convert 5 | 6 | 7 | function convert() { 8 | python3 ../../utils/font2bitmap.py \ 9 | -s "万事起头难。熟能生巧。冰冻三尺,非一日之寒。三个臭皮匠,胜过诸葛亮。今日事,今日毕。师父领进门,修行在个人。一口吃不成胖子。欲速则不达。百闻不如一见。不入虎穴,焉得虎子。" \ 10 | NotoSansSC-Regular.otf $1 >notosanssc$1.py 11 | } 12 | 13 | convert $1 14 | mpy-cross notosanssc$1.py 15 | mpremote cp notosanssc$1.mpy :notosanssc.mpy 16 | mpremote cp proverbs.py : 17 | -------------------------------------------------------------------------------- /examples/proverbs/notosanssc20.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/proverbs/notosanssc20.mpy -------------------------------------------------------------------------------- /examples/proverbs/notosanssc45.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/proverbs/notosanssc45.mpy -------------------------------------------------------------------------------- /examples/proverbs/proverbs.py: -------------------------------------------------------------------------------- 1 | """ 2 | proverbs.py - Displays what I hope are chinese proverbs in simplified chinese to test UTF-8 3 | font support. 4 | """ 5 | 6 | import utime 7 | import s3lcd 8 | import tft_config 9 | import notosanssc as font 10 | 11 | 12 | tft = tft_config.config(tft_config.WIDE) 13 | 14 | 15 | def cycle(p): 16 | """return the next item in a list""" 17 | try: 18 | len(p) 19 | except TypeError: 20 | cache = [] 21 | for i in p: 22 | yield i 23 | cache.append(i) 24 | 25 | p = cache 26 | while p: 27 | yield from p 28 | 29 | 30 | COLORS = ( 31 | s3lcd.RED, 32 | s3lcd.GREEN, 33 | s3lcd.BLUE, 34 | s3lcd.CYAN, 35 | s3lcd.MAGENTA, 36 | s3lcd.YELLOW, 37 | s3lcd.WHITE, 38 | ) 39 | 40 | COLOR = cycle(COLORS) 41 | 42 | 43 | def main(): 44 | 45 | proverbs = [ 46 | "一口吃不成胖子", 47 | "万事起头难", 48 | "熟能生巧", 49 | "冰冻三尺,非一日之寒", 50 | "三个臭皮匠,胜过诸葛亮", 51 | "今日事,今日毕", 52 | "师父领进门,修行在个人", 53 | "欲速则不达", 54 | "百闻不如一见", 55 | "不入虎穴,焉得虎子", 56 | ] 57 | 58 | try: 59 | # initialize display 60 | tft.init() 61 | line_height = font.HEIGHT + 8 62 | half_height = tft.height() // 2 63 | half_width = tft.width() // 2 64 | 65 | tft.fill(s3lcd.BLACK) 66 | 67 | while True: 68 | for proverb in proverbs: 69 | proverb_lines = proverb.split(",") 70 | half_lines_height = len(proverb_lines) * line_height // 2 71 | 72 | tft.fill(s3lcd.BLACK) 73 | color = next(COLOR) 74 | 75 | for count, proverb_line in enumerate(proverb_lines): 76 | half_length = tft.write_len(font, proverb_line) // 2 77 | 78 | tft.write( 79 | font, 80 | proverb_line, 81 | half_width - half_length, 82 | half_height - half_lines_height + count * line_height, 83 | color, 84 | ) 85 | tft.show() 86 | utime.sleep(5) 87 | 88 | finally: 89 | tft.deinit() 90 | 91 | 92 | main() 93 | -------------------------------------------------------------------------------- /examples/scroll.py: -------------------------------------------------------------------------------- 1 | """ 2 | scroll.py 3 | 4 | Smoothly scroll all characters of a font up the display. 5 | Fonts heights must be even multiples of the screen height 6 | (i.e. 8 or 16 pixels high). 7 | """ 8 | 9 | import time 10 | import s3lcd 11 | import tft_config 12 | import vga1_bold_16x32 as big 13 | import vga1_8x8 as small 14 | 15 | 16 | print(0) 17 | tft = tft_config.config(tft_config.WIDE) 18 | 19 | 20 | def cycle(p): 21 | try: 22 | len(p) 23 | except TypeError: 24 | cache = [] 25 | for i in p: 26 | yield i 27 | cache.append(i) 28 | p = cache 29 | while p: 30 | yield from p 31 | 32 | 33 | def main(): 34 | 35 | try: 36 | tft.init() 37 | 38 | color = cycle( 39 | ( 40 | s3lcd.RED, 41 | s3lcd.GREEN, 42 | s3lcd.BLUE, 43 | s3lcd.CYAN, 44 | s3lcd.MAGENTA, 45 | s3lcd.YELLOW, 46 | s3lcd.WHITE, 47 | ) 48 | ) 49 | 50 | foreground = next(color) 51 | background = s3lcd.BLACK 52 | 53 | tft.fill(background) 54 | 55 | height = tft.height() 56 | width = tft.width() 57 | 58 | font = small if tft.width() < 96 else big 59 | line = height - font.HEIGHT 60 | 61 | while True: 62 | for character in range(font.FIRST, font.LAST + 1): 63 | # write character hex value as a string 64 | tft.text(font, f"x{character:02x}", 16, line, foreground, background) 65 | 66 | # write character using a integer (could be > 0x7f) 67 | tft.text( 68 | font, 69 | character, 70 | width - font.WIDTH * 2, 71 | line, 72 | foreground, 73 | background, 74 | ) 75 | 76 | # change color for next line 77 | foreground = next(color) 78 | 79 | # next character with rollover at 256 80 | character = (character +1) % height 81 | 82 | # scroll the screen up by one character height 83 | for _ in range(font.HEIGHT // 2): 84 | tft.scroll(0, -2) 85 | tft.show() 86 | 87 | 88 | finally: 89 | tft.deinit() 90 | 91 | 92 | main() 93 | -------------------------------------------------------------------------------- /examples/test_examples: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "This script erases, uploads firmware and demos to device, then runs" 4 | echo "each demo. Use CTRL-C to stop the demo, then press return for the next." 5 | echo 6 | 7 | function run() { 8 | echo "Running $1..." 9 | mpremote run $1 10 | read -p "Press enter to continue" 11 | } 12 | 13 | # comment out of you dont want to erase and flash firmware 14 | ./upload-examples.sh 15 | 16 | run bitarray.py 17 | run bitmap_fonts.py 18 | run blit_tests/blit_bounce.py 19 | run chango/chango.py 20 | run color_test.py 21 | run feathers.py 22 | run hello.py 23 | run hershey.py 24 | run jpg_tests/jpg_bounce.py 25 | run jpg_tests/jpg_logo.py 26 | run jpg_tests/jpg_tests.py 27 | run mono_fonts/mono_fonts.py 28 | run nasa/nasa_clock.py 29 | run nasa/nasa_images.py 30 | run noto_fonts.py 31 | run pinball.py 32 | run png_tests/png_bounce.py 33 | run png_tests/alien.py 34 | run proverbs/proverbs.py 35 | run roids.py 36 | run scroll.py 37 | run tiny_hello.py 38 | run tiny_toasters/tiny_toasters.py 39 | run toasters/toasters.py 40 | run toasters_jpg/toasters_jpg.py 41 | run watch/watch.py 42 | -------------------------------------------------------------------------------- /examples/tiny_hello.py: -------------------------------------------------------------------------------- 1 | """ 2 | hello.py 3 | 4 | Writes "Hello!" in random colors at random locations on the display. 5 | """ 6 | 7 | import random 8 | import time 9 | 10 | import vga1_8x8 as font 11 | import tft_config 12 | import s3lcd 13 | 14 | tft = tft_config.config(tft_config.WIDE) 15 | 16 | 17 | def center(text, fg=s3lcd.WHITE, bg=s3lcd.BLACK): 18 | """ 19 | Centers the given text on the display. 20 | """ 21 | length = len(text) 22 | tft.text( 23 | font, 24 | text, 25 | tft.width() // 2 - length // 2 * font.WIDTH, 26 | tft.height() // 2 - font.HEIGHT, 27 | fg, 28 | bg, 29 | ) 30 | 31 | 32 | def main(): 33 | """ 34 | The big show! 35 | """ 36 | try: 37 | tft.init() 38 | for color in [s3lcd.RED, s3lcd.GREEN, s3lcd.BLUE]: 39 | tft.fill(color) 40 | tft.rect(0, 0, tft.width(), tft.height(), s3lcd.WHITE) 41 | center("Hello!", s3lcd.WHITE, color) 42 | tft.show() 43 | time.sleep(1) 44 | 45 | while True: 46 | for rotation in range(4): 47 | now = time.ticks_ms() 48 | tft.rotation(rotation) 49 | tft.fill(0) 50 | col_max = tft.width() - font.WIDTH * 6 51 | row_max = tft.height() - font.HEIGHT 52 | 53 | for _ in range(128): 54 | tft.text( 55 | font, 56 | "Hello!", 57 | random.randint(0, col_max), 58 | random.randint(0, row_max), 59 | s3lcd.color565( 60 | random.getrandbits(8), 61 | random.getrandbits(8), 62 | random.getrandbits(8), 63 | ), 64 | s3lcd.color565( 65 | random.getrandbits(8), 66 | random.getrandbits(8), 67 | random.getrandbits(8), 68 | ), 69 | ) 70 | 71 | tft.show() 72 | 73 | # print(time.ticks_ms() - now, "ms") 74 | 75 | finally: 76 | tft_config.deinit(tft) 77 | 78 | 79 | main() 80 | -------------------------------------------------------------------------------- /examples/tiny_toasters/ttoast_bitmaps.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/tiny_toasters/ttoast_bitmaps.mpy -------------------------------------------------------------------------------- /examples/tiny_toasters/ttoasters.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/tiny_toasters/ttoasters.bmp -------------------------------------------------------------------------------- /examples/toasters/maketoast: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # grab sprites from spritesheet using ImageMagick and convert to bitmap format. 5 | # 6 | # spritesheet from CircuitPython_Flying_Toasters 7 | # https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 8 | # 9 | 10 | convert toasters.bmp -crop 64x64+64+0 t1.png 11 | convert toasters.bmp -crop 64x64+128+0 t2.png 12 | convert toasters.bmp -crop 64x64+192+0 t3.png 13 | convert toasters.bmp -crop 64x64+256+0 t4.png 14 | convert toasters.bmp -crop 64x64+320+0 t5.png 15 | 16 | # use 3 bits per pixel / 8 colors 17 | 18 | ../../utils/imgtobitmap.py t1.png 3 >t1.py 19 | ../../utils/imgtobitmap.py t2.png 3 >t2.py 20 | ../../utils/imgtobitmap.py t3.png 3 >t3.py 21 | ../../utils/imgtobitmap.py t4.png 3 >t4.py 22 | ../../utils/imgtobitmap.py t5.png 3 >t5.py 23 | -------------------------------------------------------------------------------- /examples/toasters/t1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters/t1.png -------------------------------------------------------------------------------- /examples/toasters/t2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters/t2.png -------------------------------------------------------------------------------- /examples/toasters/t3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters/t3.png -------------------------------------------------------------------------------- /examples/toasters/t4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters/t4.png -------------------------------------------------------------------------------- /examples/toasters/t5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters/t5.png -------------------------------------------------------------------------------- /examples/toasters/toast_bitmaps.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters/toast_bitmaps.mpy -------------------------------------------------------------------------------- /examples/toasters/toasters.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters/toasters.bmp -------------------------------------------------------------------------------- /examples/toasters_jpg/toaster.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/toasters_jpg/toaster.jpg -------------------------------------------------------------------------------- /examples/toasters_jpg/toasters_jpg.py: -------------------------------------------------------------------------------- 1 | """ 2 | toasters_jpg.py 3 | 4 | An example using a jpg sprite map to draw sprites on T-Display. This is an older version of the 5 | toasters.py and tiny_toasters example. It uses the jpg_decode() method to grab a bitmap of each 6 | sprite from the toaster.jpg sprite sheet. 7 | 8 | youtube video: https://youtu.be/0uWsjKQmCpU 9 | 10 | spritesheet from CircuitPython_Flying_Toasters 11 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 12 | """ 13 | 14 | import time 15 | import random 16 | import tft_config 17 | import s3lcd 18 | 19 | tft = tft_config.config(tft_config.WIDE) 20 | 21 | 22 | class toast: 23 | """ 24 | toast class to keep track of a sprites locaton and step 25 | """ 26 | 27 | def __init__(self, sprites, x, y): 28 | self.sprites = sprites 29 | self.steps = len(sprites) 30 | self.x = x 31 | self.y = y 32 | self.step = random.randint(0, self.steps - 1) 33 | self.speed = random.randint(2, 5) 34 | 35 | def move(self): 36 | if self.x <= 0: 37 | self.speed = random.randint(2, 5) 38 | self.x = tft.width() - 64 39 | 40 | self.step += 1 41 | self.step %= self.steps 42 | self.x -= self.speed 43 | 44 | 45 | def main(): 46 | """ 47 | Draw and move sprite 48 | """ 49 | 50 | try: 51 | # enable display and clear screen 52 | tft.init() 53 | tft.fill(s3lcd.BLACK) 54 | tft.show() 55 | 56 | width = 64 57 | height = 64 58 | 59 | # grab each sprite from the toaster.jpg sprite sheet 60 | t1 = tft.jpg_decode("toaster.jpg", 0, 0, width, height) 61 | t2 = tft.jpg_decode("toaster.jpg", width, 0, width, height) 62 | t3 = tft.jpg_decode("toaster.jpg", width * 2, 0, width, height) 63 | t4 = tft.jpg_decode("toaster.jpg", 0, height, width, height) 64 | t5 = tft.jpg_decode("toaster.jpg", width, height, width, height) 65 | 66 | TOASTERS = [t1[0], t2[0], t3[0], t4[0]] 67 | TOAST = [t5[0]] 68 | 69 | sprites = [ 70 | toast(TOASTERS, tft.width() - width, 0), 71 | toast(TOAST, tft.width() - width, height), 72 | toast(TOASTERS, tft.width() - width, height * 2), 73 | ] 74 | 75 | # move and draw sprites 76 | while True: 77 | for man in sprites: 78 | bitmap = man.sprites[man.step] 79 | 80 | tft.fill_rect( 81 | man.x + width - man.speed, 82 | man.y, 83 | man.speed, 84 | height, 85 | s3lcd.BLACK, 86 | ) 87 | 88 | man.move() 89 | 90 | if man.x > 0: 91 | tft.blit_buffer(bitmap, man.x, man.y, width, height) 92 | else: 93 | tft.fill_rect(0, man.y, width, height, s3lcd.BLACK) 94 | 95 | tft.show() 96 | time.sleep(0.03) 97 | 98 | finally: 99 | tft.deinit() 100 | 101 | 102 | main() 103 | -------------------------------------------------------------------------------- /examples/watch/LibreBaskerville-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/watch/LibreBaskerville-Regular.ttf -------------------------------------------------------------------------------- /examples/watch/create_face.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Create a watch face_{width}x{height}.jpg file for a given width and height. 5 | """ 6 | 7 | import argparse 8 | import math 9 | from PIL import Image, ImageDraw, ImageFont 10 | 11 | # get the width and height from the command line using argparse 12 | 13 | parser = argparse.ArgumentParser(prog='create_face.py', 14 | description=("Create a watch face_{width}x{height}.jpg file for a given width and height.") 15 | ) 16 | parser.add_argument("width", type=int, help="width of the display") 17 | parser.add_argument("height", type=int, help="height of the display") 18 | args = parser.parse_args() 19 | width = args.width # width of the display 20 | height = args.height # height of the display 21 | 22 | face = min(width, height) # face is the smaller of the two 23 | ofs_x = (width - face) // 2 # offset from the left side of the display 24 | ofs_y = (height - face) // 2 # offset from the top of the display 25 | font_size = 10 if height < 100 else 18 26 | 27 | # create an image 28 | out = Image.new("RGB", (width, height), (255, 255, 255)) 29 | 30 | fnt = ImageFont.truetype("./LibreBaskerville-Regular.ttf", font_size) # get a font of an appropriate size 31 | d = ImageDraw.Draw(out) # get a drawing context 32 | radius = int(face // 2 * 0.8) # radius of the clock face 33 | cx = int(face // 2) # center x of the clock face 34 | 35 | second = 0 36 | for minute in range(1, 60): 37 | # get the angle of the minute hand 38 | angle = (minute*math.pi/30)+(second*math.pi/1800) 39 | cos_a = math.cos(angle) 40 | sin_a = math.sin(angle) 41 | 42 | # x and y coordinates of the outer minute tick 43 | y1 = -cx * cos_a * 0.76 44 | x1 = cx * sin_a * 0.76 45 | 46 | # x and y coordinates of the inner minute tick 47 | y2 = -cx * cos_a * 0.7 48 | x2 = cx * sin_a * 0.7 49 | 50 | # draw the minute tick 51 | d.line([ofs_x+x1+cx, ofs_y+y1+cx, ofs_x+x2+cx, ofs_y+y2+cx], width=1, fill="#000000") 52 | 53 | for hour in range(1, 13): 54 | # get the angle of the hour hand 55 | angle = hour*math.pi/6 56 | cos_a = math.cos(angle) 57 | sin_a = math.sin(angle) 58 | 59 | # x and y coordinates of the outer hour tick 60 | y1 = -cx * cos_a * 0.76 61 | x1 = cx * sin_a * 0.76 62 | 63 | # x and y coordinates of the inner hour tick 64 | y2 = -cx * cos_a * 0.7 65 | x2 = cx * sin_a * 0.7 66 | 67 | # draw the hour tick 68 | d.line([ofs_x+x1+cx, ofs_y+y1+cx, ofs_x+x2+cx, ofs_y+y2+cx], width=5, fill="#ff0000") 69 | 70 | # x and y coordinates of the hour number 71 | y = -cx * cos_a * 0.9 72 | x = cx * sin_a * 0.9 73 | 74 | # draw the hour number in our previously selected font 75 | size = d.textbbox((0, 0), str(hour), font=fnt) 76 | d.text( 77 | (ofs_x+x+cx-((size[2]+size[0] >> 1)), ofs_y+y+cx-((size[3]+size[1]) >> 1)), 78 | str(hour), 79 | font=fnt, 80 | fill=(0, 0, 0), 81 | align="center") 82 | 83 | # save the face as a jpeg file 84 | out.save(f'face_{width}x{height}.jpg', "JPEG", quality=100, optimize=True, progressive=False) 85 | # out.show() 86 | -------------------------------------------------------------------------------- /examples/watch/create_faces: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./create_face.py 160 80 4 | ./create_face.py 240 320 5 | ./create_face.py 320 170 6 | ./create_face.py 320 240 7 | ./create_face.py 480 320 8 | ./create_face.py 128 128 9 | -------------------------------------------------------------------------------- /examples/watch/face_128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/watch/face_128x128.jpg -------------------------------------------------------------------------------- /examples/watch/face_160x80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/watch/face_160x80.jpg -------------------------------------------------------------------------------- /examples/watch/face_240x320.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/watch/face_240x320.jpg -------------------------------------------------------------------------------- /examples/watch/face_320x170.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/watch/face_320x170.jpg -------------------------------------------------------------------------------- /examples/watch/face_320x240.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/watch/face_320x240.jpg -------------------------------------------------------------------------------- /examples/watch/face_480x320.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/examples/watch/face_480x320.jpg -------------------------------------------------------------------------------- /examples/watch/watch.py: -------------------------------------------------------------------------------- 1 | """" 2 | watch.py - Analog Watch Display using jpg for the face and filled polygons for the hands 3 | Requires face_{width}x{height}.jpg in the same directory as this script. See the create_face.py 4 | script for creating a face image for a given sized display. 5 | 6 | Previous version video: https://youtu.be/NItKb6umMc4 7 | """ 8 | 9 | import utime 10 | import math 11 | import s3lcd 12 | import tft_config 13 | 14 | 15 | tft = tft_config.config(tft_config.WIDE) 16 | 17 | 18 | def hand_polygon(length, radius): 19 | return [ 20 | (0, 0), 21 | (-radius, radius), 22 | (-radius, int(length * 0.3)), 23 | (-1, length), 24 | (1, length), 25 | (radius, int(length * 0.3)), 26 | (radius, radius), 27 | (0, 0), 28 | ] 29 | 30 | 31 | def main(): 32 | """ 33 | Draw analog watch face and update time 34 | """ 35 | 36 | try: 37 | # enable display 38 | tft.init() 39 | width = tft.width() 40 | height = tft.height() 41 | radius = min(width, height) # face is the smaller of the two 42 | ofs_x = (width - radius) // 2 # offset from the left to center the face 43 | ofs_y = (height - radius) // 2 # offset from the top to center the face 44 | center_x = radius // 2 + ofs_x - 1 # center of the face horizontally 45 | center_y = radius // 2 + ofs_y - 1 # center of the face vertically 46 | 47 | # load and decode the watch face background 48 | face_file = f"face_{width}x{height}.jpg" 49 | print(f"Loading {face_file}...") 50 | face = tft.jpg_decode(face_file) 51 | 52 | # create the polygons for the hour, minute and second hands 53 | # polygons must be closed convex polygons or bad things(tm) happen. 54 | 55 | second_len = int(radius * 0.65 / 2) 56 | second_poly = hand_polygon(second_len, 2) 57 | 58 | minute_len = int(radius * 0.6 / 2) 59 | minute_poly = hand_polygon(minute_len, 2) 60 | 61 | hour_len = int(radius * 0.5 / 2) 62 | hour_poly = hand_polygon(hour_len, 3) 63 | 64 | # constants for calculating hand angles. 65 | pi_div_6 = math.pi / 6 66 | pi_div_30 = math.pi / 30 67 | pi_div_360 = math.pi / 360 68 | pi_div_1800 = math.pi / 1800 69 | pi_div_2160 = math.pi / 2160 70 | 71 | while True: 72 | # draw the watch face 73 | tft.bitmap(face, 0, 0) 74 | 75 | # save the current time in seconds so we can determine when 76 | # when to update the display. 77 | last = utime.time() 78 | 79 | # get the current hour, minute and second 80 | _, _, _, hour, minute, second, _, _ = utime.localtime() 81 | 82 | # constrain hours to 12 hour time 83 | hour %= 12 84 | 85 | # calculate the angle of the hour hand in radians 86 | hour_ang = ( 87 | (hour * pi_div_6) + (minute * pi_div_360) + (second * pi_div_2160) 88 | ) 89 | 90 | # calculate the angle of the minute hand in radians 91 | minute_ang = (minute * pi_div_30) + (second * pi_div_1800) 92 | 93 | # calculate the angle of the second hand on radians 94 | second_ang = second * pi_div_30 95 | 96 | # draw and fill the hour hand polygon rotated to hour_ang 97 | tft.fill_polygon(hour_poly, center_x, center_y, s3lcd.BLACK, 255, hour_ang) 98 | 99 | # draw and fill the minute hand polygon rotated to minute_ang 100 | tft.fill_polygon( 101 | minute_poly, center_x, center_y, s3lcd.BLACK, 255, minute_ang 102 | ) 103 | 104 | # draw and fill the second hand polygon rotated to second_ang 105 | tft.fill_polygon( 106 | second_poly, center_x, center_y, s3lcd.RED, 255, second_ang 107 | ) 108 | 109 | # draw the hub again to cover up the second hand 110 | tft.fill_circle(center_x, center_y, 5, s3lcd.BLACK) 111 | 112 | # update the display 113 | tft.show() 114 | 115 | # wait until the current second changes 116 | while last == utime.time(): 117 | utime.sleep_ms(50) 118 | 119 | finally: 120 | tft.deinit() 121 | 122 | 123 | main() 124 | -------------------------------------------------------------------------------- /firmware/GENERIC_S3_16M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_16M/firmware.bin -------------------------------------------------------------------------------- /firmware/GENERIC_S3_32M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_32M/firmware.bin -------------------------------------------------------------------------------- /firmware/GENERIC_S3_4M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_4M/firmware.bin -------------------------------------------------------------------------------- /firmware/GENERIC_S3_8M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_8M/firmware.bin -------------------------------------------------------------------------------- /firmware/GENERIC_S3_OCT_16M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_OCT_16M/firmware.bin -------------------------------------------------------------------------------- /firmware/GENERIC_S3_OCT_32M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_OCT_32M/firmware.bin -------------------------------------------------------------------------------- /firmware/GENERIC_S3_OCT_4M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_OCT_4M/firmware.bin -------------------------------------------------------------------------------- /firmware/GENERIC_S3_OCT_8M/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/GENERIC_S3_OCT_8M/firmware.bin -------------------------------------------------------------------------------- /firmware/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2022 Damien P. George 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 13 | all 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 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | Unless specified otherwise (see below), the above license and copyright applies 26 | to all files in this repository. 27 | 28 | Individual files may include additional copyright holders. 29 | 30 | The various ports of MicroPython may include third-party software that is 31 | licensed under different terms. These licenses are summarised in the tree 32 | below, please refer to these files and directories for further license and 33 | copyright information. Note that (L)GPL-licensed code listed below is only 34 | used during the build process and is not part of the compiled source code. 35 | 36 | / (MIT) 37 | /drivers 38 | /cc3100 (BSD-3-clause) 39 | /wiznet5k (BSD-3-clause) 40 | /lib 41 | /asf4 (Apache-2.0) 42 | /axtls (BSD-3-clause) 43 | /config 44 | /scripts 45 | /config (GPL-2.0-or-later) 46 | /Rules.mak (GPL-2.0) 47 | /berkeley-db-1xx (BSD-4-clause) 48 | /btstack (See btstack/LICENSE) 49 | /cmsis (BSD-3-clause) 50 | /crypto-algorithms (NONE) 51 | /libhydrogen (ISC) 52 | /littlefs (BSD-3-clause) 53 | /lwip (BSD-3-clause) 54 | /mynewt-nimble (Apache-2.0) 55 | /nrfx (BSD-3-clause) 56 | /nxp_driver (BSD-3-Clause) 57 | /oofatfs (BSD-1-clause) 58 | /pico-sdk (BSD-3-clause) 59 | /re15 (BSD-3-clause) 60 | /stm32lib (BSD-3-clause) 61 | /tinytest (BSD-3-clause) 62 | /tinyusb (MIT) 63 | /uzlib (Zlib) 64 | /logo (uses OFL-1.1) 65 | /ports 66 | /cc3200 67 | /hal (BSD-3-clause) 68 | /simplelink (BSD-3-clause) 69 | /FreeRTOS (GPL-2.0 with FreeRTOS exception) 70 | /stm32 71 | /usbd*.c (MCD-ST Liberty SW License Agreement V2) 72 | /stm32_it.* (MIT + BSD-3-clause) 73 | /system_stm32*.c (MIT + BSD-3-clause) 74 | /boards 75 | /startup_stm32*.s (BSD-3-clause) 76 | /*/stm32*.h (BSD-3-clause) 77 | /usbdev (MCD-ST Liberty SW License Agreement V2) 78 | /usbhost (MCD-ST Liberty SW License Agreement V2) 79 | /teensy 80 | /core (PJRC.COM) 81 | /zephyr 82 | /src (Apache-2.0) 83 | /tools 84 | /dfu.py (LGPL-3.0-only) 85 | -------------------------------------------------------------------------------- /firmware/README.md: -------------------------------------------------------------------------------- 1 | # ESP32-S3 Firmware 2 | 3 | The firmware.bin files have been tested on the devices listed below. 4 | 5 | ## GENERIC_S3_4M: with or without Quad SPIRAM 4M Flash 6 | 7 | - T-QT Pro 8 | 9 | ## GENERIC_S3_8M: with or without Quad SPIRAM 8M Flash 10 | 11 | - M5STACK ATOM-S3 12 | 13 | ## GENERIC_S3_16M: with or without Quad SPIRAM 16M Flash 14 | 15 | - T-Dongle-S3 16 | - T-Embed 17 | - WT32-SC01 Plus 18 | - M5STACK CORES3 19 | 20 | ## GENERIC_S3_32M: with or without Quad SPIRAM 16M Flash 21 | 22 | ## GENERIC_S3_OCT_4M: Octal SPIRAM 4M Flash 23 | 24 | ## GENERIC_S3_OCT_8M: Octal SPIRAM 8M Flash 25 | 26 | ## GENERIC_S3_16M: Octal SPIRAM 16M Flash 27 | 28 | - T-Display-S3 29 | - T-HMI 30 | - ESP32-S3-BOX 31 | - ESP32-S3-BOX-LITE 32 | 33 | ## GENERIC_S3_32M: Octal SPIRAM 16M Flash 34 | -------------------------------------------------------------------------------- /firmware/UM_FEATHERS3/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/UM_FEATHERS3/firmware.bin -------------------------------------------------------------------------------- /firmware/UM_NANOS3/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/UM_NANOS3/firmware.bin -------------------------------------------------------------------------------- /firmware/UM_PROS3/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/UM_PROS3/firmware.bin -------------------------------------------------------------------------------- /firmware/UM_TINYS3/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/UM_TINYS3/firmware.bin -------------------------------------------------------------------------------- /firmware/UM_TINYWATCHS3/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/firmware/UM_TINYWATCHS3/firmware.bin -------------------------------------------------------------------------------- /fonts/bitmap/README.md: -------------------------------------------------------------------------------- 1 | # Included Font Files 2 | 3 | Frozen font files are included in the firmware. 4 | 5 | ## Bit mapped fonts for use with Text method 6 | 7 | The font_from_romfont utility can convert fonts from the font-bin directory of 8 | spacerace's https://github.com/spacerace/romfont repo. 9 | 10 | ### 128 Character Bit Mapped Fonts 11 | 12 | Frozen | Font | Example 13 | ------ | ------------------------------------------------------ | ----------------------------- 14 | Yes | [vga1_8x8.py](/fonts/bitmap/vga1_8x8.py) | ![Image](/docs/vga1_8x8.png) 15 | Yes | [vga1_16x16.py](/fonts/bitmap/vga1_16x16.py) | ![Image](/docs/vga1_16x16.png) 16 | Yes | [vga1_16x32.py](/fonts/bitmap/vga1_16x32.py) | ![Image](/docs/vga1_16x32.png) 17 | Yes | [vga1_bold_16x16.py](/fonts/bitmap/vga1_bold_16x16.py) | ![Image](/docs/vga1_bold_16x16.png) 18 | Yes | [vga1_bold_16x32.py](/fonts/bitmap/vga1_bold_16x32.py) | ![Image](/docs/vga1_bold_16x32.png) 19 | 20 | 21 | ### 256 Character Bit Mapped Fonts 22 | 23 | Frozen | Font | Example 24 | ------ | ------------------------------------------------------ | -------------------------- 25 | No | [vga2_8x8.py](/fonts/bitmap/vga2_8x8.py) | ![Image](/docs/vga2_8x8.png) 26 | No | [vga2_8x16.py](/fonts/bitmap/vga2_8x16.py) | ![Image](/docs/vga2_8x16.png) 27 | No | [vga2_16x16.py](/fonts/bitmap/vga2_16x16.py) | ![Image](/docs/vga2_16x16.png) 28 | No | [vga2_16x32.py](/fonts/bitmap/vga2_16x32.py) | ![Image](/docs/vga2_16x32.png) 29 | No | [vga2_bold_16x16.py](/fonts/bitmap/vga2_bold_16x16.py) | ![Image](/docs/vga2_bold_16x16.png) 30 | No | [vga2_bold_16x32.py](/fonts/bitmap/vga2_bold_16x32.py) | ![Image](/docs/vga2_bold_16x32.png) 31 | 32 | -------------------------------------------------------------------------------- /fonts/bitmap/vga1_8x8.py: -------------------------------------------------------------------------------- 1 | """converted from vga_8x8.bin """ 2 | WIDTH = 8 3 | HEIGHT = 8 4 | FIRST = 0x20 5 | LAST = 0x7f 6 | _FONT =\ 7 | b'\x00\x00\x00\x00\x00\x00\x00\x00'\ 8 | b'\x18\x3c\x3c\x18\x18\x00\x18\x00'\ 9 | b'\x66\x66\x24\x00\x00\x00\x00\x00'\ 10 | b'\x6c\x6c\xfe\x6c\xfe\x6c\x6c\x00'\ 11 | b'\x18\x3e\x60\x3c\x06\x7c\x18\x00'\ 12 | b'\x00\xc6\xcc\x18\x30\x66\xc6\x00'\ 13 | b'\x38\x6c\x38\x76\xdc\xcc\x76\x00'\ 14 | b'\x18\x18\x30\x00\x00\x00\x00\x00'\ 15 | b'\x0c\x18\x30\x30\x30\x18\x0c\x00'\ 16 | b'\x30\x18\x0c\x0c\x0c\x18\x30\x00'\ 17 | b'\x00\x66\x3c\xff\x3c\x66\x00\x00'\ 18 | b'\x00\x18\x18\x7e\x18\x18\x00\x00'\ 19 | b'\x00\x00\x00\x00\x00\x18\x18\x30'\ 20 | b'\x00\x00\x00\x7e\x00\x00\x00\x00'\ 21 | b'\x00\x00\x00\x00\x00\x18\x18\x00'\ 22 | b'\x06\x0c\x18\x30\x60\xc0\x80\x00'\ 23 | b'\x38\x6c\xc6\xd6\xc6\x6c\x38\x00'\ 24 | b'\x18\x38\x18\x18\x18\x18\x7e\x00'\ 25 | b'\x7c\xc6\x06\x1c\x30\x66\xfe\x00'\ 26 | b'\x7c\xc6\x06\x3c\x06\xc6\x7c\x00'\ 27 | b'\x1c\x3c\x6c\xcc\xfe\x0c\x1e\x00'\ 28 | b'\xfe\xc0\xc0\xfc\x06\xc6\x7c\x00'\ 29 | b'\x38\x60\xc0\xfc\xc6\xc6\x7c\x00'\ 30 | b'\xfe\xc6\x0c\x18\x30\x30\x30\x00'\ 31 | b'\x7c\xc6\xc6\x7c\xc6\xc6\x7c\x00'\ 32 | b'\x7c\xc6\xc6\x7e\x06\x0c\x78\x00'\ 33 | b'\x00\x18\x18\x00\x00\x18\x18\x00'\ 34 | b'\x00\x18\x18\x00\x00\x18\x18\x30'\ 35 | b'\x06\x0c\x18\x30\x18\x0c\x06\x00'\ 36 | b'\x00\x00\x7e\x00\x00\x7e\x00\x00'\ 37 | b'\x60\x30\x18\x0c\x18\x30\x60\x00'\ 38 | b'\x7c\xc6\x0c\x18\x18\x00\x18\x00'\ 39 | b'\x7c\xc6\xde\xde\xde\xc0\x78\x00'\ 40 | b'\x38\x6c\xc6\xfe\xc6\xc6\xc6\x00'\ 41 | b'\xfc\x66\x66\x7c\x66\x66\xfc\x00'\ 42 | b'\x3c\x66\xc0\xc0\xc0\x66\x3c\x00'\ 43 | b'\xf8\x6c\x66\x66\x66\x6c\xf8\x00'\ 44 | b'\xfe\x62\x68\x78\x68\x62\xfe\x00'\ 45 | b'\xfe\x62\x68\x78\x68\x60\xf0\x00'\ 46 | b'\x3c\x66\xc0\xc0\xce\x66\x3a\x00'\ 47 | b'\xc6\xc6\xc6\xfe\xc6\xc6\xc6\x00'\ 48 | b'\x3c\x18\x18\x18\x18\x18\x3c\x00'\ 49 | b'\x1e\x0c\x0c\x0c\xcc\xcc\x78\x00'\ 50 | b'\xe6\x66\x6c\x78\x6c\x66\xe6\x00'\ 51 | b'\xf0\x60\x60\x60\x62\x66\xfe\x00'\ 52 | b'\xc6\xee\xfe\xfe\xd6\xc6\xc6\x00'\ 53 | b'\xc6\xe6\xf6\xde\xce\xc6\xc6\x00'\ 54 | b'\x7c\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 55 | b'\xfc\x66\x66\x7c\x60\x60\xf0\x00'\ 56 | b'\x7c\xc6\xc6\xc6\xc6\xce\x7c\x0e'\ 57 | b'\xfc\x66\x66\x7c\x6c\x66\xe6\x00'\ 58 | b'\x3c\x66\x30\x18\x0c\x66\x3c\x00'\ 59 | b'\x7e\x7e\x5a\x18\x18\x18\x3c\x00'\ 60 | b'\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 61 | b'\xc6\xc6\xc6\xc6\xc6\x6c\x38\x00'\ 62 | b'\xc6\xc6\xc6\xd6\xd6\xfe\x6c\x00'\ 63 | b'\xc6\xc6\x6c\x38\x6c\xc6\xc6\x00'\ 64 | b'\x66\x66\x66\x3c\x18\x18\x3c\x00'\ 65 | b'\xfe\xc6\x8c\x18\x32\x66\xfe\x00'\ 66 | b'\x3c\x30\x30\x30\x30\x30\x3c\x00'\ 67 | b'\xc0\x60\x30\x18\x0c\x06\x02\x00'\ 68 | b'\x3c\x0c\x0c\x0c\x0c\x0c\x3c\x00'\ 69 | b'\x10\x38\x6c\xc6\x00\x00\x00\x00'\ 70 | b'\x00\x00\x00\x00\x00\x00\x00\xff'\ 71 | b'\x30\x18\x0c\x00\x00\x00\x00\x00'\ 72 | b'\x00\x00\x78\x0c\x7c\xcc\x76\x00'\ 73 | b'\xe0\x60\x7c\x66\x66\x66\xdc\x00'\ 74 | b'\x00\x00\x7c\xc6\xc0\xc6\x7c\x00'\ 75 | b'\x1c\x0c\x7c\xcc\xcc\xcc\x76\x00'\ 76 | b'\x00\x00\x7c\xc6\xfe\xc0\x7c\x00'\ 77 | b'\x3c\x66\x60\xf8\x60\x60\xf0\x00'\ 78 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\xf8'\ 79 | b'\xe0\x60\x6c\x76\x66\x66\xe6\x00'\ 80 | b'\x18\x00\x38\x18\x18\x18\x3c\x00'\ 81 | b'\x06\x00\x06\x06\x06\x66\x66\x3c'\ 82 | b'\xe0\x60\x66\x6c\x78\x6c\xe6\x00'\ 83 | b'\x38\x18\x18\x18\x18\x18\x3c\x00'\ 84 | b'\x00\x00\xec\xfe\xd6\xd6\xd6\x00'\ 85 | b'\x00\x00\xdc\x66\x66\x66\x66\x00'\ 86 | b'\x00\x00\x7c\xc6\xc6\xc6\x7c\x00'\ 87 | b'\x00\x00\xdc\x66\x66\x7c\x60\xf0'\ 88 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\x1e'\ 89 | b'\x00\x00\xdc\x76\x60\x60\xf0\x00'\ 90 | b'\x00\x00\x7e\xc0\x7c\x06\xfc\x00'\ 91 | b'\x30\x30\xfc\x30\x30\x36\x1c\x00'\ 92 | b'\x00\x00\xcc\xcc\xcc\xcc\x76\x00'\ 93 | b'\x00\x00\xc6\xc6\xc6\x6c\x38\x00'\ 94 | b'\x00\x00\xc6\xd6\xd6\xfe\x6c\x00'\ 95 | b'\x00\x00\xc6\x6c\x38\x6c\xc6\x00'\ 96 | b'\x00\x00\xc6\xc6\xc6\x7e\x06\xfc'\ 97 | b'\x00\x00\x7e\x4c\x18\x32\x7e\x00'\ 98 | b'\x0e\x18\x18\x70\x18\x18\x0e\x00'\ 99 | b'\x18\x18\x18\x18\x18\x18\x18\x00'\ 100 | b'\x70\x18\x18\x0e\x18\x18\x70\x00'\ 101 | b'\x76\xdc\x00\x00\x00\x00\x00\x00'\ 102 | b'\x00\x10\x38\x6c\xc6\xc6\xfe\x00'\ 103 | 104 | FONT = memoryview(_FONT) 105 | -------------------------------------------------------------------------------- /fonts/bitmap/vga_8x16.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/fonts/bitmap/vga_8x16.bin -------------------------------------------------------------------------------- /fonts/bitmap/vga_8x8.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/fonts/bitmap/vga_8x8.bin -------------------------------------------------------------------------------- /fonts/truetype/Chango-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/fonts/truetype/Chango-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/LICENSE_OFL.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, 2 | Version 1.1. 3 | 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | ----------------------------------------------------------- 8 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 9 | ----------------------------------------------------------- 10 | 11 | PREAMBLE 12 | The goals of the Open Font License (OFL) are to stimulate worldwide 13 | development of collaborative font projects, to support the font 14 | creation efforts of academic and linguistic communities, and to 15 | provide a free and open framework in which fonts may be shared and 16 | improved in partnership with others. 17 | 18 | The OFL allows the licensed fonts to be used, studied, modified and 19 | redistributed freely as long as they are not sold by themselves. The 20 | fonts, including any derivative works, can be bundled, embedded, 21 | redistributed and/or sold with any software provided that any reserved 22 | names are not used by derivative works. The fonts and derivatives, 23 | however, cannot be released under any other type of license. The 24 | requirement for fonts to remain under this license does not apply to 25 | any document created using the fonts or their derivatives. 26 | 27 | DEFINITIONS 28 | "Font Software" refers to the set of files released by the Copyright 29 | Holder(s) under this license and clearly marked as such. This may 30 | include source files, build scripts and documentation. 31 | 32 | "Reserved Font Name" refers to any names specified as such after the 33 | copyright statement(s). 34 | 35 | "Original Version" refers to the collection of Font Software 36 | components as distributed by the Copyright Holder(s). 37 | 38 | "Modified Version" refers to any derivative made by adding to, 39 | deleting, or substituting -- in part or in whole -- any of the 40 | components of the Original Version, by changing formats or by porting 41 | the Font Software to a new environment. 42 | 43 | "Author" refers to any designer, engineer, programmer, technical 44 | writer or other person who contributed to the Font Software. 45 | 46 | PERMISSION & CONDITIONS 47 | Permission is hereby granted, free of charge, to any person obtaining 48 | a copy of the Font Software, to use, study, copy, merge, embed, 49 | modify, redistribute, and sell modified and unmodified copies of the 50 | Font Software, subject to the following conditions: 51 | 52 | 1) Neither the Font Software nor any of its individual components, in 53 | Original or Modified Versions, may be sold by itself. 54 | 55 | 2) Original or Modified Versions of the Font Software may be bundled, 56 | redistributed and/or sold with any software, provided that each copy 57 | contains the above copyright notice and this license. These can be 58 | included either as stand-alone text files, human-readable headers or 59 | in the appropriate machine-readable metadata fields within text or 60 | binary files as long as those fields can be easily viewed by the user. 61 | 62 | 3) No Modified Version of the Font Software may use the Reserved Font 63 | Name(s) unless explicit written permission is granted by the 64 | corresponding Copyright Holder. This restriction only applies to the 65 | primary font name as presented to the users. 66 | 67 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 68 | Software shall not be used to promote, endorse or advertise any 69 | Modified Version, except to acknowledge the contribution(s) of the 70 | Copyright Holder(s) and the Author(s) or with their explicit written 71 | permission. 72 | 73 | 5) The Font Software, modified or unmodified, in part or in whole, 74 | must be distributed entirely under this license, and must not be 75 | distributed under any other license. The requirement for fonts to 76 | remain under this license does not apply to any document created using 77 | the Font Software. 78 | 79 | TERMINATION 80 | This license becomes null and void if any of the above conditions are 81 | not met. 82 | 83 | DISCLAIMER 84 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 85 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 86 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 87 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 88 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 89 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 90 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 91 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 92 | OTHER DEALINGS IN THE FONT SOFTWARE. 93 | -------------------------------------------------------------------------------- /fonts/truetype/NotoSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/fonts/truetype/NotoSans-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/NotoSansMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/fonts/truetype/NotoSansMono-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/NotoSerif-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/fonts/truetype/NotoSerif-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/README.md: -------------------------------------------------------------------------------- 1 | # SIL Open Font License fonts 2 | 3 | Here are a few of the SIL Open Font Licensed fonts I used for testing the 4 | `monofont2bitmap` and `font2bitmap` utilies. 5 | 6 | ## Proportional fonts 7 | 8 | These are suitable for use with `font2bitmap` utility and the drivers `write` 9 | method. 10 | 11 | - Chango-Regular.ttf 12 | - NotoSans-Regular.ttf 13 | - NotoSerif-Regular.ttf 14 | 15 | ## Monospaced fonts 16 | 17 | This font is suitable for use with `font2bitmap` utility and the drivers `write` 18 | method. It can also be used with the `monofont2bitmap` utility and the drivers 19 | `bitmap` method. 20 | 21 | - inconsolata-700.ttf 22 | - NotoSansMono-Regular.ttf 23 | 24 | -------------------------------------------------------------------------------- /fonts/truetype/inconsolata-700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/s3lcd/f254daf512a6ae7c36d3361540a2b90ad36a078b/fonts/truetype/inconsolata-700.ttf -------------------------------------------------------------------------------- /fonts/vector/README.md: -------------------------------------------------------------------------------- 1 | # Included Font Files 2 | 3 | Frozen font files are included in the firmware. 4 | 5 | ## Vector fonts for use with the Draw method 6 | 7 | ### Hershey Vector Fonts 8 | 9 | Frozen | Font | Example 10 | ------ | ---------------------------------------- | ---------------------- 11 | No | [astrol.py](/fonts/vector/astrol.py) | ![Image](/docs/astrol.svg) 12 | Yes | [cyrilc.py](/fonts/vector/cyrilc.py) | ![Image](/docs/cyrilc.svg) 13 | Yes | [gotheng.py](/fonts/vector/gotheng.py) | ![Image](/docs/gotheng.svg) 14 | Yes | [gothger.py](/fonts/vector/gothger.py) | ![Image](/docs/gothger.svg) 15 | Yes | [gothita.py](/fonts/vector/gothita.py) | ![Image](/docs/gothita.svg) 16 | Yes | [greekc.py](/fonts/vector/greekc.py) | ![Image](/docs/greekc.svg) 17 | Yes | [greekcs.py](/fonts/vector/greekcs.py) | ![Image](/docs/greekcs.svg) 18 | Yes | [greekp.py](/fonts/vector/greekp.py) | ![Image](/docs/greekp.svg) 19 | Yes | [greeks.py](/fonts/vector/greeks.py) | ![Image](/docs/greeks.svg) 20 | Yes | [italicc.py](/fonts/vector/italicc.py) | ![Image](/docs/italicc.svg) 21 | Yes | [italiccs.py](/fonts/vector/italiccs.py) | ![Image](/docs/italiccs.svg) 22 | Yes | [italict.py](/fonts/vector/italict.py) | ![Image](/docs/italict.svg) 23 | Yes | [lowmat.py](/fonts/vector/lowmat.py) | ![Image](/docs/lowmat.svg) 24 | Yes | [marker.py](/fonts/vector/marker.py) | ![Image](/docs/marker.svg) 25 | Yes | [meteo.py](/fonts/vector/meteo.py) | ![Image](/docs/meteo.svg) 26 | Yes | [music.py](/fonts/vector/music.py) | ![Image](/docs/music.svg) 27 | Yes | [romanc.py](/fonts/vector/romanc.py) | ![Image](/docs/romanc.svg) 28 | Yes | [romancs.py](/fonts/vector/romancs.py) | ![Image](/docs/romancs.svg) 29 | Yes | [romand.py](/fonts/vector/romand.py) | ![Image](/docs/romand.svg) 30 | Yes | [romanp.py](/fonts/vector/romanp.py) | ![Image](/docs/romanp.svg) 31 | Yes | [romans.py](/fonts/vector/romans.py) | ![Image](/docs/romans.svg) 32 | Yes | [romant.py](/fonts/vector/romant.py) | ![Image](/docs/romant.svg) 33 | Yes | [scriptc.py](/fonts/vector/scriptc.py) | ![Image](/docs/scriptc.svg) 34 | Yes | [scripts.py](/fonts/vector/scripts.py) | ![Image](/docs/scripts.svg) 35 | Yes | [symbol.py](/fonts/vector/symbol.py) | ![Image](/docs/symbol.svg) 36 | Yes | [uppmat.py](/fonts/vector/uppmat.py) | ![Image](/docs/uppmat.svg) 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /manifest.py: -------------------------------------------------------------------------------- 1 | include("$(PORT_DIR)/boards/manifest.py") 2 | freeze("modules") 3 | -------------------------------------------------------------------------------- /modules/df.py: -------------------------------------------------------------------------------- 1 | import uos 2 | fs_stat = uos.statvfs('/flash') 3 | fs_size = fs_stat[0] * fs_stat[2] 4 | fs_free = fs_stat[0] * fs_stat[3] 5 | print("File System Size {:,} - Free Space {:,}".format(fs_size, fs_free)) 6 | -------------------------------------------------------------------------------- /modules/mf.py: -------------------------------------------------------------------------------- 1 | import gc 2 | 3 | print("Allocating 1K bytes until memory is full... ", end='') 4 | memory = [] 5 | i = 0 6 | gc.collect() 7 | 8 | try: 9 | while True: 10 | memory.append(bytearray(1024)) 11 | i += 1 12 | 13 | except MemoryError: 14 | gc.collect() 15 | print(f'{i}K bytes Allocated.') 16 | -------------------------------------------------------------------------------- /modules/vga1_8x8.py: -------------------------------------------------------------------------------- 1 | """converted from vga_8x8.bin """ 2 | WIDTH = 8 3 | HEIGHT = 8 4 | FIRST = 0x20 5 | LAST = 0x7f 6 | _FONT =\ 7 | b'\x00\x00\x00\x00\x00\x00\x00\x00'\ 8 | b'\x18\x3c\x3c\x18\x18\x00\x18\x00'\ 9 | b'\x66\x66\x24\x00\x00\x00\x00\x00'\ 10 | b'\x6c\x6c\xfe\x6c\xfe\x6c\x6c\x00'\ 11 | b'\x18\x3e\x60\x3c\x06\x7c\x18\x00'\ 12 | b'\x00\xc6\xcc\x18\x30\x66\xc6\x00'\ 13 | b'\x38\x6c\x38\x76\xdc\xcc\x76\x00'\ 14 | b'\x18\x18\x30\x00\x00\x00\x00\x00'\ 15 | b'\x0c\x18\x30\x30\x30\x18\x0c\x00'\ 16 | b'\x30\x18\x0c\x0c\x0c\x18\x30\x00'\ 17 | b'\x00\x66\x3c\xff\x3c\x66\x00\x00'\ 18 | b'\x00\x18\x18\x7e\x18\x18\x00\x00'\ 19 | b'\x00\x00\x00\x00\x00\x18\x18\x30'\ 20 | b'\x00\x00\x00\x7e\x00\x00\x00\x00'\ 21 | b'\x00\x00\x00\x00\x00\x18\x18\x00'\ 22 | b'\x06\x0c\x18\x30\x60\xc0\x80\x00'\ 23 | b'\x38\x6c\xc6\xd6\xc6\x6c\x38\x00'\ 24 | b'\x18\x38\x18\x18\x18\x18\x7e\x00'\ 25 | b'\x7c\xc6\x06\x1c\x30\x66\xfe\x00'\ 26 | b'\x7c\xc6\x06\x3c\x06\xc6\x7c\x00'\ 27 | b'\x1c\x3c\x6c\xcc\xfe\x0c\x1e\x00'\ 28 | b'\xfe\xc0\xc0\xfc\x06\xc6\x7c\x00'\ 29 | b'\x38\x60\xc0\xfc\xc6\xc6\x7c\x00'\ 30 | b'\xfe\xc6\x0c\x18\x30\x30\x30\x00'\ 31 | b'\x7c\xc6\xc6\x7c\xc6\xc6\x7c\x00'\ 32 | b'\x7c\xc6\xc6\x7e\x06\x0c\x78\x00'\ 33 | b'\x00\x18\x18\x00\x00\x18\x18\x00'\ 34 | b'\x00\x18\x18\x00\x00\x18\x18\x30'\ 35 | b'\x06\x0c\x18\x30\x18\x0c\x06\x00'\ 36 | b'\x00\x00\x7e\x00\x00\x7e\x00\x00'\ 37 | b'\x60\x30\x18\x0c\x18\x30\x60\x00'\ 38 | b'\x7c\xc6\x0c\x18\x18\x00\x18\x00'\ 39 | b'\x7c\xc6\xde\xde\xde\xc0\x78\x00'\ 40 | b'\x38\x6c\xc6\xfe\xc6\xc6\xc6\x00'\ 41 | b'\xfc\x66\x66\x7c\x66\x66\xfc\x00'\ 42 | b'\x3c\x66\xc0\xc0\xc0\x66\x3c\x00'\ 43 | b'\xf8\x6c\x66\x66\x66\x6c\xf8\x00'\ 44 | b'\xfe\x62\x68\x78\x68\x62\xfe\x00'\ 45 | b'\xfe\x62\x68\x78\x68\x60\xf0\x00'\ 46 | b'\x3c\x66\xc0\xc0\xce\x66\x3a\x00'\ 47 | b'\xc6\xc6\xc6\xfe\xc6\xc6\xc6\x00'\ 48 | b'\x3c\x18\x18\x18\x18\x18\x3c\x00'\ 49 | b'\x1e\x0c\x0c\x0c\xcc\xcc\x78\x00'\ 50 | b'\xe6\x66\x6c\x78\x6c\x66\xe6\x00'\ 51 | b'\xf0\x60\x60\x60\x62\x66\xfe\x00'\ 52 | b'\xc6\xee\xfe\xfe\xd6\xc6\xc6\x00'\ 53 | b'\xc6\xe6\xf6\xde\xce\xc6\xc6\x00'\ 54 | b'\x7c\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 55 | b'\xfc\x66\x66\x7c\x60\x60\xf0\x00'\ 56 | b'\x7c\xc6\xc6\xc6\xc6\xce\x7c\x0e'\ 57 | b'\xfc\x66\x66\x7c\x6c\x66\xe6\x00'\ 58 | b'\x3c\x66\x30\x18\x0c\x66\x3c\x00'\ 59 | b'\x7e\x7e\x5a\x18\x18\x18\x3c\x00'\ 60 | b'\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 61 | b'\xc6\xc6\xc6\xc6\xc6\x6c\x38\x00'\ 62 | b'\xc6\xc6\xc6\xd6\xd6\xfe\x6c\x00'\ 63 | b'\xc6\xc6\x6c\x38\x6c\xc6\xc6\x00'\ 64 | b'\x66\x66\x66\x3c\x18\x18\x3c\x00'\ 65 | b'\xfe\xc6\x8c\x18\x32\x66\xfe\x00'\ 66 | b'\x3c\x30\x30\x30\x30\x30\x3c\x00'\ 67 | b'\xc0\x60\x30\x18\x0c\x06\x02\x00'\ 68 | b'\x3c\x0c\x0c\x0c\x0c\x0c\x3c\x00'\ 69 | b'\x10\x38\x6c\xc6\x00\x00\x00\x00'\ 70 | b'\x00\x00\x00\x00\x00\x00\x00\xff'\ 71 | b'\x30\x18\x0c\x00\x00\x00\x00\x00'\ 72 | b'\x00\x00\x78\x0c\x7c\xcc\x76\x00'\ 73 | b'\xe0\x60\x7c\x66\x66\x66\xdc\x00'\ 74 | b'\x00\x00\x7c\xc6\xc0\xc6\x7c\x00'\ 75 | b'\x1c\x0c\x7c\xcc\xcc\xcc\x76\x00'\ 76 | b'\x00\x00\x7c\xc6\xfe\xc0\x7c\x00'\ 77 | b'\x3c\x66\x60\xf8\x60\x60\xf0\x00'\ 78 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\xf8'\ 79 | b'\xe0\x60\x6c\x76\x66\x66\xe6\x00'\ 80 | b'\x18\x00\x38\x18\x18\x18\x3c\x00'\ 81 | b'\x06\x00\x06\x06\x06\x66\x66\x3c'\ 82 | b'\xe0\x60\x66\x6c\x78\x6c\xe6\x00'\ 83 | b'\x38\x18\x18\x18\x18\x18\x3c\x00'\ 84 | b'\x00\x00\xec\xfe\xd6\xd6\xd6\x00'\ 85 | b'\x00\x00\xdc\x66\x66\x66\x66\x00'\ 86 | b'\x00\x00\x7c\xc6\xc6\xc6\x7c\x00'\ 87 | b'\x00\x00\xdc\x66\x66\x7c\x60\xf0'\ 88 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\x1e'\ 89 | b'\x00\x00\xdc\x76\x60\x60\xf0\x00'\ 90 | b'\x00\x00\x7e\xc0\x7c\x06\xfc\x00'\ 91 | b'\x30\x30\xfc\x30\x30\x36\x1c\x00'\ 92 | b'\x00\x00\xcc\xcc\xcc\xcc\x76\x00'\ 93 | b'\x00\x00\xc6\xc6\xc6\x6c\x38\x00'\ 94 | b'\x00\x00\xc6\xd6\xd6\xfe\x6c\x00'\ 95 | b'\x00\x00\xc6\x6c\x38\x6c\xc6\x00'\ 96 | b'\x00\x00\xc6\xc6\xc6\x7e\x06\xfc'\ 97 | b'\x00\x00\x7e\x4c\x18\x32\x7e\x00'\ 98 | b'\x0e\x18\x18\x70\x18\x18\x0e\x00'\ 99 | b'\x18\x18\x18\x18\x18\x18\x18\x00'\ 100 | b'\x70\x18\x18\x0e\x18\x18\x70\x00'\ 101 | b'\x76\xdc\x00\x00\x00\x00\x00\x00'\ 102 | b'\x00\x10\x38\x6c\xc6\xc6\xfe\x00'\ 103 | 104 | FONT = memoryview(_FONT) 105 | -------------------------------------------------------------------------------- /src/jpg/tjpgd565.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------/ 2 | / TJpgDec - Tiny JPEG Decompressor include file (C)ChaN, 2020 3 | /----------------------------------------------------------------------------*/ 4 | #ifndef DEF_TJPGDEC 5 | #define DEF_TJPGDEC 6 | /*---------------------------------------------------------------------------*/ 7 | /* System Configurations */ 8 | 9 | #define JD_SZBUF 512 /* Size of stream input buffer */ 10 | #define JD_FORMAT 1 /* Output pixel format 0:RGB888 (3 BYTE/pix), 1:RGB565 (1 WORD/pix) */ 11 | #define JD_USE_SCALE 1 /* Use descaling feature for output */ 12 | #define JD_TBLCLIP 1 /* Use table for saturation (might be a bit faster but increases 1K bytes of code size) */ 13 | 14 | /*---------------------------------------------------------------------------*/ 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #include "stdint.h" 21 | 22 | /* Error code */ 23 | typedef enum { 24 | JDR_OK = 0, /* 0: Succeeded */ 25 | JDR_INTR, /* 1: Interrupted by output function */ 26 | JDR_INP, /* 2: Device error or wrong termination of input stream */ 27 | JDR_MEM1, /* 3: Insufficient memory pool for the image */ 28 | JDR_MEM2, /* 4: Insufficient stream input buffer */ 29 | JDR_PAR, /* 5: Parameter error */ 30 | JDR_FMT1, /* 6: Data format error (may be damaged data) */ 31 | JDR_FMT2, /* 7: Right format but not supported */ 32 | JDR_FMT3 /* 8: Not supported JPEG standard */ 33 | } JRESULT; 34 | 35 | 36 | 37 | /* Rectangular structure */ 38 | typedef struct { 39 | uint16_t left, right, top, bottom; 40 | } JRECT; 41 | 42 | 43 | 44 | /* Decompressor object structure */ 45 | typedef struct JDEC JDEC; 46 | struct JDEC { 47 | unsigned int dctr; /* Number of bytes available in the input buffer */ 48 | uint8_t* dptr; /* Current data read ptr */ 49 | uint8_t* inbuf; /* Bit stream input buffer */ 50 | uint8_t dmsk; /* Current bit in the current read byte */ 51 | uint8_t scale; /* Output scaling ratio */ 52 | uint8_t msx, msy; /* MCU size in unit of block (width, height) */ 53 | uint8_t qtid[3]; /* Quantization table ID of each component */ 54 | int16_t dcv[3]; /* Previous DC element of each component */ 55 | uint16_t nrst; /* Restart inverval */ 56 | uint16_t width, height; /* Size of the input image (pixel) */ 57 | uint8_t* huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ 58 | uint16_t* huffcode[2][2]; /* Huffman code word tables [id][dcac] */ 59 | uint8_t* huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */ 60 | int32_t* qttbl[4]; /* Dequantizer tables [id] */ 61 | void* workbuf; /* Working buffer for IDCT and RGB output */ 62 | uint8_t* mcubuf; /* Working buffer for the MCU */ 63 | void* pool; /* Pointer to available memory pool */ 64 | unsigned int sz_pool; /* Size of momory pool (bytes available) */ 65 | unsigned int (*infunc)(JDEC*, uint8_t*, unsigned int); /* Pointer to jpeg stream input function */ 66 | void* device; /* Pointer to I/O device identifiler for the session */ 67 | int16_t x_offs; /* x offset for slow method */ 68 | int16_t y_offs; /* y offset for slow method */ 69 | }; 70 | 71 | 72 | /* TJpgDec API functions */ 73 | JRESULT jd_prepare (JDEC* jd, unsigned int (*infunc)(JDEC*,uint8_t*,unsigned int), void* pool, unsigned int sz_pool, void* dev); 74 | JRESULT jd_decomp (JDEC* jd, int (*outfunc)(JDEC*,void*,JRECT*), uint8_t scale); 75 | 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* _TJPGDEC */ 82 | -------------------------------------------------------------------------------- /src/micropython.cmake: -------------------------------------------------------------------------------- 1 | # Create an INTERFACE library for our C module. 2 | add_library(usermod_s3lcd INTERFACE) 3 | 4 | # Add our source files to the lib 5 | target_sources(usermod_s3lcd INTERFACE 6 | ${CMAKE_CURRENT_LIST_DIR}/s3lcd.c 7 | ${CMAKE_CURRENT_LIST_DIR}/s3lcd_i80_bus.c 8 | ${CMAKE_CURRENT_LIST_DIR}/s3lcd_spi_bus.c 9 | ${CMAKE_CURRENT_LIST_DIR}/mpfile.c 10 | ${CMAKE_CURRENT_LIST_DIR}/jpg/tjpgd565.c 11 | ${CMAKE_CURRENT_LIST_DIR}/png/pngle.c 12 | ${CMAKE_CURRENT_LIST_DIR}/png/miniz.c 13 | ${CMAKE_CURRENT_LIST_DIR}/pngenc/adler32.c 14 | ${CMAKE_CURRENT_LIST_DIR}/pngenc/crc32.c 15 | ${CMAKE_CURRENT_LIST_DIR}/pngenc/deflate.c 16 | ${CMAKE_CURRENT_LIST_DIR}/pngenc/pngenc.c 17 | ${CMAKE_CURRENT_LIST_DIR}/pngenc/trees.c 18 | ${CMAKE_CURRENT_LIST_DIR}/pngenc/zutil.c 19 | ) 20 | 21 | # Add the current directory as an include directory. 22 | target_include_directories(usermod_s3lcd INTERFACE 23 | ${IDF_PATH}/components/esp_lcd/include/ 24 | ${CMAKE_CURRENT_LIST_DIR} 25 | ) 26 | 27 | # Link our INTERFACE library to the usermod target. 28 | target_link_libraries(usermod INTERFACE usermod_s3lcd) 29 | -------------------------------------------------------------------------------- /src/mpfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Micro Python project, http://micropython.org/ 3 | * 4 | * The MIT License (MIT) 5 | * 6 | * Copyright (c) 2016 Dave Hylands 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | #ifndef __MICROPY_INCLUDED_PY_MPFILE_H__ 28 | #define __MICROPY_INCLUDED_PY_MPFILE_H__ 29 | 30 | #include "py/obj.h" 31 | #include // for off_t 32 | 33 | // A C API for performing I/O on files or file-like objects. 34 | 35 | typedef struct { 36 | mp_obj_base_t base; 37 | mp_obj_t file_obj; 38 | mp_obj_t readinto_fn; 39 | mp_obj_t write_fn; 40 | mp_obj_t seek_fn; 41 | mp_obj_t tell_fn; 42 | } mp_file_t; 43 | 44 | #define MP_SEEK_SET 0 45 | #define MP_SEEK_CUR 1 46 | #define MP_SEEK_END 2 47 | 48 | mp_file_t *mp_file_from_file_obj(mp_obj_t file_obj); 49 | mp_file_t *mp_open(const char *filename, const char *mode); 50 | mp_int_t mp_readinto(mp_file_t *file, void *buf, size_t num_bytes); 51 | mp_int_t mp_write(mp_file_t *file, void *buf, size_t num_bytes); 52 | off_t mp_seek(mp_file_t *file, off_t offset, int whence); 53 | off_t mp_tell(mp_file_t *file); 54 | void mp_close(mp_file_t *file); 55 | 56 | 57 | #endif // __MICROPY_INCLUDED_PY_MPFILE_H__ 58 | -------------------------------------------------------------------------------- /src/png/miniz.h: -------------------------------------------------------------------------------- 1 | #define MINIZ_HEADER_FILE_ONLY 2 | #include "miniz.c" 3 | -------------------------------------------------------------------------------- /src/png/pngle.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * MIT License 3 | * 4 | * Copyright (c) 2019 kikuchan 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __PNGLE_H__ 26 | #define __PNGLE_H__ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | // Main Pngle object 35 | typedef struct _pngle_t pngle_t; 36 | 37 | // Callback signatures 38 | typedef void (*pngle_init_callback_t)(pngle_t *pngle, uint32_t w, uint32_t h); 39 | typedef void (*pngle_draw_callback_t)(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]); 40 | typedef void (*pngle_done_callback_t)(pngle_t *pngle); 41 | 42 | // ---------------- 43 | // Basic interfaces 44 | // ---------------- 45 | pngle_t *pngle_new(); 46 | void pngle_destroy(pngle_t *pngle); 47 | void pngle_reset(pngle_t *pngle); // clear its internal state (not applied to pngle_set_* functions) 48 | const char *pngle_error(pngle_t *pngle); 49 | int pngle_feed(pngle_t *pngle, const void *buf, size_t len); // returns -1: On error, 0: Need more data, n: n bytes eaten 50 | 51 | uint32_t pngle_get_width(pngle_t *pngle); 52 | uint32_t pngle_get_height(pngle_t *pngle); 53 | 54 | void pngle_set_init_callback(pngle_t *png, pngle_init_callback_t callback); 55 | void pngle_set_draw_callback(pngle_t *png, pngle_draw_callback_t callback); 56 | void pngle_set_done_callback(pngle_t *png, pngle_done_callback_t callback); 57 | 58 | void pngle_set_display_gamma(pngle_t *pngle, double display_gamma); // enables gamma correction by specifying display gamma, typically 2.2. No effect when gAMA chunk is missing 59 | 60 | void pngle_set_user_data(pngle_t *pngle, void *user_data); 61 | void *pngle_get_user_data(pngle_t *pngle); 62 | 63 | 64 | // ---------------- 65 | // Debug interfaces 66 | // ---------------- 67 | 68 | typedef struct _pngle_ihdr_t { 69 | uint32_t width; 70 | uint32_t height; 71 | uint8_t depth; 72 | uint8_t color_type; 73 | uint8_t compression; 74 | uint8_t filter; 75 | uint8_t interlace; 76 | } pngle_ihdr_t; 77 | 78 | // Get IHDR information 79 | pngle_ihdr_t *pngle_get_ihdr(pngle_t *pngle); 80 | 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif /* __PNGLE_H__ */ 87 | -------------------------------------------------------------------------------- /src/s3lcd.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __S3LCD_H__ 3 | #define __S3LCD_H__ 4 | 5 | #include "esp_lcd_panel_io.h" 6 | #include "mpfile.h" 7 | 8 | // 9 | // Default Values for T-Display-S3 170x320 ST7796 10 | // 11 | 12 | #define TFT_WIDTH 170 13 | #define TFT_HEIGHT 320 14 | #define TFT_MAX_TRANSFER (TFT_WIDTH * TFT_HEIGHT * sizeof(uint16_t)) 15 | 16 | #define TFT_POWER GPIO_NUM_15 17 | #define TFT_RST GPIO_NUM_5 18 | #define TFT_CS GPIO_NUM_6 19 | #define TFT_DC GPIO_NUM_7 20 | #define TFT_BL GPIO_NUM_38 21 | #define TFT_WR GPIO_NUM_8 22 | #define TFT_RD GPIO_NUM_9 23 | #define TFT_D0 GPIO_NUM_39 24 | #define TFT_D1 GPIO_NUM_40 25 | #define TFT_D2 GPIO_NUM_41 26 | #define TFT_D3 GPIO_NUM_42 27 | #define TFT_D4 GPIO_NUM_45 28 | #define TFT_D5 GPIO_NUM_46 29 | #define TFT_D6 GPIO_NUM_47 30 | #define TFT_D7 GPIO_NUM_48 31 | 32 | // ST77XX Commands 33 | #define ST77XX_VSCRDEF 0x33 34 | #define ST77XX_VSCSAD 0x37 35 | #define ST77XX_IDLEOFF 0x38 36 | #define ST77XX_IDLEON 0x39 37 | 38 | // Color definitions 39 | #define BLACK 0x0000 40 | #define BLUE 0x001F 41 | #define RED 0xF800 42 | #define GREEN 0x07E0 43 | #define CYAN 0x07FF 44 | #define MAGENTA 0xF81F 45 | #define YELLOW 0xFFE0 46 | #define WHITE 0xFFFF 47 | 48 | // driver options 49 | #define OPTIONS_WRAP_V 0x01 50 | #define OPTIONS_WRAP_H 0x02 51 | #define OPTIONS_WRAP 0x03 52 | 53 | // scroll directions 54 | #define SCROLL_UP 0 55 | #define SCROLL_DOWN 1 56 | #define SCROLL_LEFT 2 57 | #define SCROLL_RIGHT 3 58 | 59 | typedef struct _Point { 60 | mp_float_t x; 61 | mp_float_t y; 62 | } Point; 63 | 64 | typedef struct _Polygon { 65 | int length; 66 | Point *points; 67 | } Polygon; 68 | 69 | typedef union _bus_handle_t { 70 | esp_lcd_i80_bus_handle_t i80; 71 | esp_lcd_spi_bus_handle_t spi; 72 | } bus_handle_t; 73 | 74 | 75 | typedef struct _s3lcd_rotation_t { 76 | uint16_t width; // width of the display in this rotation 77 | uint16_t height; // height of the display in this rotation 78 | uint16_t x_gap; // gap on x axis, in pixels 79 | uint16_t y_gap; // gap on y axis, in pixels 80 | bool swap_xy; // set MADCTL_MV bit 0x20 81 | bool mirror_x; // set MADCTL MX bit 0x40 82 | bool mirror_y; // set MADCTL MY bit 0x80 83 | } s3lcd_rotation_t; 84 | 85 | typedef struct _s3lcd_obj_t { 86 | mp_obj_base_t base; 87 | mp_obj_t bus; 88 | bus_handle_t bus_handle; 89 | esp_lcd_panel_io_handle_t io_handle; 90 | esp_lcd_panel_handle_t panel_handle; 91 | 92 | uint8_t color_space; 93 | bool inversion_mode; 94 | mp_file_t *fp; // file object 95 | size_t frame_buffer_size; // frame buffer size in bytes 96 | uint16_t *frame_buffer; // frame buffer 97 | uint16_t dma_rows; // dma transfer buffer height in rows 98 | uint16_t *dma_buffer; // dma transfer buffer 99 | size_t dma_buffer_size; // dma transfer buffer size in bytes 100 | uint16_t *work_buffer; // work frame buffer 101 | void *work; // work buffer for jpg & png decoding 102 | uint8_t *scanline_ringbuf; // png scanline_ringbuf 103 | uint8_t *palette; // png palette 104 | uint8_t *trans_palette; // png trans_palette 105 | uint8_t *gamma_table; // png gamma_table 106 | uint16_t width; // logical width (after rotation) 107 | uint16_t height; // logical height (after rotation) 108 | uint8_t rotation; // current rotation 109 | s3lcd_rotation_t *rotations; // list of rotation tuples 110 | mp_obj_t custom_init; // custom init sequence 111 | uint8_t rotations_len; // number of rotations 112 | uint8_t options; // options bit array: wrap (optional) 113 | gpio_num_t rst; 114 | bool swap_color_bytes; // swap color bytes (SPI only, I80 is builtin) 115 | } s3lcd_obj_t; 116 | 117 | mp_obj_t s3lcd_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); 118 | 119 | extern void draw_pixel(s3lcd_obj_t *self, int16_t x, int16_t y, uint16_t color, uint8_t alpha); 120 | extern void fast_hline(s3lcd_obj_t *self, int16_t x, int16_t y, int16_t w, uint16_t color, uint8_t alpha); 121 | 122 | #endif // __ST7796_H__ -------------------------------------------------------------------------------- /src/s3lcd_i80_bus.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Russ Hughes 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __s3lcd_i80_bus_H__ 24 | #define __s3lcd_i80_bus_H__ 25 | 26 | #include "mphalport.h" 27 | #include "py/obj.h" 28 | #include "esp_lcd_panel_io.h" 29 | 30 | // i80 Configuration 31 | 32 | typedef struct _s3lcd_i80_bus_obj_t { 33 | mp_obj_base_t base; // base class 34 | char *name; // name of the display 35 | int data_gpio_nums[24]; // GPIOs used for data lines 36 | int dc_gpio_num; // GPIO used for D/C line 37 | int wr_gpio_num; // GPIO used for WR line 38 | int rd_gpio_num; // GPIO used for RD line, set to -1 will not read from the display 39 | int cs_gpio_num; // GPIO used for CS line, set to -1 will declaim exclusively use of I80 bus 40 | int reset_gpio_num; // GPIO used for RESET line, set to -1 will not reset the display 41 | 42 | unsigned int pclk_hz; // Frequency of pixel clock 43 | size_t bus_width; // Number of data lines, 8 or 16 44 | int lcd_cmd_bits; // Bit-width of LCD command 45 | int lcd_param_bits; // Bit-width of LCD parameter 46 | 47 | struct { 48 | unsigned int dc_idle_level: 1; // Level of DC line in IDLE phase 49 | unsigned int dc_cmd_level: 1; // Level of DC line in CMD phase 50 | unsigned int dc_dummy_level: 1; // Level of DC line in DUMMY phase 51 | unsigned int dc_data_level: 1; // Level of DC line in DATA phase 52 | } dc_levels; 53 | 54 | struct { 55 | unsigned int cs_active_high: 1; // Whether the CS line is active on high level 56 | unsigned int reverse_color_bits: 1; // Reverse the data bits, D[N:0] -> D[0:N] 57 | unsigned int swap_color_bytes: 1; // Swap adjacent two data bytes before sending out 58 | unsigned int pclk_active_neg: 1; // The display will write data lines when there's a falling edge on WR line 59 | unsigned int pclk_idle_low: 1; // The WR line keeps at low level in IDLE phase 60 | } flags; 61 | 62 | } s3lcd_i80_bus_obj_t; 63 | 64 | extern const mp_obj_type_t s3lcd_i80_bus_type; 65 | 66 | #endif /* __i80_bus_H__ */ 67 | -------------------------------------------------------------------------------- /src/s3lcd_spi_bus.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Russ Hughes 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __s3lcd_spi_bus_H__ 24 | #define __s3lcd_spi_bus_H__ 25 | 26 | #include "mphalport.h" 27 | #include "py/obj.h" 28 | #include "esp_lcd_panel_io.h" 29 | 30 | // spi Configuration 31 | 32 | typedef struct _s3lcd_spi_bus_obj_t { 33 | mp_obj_base_t base; // base class 34 | char *name; // name of the display 35 | int spi_host; // SPI host 36 | int sclk_io_num; // GPIO used for SCLK line 37 | int mosi_io_num; // GPIO used for MOSI line 38 | int miso_io_num; // GPIO used for MISO line 39 | int quadwp_io_num; // GPIO used for QuadWP line 40 | int quadhd_io_num; // GPIO used for QuadHD line 41 | int cs_gpio_num; // GPIO used for CS line */ 42 | int dc_gpio_num; // GPIO used to select the D/C line, set this to -1 if the D/C line not controlled by manually pulling high/low GPIO */ 43 | int spi_mode; // Traditional SPI mode (0~3) */ 44 | unsigned int pclk_hz; // Frequency of pixel clock */ 45 | size_t trans_queue_depth; // Size of internal transaction queue */ 46 | int lcd_cmd_bits; // Bit-width of LCD command */ 47 | int lcd_param_bits; // Bit-width of LCD parameter */ 48 | struct { // Extra flags to fine-tune the SPI device 49 | unsigned int dc_as_cmd_phase: 1; // D/C line value is encoded into SPI transaction command phase 50 | unsigned int dc_low_on_data: 1; // If this flag is enabled, DC line = 0 means transfer data, DC line = 1 means transfer command; vice versa 51 | unsigned int octal_mode: 1; // transmit with octal mode (8 data lines), this mode is used to simulate Intel 8080 timing 52 | unsigned int lsb_first: 1; // transmit LSB bit first */ 53 | unsigned int swap_color_bytes:1; // Swap color bytes in 16-bit color mode */ 54 | } flags; 55 | 56 | } s3lcd_spi_bus_obj_t; 57 | 58 | extern const mp_obj_type_t s3lcd_spi_bus_type; 59 | 60 | #endif /* __spi_bus_H__ */ 61 | -------------------------------------------------------------------------------- /utils/font_from_romfont.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Convert fonts from the font-bin directory of spacerace's 4 | https://github.com/spacerace/romfont repo. 5 | 6 | Reads all romfont bin files from the specified -input-directory (-i) and writes 7 | python font files to the specified -output-directory (-o). Optionally limiting 8 | characters included to -first-char (-f) thru -last-char (-l). 9 | 10 | Example: 11 | 12 | font_from_romfont -i font-bin -o pyfont -f 32 -l 127 13 | 14 | requires argparse 15 | """ 16 | import os 17 | import re 18 | import argparse 19 | 20 | def convert_font(file_in, file_out, width, height, first=0x0, last=0xff): 21 | chunk_size = height 22 | with open(file_in, "rb") as bin_file: 23 | bin_file.seek(first * height) 24 | current = first 25 | with open(file_out, 'wt') as font_file: 26 | print(f'"""converted from {file_in} """', file=font_file) 27 | print(f'WIDTH = {width}', file=font_file) 28 | print(f'HEIGHT = {height}', file=font_file) 29 | print(f'FIRST = 0x{first:02x}', file=font_file) 30 | print(f'LAST = 0x{last:02x}', file=font_file) 31 | print('_FONT =\\\n', sep='', end='', file=font_file) 32 | for chunk in iter(lambda: bin_file.read(chunk_size), b''): 33 | print('b\'', sep='', end='', file=font_file) 34 | for data in chunk: 35 | print(f'\\x{data:02x}', end='', file=font_file) 36 | print('\'\\', file=font_file) 37 | current += 1 38 | if current > last: 39 | break 40 | 41 | print('', file=font_file) 42 | print('FONT = memoryview(_FONT)', file=font_file) 43 | 44 | def auto_int(x): 45 | return int(x, 0) 46 | 47 | def main(): 48 | parser = argparse.ArgumentParser( 49 | description='Convert Romfont.bin font files in input to python in font_directory.') 50 | parser.add_argument('input', help='file or directory containing binary font file(s).') 51 | parser.add_argument('output', help='file or directory to contain python font file(s).') 52 | parser.add_argument('-f', '--first-char', type=auto_int, default=0x20) 53 | parser.add_argument('-l', '--last-char', type=auto_int, default=0x7f) 54 | args = parser.parse_args() 55 | 56 | file_re = re.compile(r'^(.*)(\d+)x(\d+)\.bin$') 57 | 58 | is_dir = os.path.isdir(args.input) 59 | bin_files = os.listdir(args.input) if is_dir else [args.input] 60 | for bin_file_name in bin_files: 61 | match = file_re.match(bin_file_name) 62 | if match: 63 | font_width = int(match.group(2)) 64 | font_height = int(match.group(3)) 65 | 66 | if is_dir: 67 | bin_file_name = args.input+'/'+bin_file_name 68 | 69 | if is_dir: 70 | font_file_name = ( 71 | args.font_directory + '/' + 72 | match.group(1).rstrip('_').lower()+ 73 | f'_{font_width}x{font_height}.py') 74 | else: 75 | font_file_name = args.output 76 | 77 | print("converting", bin_file_name, 'to', font_file_name) 78 | 79 | convert_font( 80 | bin_file_name, 81 | font_file_name, 82 | font_width, 83 | font_height, 84 | args.first_char, 85 | args.last_char) 86 | 87 | main() 88 | -------------------------------------------------------------------------------- /utils/howto-convert-to-jpg: -------------------------------------------------------------------------------- 1 | # 2 | # You can convert images to compatible jpg's by using ImageMagick's convert 3 | # utility by specifying the output type as TrueColor. ImageMagick downloads 4 | # are available from https://imagemagick.org/ for Linux, OSX, Windows and 5 | # other operating systems. 6 | # 7 | # The wi-alien.svg icon is from https://github.com/erikflowers/weather-icons 8 | # licensed under SIL OFL 1.1 9 | # 10 | 11 | convert wi-alien.svg -type TrueColor alien.jpg 12 | -------------------------------------------------------------------------------- /utils/imgtobitmap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | Convert image file to python module for use with blit_bitmap. 4 | 5 | Usage imgtobitmap image_file bits_per_pixel >image.py 6 | ''' 7 | 8 | import sys 9 | from PIL import Image 10 | import argparse 11 | 12 | 13 | def main(): 14 | 15 | parser = argparse.ArgumentParser( 16 | prog='imgtobitmap', 17 | description='Convert image file to python module for use with bitmap method.') 18 | 19 | parser.add_argument( 20 | 'image_file', 21 | help='Name of file containing image to convert') 22 | 23 | parser.add_argument( 24 | 'bits_per_pixel', 25 | type=int, 26 | choices=range(1, 9), 27 | default=1, 28 | metavar='bits_per_pixel', 29 | help='The number of bits to use per pixel (1..8)') 30 | 31 | args = parser.parse_args() 32 | bits = args.bits_per_pixel 33 | colors_requested = 1 << bits 34 | img = Image.open(args.image_file) 35 | img = img.convert("P", palette=Image.Palette.ADAPTIVE, colors=colors_requested) 36 | palette = img.getpalette() # Make copy of palette colors 37 | palette_colors = len(palette) // 3 38 | bits_required = palette_colors.bit_length() 39 | if (bits_required < bits): 40 | print(f'\nNOTE: Quantization reduced colors to {palette_colors} from the {colors_requested} ' 41 | f'requested, reconverting using {bits_required} bit per pixel could save memory.\n''', file=sys.stderr) 42 | 43 | # For all the colors in the palette 44 | colors = [] 45 | 46 | for color in range(palette_colors): 47 | 48 | # get rgb values and convert to 565 49 | color565 = ( 50 | ((palette[color*3] & 0xF8) << 8) 51 | | ((palette[color*3+1] & 0xFC) << 3) 52 | | ((palette[color*3+2] & 0xF8) >> 3)) 53 | 54 | # swap bytes in 565 55 | color = ((color565 & 0xff) << 8) + ((color565 & 0xff00) >> 8) 56 | 57 | # append byte swapped 565 color to colors 58 | colors.append(f'{color:04x}') 59 | 60 | image_bitstring = '' 61 | max_colors = len(colors) 62 | 63 | # Run through the image and create a string with the ascii binary 64 | # representation of the color of each pixel. 65 | for y in range(img.height): 66 | for x in range(img.width): 67 | pixel = img.getpixel((x, y)) 68 | color = pixel 69 | bstring = ''.join( 70 | '1' if (color & (1 << bit - 1)) else '0' 71 | for bit in range(bits, 0, -1) 72 | ) 73 | 74 | image_bitstring += bstring 75 | 76 | bitmap_bits = len(image_bitstring) 77 | 78 | # Create python source with image parameters 79 | print(f'HEIGHT = {img.height}') 80 | print(f'WIDTH = {img.width}') 81 | print(f'COLORS = {max_colors}') 82 | print(f'BITS = {bitmap_bits}') 83 | print(f'BPP = {bits}') 84 | print('PALETTE = [', sep='', end='') 85 | 86 | for color, rgb in enumerate(colors): 87 | if color: 88 | print(',', sep='', end='') 89 | print(f'0x{rgb}', sep='', end='') 90 | print("]") 91 | 92 | # Run though image bit string 8 bits at a time 93 | # and create python array source for memoryview 94 | 95 | print("_bitmap =\\", sep='') 96 | print("b'", sep='', end='') 97 | 98 | for i in range(0, bitmap_bits, 8): 99 | 100 | if i and i % (16*8) == 0: 101 | print("'\\\nb'", end='', sep='') 102 | 103 | value = image_bitstring[i:i+8] 104 | color = int(value, 2) 105 | print(f'\\x{color:02x}', sep='', end='') 106 | 107 | print("'\nBITMAP = memoryview(_bitmap)") 108 | 109 | 110 | main() 111 | -------------------------------------------------------------------------------- /utils/png_from_font.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Imports all the python font files from the specified -input-directory (-i) and 5 | creates png samples of each font in the specified -output-directory (-o). 6 | 7 | Example: 8 | png_from_font.py font_directory png_directory 9 | 10 | Requires argparse, importlib and pypng 11 | """ 12 | 13 | import os 14 | import importlib 15 | import png 16 | import argparse 17 | 18 | def create_png(font_file_name, png_file_name): 19 | 20 | module_spec = importlib.util.spec_from_file_location('font', font_file_name) 21 | font = importlib.util.module_from_spec(module_spec) 22 | module_spec.loader.exec_module(font) 23 | char_count = font.LAST - font.FIRST 24 | column_count = 16 25 | row_count = (char_count // column_count) 26 | 27 | with open(png_file_name, 'wb') as png_file: 28 | image = png.Writer((16+2) * font.WIDTH, (row_count+3) * font.HEIGHT, bitdepth=1) 29 | image_data = [[0 for j in range((16+2) * font.WIDTH)] for i in range((row_count+3)* font.HEIGHT)] 30 | for chart_row in range(row_count+2): 31 | for chart_col in range(16): 32 | chart_idx = chart_row * 16 + chart_col 33 | for char_line in range(font.HEIGHT): 34 | for char_byte in range(font.WIDTH//8): 35 | ch_idx = chart_idx * font.HEIGHT * font.WIDTH//8 + char_byte + char_line * font.WIDTH//8 36 | print(chart_idx, char_count) 37 | if (chart_idx <= char_count): 38 | data = font.FONT[ch_idx] 39 | else: 40 | data = 0 41 | 42 | for bit in range(8): 43 | png_row = (chart_row+1)*font.HEIGHT+char_line 44 | png_col = (chart_col+1)*font.WIDTH+char_byte*8+bit 45 | if data & 1 << 7-bit: 46 | image_data[png_row][png_col] = 1 47 | else: 48 | image_data[png_row][png_col] = 0 49 | 50 | print("Creating", png_file_name) 51 | image.write(png_file, image_data) 52 | 53 | def main(): 54 | parser = argparse.ArgumentParser( 55 | description='Convert 8bit font-bin.bin font files in bin_directory to python in font_directory.') 56 | parser.add_argument( 57 | 'font_directory', help='directory containing python font files. (input)') 58 | parser.add_argument( 59 | 'png_directory', help='directory to contain binary font files. (output)') 60 | args = parser.parse_args() 61 | 62 | for file_name in os.listdir(args.font_directory): 63 | if file_name.endswith('.py'): 64 | font_file_name = args.font_directory+'/'+file_name 65 | png_file_name = args.png_directory+'/'+os.path.splitext(file_name)[0]+'.png' 66 | create_png(font_file_name, png_file_name) 67 | 68 | main() 69 | -------------------------------------------------------------------------------- /utils/requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow==9.0.1 2 | pypng==0.0.20 3 | freetype-py==2.2.0 -------------------------------------------------------------------------------- /utils/sprites2bitmap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | Convert a sprite sheet image to python a module for use with indexed bitmap method. 5 | Sprite sheet width and height should be a multiple of sprite width and height. There 6 | should be no extra pixels between sprites. All sprites will share the same palette. 7 | 8 | Usage: 9 | sprites2bitmap image_file spite_width sprite_height bits_per_pixel >sprites.py 10 | 11 | MicroPython: 12 | import sprites 13 | ... tft config and init code ... 14 | tft.bitmap(sprites, x, y, index) 15 | 16 | ''' 17 | 18 | from os import setpriority 19 | from PIL import Image 20 | import argparse 21 | 22 | def main(): 23 | 24 | parser = argparse.ArgumentParser( 25 | prog='imgtobitmap', 26 | description='Convert image file to python module for use with bitmap method.') 27 | 28 | parser.add_argument( 29 | 'image_file', 30 | help='Name of file containing image to convert') 31 | 32 | parser.add_argument( 33 | 'sprite_width', 34 | type=int, 35 | help='width of sprites in pixels') 36 | 37 | parser.add_argument( 38 | 'sprite_height', 39 | type=int, 40 | help='height of sprites in pixels') 41 | 42 | parser.add_argument( 43 | 'bits_per_pixel', 44 | type=int, 45 | choices=range(1, 9), 46 | default=1, 47 | metavar='bits_per_pixel', 48 | help='The number of bits to use per pixel (1..8)') 49 | 50 | args = parser.parse_args() 51 | 52 | bits = args.bits_per_pixel 53 | img = Image.open(args.image_file) 54 | img = img.convert("P", palette=Image.ADAPTIVE, colors=2**bits) 55 | palette = img.getpalette() # Make copy of palette colors 56 | 57 | # For all the colors in the palette 58 | colors = [] 59 | for color in range(1 << bits): 60 | 61 | # get rgb values and convert to 565 62 | color565 = ( 63 | ((palette[color*3] & 0xF8) << 8) | 64 | ((palette[color*3+1] & 0xFC) << 3) | 65 | ((palette[color*3+2] & 0xF8) >> 3)) 66 | 67 | # swap bytes in 565 68 | color = ((color565 & 0xff) << 8) + ((color565 & 0xff00) >> 8) 69 | 70 | # append byte swapped 565 color to colors 71 | colors.append(f'{color:04x}') 72 | 73 | image_bitstring = '' 74 | max_colors = 1 << bits 75 | bitmaps = 0 76 | # Run through the image and create a string with the ascii binary 77 | # representation of the color of each pixel. 78 | for y in range(0, img.height, args.sprite_height): 79 | for x in range(0, img.width, args.sprite_width): 80 | bitmaps += 1 81 | for yy in range(y, y + args.sprite_height): 82 | for xx in range(x, x + args.sprite_width): 83 | pixel = img.getpixel((xx, yy)) 84 | color = pixel 85 | image_bitstring += ''.join( 86 | '1' if (color & (1 << bit - 1)) else '0' for bit in range(bits, 0, -1)) 87 | 88 | bitmap_bits = len(image_bitstring) 89 | 90 | # Create python source with image parameters 91 | print(f'BITMAPS = {bitmaps}') 92 | print(f'HEIGHT = {args.sprite_height}') 93 | print(f'WIDTH = {args.sprite_width}') 94 | print(f'COLORS = {max_colors}') 95 | print(f'BITS = {bitmap_bits}') 96 | print(f'BPP = {bits}') 97 | print('PALETTE = [', sep='', end='') 98 | 99 | for color, rgb in enumerate(colors): 100 | if color: 101 | print(',', sep='', end='') 102 | print(f'0x{rgb}', sep='', end='') 103 | print("]") 104 | 105 | # Run though image bit string 8 bits at a time 106 | # and create python array source for memoryview 107 | 108 | print("_bitmap =\\", sep='') 109 | print("b'", sep='', end='') 110 | 111 | for i in range(0, bitmap_bits, 8): 112 | 113 | if i and i % (16*8) == 0: 114 | print("'\\\nb'", end='', sep='') 115 | 116 | value = image_bitstring[i:i+8] 117 | color = int(value, 2) 118 | print(f'\\x{color:02x}', sep='', end='') 119 | 120 | print("'\nBITMAP = memoryview(_bitmap)") 121 | 122 | 123 | main() 124 | -------------------------------------------------------------------------------- /utils/wi-alien.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 16 | 17 | --------------------------------------------------------------------------------