66`adafruit_epd.ssd1680` - Adafruit SSD1680 - ePaper display driver
77====================================================================================
88CircuitPython driver for Adafruit SSD1680 display breakouts
9- * Author(s): Melissa LeBlanc-Williams Mikey Sklar
9+ * Author(s): Melissa LeBlanc-Williams
1010"""
11+
1112import time
1213from micropython import const
1314import adafruit_framebuf
1415from adafruit_epd .epd import Adafruit_EPD
1516
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+
1730_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 )
1838_SSD1680_DATA_MODE = const (0x11 )
1939_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 )
2249_SSD1680_WRITE_BWRAM = const (0x24 )
2350_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 )
2475_SSD1680_SET_RAMXCOUNT = const (0x4E )
2576_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 )
2978
3079
3180class Adafruit_SSD1680 (Adafruit_EPD ):
32- """Driver for SSD1680 ePaper display, default driver. """
81+ """driver class for Adafruit SSD1680 ePaper display breakouts """
3382
34- # pylint: disable=too-many-arguments, useless-parent-delegation
83+ # pylint: disable=too-many-arguments
3584 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 :
3996 super ().__init__ (
4097 width , height , spi , cs_pin , dc_pin , sramcs_pin , rst_pin , busy_pin
4198 )
4299
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"""
55100 stride = width
56101 if stride % 8 != 0 :
57102 stride += 8 - stride % 8
58103
59104 self ._buffer1_size = int (stride * height / 8 )
60105 self ._buffer2_size = self ._buffer1_size
61106
62- if self . sramcs_pin :
107+ if sramcs_pin :
63108 self ._buffer1 = self .sram .get_view (0 )
64109 self ._buffer2 = self .sram .get_view (self ._buffer1_size )
65110 else :
66111 self ._buffer1 = bytearray (self ._buffer1_size )
67112 self ._buffer2 = bytearray (self ._buffer2_size )
68113
69114 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 ,
71120 )
72121 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 ,
74127 )
75128 self .set_black_buffer (0 , True )
76129 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 ()
77137
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 :
82143 time .sleep (0.01 )
83144 else :
84145 time .sleep (0.5 )
85146
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 """
88149 self .hardware_reset ()
89150 self .busy_wait ()
90151 self .command (_SSD1680_SW_RESET )
91152 self .busy_wait ()
92-
153+ # driver output control
93154 self .command (
94155 _SSD1680_DRIVER_CONTROL ,
95156 bytearray ([self ._height - 1 , (self ._height - 1 ) >> 8 , 0x00 ]),
96157 )
158+ # data entry mode
97159 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
98167 self .command (_SSD1680_SET_RAMXPOS , bytearray ([0x01 , 0x10 ]))
168+ # Set ram Y start/end postion
99169 self .command (
100170 _SSD1680_SET_RAMYPOS ,
101171 bytearray ([0 , 0 , self ._height - 1 , (self ._height - 1 ) >> 8 ]),
102172 )
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
103194
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."""
106199 if index == 0 :
107200 return self .command (_SSD1680_WRITE_BWRAM , end = False )
108201 if index == 1 :
109202 return self .command (_SSD1680_WRITE_REDRAM , end = False )
110-
111- # Raise an error if the index is not 0 or 1
112203 raise RuntimeError ("RAM index must be 0 or 1" )
113204
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
116211 self .command (_SSD1680_SET_RAMXCOUNT , bytearray ([x + 1 ]))
212+ # Set RAM Y address counter
117213 self .command (_SSD1680_SET_RAMYCOUNT , bytearray ([y , y >> 8 ]))
118214
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-
132215
133216class Adafruit_SSD1680Z (Adafruit_SSD1680 ):
134217 """Driver for SSD1680Z ePaper display, overriding SSD1680 settings."""
@@ -148,6 +231,7 @@ def __init__(
148231 rst_pin = rst_pin ,
149232 busy_pin = busy_pin ,
150233 )
234+ self .busy_pin = busy_pin # Ensure busy_pin is set
151235
152236 # pylint: enable=too-many-arguments, useless-parent-delegation
153237
0 commit comments