st7735.py
  1  # The MIT License (MIT)
  2  #
  3  # Copyright (c) 2017 Radomir Dopieralski and Adafruit Industries
  4  #
  5  # Permission is hereby granted, free of charge, to any person obtaining a copy
  6  # of this software and associated documentation files (the "Software"), to deal
  7  # in the Software without restriction, including without limitation the rights
  8  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9  # copies of the Software, and to permit persons to whom the Software is
 10  # furnished to do so, subject to the following conditions:
 11  #
 12  # The above copyright notice and this permission notice shall be included in
 13  # all copies or substantial portions of the Software.
 14  #
 15  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 21  # THE SOFTWARE.
 22  """
 23  `adafruit_rgb_display.st7735`
 24  ====================================================
 25  
 26  A simple driver for the ST7735-based displays.
 27  
 28  * Author(s): Radomir Dopieralski, Michael McWethy
 29  """
 30  
 31  try:
 32      import struct
 33  except ImportError:
 34      import ustruct as struct
 35  from micropython import const
 36  from adafruit_rgb_display.rgb import DisplaySPI
 37  
 38  __version__ = "0.0.0-auto.0"
 39  __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display.git"
 40  
 41  _NOP = const(0x00)
 42  _SWRESET = const(0x01)
 43  _RDDID = const(0x04)
 44  _RDDST = const(0x09)
 45  
 46  _SLPIN = const(0x10)
 47  _SLPOUT = const(0x11)
 48  _PTLON = const(0x12)
 49  _NORON = const(0x13)
 50  
 51  _INVOFF = const(0x20)
 52  _INVON = const(0x21)
 53  _DISPOFF = const(0x28)
 54  _DISPON = const(0x29)
 55  _CASET = const(0x2A)
 56  _RASET = const(0x2B)
 57  _RAMWR = const(0x2C)
 58  _RAMRD = const(0x2E)
 59  
 60  _PTLAR = const(0x30)
 61  _COLMOD = const(0x3A)
 62  _MADCTL = const(0x36)
 63  
 64  _FRMCTR1 = const(0xB1)
 65  _FRMCTR2 = const(0xB2)
 66  _FRMCTR3 = const(0xB3)
 67  _INVCTR = const(0xB4)
 68  _DISSET5 = const(0xB6)
 69  
 70  _PWCTR1 = const(0xC0)
 71  _PWCTR2 = const(0xC1)
 72  _PWCTR3 = const(0xC2)
 73  _PWCTR4 = const(0xC3)
 74  _PWCTR5 = const(0xC4)
 75  _VMCTR1 = const(0xC5)
 76  
 77  _RDID1 = const(0xDA)
 78  _RDID2 = const(0xDB)
 79  _RDID3 = const(0xDC)
 80  _RDID4 = const(0xDD)
 81  
 82  _PWCTR6 = const(0xFC)
 83  
 84  _GMCTRP1 = const(0xE0)
 85  _GMCTRN1 = const(0xE1)
 86  
 87  
 88  class ST7735(DisplaySPI):
 89      """
 90      A simple driver for the ST7735-based displays.
 91  
 92      >>> import busio
 93      >>> import digitalio
 94      >>> import board
 95      >>> from adafruit_rgb_display import color565
 96      >>> import adafruit_rgb_display.st7735 as st7735
 97      >>> spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)
 98      >>> display = st7735.ST7735(spi, cs=digitalio.DigitalInOut(board.GPIO0),
 99      ...    dc=digitalio.DigitalInOut(board.GPIO15), rst=digitalio.DigitalInOut(board.GPIO16))
100      >>> display.fill(0x7521)
101      >>> display.pixel(64, 64, 0)
102      """
103  
104      _COLUMN_SET = _CASET
105      _PAGE_SET = _RASET
106      _RAM_WRITE = _RAMWR
107      _RAM_READ = _RAMRD
108      _INIT = (
109          (_SWRESET, None),
110          (_SLPOUT, None),
111          (_COLMOD, b"\x05"),  # 16bit color
112          # fastest refresh, 6 lines front porch, 3 line back porch
113          (_FRMCTR1, b"\x00\x06\x03"),
114          (_MADCTL, b"\x08"),  # bottom to top refresh
115          # 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie,
116          # fix on VTL
117          (_DISSET5, b"\x15\x02"),
118          (_INVCTR, b"0x00"),  # line inversion
119          (_PWCTR1, b"\x02\x70"),  # GVDD = 4.7V, 1.0uA
120          (_PWCTR2, b"\x05"),  # VGH=14.7V, VGL=-7.35V
121          (_PWCTR3, b"\x01\x02"),  # Opamp current small, Boost frequency
122          (_VMCTR1, b"\x3c\x38"),  # VCOMH = 4V, VOML = -1.1V
123          (_PWCTR6, b"\x11\x15"),
124          (
125              _GMCTRP1,
126              b"\x09\x16\x09\x20\x21\x1b\x13\x19" b"\x17\x15\x1e\x2b\x04\x05\x02\x0e",
127          ),  # Gamma
128          (
129              _GMCTRN1,
130              b"\x08\x14\x08\x1e\x22\x1d\x18\x1e" b"\x18\x1a\x24\x2b\x06\x06\x02\x0f",
131          ),
132          (_CASET, b"\x00\x02\x00\x81"),  # XSTART = 2, XEND = 129
133          (_RASET, b"\x00\x02\x00\x81"),  # XSTART = 2, XEND = 129
134          (_NORON, None),
135          (_DISPON, None),
136      )
137      _ENCODE_PIXEL = ">H"
138      _ENCODE_POS = ">HH"
139  
140      # pylint: disable-msg=useless-super-delegation, too-many-arguments
141      def __init__(
142          self,
143          spi,
144          dc,
145          cs,
146          rst=None,
147          width=128,
148          height=128,
149          baudrate=16000000,
150          polarity=0,
151          phase=0,
152          *,
153          x_offset=0,
154          y_offset=0,
155          rotation=0
156      ):
157          super().__init__(
158              spi,
159              dc,
160              cs,
161              rst,
162              width,
163              height,
164              baudrate=baudrate,
165              polarity=polarity,
166              phase=phase,
167              x_offset=x_offset,
168              y_offset=y_offset,
169              rotation=rotation,
170          )
171  
172  
173  class ST7735R(ST7735):
174      """A simple driver for the ST7735R-based displays."""
175  
176      _INIT = (
177          (_SWRESET, None),
178          (_SLPOUT, None),
179          (_MADCTL, b"\xc8"),
180          (_COLMOD, b"\x05"),  # 16bit color
181          (_INVCTR, b"\x07"),
182          (_FRMCTR1, b"\x01\x2c\x2d"),
183          (_FRMCTR2, b"\x01\x2c\x2d"),
184          (_FRMCTR3, b"\x01\x2c\x2d\x01\x2c\x2d"),
185          (_PWCTR1, b"\x02\x02\x84"),
186          (_PWCTR2, b"\xc5"),
187          (_PWCTR3, b"\x0a\x00"),
188          (_PWCTR4, b"\x8a\x2a"),
189          (_PWCTR5, b"\x8a\xee"),
190          (_VMCTR1, b"\x0e"),
191          (_INVOFF, None),
192          (
193              _GMCTRP1,
194              b"\x02\x1c\x07\x12\x37\x32\x29\x2d" b"\x29\x25\x2B\x39\x00\x01\x03\x10",
195          ),  # Gamma
196          (
197              _GMCTRN1,
198              b"\x03\x1d\x07\x06\x2E\x2C\x29\x2D" b"\x2E\x2E\x37\x3F\x00\x00\x02\x10",
199          ),
200      )
201  
202      # pylint: disable-msg=useless-super-delegation, too-many-arguments
203      def __init__(
204          self,
205          spi,
206          dc,
207          cs,
208          rst=None,
209          width=128,
210          height=160,
211          baudrate=16000000,
212          polarity=0,
213          phase=0,
214          *,
215          x_offset=0,
216          y_offset=0,
217          rotation=0,
218          bgr=False
219      ):
220          self._bgr = bgr
221          super().__init__(
222              spi,
223              dc,
224              cs,
225              rst,
226              width,
227              height,
228              baudrate=baudrate,
229              polarity=polarity,
230              phase=phase,
231              x_offset=x_offset,
232              y_offset=y_offset,
233              rotation=rotation,
234          )
235  
236      def init(self):
237          super().init()
238          cols = struct.pack(">HH", 0, self.width - 1)
239          rows = struct.pack(">HH", 0, self.height - 1)
240  
241          for command, data in (
242              (_CASET, cols),
243              (_RASET, rows),
244              (_NORON, None),
245              (_DISPON, None),
246          ):
247              self.write(command, data)
248          if self._bgr:
249              self.write(_MADCTL, b"\xc0")
250  
251  
252  class ST7735S(ST7735):
253      """A simple driver for the ST7735S-based displays."""
254  
255      _INIT = (
256          # Frame Rate
257          (_FRMCTR1, b"\x01\x2c\x2d"),
258          (_FRMCTR2, b"\x01\x2c\x2d"),
259          (_FRMCTR3, b"\x01\x2c\x2d\x01\x2c\x2d"),
260          # Column inversion
261          (_INVCTR, b"\x07"),
262          # Power Sequence
263          (_PWCTR1, b"\xa2\x02\x84"),
264          (_PWCTR2, b"\xc5"),
265          (_PWCTR3, b"\x0a\x00"),
266          (_PWCTR4, b"\x8a\x2a"),
267          (_PWCTR5, b"\x8a\xee"),
268          # VCOM
269          (_VMCTR1, b"\x0e"),
270          # Gamma
271          (
272              _GMCTRP1,
273              b"\x0f\x1a\x0f\x18\x2f\x28\x20\x22" b"\x1f\x1b\x23\x37\x00\x07\x02\x10",
274          ),
275          (
276              _GMCTRN1,
277              b"\x0f\x1b\x0f\x17\x33\x2c\x29\x2e" b"\x30\x30\x39\x3f\x00\x07\x03\x10",
278          ),
279          # 65k mode
280          (_COLMOD, b"\x05"),
281          # set scan direction: up to down, right to left
282          (_MADCTL, b"\x60"),
283          (_SLPOUT, None),
284          (_DISPON, None),
285      )
286  
287      # pylint: disable-msg=useless-super-delegation, too-many-arguments
288      def __init__(
289          self,
290          spi,
291          dc,
292          cs,
293          bl,
294          rst=None,
295          width=128,
296          height=160,
297          baudrate=16000000,
298          polarity=0,
299          phase=0,
300          *,
301          x_offset=2,
302          y_offset=1,
303          rotation=0
304      ):
305          self._bl = bl
306          # Turn on backlight
307          self._bl.switch_to_output(value=1)
308          super().__init__(
309              spi,
310              dc,
311              cs,
312              rst,
313              width,
314              height,
315              baudrate=baudrate,
316              polarity=polarity,
317              phase=phase,
318              x_offset=x_offset,
319              y_offset=y_offset,
320              rotation=rotation,
321          )