]> vault307.fbx.one Git - PicoTamachibi.git/blob - ssd1306.py
Nett hier aber waren Sie schon mal in Hamburg?
[PicoTamachibi.git] / ssd1306.py
1 # MicroPython SSD1306 OLED driver, I2C and SPI interfaces
2
3 from micropython import const
4 import framebuf
5
6
7 # register definitions
8 SET_CONTRAST = const(0x81)
9 SET_ENTIRE_ON = const(0xA4)
10 SET_NORM_INV = const(0xA6)
11 SET_DISP = const(0xAE)
12 SET_MEM_ADDR = const(0x20)
13 SET_COL_ADDR = const(0x21)
14 SET_PAGE_ADDR = const(0x22)
15 SET_DISP_START_LINE = const(0x40)
16 SET_SEG_REMAP = const(0xA0)
17 SET_MUX_RATIO = const(0xA8)
18 SET_COM_OUT_DIR = const(0xC0)
19 SET_DISP_OFFSET = const(0xD3)
20 SET_COM_PIN_CFG = const(0xDA)
21 SET_DISP_CLK_DIV = const(0xD5)
22 SET_PRECHARGE = const(0xD9)
23 SET_VCOM_DESEL = const(0xDB)
24 SET_CHARGE_PUMP = const(0x8D)
25
26 # Subclassing FrameBuffer provides support for graphics primitives
27 # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
28 class SSD1306(framebuf.FrameBuffer):
29 def __init__(self, width, height, external_vcc):
30 self.width = width
31 self.height = height
32 self.external_vcc = external_vcc
33 self.pages = self.height // 8
34 self.buffer = bytearray(self.pages * self.width)
35 super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
36 self.init_display()
37
38 def init_display(self):
39 for cmd in (
40 SET_DISP | 0x00, # off
41 # address setting
42 SET_MEM_ADDR,
43 0x00, # horizontal
44 # resolution and layout
45 SET_DISP_START_LINE | 0x00,
46 SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
47 SET_MUX_RATIO,
48 self.height - 1,
49 SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
50 SET_DISP_OFFSET,
51 0x00,
52 SET_COM_PIN_CFG,
53 0x02 if self.width > 2 * self.height else 0x12,
54 # timing and driving scheme
55 SET_DISP_CLK_DIV,
56 0x80,
57 SET_PRECHARGE,
58 0x22 if self.external_vcc else 0xF1,
59 SET_VCOM_DESEL,
60 0x30, # 0.83*Vcc
61 # display
62 SET_CONTRAST,
63 0xFF, # maximum
64 SET_ENTIRE_ON, # output follows RAM contents
65 SET_NORM_INV, # not inverted
66 # charge pump
67 SET_CHARGE_PUMP,
68 0x10 if self.external_vcc else 0x14,
69 SET_DISP | 0x01,
70 ): # on
71 self.write_cmd(cmd)
72 self.fill(0)
73 self.show()
74
75 def poweroff(self):
76 self.write_cmd(SET_DISP | 0x00)
77
78 def poweron(self):
79 self.write_cmd(SET_DISP | 0x01)
80
81 def contrast(self, contrast):
82 self.write_cmd(SET_CONTRAST)
83 self.write_cmd(contrast)
84
85 def invert(self, invert):
86 self.write_cmd(SET_NORM_INV | (invert & 1))
87
88 def show(self):
89 x0 = 0
90 x1 = self.width - 1
91 if self.width == 64:
92 # displays with width of 64 pixels are shifted by 32
93 x0 += 32
94 x1 += 32
95 self.write_cmd(SET_COL_ADDR)
96 self.write_cmd(x0)
97 self.write_cmd(x1)
98 self.write_cmd(SET_PAGE_ADDR)
99 self.write_cmd(0)
100 self.write_cmd(self.pages - 1)
101 self.write_data(self.buffer)
102
103
104 class SSD1306_I2C(SSD1306):
105 def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
106 self.i2c = i2c
107 self.addr = addr
108 self.temp = bytearray(2)
109 self.write_list = [b"\x40", None] # Co=0, D/C#=1
110 super().__init__(width, height, external_vcc)
111
112 def write_cmd(self, cmd):
113 self.temp[0] = 0x80 # Co=1, D/C#=0
114 self.temp[1] = cmd
115 self.i2c.writeto(self.addr, self.temp)
116
117 def write_data(self, buf):
118 self.write_list[1] = buf
119 self.i2c.writevto(self.addr, self.write_list)
120
121
122 class SSD1306_SPI(SSD1306):
123 def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
124 self.rate = 10 * 1024 * 1024
125 dc.init(dc.OUT, value=0)
126 res.init(res.OUT, value=0)
127 cs.init(cs.OUT, value=1)
128 self.spi = spi
129 self.dc = dc
130 self.res = res
131 self.cs = cs
132 import time
133
134 self.res(1)
135 time.sleep_ms(1)
136 self.res(0)
137 time.sleep_ms(10)
138 self.res(1)
139 super().__init__(width, height, external_vcc)
140
141 def write_cmd(self, cmd):
142 self.spi.init(baudrate=self.rate, polarity=0, phase=0)
143 self.cs(1)
144 self.dc(0)
145 self.cs(0)
146 self.spi.write(bytearray([cmd]))
147 self.cs(1)
148
149 def write_data(self, buf):
150 self.spi.init(baudrate=self.rate, polarity=0, phase=0)
151 self.cs(1)
152 self.dc(1)
153 self.cs(0)
154 self.spi.write(buf)
155 self.cs(1)