ST7735.py.orig 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. # Copyright (c) 2014 Adafruit Industries
  2. # Author: Tony DiCola
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining a copy
  5. # of this software and associated documentation files (the "Software"), to deal
  6. # in the Software without restriction, including without limitation the rights
  7. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. # copies of the Software, and to permit persons to whom the Software is
  9. # furnished to do so, subject to the following conditions:
  10. #
  11. # The above copyright notice and this permission notice shall be included in
  12. # all copies or substantial portions of the Software.
  13. #
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. # THE SOFTWARE.
  21. import numbers
  22. import time
  23. import numpy as np
  24. from PIL import Image
  25. from PIL import ImageDraw
  26. import Adafruit_GPIO as GPIO
  27. import Adafruit_GPIO.SPI as SPI
  28. # SPI_CLOCK_HZ = 64000000 # 64 MHz
  29. SPI_CLOCK_HZ = 4000000 # 4 MHz
  30. # Constants for interacting with display registers.
  31. ST7735_TFTWIDTH = 128
  32. ST7735_TFTHEIGHT = 160
  33. ST7735_NOP = 0x00
  34. ST7735_SWRESET = 0x01
  35. ST7735_RDDID = 0x04
  36. ST7735_RDDST = 0x09
  37. ST7735_SLPIN = 0x10
  38. ST7735_SLPOUT = 0x11
  39. ST7735_PTLON = 0x12
  40. ST7735_NORON = 0x13
  41. # ILI9341_RDMODE = 0x0A
  42. # ILI9341_RDMADCTL = 0x0B
  43. # ILI9341_RDPIXFMT = 0x0C
  44. # ILI9341_RDIMGFMT = 0x0A
  45. # ILI9341_RDSELFDIAG = 0x0F
  46. ST7735_INVOFF = 0x20
  47. ST7735_INVON = 0x21
  48. # ILI9341_GAMMASET = 0x26
  49. ST7735_DISPOFF = 0x28
  50. ST7735_DISPON = 0x29
  51. ST7735_CASET = 0x2A
  52. ST7735_RASET = 0x2B
  53. ST7735_RAMWR = 0x2C
  54. ST7735_RAMRD = 0x2E
  55. ST7735_PTLAR = 0x30
  56. ST7735_MADCTL = 0x36
  57. # ST7735_PIXFMT = 0x3A
  58. ST7735_COLMOD = 0x3A
  59. ST7735_FRMCTR1 = 0xB1
  60. ST7735_FRMCTR2 = 0xB2
  61. ST7735_FRMCTR3 = 0xB3
  62. ST7735_INVCTR = 0xB4
  63. # ILI9341_DFUNCTR = 0xB6
  64. ST7735_DISSET5 = 0xB6
  65. ST7735_PWCTR1 = 0xC0
  66. ST7735_PWCTR2 = 0xC1
  67. ST7735_PWCTR3 = 0xC2
  68. ST7735_PWCTR4 = 0xC3
  69. ST7735_PWCTR5 = 0xC4
  70. ST7735_VMCTR1 = 0xC5
  71. # ILI9341_VMCTR2 = 0xC7
  72. ST7735_RDID1 = 0xDA
  73. ST7735_RDID2 = 0xDB
  74. ST7735_RDID3 = 0xDC
  75. ST7735_RDID4 = 0xDD
  76. ST7735_GMCTRP1 = 0xE0
  77. ST7735_GMCTRN1 = 0xE1
  78. ST7735_PWCTR6 = 0xFC
  79. # Colours for convenience
  80. ST7735_BLACK = 0x0000 # 0b 00000 000000 00000
  81. ST7735_BLUE = 0x001F # 0b 00000 000000 11111
  82. ST7735_GREEN = 0x07E0 # 0b 00000 111111 00000
  83. ST7735_RED = 0xF800 # 0b 11111 000000 00000
  84. ST7735_CYAN = 0x07FF # 0b 00000 111111 11111
  85. ST7735_MAGENTA = 0xF81F # 0b 11111 000000 11111
  86. ST7735_YELLOW = 0xFFE0 # 0b 11111 111111 00000
  87. ST7735_WHITE = 0xFFFF # 0b 11111 111111 11111
  88. def color565(r, g, b):
  89. """Convert red, green, blue components to a 16-bit 565 RGB value. Components
  90. should be values 0 to 255.
  91. """
  92. return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
  93. def image_to_data(image):
  94. """Generator function to convert a PIL image to 16-bit 565 RGB bytes."""
  95. # NumPy is much faster at doing this. NumPy code provided by:
  96. # Keith (https://www.blogger.com/profile/02555547344016007163)
  97. pb = np.array(image.convert('RGB')).astype('uint16')
  98. # color = ((pb[:,:,0] & 0xF8) << 8) | ((pb[:,:,1] & 0xFC) << 3) | (pb[:,:,2] >> 3)
  99. color = ((pb[:,:,2] & 0xF8) << 8) | ((pb[:,:,1] & 0xFC) << 3) | (pb[:,:,0] >> 3)
  100. return np.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()
  101. class ST7735(object):
  102. """Representation of an ST7735 TFT LCD."""
  103. def __init__(self, dc, spi, rst=None, gpio=None, width=ST7735_TFTWIDTH,
  104. height=ST7735_TFTHEIGHT):
  105. """Create an instance of the display using SPI communication. Must
  106. provide the GPIO pin number for the D/C pin and the SPI driver. Can
  107. optionally provide the GPIO pin number for the reset pin as the rst
  108. parameter.
  109. """
  110. self._dc = dc
  111. self._rst = rst
  112. self._spi = spi
  113. self._gpio = gpio
  114. self.width = width
  115. self.height = height
  116. if self._gpio is None:
  117. self._gpio = GPIO.get_platform_gpio()
  118. # Set DC as output.
  119. self._gpio.setup(dc, GPIO.OUT)
  120. # Setup reset as output (if provided).
  121. if rst is not None:
  122. self._gpio.setup(rst, GPIO.OUT)
  123. # Set SPI to mode 0, MSB first.
  124. spi.set_mode(0)
  125. spi.set_bit_order(SPI.MSBFIRST)
  126. spi.set_clock_hz(SPI_CLOCK_HZ)
  127. # Create an image buffer.
  128. self.buffer = Image.new('RGB', (width, height))
  129. def send(self, data, is_data=True, chunk_size=4096):
  130. """Write a byte or array of bytes to the display. Is_data parameter
  131. controls if byte should be interpreted as display data (True) or command
  132. data (False). Chunk_size is an optional size of bytes to write in a
  133. single SPI transaction, with a default of 4096.
  134. """
  135. # Set DC low for command, high for data.
  136. self._gpio.output(self._dc, is_data)
  137. # Convert scalar argument to list so either can be passed as parameter.
  138. if isinstance(data, numbers.Number):
  139. data = [data & 0xFF]
  140. # Write data a chunk at a time.
  141. for start in range(0, len(data), chunk_size):
  142. end = min(start+chunk_size, len(data))
  143. self._spi.write(data[start:end])
  144. def command(self, data):
  145. """Write a byte or array of bytes to the display as command data."""
  146. self.send(data, False)
  147. def data(self, data):
  148. """Write a byte or array of bytes to the display as display data."""
  149. self.send(data, True)
  150. def reset(self):
  151. """Reset the display, if reset pin is connected."""
  152. if self._rst is not None:
  153. self._gpio.set_high(self._rst)
  154. time.sleep(0.500)
  155. self._gpio.set_low(self._rst)
  156. time.sleep(0.500)
  157. self._gpio.set_high(self._rst)
  158. time.sleep(0.500)
  159. def _init(self):
  160. # Initialize the display. Broken out as a separate function so it can
  161. # be overridden by other displays in the future.
  162. self.command(ST7735_SWRESET) # Software reset
  163. time.sleep(0.150) # delay 150 ms
  164. self.command(ST7735_SLPOUT) # Out of sleep mode
  165. time.sleep(0.500) # delay 500 ms
  166. self.command(ST7735_FRMCTR1) # Frame rate ctrl - normal mode
  167. self.data(0x01) # Rate = fosc/(1x2+40) * (LINE+2C+2D)
  168. self.data(0x2C)
  169. self.data(0x2D)
  170. self.command(ST7735_FRMCTR2) # Frame rate ctrl - idle mode
  171. self.data(0x01) # Rate = fosc/(1x2+40) * (LINE+2C+2D)
  172. self.data(0x2C)
  173. self.data(0x2D)
  174. self.command(ST7735_FRMCTR3) # Frame rate ctrl - partial mode
  175. self.data(0x01) # Dot inversion mode
  176. self.data(0x2C)
  177. self.data(0x2D)
  178. self.data(0x01) # Line inversion mode
  179. self.data(0x2C)
  180. self.data(0x2D)
  181. self.command(ST7735_INVCTR) # Display inversion ctrl
  182. self.data(0x07) # No inversion
  183. self.command(ST7735_PWCTR1) # Power control
  184. self.data(0xA2)
  185. self.data(0x02) # -4.6V
  186. self.data(0x84) # auto mode
  187. self.command(ST7735_PWCTR2) # Power control
  188. self.data(0x0A) # Opamp current small
  189. self.data(0x00) # Boost frequency
  190. self.command(ST7735_PWCTR4) # Power control
  191. self.data(0x8A) # BCLK/2, Opamp current small & Medium low
  192. self.data(0x2A)
  193. self.command(ST7735_PWCTR5) # Power control
  194. self.data(0x8A)
  195. self.data(0xEE)
  196. self.command(ST7735_VMCTR1) # Power control
  197. self.data(0x0E)
  198. self.command(ST7735_INVOFF) # Don't invert display
  199. self.command(ST7735_MADCTL) # Memory access control (directions)
  200. self.data(0xC8) # row addr/col addr, bottom to top refresh
  201. self.command(ST7735_COLMOD) # set color mode
  202. self.data(0x05) # 16-bit color
  203. #
  204. self.command(ST7735_CASET) # Column addr set
  205. self.data(0x00) # XSTART = 0
  206. self.data(0x00)
  207. self.data(0x00) # XEND = 127
  208. self.data(0x7F)
  209. self.command(ST7735_RASET) # Row addr set
  210. self.data(0x00) # XSTART = 0
  211. self.data(0x00)
  212. self.data(0x00) # XEND = 159
  213. self.data(0x9F)
  214. #
  215. self.command(ST7735_GMCTRP1) # Set Gamma
  216. self.data(0x02)
  217. self.data(0x1c)
  218. self.data(0x07)
  219. self.data(0x12)
  220. self.data(0x37)
  221. self.data(0x32)
  222. self.data(0x29)
  223. self.data(0x2d)
  224. self.data(0x29)
  225. self.data(0x25)
  226. self.data(0x2B)
  227. self.data(0x39)
  228. self.data(0x00)
  229. self.data(0x01)
  230. self.data(0x03)
  231. self.data(0x10)
  232. self.command(ST7735_GMCTRN1) # Set Gamma
  233. self.data(0x03)
  234. self.data(0x1d)
  235. self.data(0x07)
  236. self.data(0x06)
  237. self.data(0x2E)
  238. self.data(0x2C)
  239. self.data(0x29)
  240. self.data(0x2D)
  241. self.data(0x2E)
  242. self.data(0x2E)
  243. self.data(0x37)
  244. self.data(0x3F)
  245. self.data(0x00)
  246. self.data(0x00)
  247. self.data(0x02)
  248. self.data(0x10)
  249. self.command(ST7735_NORON) # Normal display on
  250. time.sleep(0.10) # 10 ms
  251. self.command(ST7735_DISPON) # Display on
  252. time.sleep(0.100) # 100 ms
  253. def begin(self):
  254. """Initialize the display. Should be called once before other calls that
  255. interact with the display are called.
  256. """
  257. self.reset()
  258. self._init()
  259. def set_window(self, x0=0, y0=0, x1=None, y1=None):
  260. """Set the pixel address window for proceeding drawing commands. x0 and
  261. x1 should define the minimum and maximum x pixel bounds. y0 and y1
  262. should define the minimum and maximum y pixel bound. If no parameters
  263. are specified the default will be to update the entire display from 0,0
  264. to width-1,height-1.
  265. """
  266. if x1 is None:
  267. x1 = self.width-1
  268. if y1 is None:
  269. y1 = self.height-1
  270. self.command(ST7735_CASET) # Column addr set
  271. self.data(x0 >> 8)
  272. self.data(x0) # XSTART
  273. self.data(x1 >> 8)
  274. self.data(x1) # XEND
  275. self.command(ST7735_RASET) # Row addr set
  276. self.data(y0 >> 8)
  277. self.data(y0) # YSTART
  278. self.data(y1 >> 8)
  279. self.data(y1) # YEND
  280. self.command(ST7735_RAMWR) # write to RAM
  281. def display(self, image=None):
  282. """Write the display buffer or provided image to the hardware. If no
  283. image parameter is provided the display buffer will be written to the
  284. hardware. If an image is provided, it should be RGB format and the
  285. same dimensions as the display hardware.
  286. """
  287. # By default write the internal buffer to the display.
  288. if image is None:
  289. image = self.buffer
  290. # Set address bounds to entire display.
  291. self.set_window()
  292. # Convert image to array of 16bit 565 RGB data bytes.
  293. # Unfortunate that this copy has to occur, but the SPI byte writing
  294. # function needs to take an array of bytes and PIL doesn't natively
  295. # store images in 16-bit 565 RGB format.
  296. pixelbytes = list(image_to_data(image))
  297. # Write data to hardware.
  298. self.data(pixelbytes)
  299. def clear(self, color=(0,0,0)):
  300. """Clear the image buffer to the specified RGB color (default black)."""
  301. width, height = self.buffer.size
  302. self.buffer.putdata([color]*(width*height))
  303. def draw(self):
  304. """Return a PIL ImageDraw instance for 2D drawing on the image buffer."""
  305. return ImageDraw.Draw(self.buffer)