118 lines
3.7 KiB
Python
118 lines
3.7 KiB
Python
# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
"""
|
|
`adafruit_displayio_ssd1306`
|
|
================================================================================
|
|
|
|
DisplayIO driver for SSD1306 monochrome displays
|
|
|
|
|
|
* Author(s): Scott Shawcroft
|
|
|
|
Implementation Notes
|
|
--------------------
|
|
|
|
**Hardware:**
|
|
|
|
* `Monochrome 1.3" 128x64 OLED graphic display <https://www.adafruit.com/product/938>`_
|
|
* `Monochrome 128x32 I2C OLED graphic display <https://www.adafruit.com/product/931>`_
|
|
* `Monochrome 0.96" 128x64 OLED graphic display <https://www.adafruit.com/product/326>`_
|
|
* `Monochrome 128x32 SPI OLED graphic display <https://www.adafruit.com/product/661>`_
|
|
* `Adafruit FeatherWing OLED - 128x32 OLED <https://www.adafruit.com/product/2900>`_
|
|
|
|
**Software and Dependencies:**
|
|
|
|
* Adafruit CircuitPython (version 5+) firmware for the supported boards:
|
|
https://github.com/adafruit/circuitpython/releases
|
|
|
|
"""
|
|
|
|
import displayio
|
|
|
|
__version__ = "0.0.0-auto.0"
|
|
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_SSD1306.git"
|
|
|
|
# Sequence from page 19 here: https://cdn-shop.adafruit.com/datasheets/UG-2864HSWEG01+user+guide.pdf
|
|
_INIT_SEQUENCE = (
|
|
b"\xAE\x00" # DISPLAY_OFF
|
|
b"\x20\x01\x00" # Set memory addressing to horizontal mode.
|
|
b"\x81\x01\xcf" # set contrast control
|
|
b"\xA1\x00" # Column 127 is segment 0
|
|
b"\xA6\x00" # Normal display
|
|
b"\xc8\x00" # Normal display
|
|
b"\xA8\x01\x3f" # Mux ratio is 1/64
|
|
b"\xd5\x01\x80" # Set divide ratio
|
|
b"\xd9\x01\xf1" # Set pre-charge period
|
|
b"\xda\x01\x12" # Set com configuration
|
|
b"\xdb\x01\x40" # Set vcom configuration
|
|
b"\x8d\x01\x14" # Enable charge pump
|
|
b"\xAF\x00" # DISPLAY_ON
|
|
)
|
|
|
|
|
|
class SSD1306(displayio.Display):
|
|
"""
|
|
SSD1306 driver
|
|
|
|
:param int width: The width of the display
|
|
:param int height: The height of the display
|
|
:param int rotation: The rotation of the display in degrees. Default is 0. Must be one of
|
|
(0, 90, 180, 270)
|
|
"""
|
|
|
|
def __init__(self, bus, **kwargs):
|
|
# Patch the init sequence for 32 pixel high displays.
|
|
init_sequence = bytearray(_INIT_SEQUENCE)
|
|
height = kwargs["height"]
|
|
if "rotation" in kwargs and kwargs["rotation"] % 180 != 0:
|
|
height = kwargs["width"]
|
|
init_sequence[16] = height - 1 # patch mux ratio
|
|
if kwargs["height"] == 32:
|
|
init_sequence[25] = 0x02 # patch com configuration
|
|
super().__init__(
|
|
bus,
|
|
init_sequence,
|
|
**kwargs,
|
|
color_depth=1,
|
|
grayscale=True,
|
|
pixels_in_byte_share_row=False,
|
|
set_column_command=0x21,
|
|
set_row_command=0x22,
|
|
data_as_commands=True,
|
|
brightness_command=0x81,
|
|
single_byte_bounds=True,
|
|
)
|
|
self._is_awake = True # Display starts in active state (_INIT_SEQUENCE)
|
|
|
|
@property
|
|
def is_awake(self):
|
|
"""
|
|
The power state of the display. (read-only)
|
|
|
|
`True` if the display is active, `False` if in sleep mode.
|
|
|
|
:type: bool
|
|
"""
|
|
return self._is_awake
|
|
|
|
def sleep(self):
|
|
"""
|
|
Put display into sleep mode.
|
|
|
|
Display uses < 10uA in sleep mode. Display remembers display data and operation mode
|
|
active prior to sleeping. MP can access (update) the built-in display RAM.
|
|
"""
|
|
if self._is_awake:
|
|
self.bus.send(0xAE, b"") # 0xAE = display off, sleep mode
|
|
self._is_awake = False
|
|
|
|
def wake(self):
|
|
"""
|
|
Wake display from sleep mode
|
|
"""
|
|
if not self._is_awake:
|
|
self.bus.send(0xAF, b"") # 0xAF = display on
|
|
self._is_awake = True
|