-
Notifications
You must be signed in to change notification settings - Fork 8
/
adafruit_pcd8544.py
171 lines (137 loc) · 4.87 KB
/
adafruit_pcd8544.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# SPDX-FileCopyrightText: 2018 Tony DiCola for Adafruit Industries
# SPDX-FileCopyrightText: 2018 ladyada for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
`adafruit_pcd8544`
====================================================
A display control library for Nokia 5110 PCD8544 monochrome displays
* Author(s): ladyada
Implementation Notes
--------------------
**Hardware:**
* `Nokia 5110 PCD8544 Display <https://www.adafruit.com/product/338>`_
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
"""
import time
from micropython import const
from adafruit_bus_device import spi_device
try:
import framebuf
except ImportError:
import adafruit_framebuf as framebuf
try:
from typing import Optional
from digitalio import DigitalInOut
from busio import SPI
except ImportError:
pass
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PCD8544.git"
_LCDWIDTH = const(84)
_LCDHEIGHT = const(48)
_PCD8544_POWERDOWN = const(0x04)
_PCD8544_ENTRYMODE = const(0x02)
_PCD8544_EXTENDEDINSTRUCTION = const(0x01)
_PCD8544_DISPLAYBLANK = const(0x0)
_PCD8544_DISPLAYNORMAL = const(0x4)
_PCD8544_DISPLAYALLON = const(0x1)
_PCD8544_DISPLAYINVERTED = const(0x5)
_PCD8544_FUNCTIONSET = const(0x20)
_PCD8544_DISPLAYCONTROL = const(0x08)
_PCD8544_SETYADDR = const(0x40)
_PCD8544_SETXADDR = const(0x80)
_PCD8544_SETTEMP = const(0x04)
_PCD8544_SETBIAS = const(0x10)
_PCD8544_SETVOP = const(0x80)
class PCD8544(framebuf.FrameBuffer):
"""Nokia 5110/3310 PCD8544-based LCD display."""
# pylint: disable=too-many-instance-attributes
def __init__(
self,
spi: SPI,
dc_pin: DigitalInOut,
cs_pin: DigitalInOut,
reset_pin: Optional[DigitalInOut] = None,
*,
contrast: int = 80,
bias: int = 4,
baudrate: int = 1000000
) -> None:
self._dc_pin = dc_pin
dc_pin.switch_to_output(value=False)
self.spi_device = spi_device.SPIDevice(spi, cs_pin, baudrate=baudrate)
self._reset_pin = reset_pin
if reset_pin:
reset_pin.switch_to_output(value=True)
self.buffer = bytearray((_LCDHEIGHT // 8) * _LCDWIDTH)
super().__init__(self.buffer, _LCDWIDTH, _LCDHEIGHT)
self._contrast = None
self._bias = None
self._invert = False
self.reset()
# Set LCD bias.
self.bias = bias
self.contrast = contrast
def reset(self) -> None:
"""Reset the display"""
if self._reset_pin:
# Toggle RST low to reset.
self._reset_pin.value = False
time.sleep(0.5)
self._reset_pin.value = True
time.sleep(0.5)
def write_cmd(self, cmd: int) -> None:
"""Send a command to the SPI device"""
self._dc_pin.value = 0
with self.spi_device as spi:
spi.write(bytearray([cmd])) # pylint: disable=no-member
def extended_command(self, cmd: int) -> None:
"""Send a command in extended mode"""
# Set extended command mode
self.write_cmd(_PCD8544_FUNCTIONSET | _PCD8544_EXTENDEDINSTRUCTION)
self.write_cmd(cmd)
# Set normal display mode.
self.write_cmd(_PCD8544_FUNCTIONSET)
self.write_cmd(_PCD8544_DISPLAYCONTROL | _PCD8544_DISPLAYNORMAL)
def show(self) -> None:
"""write out the frame buffer via SPI"""
self.write_cmd(_PCD8544_SETYADDR)
self.write_cmd(_PCD8544_SETXADDR)
self._dc_pin.value = True
with self.spi_device as spi:
spi.write(self.buffer) # pylint: disable=no-member
@property
def invert(self) -> bool:
"""Whether the display is inverted, cached value"""
return self._invert
@invert.setter
def invert(self, val: bool) -> None:
"""Set invert on or normal display on"""
self._invert = val
self.write_cmd(_PCD8544_FUNCTIONSET)
if val:
self.write_cmd(_PCD8544_DISPLAYCONTROL | _PCD8544_DISPLAYINVERTED)
else:
self.write_cmd(_PCD8544_DISPLAYCONTROL | _PCD8544_DISPLAYNORMAL)
@property
def contrast(self) -> int:
"""The cached contrast value"""
return self._contrast
@contrast.setter
def contrast(self, val: int) -> None:
"""Set contrast to specified value (should be 0-127)."""
self._contrast = max(0, min(val, 0x7F)) # Clamp to values 0-0x7f
self.extended_command(_PCD8544_SETVOP | self._contrast)
@property
def bias(self) -> int:
"""The cached bias value"""
return self._bias
@bias.setter
def bias(self, val: int) -> None:
"""Set display bias"""
self._bias = val
self.extended_command(_PCD8544_SETBIAS | self._bias)