6
6
`adafruit_epd.ssd1680` - Adafruit SSD1680 - ePaper display driver
7
7
====================================================================================
8
8
CircuitPython driver for Adafruit SSD1680 display breakouts
9
- * Author(s): Melissa LeBlanc-Williams Mikey Sklar
9
+ * Author(s): Melissa LeBlanc-Williams
10
10
"""
11
+
11
12
import time
12
13
from micropython import const
13
14
import adafruit_framebuf
14
15
from adafruit_epd .epd import Adafruit_EPD
15
16
16
- # Define all SSD1680 constants
17
+ try :
18
+ """Needed for type annotations"""
19
+ import typing # pylint: disable=unused-import
20
+ from typing_extensions import Literal
21
+ from busio import SPI
22
+ from digitalio import DigitalInOut
23
+
24
+ except ImportError :
25
+ pass
26
+
27
+ __version__ = "0.0.0+auto.0"
28
+ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EPD.git"
29
+
17
30
_SSD1680_DRIVER_CONTROL = const (0x01 )
31
+ _SSD1680_GATE_VOLTAGE = const (0x03 )
32
+ _SSD1680_SOURCE_VOLTAGE = const (0x04 )
33
+ _SSD1680_INIT_SETTING = const (0x08 )
34
+ _SSD1680_INIT_WRITE_REG = const (0x09 )
35
+ _SSD1680_INIT_READ_REG = const (0x0A )
36
+ _SSD1680_BOOSTER_SOFT_START = const (0x0C )
37
+ _SSD1680_DEEP_SLEEP = const (0x10 )
18
38
_SSD1680_DATA_MODE = const (0x11 )
19
39
_SSD1680_SW_RESET = const (0x12 )
20
- _SSD1680_SET_RAMXPOS = const (0x44 )
21
- _SSD1680_SET_RAMYPOS = const (0x45 )
40
+ _SSD1680_HV_DETECT = const (0x14 )
41
+ _SSD1680_VCI_DETECT = const (0x15 )
42
+ _SSD1680_TEMP_CONTROL = const (0x18 )
43
+ _SSD1680_TEMP_WRITE = const (0x1A )
44
+ _SSD1680_TEMP_READ = const (0x1B )
45
+ _SSD1680_EXTTEMP_WRITE = const (0x1C )
46
+ _SSD1680_MASTER_ACTIVATE = const (0x20 )
47
+ _SSD1680_DISP_CTRL1 = const (0x21 )
48
+ _SSD1680_DISP_CTRL2 = const (0x22 )
22
49
_SSD1680_WRITE_BWRAM = const (0x24 )
23
50
_SSD1680_WRITE_REDRAM = const (0x26 )
51
+ _SSD1680_READ_RAM = const (0x27 )
52
+ _SSD1680_VCOM_SENSE = const (0x28 )
53
+ _SSD1680_VCOM_DURATION = const (0x29 )
54
+ _SSD1680_WRITE_VCOM_OTP = const (0x2A )
55
+ _SSD1680_WRITE_VCOM_CTRL = const (0x2B )
56
+ _SSD1680_WRITE_VCOM_REG = const (0x2C )
57
+ _SSD1680_READ_OTP = const (0x2D )
58
+ _SSD1680_READ_USERID = const (0x2E )
59
+ _SSD1680_READ_STATUS = const (0x2F )
60
+ _SSD1680_WRITE_WS_OTP = const (0x30 )
61
+ _SSD1680_LOAD_WS_OTP = const (0x31 )
62
+ _SSD1680_WRITE_LUT = const (0x32 )
63
+ _SSD1680_CRC_CALC = const (0x34 )
64
+ _SSD1680_CRC_READ = const (0x35 )
65
+ _SSD1680_PROG_OTP = const (0x36 )
66
+ _SSD1680_WRITE_DISPLAY_OPT = const (0x37 )
67
+ _SSD1680_WRITE_USERID = const (0x38 )
68
+ _SSD1680_OTP_PROGMODE = const (0x39 )
69
+ _SSD1680_WRITE_BORDER = const (0x3C )
70
+ _SSD1680_END_OPTION = const (0x3F )
71
+ _SSD1680_SET_RAMXPOS = const (0x44 )
72
+ _SSD1680_SET_RAMYPOS = const (0x45 )
73
+ _SSD1680_AUTOWRITE_RED = const (0x46 )
74
+ _SSD1680_AUTOWRITE_BW = const (0x47 )
24
75
_SSD1680_SET_RAMXCOUNT = const (0x4E )
25
76
_SSD1680_SET_RAMYCOUNT = const (0x4F )
26
- _SSD1680_DISP_CTRL2 = const (0x22 )
27
- _SSD1680_MASTER_ACTIVATE = const (0x20 )
28
- _SSD1680_DEEP_SLEEP = const (0x10 )
77
+ _SSD1680_NOP = const (0xFF )
29
78
30
79
31
80
class Adafruit_SSD1680 (Adafruit_EPD ):
32
- """Driver for SSD1680 ePaper display, default driver. """
81
+ """driver class for Adafruit SSD1680 ePaper display breakouts """
33
82
34
- # pylint: disable=too-many-arguments, useless-parent-delegation
83
+ # pylint: disable=too-many-arguments
35
84
def __init__ (
36
- self , width , height , spi , * , cs_pin , dc_pin , sramcs_pin , rst_pin , busy_pin
37
- ):
38
- # Call parent class's __init__ to initialize sram and other attributes
85
+ self ,
86
+ width : int ,
87
+ height : int ,
88
+ spi : SPI ,
89
+ * ,
90
+ cs_pin : DigitalInOut ,
91
+ dc_pin : DigitalInOut ,
92
+ sramcs_pin : DigitalInOut ,
93
+ rst_pin : DigitalInOut ,
94
+ busy_pin : DigitalInOut
95
+ ) -> None :
39
96
super ().__init__ (
40
97
width , height , spi , cs_pin , dc_pin , sramcs_pin , rst_pin , busy_pin
41
98
)
42
99
43
- self .cs_pin = cs_pin
44
- self .dc_pin = dc_pin
45
- self .sramcs_pin = sramcs_pin
46
- self .rst_pin = rst_pin
47
- self .busy_pin = busy_pin
48
-
49
- self .initialize_buffers (width , height )
50
-
51
- # pylint: enable=too-many-arguments, useless-parent-delegation
52
-
53
- def initialize_buffers (self , width , height ):
54
- """Initialize width height stride buffers"""
55
100
stride = width
56
101
if stride % 8 != 0 :
57
102
stride += 8 - stride % 8
58
103
59
104
self ._buffer1_size = int (stride * height / 8 )
60
105
self ._buffer2_size = self ._buffer1_size
61
106
62
- if self . sramcs_pin :
107
+ if sramcs_pin :
63
108
self ._buffer1 = self .sram .get_view (0 )
64
109
self ._buffer2 = self .sram .get_view (self ._buffer1_size )
65
110
else :
66
111
self ._buffer1 = bytearray (self ._buffer1_size )
67
112
self ._buffer2 = bytearray (self ._buffer2_size )
68
113
69
114
self ._framebuf1 = adafruit_framebuf .FrameBuffer (
70
- self ._buffer1 , width , height , buf_format = adafruit_framebuf .MHMSB
115
+ self ._buffer1 ,
116
+ width ,
117
+ height ,
118
+ stride = stride ,
119
+ buf_format = adafruit_framebuf .MHMSB ,
71
120
)
72
121
self ._framebuf2 = adafruit_framebuf .FrameBuffer (
73
- self ._buffer2 , width , height , buf_format = adafruit_framebuf .MHMSB
122
+ self ._buffer2 ,
123
+ width ,
124
+ height ,
125
+ stride = stride ,
126
+ buf_format = adafruit_framebuf .MHMSB ,
74
127
)
75
128
self .set_black_buffer (0 , True )
76
129
self .set_color_buffer (1 , False )
130
+ # pylint: enable=too-many-arguments
131
+
132
+ def begin (self , reset : bool = True ) -> None :
133
+ """Begin communication with the display and set basic settings"""
134
+ if reset :
135
+ self .hardware_reset ()
136
+ self .power_down ()
77
137
78
- def busy_wait (self ):
79
- """Wait for the display to complete its current task."""
80
- if self .busy_pin :
81
- while self .busy_pin .value :
138
+ def busy_wait (self ) -> None :
139
+ """Wait for display to be done with current task, either by polling the
140
+ busy pin, or pausing"""
141
+ if self ._busy :
142
+ while self ._busy .value :
82
143
time .sleep (0.01 )
83
144
else :
84
145
time .sleep (0.5 )
85
146
86
- def power_up (self ):
87
- """Power up sequence for SSD1680. """
147
+ def power_up (self ) -> None :
148
+ """Power up the display in preparation for writing RAM and updating """
88
149
self .hardware_reset ()
89
150
self .busy_wait ()
90
151
self .command (_SSD1680_SW_RESET )
91
152
self .busy_wait ()
92
-
153
+ # driver output control
93
154
self .command (
94
155
_SSD1680_DRIVER_CONTROL ,
95
156
bytearray ([self ._height - 1 , (self ._height - 1 ) >> 8 , 0x00 ]),
96
157
)
158
+ # data entry mode
97
159
self .command (_SSD1680_DATA_MODE , bytearray ([0x03 ]))
160
+
161
+ # Set voltages
162
+ self .command (_SSD1680_WRITE_VCOM_REG , bytearray ([0x36 ]))
163
+ self .command (_SSD1680_GATE_VOLTAGE , bytearray ([0x17 ]))
164
+ self .command (_SSD1680_SOURCE_VOLTAGE , bytearray ([0x41 , 0x00 , 0x32 ]))
165
+
166
+ # Set ram X start/end postion
98
167
self .command (_SSD1680_SET_RAMXPOS , bytearray ([0x01 , 0x10 ]))
168
+ # Set ram Y start/end postion
99
169
self .command (
100
170
_SSD1680_SET_RAMYPOS ,
101
171
bytearray ([0 , 0 , self ._height - 1 , (self ._height - 1 ) >> 8 ]),
102
172
)
173
+ # Set border waveform
174
+ self .command (_SSD1680_WRITE_BORDER , bytearray ([0x05 ]))
175
+
176
+ # Set ram X count
177
+ self .command (_SSD1680_SET_RAMXCOUNT , bytearray ([0x01 ]))
178
+ # Set ram Y count
179
+ self .command (_SSD1680_SET_RAMYCOUNT , bytearray ([self ._height - 1 , 0 ]))
180
+ self .busy_wait ()
181
+
182
+ def power_down (self ) -> None :
183
+ """Power down the display - required when not actively displaying!"""
184
+ self .command (_SSD1680_DEEP_SLEEP , bytearray ([0x01 ]))
185
+ time .sleep (0.1 )
186
+
187
+ def update (self ) -> None :
188
+ """Update the display from internal memory"""
189
+ self .command (_SSD1680_DISP_CTRL2 , bytearray ([0xF4 ]))
190
+ self .command (_SSD1680_MASTER_ACTIVATE )
191
+ self .busy_wait ()
192
+ if not self ._busy :
193
+ time .sleep (3 ) # wait 3 seconds
103
194
104
- def write_ram (self , index ):
105
- """Write to RAM for SSD1680."""
195
+ def write_ram (self , index : Literal [0 , 1 ]) -> int :
196
+ """Send the one byte command for starting the RAM write process. Returns
197
+ the byte read at the same time over SPI. index is the RAM buffer, can be
198
+ 0 or 1 for tri-color displays."""
106
199
if index == 0 :
107
200
return self .command (_SSD1680_WRITE_BWRAM , end = False )
108
201
if index == 1 :
109
202
return self .command (_SSD1680_WRITE_REDRAM , end = False )
110
-
111
- # Raise an error if the index is not 0 or 1
112
203
raise RuntimeError ("RAM index must be 0 or 1" )
113
204
114
- def set_ram_address (self , x , y ):
115
- """Set RAM address location for SSD1680."""
205
+ def set_ram_address (
206
+ self , x : int , y : int
207
+ ) -> None : # pylint: disable=unused-argument, no-self-use
208
+ """Set the RAM address location, not used on this chipset but required by
209
+ the superclass"""
210
+ # Set RAM X address counter
116
211
self .command (_SSD1680_SET_RAMXCOUNT , bytearray ([x + 1 ]))
212
+ # Set RAM Y address counter
117
213
self .command (_SSD1680_SET_RAMYCOUNT , bytearray ([y , y >> 8 ]))
118
214
119
- def update (self ):
120
- """Update the display from internal memory."""
121
- self .command (_SSD1680_DISP_CTRL2 , bytearray ([0xF4 ])) # Full update
122
- self .command (_SSD1680_MASTER_ACTIVATE )
123
- self .busy_wait ()
124
- if not self .busy_pin :
125
- time .sleep (3 ) # Wait for update to complete
126
-
127
- def power_down (self ):
128
- """Power down the display."""
129
- self .command (_SSD1680_DEEP_SLEEP , bytearray ([0x01 ]))
130
- time .sleep (0.1 )
131
-
132
215
133
216
class Adafruit_SSD1680Z (Adafruit_SSD1680 ):
134
217
"""Driver for SSD1680Z ePaper display, overriding SSD1680 settings."""
@@ -148,6 +231,7 @@ def __init__(
148
231
rst_pin = rst_pin ,
149
232
busy_pin = busy_pin ,
150
233
)
234
+ self .busy_pin = busy_pin # Ensure busy_pin is set
151
235
152
236
# pylint: enable=too-many-arguments, useless-parent-delegation
153
237
0 commit comments