11
11
12
12
import time
13
13
from micropython import const
14
- from digitalio import Direction
14
+ from digitalio import Direction , DigitalInOut
15
15
from adafruit_epd import mcp_sram
16
16
17
+ try :
18
+ """Needed for type annotations"""
19
+ from typing import Any , Union , Callable
20
+ from busio import SPI
21
+ from PIL .Image import Image
22
+ except ImportError :
23
+ pass
24
+
17
25
__version__ = "0.0.0+auto.0"
18
26
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EPD.git"
19
27
@@ -29,8 +37,16 @@ class Adafruit_EPD: # pylint: disable=too-many-instance-attributes, too-many-pu
29
37
LIGHT = const (5 )
30
38
31
39
def __init__ (
32
- self , width , height , spi , cs_pin , dc_pin , sramcs_pin , rst_pin , busy_pin
33
- ): # pylint: disable=too-many-arguments
40
+ self ,
41
+ width : int ,
42
+ height : int ,
43
+ spi : SPI ,
44
+ cs_pin : DigitalInOut ,
45
+ dc_pin : DigitalInOut ,
46
+ sramcs_pin : DigitalInOut ,
47
+ rst_pin : DigitalInOut ,
48
+ busy_pin : DigitalInOut ,
49
+ ) -> None : # pylint: disable=too-many-arguments
34
50
self ._width = width
35
51
self ._height = height
36
52
@@ -76,7 +92,7 @@ def __init__(
76
92
self ._black_inverted = self ._color_inverted = True
77
93
self .hardware_reset ()
78
94
79
- def display (self ): # pylint: disable=too-many-branches
95
+ def display (self ) -> None : # pylint: disable=too-many-branches
80
96
"""show the contents of the display buffer"""
81
97
self .power_up ()
82
98
@@ -149,15 +165,15 @@ def display(self): # pylint: disable=too-many-branches
149
165
150
166
self .update ()
151
167
152
- def hardware_reset (self ):
168
+ def hardware_reset (self ) -> None :
153
169
"""If we have a reset pin, do a hardware reset by toggling it"""
154
170
if self ._rst :
155
171
self ._rst .value = False
156
172
time .sleep (0.1 )
157
173
self ._rst .value = True
158
174
time .sleep (0.1 )
159
175
160
- def command (self , cmd , data = None , end = True ):
176
+ def command (self , cmd : Any , data : Any = None , end : bool = True ) -> Any :
161
177
"""Send command byte to display."""
162
178
self ._cs .value = True
163
179
self ._dc .value = False
@@ -176,7 +192,7 @@ def command(self, cmd, data=None, end=True):
176
192
177
193
return ret
178
194
179
- def _spi_transfer (self , data ) :
195
+ def _spi_transfer (self , data : Any ) -> Any :
180
196
"""Transfer one byte or bytearray, toggling the cs pin if required by the EPD chipset"""
181
197
if isinstance (data , int ): # single byte!
182
198
self ._spibuf [0 ] = data
@@ -203,30 +219,30 @@ def _spi_transfer(self, data):
203
219
self ._spi_transfer (x )
204
220
return None
205
221
206
- def power_up (self ):
222
+ def power_up (self ) -> None :
207
223
"""Power up the display in preparation for writing RAM and updating.
208
224
must be implemented in subclass"""
209
225
raise NotImplementedError ()
210
226
211
- def power_down (self ):
227
+ def power_down (self ) -> None :
212
228
"""Power down the display, must be implemented in subclass"""
213
229
raise NotImplementedError ()
214
230
215
- def update (self ):
231
+ def update (self ) -> None :
216
232
"""Update the display from internal memory, must be implemented in subclass"""
217
233
raise NotImplementedError ()
218
234
219
- def write_ram (self , index ) :
235
+ def write_ram (self , index : int ) -> None :
220
236
"""Send the one byte command for starting the RAM write process. Returns
221
237
the byte read at the same time over SPI. index is the RAM buffer, can be
222
238
0 or 1 for tri-color displays. must be implemented in subclass"""
223
239
raise NotImplementedError ()
224
240
225
- def set_ram_address (self , x , y ) :
241
+ def set_ram_address (self , x : int , y : int ) -> None :
226
242
"""Set the RAM address location, must be implemented in subclass"""
227
243
raise NotImplementedError ()
228
244
229
- def set_black_buffer (self , index , inverted ) :
245
+ def set_black_buffer (self , index : Union [ 0 , 1 ], inverted : bool ) -> None :
230
246
"""Set the index for the black buffer data (0 or 1) and whether its inverted"""
231
247
if index == 0 :
232
248
self ._blackframebuf = self ._framebuf1
@@ -236,7 +252,7 @@ def set_black_buffer(self, index, inverted):
236
252
raise RuntimeError ("Buffer index must be 0 or 1" )
237
253
self ._black_inverted = inverted
238
254
239
- def set_color_buffer (self , index , inverted ) :
255
+ def set_color_buffer (self , index : Union [ 0 , 1 ], inverted : bool ) -> None :
240
256
"""Set the index for the color buffer data (0 or 1) and whether its inverted"""
241
257
if index == 0 :
242
258
self ._colorframebuf = self ._framebuf1
@@ -246,7 +262,12 @@ def set_color_buffer(self, index, inverted):
246
262
raise RuntimeError ("Buffer index must be 0 or 1" )
247
263
self ._color_inverted = inverted
248
264
249
- def _color_dup (self , func , args , color ):
265
+ def _color_dup (
266
+ self ,
267
+ func : Callable ,
268
+ args : Any ,
269
+ color : Union [0 , 1 , 2 , 3 , 4 , 5 ],
270
+ ) -> None :
250
271
black = getattr (self ._blackframebuf , func )
251
272
red = getattr (self ._colorframebuf , func )
252
273
if self ._blackframebuf is self ._colorframebuf : # monochrome
@@ -255,11 +276,11 @@ def _color_dup(self, func, args, color):
255
276
black (* args , color = (color == Adafruit_EPD .BLACK ) != self ._black_inverted )
256
277
red (* args , color = (color == Adafruit_EPD .RED ) != self ._color_inverted )
257
278
258
- def pixel (self , x , y , color ) :
279
+ def pixel (self , x : int , y : int , color : int ) -> None :
259
280
"""draw a single pixel in the display buffer"""
260
281
self ._color_dup ("pixel" , (x , y ), color )
261
282
262
- def fill (self , color ) :
283
+ def fill (self , color : int ) -> None :
263
284
"""fill the screen with the passed color"""
264
285
red_fill = ((color == Adafruit_EPD .RED ) != self ._color_inverted ) * 0xFF
265
286
black_fill = ((color == Adafruit_EPD .BLACK ) != self ._black_inverted ) * 0xFF
@@ -271,21 +292,34 @@ def fill(self, color):
271
292
self ._blackframebuf .fill (black_fill )
272
293
self ._colorframebuf .fill (red_fill )
273
294
274
- def rect (self , x , y , width , height , color ): # pylint: disable=too-many-arguments
295
+ def rect (
296
+ self , x : int , y : int , width : int , height : int , color : int
297
+ ) -> None : # pylint: disable=too-many-arguments
275
298
"""draw a rectangle"""
276
299
self ._color_dup ("rect" , (x , y , width , height ), color )
277
300
278
301
def fill_rect (
279
- self , x , y , width , height , color
280
- ): # pylint: disable=too-many-arguments
302
+ self , x : int , y : int , width : int , height : int , color : int
303
+ ) -> None : # pylint: disable=too-many-arguments
281
304
"""fill a rectangle with the passed color"""
282
305
self ._color_dup ("fill_rect" , (x , y , width , height ), color )
283
306
284
- def line (self , x_0 , y_0 , x_1 , y_1 , color ): # pylint: disable=too-many-arguments
307
+ def line (
308
+ self , x_0 : int , y_0 : int , x_1 : int , y_1 : int , color : int
309
+ ) -> None : # pylint: disable=too-many-arguments
285
310
"""Draw a line from (x_0, y_0) to (x_1, y_1) in passed color"""
286
311
self ._color_dup ("line" , (x_0 , y_0 , x_1 , y_1 ), color )
287
312
288
- def text (self , string , x , y , color , * , font_name = "font5x8.bin" , size = 1 ):
313
+ def text (
314
+ self ,
315
+ string : str ,
316
+ x : int ,
317
+ y : int ,
318
+ color : int ,
319
+ * ,
320
+ font_name : str = "font5x8.bin" ,
321
+ size : int = 1
322
+ ) -> None :
289
323
"""Write text string at location (x, y) in given color, using font file"""
290
324
if self ._blackframebuf is self ._colorframebuf : # monochrome
291
325
self ._blackframebuf .text (
@@ -315,39 +349,51 @@ def text(self, string, x, y, color, *, font_name="font5x8.bin", size=1):
315
349
)
316
350
317
351
@property
318
- def width (self ):
352
+ def width (self ) -> int :
319
353
"""The width of the display, accounting for rotation"""
320
354
if self .rotation in (0 , 2 ):
321
355
return self ._width
322
356
return self ._height
323
357
324
358
@property
325
- def height (self ):
359
+ def height (self ) -> int :
326
360
"""The height of the display, accounting for rotation"""
327
361
if self .rotation in (0 , 2 ):
328
362
return self ._height
329
363
return self ._width
330
364
331
365
@property
332
- def rotation (self ):
366
+ def rotation (self ) -> Union [ 0 , 1 , 2 , 3 ] :
333
367
"""The rotation of the display, can be one of (0, 1, 2, 3)"""
334
368
return self ._framebuf1 .rotation
335
369
336
370
@rotation .setter
337
- def rotation (self , val ) :
371
+ def rotation (self , val : int ) -> None :
338
372
self ._framebuf1 .rotation = val
339
373
if self ._framebuf2 :
340
374
self ._framebuf2 .rotation = val
341
375
342
- def hline (self , x , y , width , color ):
376
+ def hline (
377
+ self ,
378
+ x : int ,
379
+ y : int ,
380
+ width : int ,
381
+ color : int ,
382
+ ) -> None :
343
383
"""draw a horizontal line"""
344
384
self .fill_rect (x , y , width , 1 , color )
345
385
346
- def vline (self , x , y , height , color ):
386
+ def vline (
387
+ self ,
388
+ x : int ,
389
+ y : int ,
390
+ height : int ,
391
+ color : int ,
392
+ ) -> None :
347
393
"""draw a vertical line"""
348
394
self .fill_rect (x , y , 1 , height , color )
349
395
350
- def image (self , image ) :
396
+ def image (self , image : Image ) -> None :
351
397
"""Set buffer to value of Python Imaging Library image. The image should
352
398
be in RGB mode and a size equal to the display size.
353
399
"""
0 commit comments