ssd1306.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /****************************************************************************
  2. * drivers/lcd/ssd1306.h
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. #ifndef __DRIVERS_LCD_SSD1306_H
  21. #define __DRIVERS_LCD_SSD1306_H
  22. /****************************************************************************
  23. * Included Files
  24. ****************************************************************************/
  25. #include <nuttx/config.h>
  26. #include <stdint.h>
  27. #include <stdbool.h>
  28. #include <nuttx/lcd/lcd.h>
  29. #include <nuttx/lcd/ssd1306.h>
  30. /****************************************************************************
  31. * Pre-processor Definitions
  32. ****************************************************************************/
  33. /* Configuration ************************************************************/
  34. /* Limitations of the current configuration that I hope to fix someday */
  35. #if !defined(CONFIG_LCD_SH1106_OLED_132) && \
  36. !defined(CONFIG_LCD_UG2864HSWEG01) && \
  37. !defined(CONFIG_LCD_UG2832HSWEG04) && \
  38. !defined(CONFIG_LCD_DD12864WO4A) && \
  39. !defined(CONFIG_LCD_HILETGO)
  40. # error "Unknown and unsupported SSD1306 LCD"
  41. #endif
  42. #if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT)
  43. # warning "No support for portrait modes"
  44. # undef CONFIG_LCD_LANDSCAPE
  45. # define CONFIG_LCD_LANDSCAPE 1
  46. # undef CONFIG_LCD_PORTRAIT
  47. # undef CONFIG_LCD_RLANDSCAPE
  48. # undef CONFIG_LCD_RPORTRAIT
  49. #endif
  50. /****************************************************************************
  51. * Pre-processor Definitions
  52. ****************************************************************************/
  53. #ifndef CONFIG_NX_BGCOLOR
  54. # define CONFIG_NX_BGCOLOR SSD1306_Y1_BLACK
  55. #endif
  56. /* SSD1306 Commands *********************************************************/
  57. #define SSD1306_SETCOLL(ad) (0x00 | ((ad) & 0x0f)) /* Set Lower Column Address: (00h - 0fh) */
  58. #define SSD1306_SETCOLH(ad) (0x10 | ((ad) & 0x0f)) /* Set Higher Column Address: (10h - 1fh) */
  59. #define SSD1306_STARTLINE(ln) (0x40 | ((ln) & 0x3f)) /* Set Display Start Line: (40h - 7fh) */
  60. #define SSD1306_CONTRAST_MODE (0x81) /* Set Contrast Control Register: (Double Bytes Command) */
  61. # define SSD1306_CONTRAST(c) (c)
  62. #define SSD1306_SEGREMAP(m) (0xa0 | ((m) & 0x01)) /* Set Segment Re-map: (a0h - a1h) */
  63. # define SSD1306_REMAPRIGHT SSD1306_SEGREMAP(0) /* Right rotation */
  64. # define SSD1306_REMAPPLEFT SSD1306_SEGREMAP(1) /* Left rotation */
  65. #define SSD1306_EDISPOFFON(s) (0xa4 | ((s) & 0x01)) /* Set Entire Display OFF/ON: (a4h - a5h) */
  66. # define SSD1306_EDISPOFF SSD1306_EDISPOFFON(0) /* Display off */
  67. # define SSD1306_EDISPON SSD1306_EDISPOFFON(1) /* Display on */
  68. #define SSD1306_NORMREV(s) (0xa6 | ((s) & 0x01)) /* Set Normal/Reverse Display: (a6h -a7h) */
  69. # define SSD1306_NORMAL SSD1306_NORMREV(0) /* Normal display */
  70. # define SSD1306_REVERSE SSD1306_NORMREV(1) /* Reverse display */
  71. #define SSD1306_MRATIO_MODE (0xa8) /* Set Multiplex Ration: (Double Bytes Command) */
  72. # define SSD1306_MRATIO(d) ((d) & 0x3f)
  73. #define SSD1306_DCDC_MODE (0xad) /* Set DC-DC OFF/ON: (Double Bytes Command) */
  74. # define SSD1306_DCDC_OFF (0x8a)
  75. # define SSD1306_DCDC_ON (0x8b)
  76. #define SSD1306_DISPOFFON(s) (0xae | ((s) & 0x01)) /* Display OFF/ON: (aeh - afh) */
  77. # define SSD1306_DISPOFF SSD1306_DISPOFFON(0) /* Display off */
  78. # define SSD1306_DISPON SSD1306_DISPOFFON(1) /* Display on */
  79. #define SSD1306_PAGEADDR(a) (0xb0 | ((a) & 0x0f)) /* Set Page Address: (b0h - b7h) */
  80. #define SSD1306_SCANDIR(d) (0xc0 | ((d) & 0x08)) /* Set Common Output Scan Direction: (c0h - c8h) */
  81. # define SSD1306_SCANFROMCOM0 SSD1306_SCANDIR(0x00) /* Scan from COM[0] to COM[n-1]*/
  82. # define SSD1306_SCANTOCOM0 SSD1306_SCANDIR(0x08) /* Scan from COM[n-1] to COM[0] */
  83. #define SSD1306_DISPOFFS_MODE (0xd3) /* Set Display Offset: (Double Bytes Command) */
  84. # define SSD1306_DISPOFFS(o) ((o) & 0x3f)
  85. #define SSD1306_CLKDIV_SET (0xd5) /* Set Display Clock Divide Ratio/Oscillator Frequency: (Double Bytes Command) */
  86. # define SSD1306_CLKDIV(f,d) ((((f) & 0x0f) << 4) | ((d) & 0x0f))
  87. #define SSD1306_CHRGPER_SET (0xd9) /* Set Dis-charge/Pre-charge Period: (Double Bytes Command) */
  88. # define SSD1306_CHRGPER(d,p) ((((d) & 0x0f) << 4) | ((p) & 0x0f))
  89. #define SSD1306_CMNPAD_CONFIG (0xda) /* Set Common pads hardware configuration: (Double Bytes Command) */
  90. # define SSD1306_CMNPAD(c) ((0x02) | ((c) & 0x10))
  91. #define SSD1306_VCOM_SET (0xdb) /* Set VCOM Deselect Level: (Double Byte Command) */
  92. # define SSD1306_VCOM(v) (v)
  93. #define SSD1306_CHRPUMP_SET (0x8d) /* Charge Pump Setting */
  94. # define SSD1306_CHRPUMP_ON (0x14)
  95. # define SSD1306_CHRPUMP_OFF (0x10)
  96. #define SSD1306_RMWSTART (0xe0) /* Read-Modify-Write: (e0h) */
  97. #define SSD1306_NOP (0xe3) /* NOP: (e3h) */
  98. #define SSD1306_END (0xee) /* End: (eeh) */
  99. #define SSD1306_WRDATA(d) (d) /* Write Display Data */
  100. #define SSD1306_STATUS_BUSY (0x80) /* Read Status */
  101. #define SSD1306_STATUS_ONOFF (0x40)
  102. #define SSD1306_RDDATA(d) (d) /* Read Display Data */
  103. #define SSD1309_PROTOFF (0xfd)
  104. #define SSD1309_SETMEMORY (0x20)
  105. # define SSD1309_MEMADDR(ma) ((ma) & 0x03)
  106. /* Color Properties *********************************************************/
  107. /* Display Resolution
  108. *
  109. * The SSD1306 display controller can handle a resolution of 132x64.
  110. * The UG-2864HSWEG01 on the base board is 128x64; the UG-2832HSWEG04
  111. * is 128x32.
  112. */
  113. #if defined(CONFIG_LCD_UG2864HSWEG01)
  114. # define SSD1306_DEV_NATIVE_XRES 128 /* Only 128 of 131 columns used */
  115. # define SSD1306_DEV_NATIVE_YRES 64 /* 8 pages each 8 rows */
  116. # define SSD1306_DEV_XOFFSET 2 /* Offset to logical column 0 */
  117. # define SSD1306_DEV_PAGES 8 /* 8 pages */
  118. # define SSD1306_DEV_CMNPAD 0x12 /* COM configuration */
  119. # undef IS_SSD1309
  120. #elif defined(CONFIG_LCD_UG2832HSWEG04)
  121. # define SSD1306_DEV_NATIVE_XRES 128 /* Only 128 of 131 columns used */
  122. # define SSD1306_DEV_NATIVE_YRES 32 /* 4 pages each 8 rows */
  123. # define SSD1306_DEV_XOFFSET 2 /* Offset to logical column 0 */
  124. # define SSD1306_DEV_PAGES 4 /* 4 pages */
  125. # define SSD1306_DEV_CMNPAD 0x02 /* COM configuration */
  126. # undef IS_SSD1309
  127. #elif defined(CONFIG_LCD_SH1106_OLED_132)
  128. # define SSD1306_DEV_NATIVE_XRES 128 /* Only 128 columns used, supporting 132 is a bit difficult */
  129. # define SSD1306_DEV_NATIVE_YRES 64 /* 8 pages each 8 rows */
  130. # define SSD1306_DEV_XOFFSET 0 /* Offset to logical column 0 */
  131. # define SSD1306_DEV_PAGES 8 /* 8 pages */
  132. # define SSD1306_DEV_CMNPAD 0x12 /* COM configuration */
  133. # undef IS_SSD1309
  134. #elif defined(CONFIG_LCD_HILETGO)
  135. # define SSD1306_DEV_NATIVE_XRES 128 /* Only 128 of 132 columns supported */
  136. # define SSD1306_DEV_NATIVE_YRES 64 /* 8 pages each 8 rows */
  137. # define SSD1306_DEV_XOFFSET 0 /* Offset to logical column 0 */
  138. # define SSD1306_DEV_PAGES 8 /* 8 pages */
  139. # define SSD1306_DEV_CMNPAD 0x12 /* COM configuration */
  140. # undef IS_SSD1309
  141. #elif defined(CONFIG_LCD_DD12864WO4A)
  142. # define SSD1306_DEV_NATIVE_XRES 128 /* 128 of 128 columns used */
  143. # define SSD1306_DEV_NATIVE_YRES 64 /* 8 pages each 8 rows */
  144. # define SSD1306_DEV_XOFFSET 0 /* Offset to logical column 0 */
  145. # define SSD1306_DEV_PAGES 8 /* 8 pages */
  146. # define SSD1306_DEV_CMNPAD 0x10 /* COM configuration */
  147. # define IS_SSD1309 1 /* SSD1309 based LCD. */
  148. #endif
  149. #if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
  150. # define SSD1306_DEV_XRES SSD1306_DEV_NATIVE_XRES
  151. # define SSD1306_DEV_YRES SSD1306_DEV_NATIVE_YRES
  152. #else
  153. # define SSD1306_DEV_XRES SSD1306_DEV_NATIVE_YRES
  154. # define SSD1306_DEV_YRES SSD1306_DEV_NATIVE_XRES
  155. #endif
  156. #define SSD1306_DEV_DUTY (SSD1306_DEV_NATIVE_YRES-1)
  157. /* Bytes per logical row and actual device row */
  158. #if defined(CONFIG_LCD_SH1106_OLED_132)
  159. # define SSD1306_DEV_XSTRIDE (SSD1306_DEV_XRES >> 3)
  160. #else
  161. # define SSD1306_DEV_XSTRIDE (SSD1306_DEV_XRES >> 3)
  162. #endif
  163. #define SSD1306_DEV_YSTRIDE (SSD1306_DEV_YRES >> 3)
  164. /* Color depth and format */
  165. #define SSD1306_DEV_BPP 1
  166. #define SSD1306_DEV_COLORFMT FB_FMT_Y1
  167. /* Default contrast */
  168. #define SSD1306_DEV_CONTRAST (128)
  169. #define SSD1309_DEV_CONTRAST (255)
  170. /* The size of the shadow frame buffer or one row buffer.
  171. *
  172. * Frame buffer size: 128 columns x 64 rows / 8 bits-per-pixel
  173. * Row size: 128 columns x 8 rows-per-page / 8 bits-per-pixel
  174. */
  175. #define SSD1306_DEV_FBSIZE (SSD1306_DEV_XSTRIDE * SSD1306_DEV_YRES)
  176. #define SSD1306_DEV_ROWSIZE (SSD1306_DEV_XSTRIDE)
  177. /* Orientation. There seem to be device differences. */
  178. #if defined(CONFIG_LCD_UG2864HSWEG01)
  179. # if defined(CONFIG_LCD_LANDSCAPE)
  180. # undef SSD1306_DEV_REVERSEX
  181. # undef SSD1306_DEV_REVERSEY
  182. # elif defined(CONFIG_LCD_RLANDSCAPE)
  183. # define SSD1306_DEV_REVERSEX 1
  184. # define SSD1306_DEV_REVERSEY 1
  185. # endif
  186. #elif defined(CONFIG_LCD_UG2832HSWEG04)
  187. # if defined(CONFIG_LCD_LANDSCAPE)
  188. # define SSD1306_DEV_REVERSEX 1
  189. # undef SSD1306_DEV_REVERSEY
  190. # elif defined(CONFIG_LCD_RLANDSCAPE)
  191. # undef SSD1306_DEV_REVERSEX
  192. # define SSD1306_DEV_REVERSEY 1
  193. # endif
  194. #elif defined(CONFIG_LCD_SH1106_OLED_132)
  195. # if defined(CONFIG_LCD_LANDSCAPE)
  196. # undef SSD1306_DEV_REVERSEX
  197. # define SSD1306_DEV_REVERSEY 1
  198. # elif defined(CONFIG_LCD_RLANDSCAPE)
  199. # define SSD1306_DEV_REVERSEX 1
  200. # undef SSD1306_DEV_REVERSEY
  201. # endif
  202. #elif defined(CONFIG_LCD_DD12864WO4A)
  203. # if defined(CONFIG_LCD_LANDSCAPE)
  204. # define SSD1306_DEV_REVERSEX 1
  205. # undef SSD1306_DEV_REVERSEY
  206. # elif defined(CONFIG_LCD_RLANDSCAPE)
  207. # undef SSD1306_DEV_REVERSEX
  208. # define SSD1306_DEV_REVERSEY 1
  209. # endif
  210. #endif
  211. /* Bit helpers */
  212. #define LS_BIT (1 << 0)
  213. #define MS_BIT (1 << 7)
  214. /****************************************************************************
  215. * Public Type Definition
  216. ****************************************************************************/
  217. /* This structure describes the state of the SSD1306 driver */
  218. struct ssd1306_dev_s
  219. {
  220. struct lcd_dev_s dev; /* Publicly visible device structure */
  221. /* Private LCD-specific information follows */
  222. #ifdef CONFIG_LCD_SSD1306_SPI
  223. FAR struct spi_dev_s *spi; /* Cached SPI device reference */
  224. #else
  225. FAR struct i2c_master_s *i2c; /* Cached I2C device reference */
  226. uint8_t addr; /* 7-bit I2C address */
  227. #endif
  228. uint8_t contrast; /* Current contrast setting */
  229. bool on; /* true: display is on */
  230. bool is_conf; /* true: display had been configured */
  231. FAR const struct ssd1306_priv_s *board_priv; /* Board specific structure */
  232. /* The SSD1306 does not support reading from the display memory in SPI
  233. * mode. Since there is 1 BPP and access is byte-by-byte, it is necessary
  234. * to keep a shadow copy of the framebuffer memory. At 128x64, this
  235. * amounts to 1 KB.
  236. */
  237. uint8_t fb[SSD1306_DEV_FBSIZE];
  238. };
  239. /****************************************************************************
  240. * Public Function Prototypes
  241. ****************************************************************************/
  242. int ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval);
  243. int ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data,
  244. uint8_t len);
  245. #ifdef CONFIG_LCD_SSD1306_SPI
  246. void ssd1306_select(FAR struct ssd1306_dev_s *priv, bool cs);
  247. void ssd1306_cmddata(FAR struct ssd1306_dev_s *priv, bool cmd);
  248. void ssd1306_configspi(FAR struct spi_dev_s *spi);
  249. #else
  250. # define ssd1306_select(priv, cs)
  251. # define ssd1306_cmddata(priv, cmd)
  252. # define ssd1306_configspi(spi)
  253. #endif
  254. #endif /* __DRIVERS_LCD_SSD1306_H */