├── .hgignore ├── .travis.yml ├── LICENSE ├── README.rst ├── docs ├── Makefile ├── conf.py ├── display.rst ├── displays.rst ├── index.rst └── make.bat ├── hx8353.py ├── ili9341.py ├── rgb.py ├── rgb_text.py ├── s6d02a1.py ├── setup.py ├── ssd1331.py ├── ssd1351.py └── st7735.py /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | *.pyc 3 | *~ 4 | .*.swp 5 | docs/_build/* 6 | build/* 7 | dist/* 8 | bin/* 9 | lib/* 10 | include/* 11 | local 12 | *.egg-info 13 | cache/* 14 | *.DS_Store 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Travis CI configuration for automated .mpy file generation. 2 | # Author: Tony DiCola 3 | # License: Public Domain 4 | # This configuration will work with Travis CI (travis-ci.org) to automacially 5 | # build .mpy files for MicroPython when a new tagged release is created. This 6 | # file is relatively generic and can be shared across multiple repositories by 7 | # following these steps: 8 | # 1. Copy this file into a .travis.yml file in the root of the repository. 9 | # 2. Change the deploy > file section below to list each of the .mpy files 10 | # that should be generated. The config will automatically look for 11 | # .py files with the same name as the source for generating the .mpy files. 12 | # Note that the .mpy extension should be lower case! 13 | # 3. Commit the .travis.yml file and push it to GitHub. 14 | # 4. Go to travis-ci.org and find the repository (it needs to be setup to access 15 | # your github account, and your github account needs access to write to the 16 | # repo). Flip the 'ON' switch on for Travis and the repo, see the Travis 17 | # docs for more details: https://docs.travis-ci.com/user/getting-started/ 18 | # 5. Get a GitHub 'personal access token' which has at least 'public_repo' or 19 | # 'repo' scope: https://help.github.com/articles/creating-an-access-token-for-command-line-use/ 20 | # Keep this token safe and secure! Anyone with the token will be able to 21 | # access and write to your GitHub repositories. Travis will use the token 22 | # to attach the .mpy files to the release. 23 | # 6. In the Travis CI settings for the repository that was enabled find the 24 | # environment variable editing page: https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings 25 | # Add an environment variable named GITHUB_TOKEN and set it to the value 26 | # of the GitHub personal access token above. Keep 'Display value in build 27 | # log' flipped off. 28 | # 7. That's it! Tag a release and Travis should go to work to add .mpy files 29 | # to the release. It takes about a 2-3 minutes for a worker to spin up, 30 | # build mpy-cross, and add the binaries to the release. 31 | language: generic 32 | 33 | sudo: true 34 | 35 | deploy: 36 | provider: releases 37 | api_key: $GITHUB_TOKEN 38 | file: 39 | - "hx8353.mpy" 40 | - "ili9341.mpy" 41 | - "rgb.mpy" 42 | - "s6d02a1.mpy" 43 | - "ssd1331.mpy" 44 | - "ssd1351.mpy" 45 | - "st7735.mpy" 46 | skip_cleanup: true 47 | on: 48 | tags: true 49 | 50 | before_install: 51 | - sudo apt-get -yqq update 52 | - sudo apt-get install -y build-essential git python python-pip 53 | - git clone https://github.com/adafruit/micropython.git 54 | - make -C micropython/mpy-cross 55 | - export PATH=$PATH:$PWD/micropython/mpy-cross/ 56 | - sudo pip install shyaml 57 | 58 | before_deploy: 59 | - shyaml get-values deploy.file < .travis.yml | sed 's/.mpy/.py/' | xargs -L1 mpy-cross 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Radomir Dopieralski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | DEPRECATED LIBRARY micropython-adafruit-rgb-display 2 | =================================================== 3 | 4 | This library has been deprecated! We are leaving this up for historical and research purposes but archiving the repository. 5 | 6 | We are only supporting CircuitPython libraries. 7 | 8 | Check out the CircuitPython RGB Display library for using RGB displays with Python on microcontrollers: https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display 9 | 10 | Display drivers for MicroPython. 11 | 12 | Documentation available at http://micropython-rgb.readthedocs.io/ 13 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Display.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Display.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Display" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Display" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # µDisplay documentation build configuration file, created by 4 | # sphinx-quickstart on Sun Aug 28 10:57:39 2016. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | #needs_sphinx = '1.0' 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [ 32 | 'sphinx.ext.autodoc', 33 | 'sphinx.ext.intersphinx', 34 | 'sphinx.ext.viewcode', 35 | ] 36 | 37 | # Add any paths that contain templates here, relative to this directory. 38 | templates_path = ['_templates'] 39 | 40 | # The suffix of source filenames. 41 | source_suffix = '.rst' 42 | 43 | # The encoding of source files. 44 | #source_encoding = 'utf-8-sig' 45 | 46 | # The master toctree document. 47 | master_doc = 'index' 48 | 49 | # General information about the project. 50 | project = u'MicroPython Adafruit RGB Display' 51 | copyright = u'2016, Radomir Dopieralski' 52 | 53 | # The version info for the project you're documenting, acts as replacement for 54 | # |version| and |release|, also used in various other places throughout the 55 | # built documents. 56 | # 57 | # The short X.Y version. 58 | version = '1.0.0' 59 | # The full version, including alpha/beta/rc tags. 60 | release = '1.0.0' 61 | 62 | # The language for content autogenerated by Sphinx. Refer to documentation 63 | # for a list of supported languages. 64 | #language = None 65 | 66 | # There are two options for replacing |today|: either, you set today to some 67 | # non-false value, then it is used: 68 | #today = '' 69 | # Else, today_fmt is used as the format for a strftime call. 70 | #today_fmt = '%B %d, %Y' 71 | 72 | # List of patterns, relative to source directory, that match files and 73 | # directories to ignore when looking for source files. 74 | exclude_patterns = ['_build'] 75 | 76 | # The reST default role (used for this markup: `text`) to use for all 77 | # documents. 78 | #default_role = None 79 | 80 | # If true, '()' will be appended to :func: etc. cross-reference text. 81 | #add_function_parentheses = True 82 | 83 | # If true, the current module name will be prepended to all description 84 | # unit titles (such as .. function::). 85 | #add_module_names = True 86 | 87 | # If true, sectionauthor and moduleauthor directives will be shown in the 88 | # output. They are ignored by default. 89 | #show_authors = False 90 | 91 | # The name of the Pygments (syntax highlighting) style to use. 92 | pygments_style = 'sphinx' 93 | 94 | # A list of ignored prefixes for module index sorting. 95 | #modindex_common_prefix = [] 96 | 97 | # If true, keep warnings as "system message" paragraphs in the built documents. 98 | #keep_warnings = False 99 | 100 | 101 | # -- Options for HTML output ---------------------------------------------- 102 | 103 | # The theme to use for HTML and HTML Help pages. See the documentation for 104 | # a list of builtin themes. 105 | html_theme = 'default' 106 | 107 | # Theme options are theme-specific and customize the look and feel of a theme 108 | # further. For a list of options available for each theme, see the 109 | # documentation. 110 | #html_theme_options = {} 111 | 112 | # Add any paths that contain custom themes here, relative to this directory. 113 | #html_theme_path = [] 114 | 115 | # The name for this set of Sphinx documents. If None, it defaults to 116 | # " v documentation". 117 | #html_title = None 118 | 119 | # A shorter title for the navigation bar. Default is the same as html_title. 120 | #html_short_title = None 121 | 122 | # The name of an image file (relative to this directory) to place at the top 123 | # of the sidebar. 124 | #html_logo = None 125 | 126 | # The name of an image file (within the static path) to use as favicon of the 127 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 128 | # pixels large. 129 | #html_favicon = None 130 | 131 | # Add any paths that contain custom static files (such as style sheets) here, 132 | # relative to this directory. They are copied after the builtin static files, 133 | # so a file named "default.css" will overwrite the builtin "default.css". 134 | html_static_path = ['_static'] 135 | 136 | # Add any extra paths that contain custom files (such as robots.txt or 137 | # .htaccess) here, relative to this directory. These files are copied 138 | # directly to the root of the documentation. 139 | #html_extra_path = [] 140 | 141 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 142 | # using the given strftime format. 143 | #html_last_updated_fmt = '%b %d, %Y' 144 | 145 | # If true, SmartyPants will be used to convert quotes and dashes to 146 | # typographically correct entities. 147 | #html_use_smartypants = True 148 | 149 | # Custom sidebar templates, maps document names to template names. 150 | #html_sidebars = {} 151 | 152 | # Additional templates that should be rendered to pages, maps page names to 153 | # template names. 154 | #html_additional_pages = {} 155 | 156 | # If false, no module index is generated. 157 | #html_domain_indices = True 158 | 159 | # If false, no index is generated. 160 | #html_use_index = True 161 | 162 | # If true, the index is split into individual pages for each letter. 163 | #html_split_index = False 164 | 165 | # If true, links to the reST sources are added to the pages. 166 | #html_show_sourcelink = True 167 | 168 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 169 | #html_show_sphinx = True 170 | 171 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 172 | #html_show_copyright = True 173 | 174 | # If true, an OpenSearch description file will be output, and all pages will 175 | # contain a tag referring to it. The value of this option must be the 176 | # base URL from which the finished HTML is served. 177 | #html_use_opensearch = '' 178 | 179 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 180 | #html_file_suffix = None 181 | 182 | # Output file base name for HTML help builder. 183 | htmlhelp_basename = 'Displaydoc' 184 | 185 | 186 | # -- Options for LaTeX output --------------------------------------------- 187 | 188 | latex_elements = { 189 | # The paper size ('letterpaper' or 'a4paper'). 190 | #'papersize': 'letterpaper', 191 | 192 | # The font size ('10pt', '11pt' or '12pt'). 193 | #'pointsize': '10pt', 194 | 195 | # Additional stuff for the LaTeX preamble. 196 | #'preamble': '', 197 | } 198 | 199 | # Grouping the document tree into LaTeX files. List of tuples 200 | # (source start file, target name, title, 201 | # author, documentclass [howto, manual, or own class]). 202 | latex_documents = [ 203 | ('index', 'Display.tex', u'µDisplay Documentation', 204 | u'Radomir Dopieralski', 'manual'), 205 | ] 206 | 207 | # The name of an image file (relative to this directory) to place at the top of 208 | # the title page. 209 | #latex_logo = None 210 | 211 | # For "manual" documents, if this is true, then toplevel headings are parts, 212 | # not chapters. 213 | #latex_use_parts = False 214 | 215 | # If true, show page references after internal links. 216 | #latex_show_pagerefs = False 217 | 218 | # If true, show URL addresses after external links. 219 | #latex_show_urls = False 220 | 221 | # Documents to append as an appendix to all manuals. 222 | #latex_appendices = [] 223 | 224 | # If false, no module index is generated. 225 | #latex_domain_indices = True 226 | 227 | 228 | # -- Options for manual page output --------------------------------------- 229 | 230 | # One entry per manual page. List of tuples 231 | # (source start file, name, description, authors, manual section). 232 | man_pages = [ 233 | ('index', 'display', u'µDisplay Documentation', 234 | [u'Radomir Dopieralski'], 1) 235 | ] 236 | 237 | # If true, show URL addresses after external links. 238 | #man_show_urls = False 239 | 240 | 241 | # -- Options for Texinfo output ------------------------------------------- 242 | 243 | # Grouping the document tree into Texinfo files. List of tuples 244 | # (source start file, target name, title, author, 245 | # dir menu entry, description, category) 246 | texinfo_documents = [ 247 | ('index', 'Display', u'µDisplay Documentation', 248 | u'Radomir Dopieralski', 'Display', 'One line description of project.', 249 | 'Miscellaneous'), 250 | ] 251 | 252 | # Documents to append as an appendix to all manuals. 253 | #texinfo_appendices = [] 254 | 255 | # If false, no module index is generated. 256 | #texinfo_domain_indices = True 257 | 258 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 259 | #texinfo_show_urls = 'footnote' 260 | 261 | # If true, do not generate a @detailmenu in the "Top" node's menu. 262 | #texinfo_no_detailmenu = False 263 | 264 | 265 | # Example configuration for intersphinx: refer to the Python standard library. 266 | intersphinx_mapping = {'http://docs.python.org/': None} 267 | -------------------------------------------------------------------------------- /docs/display.rst: -------------------------------------------------------------------------------- 1 | Display Module 2 | ************** 3 | 4 | .. module:: rgb 5 | 6 | Utilities 7 | ========= 8 | 9 | .. function:: color565(r, g, b) 10 | 11 | Convert red, green and blue values (0-255) into a 16-bit 565 encoding. 12 | 13 | .. class:: DummyPin() 14 | 15 | Can be used in place of a ``Pin()`` when you want to skip it. 16 | 17 | 18 | Display Class 19 | ============= 20 | 21 | This is the interface that all the display classes share. 22 | 23 | .. class:: Display(width, height) 24 | 25 | .. method:: init() 26 | 27 | Run the initialization commands for the given display (ran 28 | automatically when the object is created). 29 | 30 | .. method:: pixel(x, y, color) 31 | 32 | Get or set the value of a pixel at the given position. 33 | 34 | .. method:: fill_rectangle(x, y, width, height, color) 35 | 36 | Draw a rectangle at specified position with specified width and 37 | height, and fill it with the specified color. 38 | 39 | .. method:: fill(color) 40 | 41 | Fill the whole display with the specified color. 42 | 43 | .. method:: hline(x, y, width, color) 44 | 45 | Draw a horizontal line. 46 | 47 | .. method:: vline(x, y, height, color) 48 | 49 | Draw a vertical line. 50 | 51 | ..method:: blit_buffer(buffer, x, y, width, height) 52 | 53 | Copy the pixels from the buffer onto the display, starting at position 54 | ``(x, y)`` and assuming the copied area has width ``width`` and height 55 | ``height``. The area has to fit entirely inside the display 56 | -------------------------------------------------------------------------------- /docs/displays.rst: -------------------------------------------------------------------------------- 1 | List of Supported Displays 2 | ************************** 3 | 4 | .. module:: rgb 5 | 6 | All of those displays support the methods of the :class:`Display` class. 7 | 8 | .. module:: hx8353 9 | .. class:: HX8353(spi, dc, cs, rst=None, width=128, height=128) 10 | 11 | A TFT display. 12 | 13 | .. module:: ili9341 14 | .. class:: ILI9341(spi, dc, cs, rst=None, width=240, height=320) 15 | 16 | A TFT display. 17 | 18 | .. method:: scroll(dy=None) 19 | 20 | Get or set the vertical scroll position. 21 | 22 | .. module:: s6d02a1 23 | .. class:: S6D02A1(spi, dc, cs, rst=None, width=128, height=160) 24 | 25 | A TFT display. 26 | 27 | .. module:: ssd1331 28 | .. class:: SSD1331(spi, dc, cs, rst=None, widht=96, height=64) 29 | 30 | An OLED display. 31 | 32 | .. module:: ssd1351 33 | .. class:: SSD1351(spi, dc, cs, rst=None, width=128, height=128) 34 | 35 | An OLED display. 36 | 37 | .. module:: st7735 38 | .. class:: ST7735(spi, dc, cs, rst=None, width=128, height=128) 39 | 40 | A TFT display. 41 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. µDisplay documentation master file, created by 2 | sphinx-quickstart on Sun Aug 28 10:57:39 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to MicroPython Adafruit RGB Displays's documentation! 7 | ============================================================= 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | display.rst 15 | displays.rst 16 | 17 | 18 | Indices and tables 19 | ================== 20 | 21 | * :ref:`genindex` 22 | * :ref:`modindex` 23 | * :ref:`search` 24 | 25 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | goto end 41 | ) 42 | 43 | if "%1" == "clean" ( 44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 45 | del /q /s %BUILDDIR%\* 46 | goto end 47 | ) 48 | 49 | 50 | %SPHINXBUILD% 2> nul 51 | if errorlevel 9009 ( 52 | echo. 53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 54 | echo.installed, then set the SPHINXBUILD environment variable to point 55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 56 | echo.may add the Sphinx directory to PATH. 57 | echo. 58 | echo.If you don't have Sphinx installed, grab it from 59 | echo.http://sphinx-doc.org/ 60 | exit /b 1 61 | ) 62 | 63 | if "%1" == "html" ( 64 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 65 | if errorlevel 1 exit /b 1 66 | echo. 67 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 68 | goto end 69 | ) 70 | 71 | if "%1" == "dirhtml" ( 72 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 73 | if errorlevel 1 exit /b 1 74 | echo. 75 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 76 | goto end 77 | ) 78 | 79 | if "%1" == "singlehtml" ( 80 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 81 | if errorlevel 1 exit /b 1 82 | echo. 83 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 84 | goto end 85 | ) 86 | 87 | if "%1" == "pickle" ( 88 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 89 | if errorlevel 1 exit /b 1 90 | echo. 91 | echo.Build finished; now you can process the pickle files. 92 | goto end 93 | ) 94 | 95 | if "%1" == "json" ( 96 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 97 | if errorlevel 1 exit /b 1 98 | echo. 99 | echo.Build finished; now you can process the JSON files. 100 | goto end 101 | ) 102 | 103 | if "%1" == "htmlhelp" ( 104 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 105 | if errorlevel 1 exit /b 1 106 | echo. 107 | echo.Build finished; now you can run HTML Help Workshop with the ^ 108 | .hhp project file in %BUILDDIR%/htmlhelp. 109 | goto end 110 | ) 111 | 112 | if "%1" == "qthelp" ( 113 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 114 | if errorlevel 1 exit /b 1 115 | echo. 116 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 117 | .qhcp project file in %BUILDDIR%/qthelp, like this: 118 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Display.qhcp 119 | echo.To view the help file: 120 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Display.ghc 121 | goto end 122 | ) 123 | 124 | if "%1" == "devhelp" ( 125 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished. 129 | goto end 130 | ) 131 | 132 | if "%1" == "epub" ( 133 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 134 | if errorlevel 1 exit /b 1 135 | echo. 136 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 137 | goto end 138 | ) 139 | 140 | if "%1" == "latex" ( 141 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 142 | if errorlevel 1 exit /b 1 143 | echo. 144 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 145 | goto end 146 | ) 147 | 148 | if "%1" == "latexpdf" ( 149 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 150 | cd %BUILDDIR%/latex 151 | make all-pdf 152 | cd %BUILDDIR%/.. 153 | echo. 154 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 155 | goto end 156 | ) 157 | 158 | if "%1" == "latexpdfja" ( 159 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 160 | cd %BUILDDIR%/latex 161 | make all-pdf-ja 162 | cd %BUILDDIR%/.. 163 | echo. 164 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 165 | goto end 166 | ) 167 | 168 | if "%1" == "text" ( 169 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 170 | if errorlevel 1 exit /b 1 171 | echo. 172 | echo.Build finished. The text files are in %BUILDDIR%/text. 173 | goto end 174 | ) 175 | 176 | if "%1" == "man" ( 177 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 178 | if errorlevel 1 exit /b 1 179 | echo. 180 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 181 | goto end 182 | ) 183 | 184 | if "%1" == "texinfo" ( 185 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 186 | if errorlevel 1 exit /b 1 187 | echo. 188 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 189 | goto end 190 | ) 191 | 192 | if "%1" == "gettext" ( 193 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 194 | if errorlevel 1 exit /b 1 195 | echo. 196 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 197 | goto end 198 | ) 199 | 200 | if "%1" == "changes" ( 201 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 202 | if errorlevel 1 exit /b 1 203 | echo. 204 | echo.The overview file is in %BUILDDIR%/changes. 205 | goto end 206 | ) 207 | 208 | if "%1" == "linkcheck" ( 209 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 210 | if errorlevel 1 exit /b 1 211 | echo. 212 | echo.Link check complete; look for any errors in the above output ^ 213 | or in %BUILDDIR%/linkcheck/output.txt. 214 | goto end 215 | ) 216 | 217 | if "%1" == "doctest" ( 218 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 219 | if errorlevel 1 exit /b 1 220 | echo. 221 | echo.Testing of doctests in the sources finished, look at the ^ 222 | results in %BUILDDIR%/doctest/output.txt. 223 | goto end 224 | ) 225 | 226 | if "%1" == "xml" ( 227 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 228 | if errorlevel 1 exit /b 1 229 | echo. 230 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 231 | goto end 232 | ) 233 | 234 | if "%1" == "pseudoxml" ( 235 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 236 | if errorlevel 1 exit /b 1 237 | echo. 238 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 239 | goto end 240 | ) 241 | 242 | :end 243 | -------------------------------------------------------------------------------- /hx8353.py: -------------------------------------------------------------------------------- 1 | from rgb import DisplaySPI, color565 2 | 3 | _SWRESET = const(0x01) 4 | _NORON = const(0x13) 5 | _INVOFF = const(0x20) 6 | _INVON = const(0x21) 7 | _DISPOFF = const(0x28) 8 | _DISPON = const(0x29) 9 | _CASET = const(0x2a) 10 | _PASET = const(0x2b) 11 | _RAMWR = const(0x2c) 12 | _RAMRD = const(0x2e) 13 | _MADCTL = const(0x36) 14 | _COLMOD = const(0x3a) 15 | 16 | class HX8353(DisplaySPI): 17 | """ 18 | A simple driver for the HX8383-based displays. 19 | 20 | >>> from machine import Pin, SPI 21 | >>> import hx8353 22 | >>> spi = SPI(0) 23 | >>> display = hx8353.HX8383(spi, dc=Pin(0), cs=Pin(15), rst=Pin(16)) 24 | >>> display.fill(0x7521) 25 | >>> display.pixel(64, 64, 0) 26 | 27 | """ 28 | _COLUMN_SET = _CASET 29 | _PAGE_SET = _PASET 30 | _RAM_WRITE = _RAMWR 31 | _RAM_READ = _RAMRD 32 | _INIT = ( 33 | (_SWRESET, None), 34 | (_DISPON, None), 35 | ) 36 | _ENCODE_PIXEL = ">H" 37 | _ENCODE_POS = ">HH" 38 | 39 | def __init__(self, spi, dc, cs, rst=None, width=128, height=128): 40 | super().__init__(spi, dc, cs, rst, width, height) 41 | -------------------------------------------------------------------------------- /ili9341.py: -------------------------------------------------------------------------------- 1 | import ustruct 2 | from rgb import DisplaySPI, color565 3 | 4 | 5 | class ILI9341(DisplaySPI): 6 | """ 7 | A simple driver for the ILI9341/ILI9340-based displays. 8 | 9 | 10 | >>> import ili9341 11 | >>> from machine import Pin, SPI 12 | >>> spi = SPI(mosi=Pin(13), sck=Pin(14)) 13 | >>> display = ili9341.ILI9341(spi, cs=Pin(15), dc=Pin(12), rst=Pin(16)) 14 | >>> display.fill(ili9341.color565(0xff, 0x11, 0x22)) 15 | >>> display.pixel(120, 160, 0) 16 | """ 17 | 18 | _COLUMN_SET = 0x2a 19 | _PAGE_SET = 0x2b 20 | _RAM_WRITE = 0x2c 21 | _RAM_READ = 0x2e 22 | _INIT = ( 23 | (0xef, b'\x03\x80\x02'), 24 | (0xcf, b'\x00\xc1\x30'), 25 | (0xed, b'\x64\x03\x12\x81'), 26 | (0xe8, b'\x85\x00\x78'), 27 | (0xcb, b'\x39\x2c\x00\x34\x02'), 28 | (0xf7, b'\x20'), 29 | (0xea, b'\x00\x00'), 30 | (0xc0, b'\x23'), # Power Control 1, VRH[5:0] 31 | (0xc1, b'\x10'), # Power Control 2, SAP[2:0], BT[3:0] 32 | (0xc5, b'\x3e\x28'), # VCM Control 1 33 | (0xc7, b'\x86'), # VCM Control 2 34 | (0x36, b'\x48'), # Memory Access Control 35 | (0x3a, b'\x55'), # Pixel Format 36 | (0xb1, b'\x00\x18'), # FRMCTR1 37 | (0xb6, b'\x08\x82\x27'), # Display Function Control 38 | (0xf2, b'\x00'), # 3Gamma Function Disable 39 | (0x26, b'\x01'), # Gamma Curve Selected 40 | (0xe0, # Set Gamma 41 | b'\x0f\x31\x2b\x0c\x0e\x08\x4e\xf1\x37\x07\x10\x03\x0e\x09\x00'), 42 | (0xe1, # Set Gamma 43 | b'\x00\x0e\x14\x03\x11\x07\x31\xc1\x48\x08\x0f\x0c\x31\x36\x0f'), 44 | (0x11, None), 45 | (0x29, None), 46 | ) 47 | _ENCODE_PIXEL = ">H" 48 | _ENCODE_POS = ">HH" 49 | _DECODE_PIXEL = ">BBB" 50 | 51 | def __init__(self, spi, dc, cs, rst=None, width=240, height=320): 52 | super().__init__(spi, dc, cs, rst, width, height) 53 | self._scroll = 0 54 | 55 | def scroll(self, dy=None): 56 | if dy is None: 57 | return self._scroll 58 | self._scroll = (self._scroll + dy) % self.height 59 | self._write(0x37, ustruct.pack('>H', self._scroll)) 60 | -------------------------------------------------------------------------------- /rgb.py: -------------------------------------------------------------------------------- 1 | import utime 2 | import ustruct 3 | 4 | 5 | def color565(r, g, b): 6 | return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3 7 | 8 | 9 | class DummyPin: 10 | """A fake gpio pin for when you want to skip pins.""" 11 | 12 | OUT = 0 13 | IN = 0 14 | PULL_UP = 0 15 | PULL_DOWN = 0 16 | OPEN_DRAIN = 0 17 | ALT = 0 18 | ALT_OPEN_DRAIN = 0 19 | LOW_POWER = 0 20 | MED_POWER = 0 21 | HIGH_PWER = 0 22 | IRQ_FALLING = 0 23 | IRQ_RISING = 0 24 | IRQ_LOW_LEVEL = 0 25 | IRQ_HIGH_LEVEL = 0 26 | 27 | def __call__(self, *args, **kwargs): 28 | return False 29 | 30 | init = __call__ 31 | value = __call__ 32 | out_value = __call__ 33 | toggle = __call__ 34 | high = __call__ 35 | low = __call__ 36 | on = __call__ 37 | off = __call__ 38 | mode = __call__ 39 | pull = __call__ 40 | drive = __call__ 41 | irq = __call__ 42 | 43 | 44 | class Display: 45 | _PAGE_SET = None 46 | _COLUMN_SET = None 47 | _RAM_WRITE = None 48 | _RAM_READ = None 49 | _INIT = () 50 | _ENCODE_PIXEL = ">H" 51 | _ENCODE_POS = ">HH" 52 | _DECODE_PIXEL = ">BBB" 53 | 54 | def __init__(self, width, height): 55 | self.width = width 56 | self.height = height 57 | self.init() 58 | 59 | def init(self): 60 | """Run the initialization commands.""" 61 | for command, data in self._INIT: 62 | self._write(command, data) 63 | 64 | def _block(self, x0, y0, x1, y1, data=None): 65 | """Read or write a block of data.""" 66 | self._write(self._COLUMN_SET, self._encode_pos(x0, x1)) 67 | self._write(self._PAGE_SET, self._encode_pos(y0, y1)) 68 | if data is None: 69 | size = ustruct.calcsize(self._DECODE_PIXEL) 70 | return self._read(self._RAM_READ, 71 | (x1 - x0 + 1) * (y1 - y0 + 1) * size) 72 | self._write(self._RAM_WRITE, data) 73 | 74 | def _encode_pos(self, a, b): 75 | """Encode a postion into bytes.""" 76 | return ustruct.pack(self._ENCODE_POS, a, b) 77 | 78 | def _encode_pixel(self, color): 79 | """Encode a pixel color into bytes.""" 80 | return ustruct.pack(self._ENCODE_PIXEL, color) 81 | 82 | def _decode_pixel(self, data): 83 | """Decode bytes into a pixel color.""" 84 | return color565(*ustruct.unpack(self._DECODE_PIXEL, data)) 85 | 86 | def pixel(self, x, y, color=None): 87 | """Read or write a pixel.""" 88 | if color is None: 89 | return self._decode_pixel(self._block(x, y, x, y)) 90 | if not 0 <= x < self.width or not 0 <= y < self.height: 91 | return 92 | self._block(x, y, x, y, self._encode_pixel(color)) 93 | 94 | def fill_rectangle(self, x, y, width, height, color): 95 | """Draw a filled rectangle.""" 96 | x = min(self.width - 1, max(0, x)) 97 | y = min(self.height - 1, max(0, y)) 98 | w = min(self.width - x, max(1, width)) 99 | h = min(self.height - y, max(1, height)) 100 | self._block(x, y, x + w - 1, y + h - 1, b'') 101 | chunks, rest = divmod(w * h, 512) 102 | pixel = self._encode_pixel(color) 103 | if chunks: 104 | data = pixel * 512 105 | for count in range(chunks): 106 | self._write(None, data) 107 | if rest: 108 | self._write(None, pixel * rest) 109 | 110 | def fill(self, color=0): 111 | """Fill whole screen.""" 112 | self.fill_rectangle(0, 0, self.width, self.height, color) 113 | 114 | def hline(self, x, y, width, color): 115 | """Draw a horizontal line.""" 116 | self.fill_rectangle(x, y, width, 1, color) 117 | 118 | def vline(self, x, y, height, color): 119 | """Draw a vertical line.""" 120 | self.fill_rectangle(x, y, 1, height, color) 121 | 122 | def blit_buffer(self, buffer, x, y, width, height): 123 | """Copy pixels from a buffer.""" 124 | if (not 0 <= x < self.width or 125 | not 0 <= y < self.height or 126 | not 0 < x + width <= self.width or 127 | not 0 < y + height <= self.height): 128 | raise ValueError("out of bounds") 129 | self._block(x, y, x + width - 1, y + height - 1, buffer) 130 | 131 | 132 | class DisplaySPI(Display): 133 | def __init__(self, spi, dc, cs=None, rst=None, width=1, height=1): 134 | self.spi = spi 135 | self.cs = cs 136 | self.dc = dc 137 | self.rst = rst 138 | if self.rst is None: 139 | self.rst = DummyPin() 140 | if self.cs is None: 141 | self.cs = DummyPin() 142 | self.cs.init(self.cs.OUT, value=1) 143 | self.dc.init(self.dc.OUT, value=0) 144 | self.rst.init(self.rst.OUT, value=1) 145 | self.reset() 146 | super().__init__(width, height) 147 | 148 | def reset(self): 149 | self.rst(0) 150 | utime.sleep_ms(50) 151 | self.rst(1) 152 | utime.sleep_ms(50) 153 | 154 | def _write(self, command=None, data=None): 155 | if command is not None: 156 | self.dc(0) 157 | self.cs(0) 158 | self.spi.write(bytearray([command])) 159 | self.cs(1) 160 | if data is not None: 161 | self.dc(1) 162 | self.cs(0) 163 | self.spi.write(data) 164 | self.cs(1) 165 | 166 | def _read(self, command=None, count=0): 167 | self.dc(0) 168 | self.cs(0) 169 | if command is not None: 170 | self.spi.write(bytearray([command])) 171 | if count: 172 | data = self.spi.read(count) 173 | self.cs(1) 174 | return data 175 | 176 | -------------------------------------------------------------------------------- /rgb_text.py: -------------------------------------------------------------------------------- 1 | import framebuf 2 | 3 | def text(display, text, x=0, y=0, color=0xffff, background=0x0000): 4 | x = min(display.width - 1, max(0, x)) 5 | y = min(display.height - 1, max(0, y)) 6 | w = display.width - x 7 | h = min(display.height - y, 8) 8 | buffer = bytearray(display.width * h * 2) 9 | fb = framebuf.FrameBuffer(buffer, w, h, framebuf.RGB565) 10 | for line in text.split('\n'): 11 | fb.fill(background) 12 | fb.text(line, 0, 0, color) 13 | display.blit_buffer(buffer, x, y, w, h) 14 | y += 8; 15 | if y >= display.height: 16 | break 17 | -------------------------------------------------------------------------------- /s6d02a1.py: -------------------------------------------------------------------------------- 1 | from rgb import DisplaySPI, color565 2 | 3 | _SWRESET = const(0x01) 4 | _DISPON = const(0x29) 5 | _SLEEPOUT = const(0x11) 6 | _CASET = const(0x2a) 7 | _PASET = const(0x2b) 8 | _RAMWR = const(0x2c) 9 | _RAMRD = const(0x2e) 10 | _COLMOD = const(0x3a) 11 | _MADCTL = const(0x36) 12 | 13 | class S6D02A1(DisplaySPI): 14 | """ 15 | A simple driver for the S6D02A1-based displays. 16 | 17 | >>> from machine import Pin, SPI 18 | >>> import s6d02a1 19 | >>> spi = SPI(0, baudrate=40000000) 20 | >>> display = s6d02a1.S6D02A1(spi, dc=Pin(0), cs=Pin(15), rst=Pin(16)) 21 | >>> display.fill(0x7521) 22 | >>> display.pixel(64, 64, 0) 23 | 24 | """ 25 | _COLUMN_SET = _CASET 26 | _PAGE_SET = _PASET 27 | _RAM_WRITE = _RAMWR 28 | _RAM_READ = _RAMRD 29 | _INIT = ( 30 | (_SWRESET, None), 31 | (_SLEEPOUT, None), 32 | (_MADCTL, b'\x10'), # bottom-top 33 | (_COLMOD, b'\x05'), # RGB565 pixel format 34 | (_DISPON, None), 35 | ) 36 | _ENCODE_PIXEL = ">H" 37 | _ENCODE_POS = ">HH" 38 | 39 | def __init__(self, spi, dc, cs, rst=None, width=128, height=160): 40 | super().__init__(spi, dc, cs, rst, width, height) 41 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | 3 | 4 | setup( 5 | name='adafruit-rgb-display', 6 | py_modules=[ 7 | 'rgb', 8 | 'hx8353', 9 | 'ili9341', 10 | 's6d02a1', 11 | 'ssd1331', 12 | 'ssd1351', 13 | 'st7735', 14 | ], 15 | version="1.0.1", 16 | description="Drivers for RGB displays for MicroPython.", 17 | long_description="""\ 18 | This library lets you use a number of popular RGB displays with MicroPython.""", 19 | author='Radomir Dopieralski', 20 | author_email='micropython@sheep.art.pl', 21 | classifiers = [ 22 | 'Programming Language :: Python :: 3', 23 | 'License :: OSI Approved :: MIT License', 24 | ], 25 | url="https://bitbucket.org/thesheep/micropython-rgb", 26 | ) 27 | -------------------------------------------------------------------------------- /ssd1331.py: -------------------------------------------------------------------------------- 1 | from rgb import DisplaySPI, color565 2 | 3 | 4 | _DRAWLINE = const(0x21) 5 | _DRAWRECT = const(0x22) 6 | _FILL = const(0x26) 7 | _PHASEPERIOD = const(0x12) 8 | _SETCOLUMN = const(0x15) 9 | _SETROW = const(0x75) 10 | _CONTRASTA = const(0x81) 11 | _CONTRASTB = const(0x82) 12 | _CONTRASTC = const(0x83) 13 | _MASTERCURRENT = const(0x87) 14 | _SETREMAP = const(0xA0) 15 | _STARTLINE = const(0xA1) 16 | _DISPLAYOFFSET = const(0xA2) 17 | _NORMALDISPLAY = const(0xA4) 18 | _DISPLAYALLON = const(0xA5) 19 | _DISPLAYALLOFF = const(0xA6) 20 | _INVERTDISPLAY = const(0xA7) 21 | _SETMULTIPLEX = const(0xA8) 22 | _SETMASTER = const(0xAD) 23 | _DISPLAYOFF = const(0xAE) 24 | _DISPLAYON = const(0xAF) 25 | _POWERMODE = const(0xB0) 26 | _PRECHARGE = const(0xB1) 27 | _CLOCKDIV = const(0xB3) 28 | _PRECHARGEA = const(0x8A) 29 | _PRECHARGEB = const(0x8B) 30 | _PRECHARGEC = const(0x8C) 31 | _PRECHARGELEVEL = const(0xBB) 32 | _VCOMH = const(0xBE) 33 | _LOCK = const(0xfd) 34 | 35 | 36 | class SSD1331(DisplaySPI): 37 | """ 38 | >>> 39 | from machine import Pin, SPI 40 | import ssd1331 41 | #spi = SPI(mosi=Pin(13), sck=Pin(14), polarity=1, phase=1) 42 | spi = SPI(1, polarity=1, phase=1) 43 | display = ssd1331.SSD1331(spi, dc=Pin(12), cs=Pin(15), rst=Pin(16)) 44 | display.fill(0x7521) 45 | display.pixel(32, 32, 0) 46 | """ 47 | _COLUMN_SET = _SETCOLUMN 48 | _PAGE_SET = _SETROW 49 | _RAM_WRITE = None 50 | _RAM_READ = None 51 | _INIT = ( 52 | (_DISPLAYOFF, b''), 53 | (_LOCK, b'\x0b'), 54 | (_SETREMAP, b'\x72'), # RGB Color 55 | (_STARTLINE, b'\x00'), 56 | (_DISPLAYOFFSET, b'\x00'), 57 | (_NORMALDISPLAY, b''), 58 | # (_FILL, b'\x01'), 59 | 60 | (_PHASEPERIOD, b'\x31'), 61 | (_SETMULTIPLEX, b'\x3f'), 62 | (_SETMASTER, b'\x8e'), 63 | (_POWERMODE,b'\x0b'), 64 | (_PRECHARGE, b'\x31'), #;//0x1F - 0x31 65 | (_CLOCKDIV, b'\xf0'), 66 | (_VCOMH, b'\x3e'), #;//0x3E - 0x3F 67 | (_MASTERCURRENT, b'\x0c'), # ;//0x06 - 0x0F 68 | (_PRECHARGEA, b'\x64'), 69 | (_PRECHARGEB, b'\x78'), 70 | (_PRECHARGEC, b'\x64'), 71 | (_PRECHARGELEVEL, b'\x3a'), # 0x3A - 0x00 72 | (_CONTRASTA, b'\x91'), #//0xEF - 0x91 73 | (_CONTRASTB, b'\x50'), #;//0x11 - 0x50 74 | (_CONTRASTC, b'\x7d'), #;//0x48 - 0x7D 75 | (_DISPLAYON, b''), 76 | ) 77 | _ENCODE_PIXEL = ">H" 78 | _ENCODE_POS = ">BB" 79 | 80 | def __init__(self, spi, dc, cs, rst=None, width=96, height=64): 81 | super().__init__(spi, dc, cs, rst, width, height) 82 | 83 | def _write(self, command=None, data=None): 84 | if command is None: 85 | self.dc(1) 86 | else: 87 | self.dc(0) 88 | self.cs(0) 89 | if command is not None: 90 | self.spi.write(bytearray([command])) 91 | if data is not None: 92 | self.spi.write(data) 93 | self.cs(1) 94 | -------------------------------------------------------------------------------- /ssd1351.py: -------------------------------------------------------------------------------- 1 | from rgb import DisplaySPI, color565 2 | 3 | 4 | _SETCOLUMN = const(0x15) 5 | _SETROW = const(0x75) 6 | _WRITERAM = const(0x5C) 7 | _READRAM = const(0x5D) 8 | _SETREMAP = const(0xA0) 9 | _STARTLINE = const(0xA1) 10 | _DISPLAYOFFSET = const(0xA2) 11 | _DISPLAYALLOFF = const(0xA4) 12 | _DISPLAYALLON = const(0xA5) 13 | _NORMALDISPLAY = const(0xA6) 14 | _INVERTDISPLAY = const(0xA7) 15 | _FUNCTIONSELECT = const(0xAB) 16 | _DISPLAYOFF = const(0xAE) 17 | _DISPLAYON = const(0xAF) 18 | _PRECHARGE = const(0xB1) 19 | _DISPLAYENHANCE = const(0xB2) 20 | _CLOCKDIV = const(0xB3) 21 | _SETVSL = const(0xB4) 22 | _SETGPIO = const(0xB5) 23 | _PRECHARGE2 = const(0xB6) 24 | _SETGRAY = const(0xB8) 25 | _USELUT = const(0xB9) 26 | _PRECHARGELEVEL = const(0xBB) 27 | _VCOMH = const(0xBE) 28 | _CONTRASTABC = const(0xC1) 29 | _CONTRASTMASTER = const(0xC7) 30 | _MUXRATIO = const(0xCA) 31 | _COMMANDLOCK = const(0xFD) 32 | _HORIZSCROLL = const(0x96) 33 | _STOPSCROLL = const(0x9E) 34 | _STARTSCROLL = const(0x9F) 35 | 36 | 37 | class SSD1351(DisplaySPI): 38 | """ 39 | >>> 40 | from machine import Pin, SPI 41 | import ssd1351 42 | spi = SPI(1, baudrate=20000000) 43 | display = ssd1351.SSD1351(spi, dc=Pin(12), cs=Pin(15), rst=Pin(16)) 44 | display.fill(0x7521) 45 | display.pixel(32, 32, 0) 46 | """ 47 | 48 | _COLUMN_SET = _SETCOLUMN 49 | _PAGE_SET = _SETROW 50 | _RAM_WRITE = _WRITERAM 51 | _RAM_READ = _READRAM 52 | _INIT = ( 53 | (_COMMANDLOCK, b'\x12'), 54 | (_COMMANDLOCK, b'\xb1'), 55 | (_DISPLAYOFF, b''), 56 | (_DISPLAYENHANCE, b'\xa4\x00\x00'), 57 | # 7:4 = Oscillator Frequency, 58 | # 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16) 59 | (_CLOCKDIV, b'\xf0'), 60 | (_MUXRATIO, b'\x7f'), # 127 61 | (_SETREMAP, b'\x74'), 62 | (_STARTLINE, b'\x00'), 63 | (_DISPLAYOFFSET, b'\x00'), 64 | (_SETGPIO, b'\x00'), 65 | (_FUNCTIONSELECT, b'\x01'), 66 | (_PRECHARGE, b'\x32'), 67 | (_PRECHARGELEVEL, b'\x1f'), 68 | (_VCOMH, b'\x05'), 69 | (_NORMALDISPLAY, b''), 70 | (_CONTRASTABC, b'\xc8\x80\xc8'), 71 | (_CONTRASTMASTER, b'\x0a'), 72 | (_SETVSL, b'\xa0\xb5\x55'), 73 | (_PRECHARGE2, b'\x01'), 74 | (_DISPLAYON, b''), 75 | ) 76 | _ENCODE_PIXEL = ">H" 77 | _ENCODE_POS = ">BB" 78 | 79 | def __init__(self, spi, dc, cs, rst=None, width=128, height=128): 80 | super().__init__(spi, dc, cs, rst, width, height) 81 | -------------------------------------------------------------------------------- /st7735.py: -------------------------------------------------------------------------------- 1 | from rgb import DisplaySPI, color565 2 | import ustruct 3 | 4 | 5 | _NOP=const(0x00) 6 | _SWRESET=const(0x01) 7 | _RDDID=const(0x04) 8 | _RDDST=const(0x09) 9 | 10 | _SLPIN=const(0x10) 11 | _SLPOUT=const(0x11) 12 | _PTLON=const(0x12) 13 | _NORON=const(0x13) 14 | 15 | _INVOFF=const(0x20) 16 | _INVON=const(0x21) 17 | _DISPOFF=const(0x28) 18 | _DISPON=const(0x29) 19 | _CASET=const(0x2A) 20 | _RASET=const(0x2B) 21 | _RAMWR=const(0x2C) 22 | _RAMRD=const(0x2E) 23 | 24 | _PTLAR=const(0x30) 25 | _COLMOD=const(0x3A) 26 | _MADCTL=const(0x36) 27 | 28 | _FRMCTR1=const(0xB1) 29 | _FRMCTR2=const(0xB2) 30 | _FRMCTR3=const(0xB3) 31 | _INVCTR=const(0xB4) 32 | _DISSET5=const(0xB6) 33 | 34 | _PWCTR1=const(0xC0) 35 | _PWCTR2=const(0xC1) 36 | _PWCTR3=const(0xC2) 37 | _PWCTR4=const(0xC3) 38 | _PWCTR5=const(0xC4) 39 | _VMCTR1=const(0xC5) 40 | 41 | _RDID1=const(0xDA) 42 | _RDID2=const(0xDB) 43 | _RDID3=const(0xDC) 44 | _RDID4=const(0xDD) 45 | 46 | _PWCTR6=const(0xFC) 47 | 48 | _GMCTRP1=const(0xE0) 49 | _GMCTRN1=const(0xE1) 50 | 51 | 52 | class ST7735(DisplaySPI): 53 | """ 54 | A simple driver for the ST7735-based displays. 55 | 56 | >>> from machine import Pin, SPI 57 | >>> import st7735 58 | >>> display = st7735.ST7735(SPI(1), dc=Pin(12), cs=Pin(15), rst=Pin(16)) 59 | >>> display = st7735.ST7735R(SPI(1, baudrate=40000000), dc=Pin(12), cs=Pin(15), rst=Pin(16)) 60 | >>> display.fill(0x7521) 61 | >>> display.pixel(64, 64, 0) 62 | 63 | """ 64 | _COLUMN_SET = _CASET 65 | _PAGE_SET = _RASET 66 | _RAM_WRITE = _RAMWR 67 | _RAM_READ = _RAMRD 68 | _INIT = ( 69 | (_SWRESET, None), 70 | (_SLPOUT, None), 71 | 72 | (_MADCTL, b'\x08'), # bottom to top refresh 73 | (_COLMOD, b'\x05'), # 16bit color 74 | (_INVCTR, b'0x00'), # line inversion 75 | 76 | # 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, 77 | # fix on VTL 78 | (_DISSET5, b'\x15\x02'), 79 | # fastest refresh, 6 lines front porch, 3 line back porch 80 | (_FRMCTR1, b'\x00\x06\x03'), 81 | 82 | (_PWCTR1, b'\x02\x70'), # GVDD = 4.7V, 1.0uA 83 | (_PWCTR2, b'\x05'), # VGH=14.7V, VGL=-7.35V 84 | (_PWCTR3, b'\x01\x02'), # Opamp current small, Boost frequency 85 | (_PWCTR6, b'\x11\x15'), 86 | 87 | (_VMCTR1, b'\x3c\x38'), # VCOMH = 4V, VOML = -1.1V 88 | 89 | (_GMCTRP1, b'\x09\x16\x09\x20\x21\x1b\x13\x19' 90 | b'\x17\x15\x1e\x2b\x04\x05\x02\x0e'), # Gamma 91 | (_GMCTRN1, b'\x08\x14\x08\x1e\x22\x1d\x18\x1e' 92 | b'\x18\x1a\x24\x2b\x06\x06\x02\x0f'), 93 | 94 | (_CASET, b'\x00\x02\x00\x81'), # XSTART = 2, XEND = 129 95 | (_RASET, b'\x00\x02\x00\x81'), # YSTART = 2, YEND = 129 96 | 97 | (_NORON, None), 98 | (_DISPON, None), 99 | ) 100 | _ENCODE_PIXEL = ">H" 101 | _ENCODE_POS = ">HH" 102 | 103 | def __init__(self, spi, dc, cs, rst=None, width=128, height=128): 104 | super().__init__(spi, dc, cs, rst, width, height) 105 | 106 | 107 | class ST7735R(ST7735): 108 | _INIT = ( 109 | (_SWRESET, None), 110 | (_SLPOUT, None), 111 | 112 | (_MADCTL, b'\xc8'), 113 | (_COLMOD, b'\x05'), # 16bit color 114 | (_INVCTR, b'\x07'), 115 | 116 | (_FRMCTR1, b'\x01\x2c\x2d'), 117 | (_FRMCTR2, b'\x01\x2c\x2d'), 118 | (_FRMCTR3, b'\x01\x2c\x2d\x01\x2c\x2d'), 119 | 120 | (_PWCTR1, b'\x02\x02\x84'), 121 | (_PWCTR2, b'\xc5'), 122 | (_PWCTR3, b'\x0a\x00'), 123 | (_PWCTR4, b'\x8a\x2a'), 124 | (_PWCTR5, b'\x8a\xee'), 125 | 126 | (_VMCTR1, b'\x0e'), 127 | (_INVOFF, None), 128 | 129 | (_GMCTRP1, b'\x02\x1c\x07\x12\x37\x32\x29\x2d' 130 | b'\x29\x25\x2B\x39\x00\x01\x03\x10'), # Gamma 131 | (_GMCTRN1, b'\x03\x1d\x07\x06\x2E\x2C\x29\x2D' 132 | b'\x2E\x2E\x37\x3F\x00\x00\x02\x10'), 133 | ) 134 | 135 | def __init__(self, spi, dc, cs, rst=None, width=128, height=160): 136 | super().__init__(spi, dc, cs, rst, width, height) 137 | 138 | def init(self): 139 | super().init() 140 | cols = ustruct.pack('>HH', 0, self.width - 1) 141 | rows = ustruct.pack('>HH', 0, self.height - 1) 142 | for command, data in ( 143 | (_CASET, cols), 144 | (_RASET, rows), 145 | 146 | (_NORON, None), 147 | (_DISPON, None), 148 | ): 149 | self._write(command, data) 150 | --------------------------------------------------------------------------------