SSD1306 OLED display driver  1.8.2
This library is developed to control SSD1306/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays
ssd1306_16bit.c
1 /*
2  MIT License
3 
4  Copyright (c) 2018-2019, Alexey Dynda
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  SOFTWARE.
23 */
24 
25 #include "ssd1306_16bit.h"
26 #include "ssd1306_generic.h"
27 #include "intf/ssd1306_interface.h"
28 #include "lcd/lcd_common.h"
29 #include "ssd1306_hal/io.h"
30 
31 extern uint16_t ssd1306_color;
32 extern uint8_t s_ssd1306_invertByte;
33 extern lcduint_t ssd1306_cursorX;
34 extern lcduint_t ssd1306_cursorY;
36 #ifdef CONFIG_SSD1306_UNICODE_ENABLE
37 extern uint8_t g_ssd1306_unicode;
38 #endif
39 
40 void ssd1306_setRgbColor16(uint8_t r, uint8_t g, uint8_t b)
41 {
42  ssd1306_color = RGB_COLOR16(r,g,b);
43 }
44 
45 static void ssd1306_drawBufferPitch16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
46 {
47  ssd1306_lcd.set_block(x, y, w);
48  while (h--)
49  {
50  lcduint_t line = w << 1;
51  while (line--)
52  {
53  ssd1306_intf.send( *data );
54  data++;
55  }
56  data += pitch - (w << 1);
57  }
59 }
60 
61 void ssd1306_drawBufferFast16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
62 {
63  ssd1306_drawBufferPitch16(x, y, w, h, w<<1, data);
64 }
65 
66 void ssd1306_drawBufferEx16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
67 {
68  ssd1306_drawBufferPitch16( x, y, w, h, pitch, data );
69 }
70 
71 // IMPORTANT: ALL 16-BIT OLED DISPLAYS ALSO SUPPORT 8-BIT DIRECT DRAW FUNCTIONS
72 // REFER TO ssd1306_8bit.c
73 
74 void ssd1306_drawMonoBuffer16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
75 {
76  uint8_t bit = 1;
77  uint16_t blackColor = s_ssd1306_invertByte ? ssd1306_color : 0x00;
78  uint16_t color = s_ssd1306_invertByte ? 0x00 : ssd1306_color;
79  ssd1306_lcd.set_block(xpos, ypos, w);
80  while (h--)
81  {
82  lcduint_t wx = w;
83  while (wx--)
84  {
85  uint8_t data = *bitmap;
86  if ( data & bit )
87  ssd1306_lcd.send_pixels16( color );
88  else
89  ssd1306_lcd.send_pixels16( blackColor );
90  bitmap++;
91  }
92  bit <<= 1;
93  if (bit == 0)
94  {
95  bit = 1;
96  }
97  else
98  {
99  bitmap -= w;
100  }
101  }
102  ssd1306_intf.stop();
103 }
104 
105 void ssd1306_fillScreen16(uint16_t fill_Data)
106 {
107  ssd1306_lcd.set_block(0, 0, 0);
108  uint32_t count = (uint32_t)ssd1306_lcd.width * (uint32_t)ssd1306_lcd.height;
109  while (count--)
110  {
111  ssd1306_lcd.send_pixels16( fill_Data );
112  }
113  ssd1306_intf.stop();
114 }
115 
117 {
118  ssd1306_fillScreen16( 0x0000 );
119 }
120 
121 void ssd1306_putPixel16(lcdint_t x, lcdint_t y)
122 {
123  ssd1306_lcd.set_block(x, y, 0);
124  ssd1306_lcd.send_pixels16( ssd1306_color );
125  ssd1306_intf.stop();
126 }
127 
128 void ssd1306_putColorPixel16(lcdint_t x, lcdint_t y, uint16_t color)
129 {
130  ssd1306_lcd.set_block(x, y, 0);
131  ssd1306_lcd.send_pixels16( color );
132  ssd1306_intf.stop();
133 }
134 
135 void ssd1306_drawVLine16(lcdint_t x1, lcdint_t y1, lcdint_t y2)
136 {
137  ssd1306_lcd.set_block(x1, y1, 1);
138  while (y1<=y2)
139  {
140  ssd1306_lcd.send_pixels16( ssd1306_color );
141  y1++;
142  }
143  ssd1306_intf.stop();
144 }
145 
146 void ssd1306_drawHLine16(lcdint_t x1, lcdint_t y1, lcdint_t x2)
147 {
148  ssd1306_lcd.set_block(x1, y1, 0);
149  while (x1 < x2)
150  {
151  ssd1306_lcd.send_pixels16( ssd1306_color );
152  x1++;
153  }
154  ssd1306_intf.stop();
155 }
156 
157 void ssd1306_drawLine16(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
158 {
159  lcduint_t dx = x1 > x2 ? (x1 - x2): (x2 - x1);
160  lcduint_t dy = y1 > y2 ? (y1 - y2): (y2 - y1);
161  lcduint_t err = 0;
162  if (dy > dx)
163  {
164  if (y1 > y2)
165  {
166  ssd1306_swap_data(x1, x2, lcdint_t);
167  ssd1306_swap_data(y1, y2, lcdint_t);
168  }
169  for(; y1<=y2; y1++)
170  {
171  err += dx;
172  if (err >= dy)
173  {
174  err -= dy;
175  x1 < x2 ? x1++: x1--;
176  }
177  ssd1306_putPixel16( x1, y1 );
178  }
179  }
180  else
181  {
182  if (x1 > x2)
183  {
184  ssd1306_swap_data(x1, x2, lcdint_t);
185  ssd1306_swap_data(y1, y2, lcdint_t);
186  }
187  for(; x1<=x2; x1++)
188  {
189  err += dy;
190  if (err >= dx)
191  {
192  err -= dx;
193  if (y1 < y2) y1++; else y1--;
194  }
195  ssd1306_putPixel16( x1, y1 );
196  }
197  }
198 }
199 
200 void ssd1306_drawRect16(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
201 {
202  ssd1306_drawHLine16(x1,y1,x2);
203  ssd1306_drawHLine16(x1,y2,x2);
204  ssd1306_drawVLine16(x1,y1,y2);
205  ssd1306_drawVLine16(x2,y1,y2);
206 }
207 
208 void ssd1306_fillRect16(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
209 {
210  if (y1 > y2)
211  {
212  ssd1306_swap_data(y1, y2, lcdint_t);
213  }
214  if (x1 > x2)
215  {
216  ssd1306_swap_data(x1, x2, lcdint_t);
217  }
218  ssd1306_lcd.set_block(x1, y1, x2 - x1 + 1);
219  uint16_t count = (x2 - x1 + 1) * (y2 - y1 + 1);
220  while (count--)
221  {
222  ssd1306_lcd.send_pixels16( ssd1306_color );
223  }
224  ssd1306_intf.stop();
225 }
226 
227 void ssd1306_drawMonoBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
228 {
229  uint8_t bit = 1;
230  uint16_t blackColor = s_ssd1306_invertByte ? ssd1306_color : 0x00;
231  uint16_t color = s_ssd1306_invertByte ? 0x00 : ssd1306_color;
232  ssd1306_lcd.set_block(xpos, ypos, w);
233  while (h--)
234  {
235  lcduint_t wx = w;
236  while ( wx-- )
237  {
238  uint8_t data = pgm_read_byte( bitmap );
239  if ( data & bit )
240  ssd1306_lcd.send_pixels16( color );
241  else
242  ssd1306_lcd.send_pixels16( blackColor );
243  bitmap++;
244  }
245  bit <<= 1;
246  if ( bit == 0 )
247  {
248  bit = 1;
249  }
250  else
251  {
252  bitmap -= w;
253  }
254  }
255  ssd1306_intf.stop();
256 }
257 
258 void ssd1306_drawBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
259 {
260  ssd1306_lcd.set_block(xpos, ypos, w);
261  uint32_t count = (w) * (h);
262  while (count--)
263  {
264  ssd1306_lcd.send_pixels16( (pgm_read_byte( &bitmap[0] ) << 8) | pgm_read_byte( &bitmap[1] ) );
265  bitmap += 2;
266  }
267  ssd1306_intf.stop();
268 }
269 
270 void ssd1306_clearBlock16(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
271 {
272  ssd1306_lcd.set_block(x, y, w);
273  uint32_t count = w * h;
274  while (count--)
275  {
276  ssd1306_lcd.send_pixels16( 0x0000 );
277  }
278  ssd1306_intf.stop();
279 }
280 
281 void ssd1306_setCursor16(lcduint_t x, lcduint_t y)
282 {
283  ssd1306_cursorX = x;
284  ssd1306_cursorY = y;
285 }
286 
287 void ssd1306_printChar16(uint8_t c)
288 {
289  uint16_t unicode = ssd1306_unicode16FromUtf8(c);
290  if (unicode == SSD1306_MORE_CHARS_REQUIRED) return;
291  SCharInfo char_info;
292  ssd1306_getCharBitmap(unicode, &char_info);
293  ssd1306_drawMonoBitmap16(ssd1306_cursorX,
294  ssd1306_cursorY,
295  char_info.width,
296  char_info.height,
297  char_info.glyph );
298 }
299 
300 size_t ssd1306_write16(uint8_t ch)
301 {
302  if (ch == '\r')
303  {
304  ssd1306_cursorX = 0;
305  return 0;
306  }
307  SCharInfo char_info;
308  uint8_t gotoNewLine = 1;
309  if (ch != '\n')
310  {
311  uint16_t unicode = ssd1306_unicode16FromUtf8(ch);
312  if (unicode == SSD1306_MORE_CHARS_REQUIRED) return 0;
313  ssd1306_getCharBitmap(unicode, &char_info);
314  gotoNewLine = (ssd1306_cursorX > (ssd1306_lcd.width - char_info.width));
315  }
316  if ( gotoNewLine )
317  {
318  ssd1306_cursorX = 0;
319  ssd1306_cursorY += s_fixedFont.h.height;
320  if ( ssd1306_cursorY > ssd1306_lcd.height - s_fixedFont.h.height )
321  {
322  ssd1306_cursorY = 0;
323  }
324  ssd1306_clearBlock16(0, ssd1306_cursorY, ssd1306_lcd.width, s_fixedFont.h.height);
325  if (ch == '\n')
326  {
327  return 0;
328  }
329  }
330  if ( 1 )
331  {
332  uint16_t color = ssd1306_color;
333  ssd1306_color = s_ssd1306_invertByte ? color : 0x0000;
334  ssd1306_fillRect16( ssd1306_cursorX, ssd1306_cursorY,
335  ssd1306_cursorX + char_info.width + char_info.spacing - 1,
336  ssd1306_cursorY + s_fixedFont.h.height - 1 );
337  ssd1306_color = color;
338  }
339  ssd1306_drawMonoBitmap16( ssd1306_cursorX,
340  ssd1306_cursorY,
341  char_info.width,
342  char_info.height,
343  char_info.glyph);
344  ssd1306_cursorX += char_info.width + char_info.spacing;
345  return 1;
346 }
347 
348 size_t ssd1306_print16(const char ch[])
349 {
350  size_t n = 0;
351  while (*ch)
352  {
353  n += ssd1306_write16(*ch);
354  ch++;
355  }
356  return n;
357 }
358 
359 uint8_t ssd1306_printFixed16(lcdint_t x, lcdint_t y, const char *ch, EFontStyle style)
360 {
361  ssd1306_cursorX = x;
362  ssd1306_cursorY = y;
363  return ssd1306_print16(ch);
364 }
365 
366 
#define RGB_COLOR16(r, g, b)
void ssd1306_printChar16(uint8_t c)
uint8_t height
char height in pixels
void ssd1306_fillScreen16(uint16_t fill_Data)
void(* send)(uint8_t data)
void ssd1306_drawBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
uint8_t ssd1306_printFixed16(lcdint_t x, lcdint_t y, const char *ch, EFontStyle style)
void ssd1306_drawRect16(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
void ssd1306_putColorPixel16(lcdint_t x, lcdint_t y, uint16_t color)
void(* send_pixels16)(uint16_t data)
Sends RGB pixel encoded in 5-6-5 format to OLED driver. Sends RGB pixel encoded in 5-6-5 format to OL...
Definition: lcd_common.h:149
void(* set_block)(lcduint_t x, lcduint_t y, lcduint_t w)
Sets block in RAM of lcd display controller to write data to.
Definition: lcd_common.h:114
void ssd1306_drawMonoBuffer16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Definition: ssd1306_16bit.c:74
void ssd1306_setCursor16(lcduint_t x, lcduint_t y)
uint8_t height
height in pixels
void ssd1306_clearBlock16(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
void ssd1306_setRgbColor16(uint8_t r, uint8_t g, uint8_t b)
Sets default color.
Definition: ssd1306_16bit.c:40
void ssd1306_drawBufferFast16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
Definition: ssd1306_16bit.c:61
ssd1306_lcd_t ssd1306_lcd
Definition: lcd_common.c:33
void ssd1306_fillRect16(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
void ssd1306_putPixel16(lcdint_t x, lcdint_t y)
ssd1306_interface_t ssd1306_intf
lcduint_t height
Definition: lcd_common.h:97
uint8_t width
char width in pixels
size_t ssd1306_write16(uint8_t ch)
Prints single character to display at current cursor position.
size_t ssd1306_print16(const char ch[])
Prints null-terminated string to display at current cursor position.
SFixedFontInfo s_fixedFont
Definition: tiler.h:44
void ssd1306_drawHLine16(lcdint_t x1, lcdint_t y1, lcdint_t x2)
void ssd1306_clearScreen16(void)
SFontHeaderRecord h
record, containing information on font
const uint8_t * glyph
char data, located in progmem.
void ssd1306_drawLine16(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
uint8_t spacing
additional spaces after char in pixels
void ssd1306_getCharBitmap(uint16_t unicode, SCharInfo *info)
returns char data for currently set (active) font.
lcduint_t width
Definition: lcd_common.h:94
void ssd1306_drawMonoBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
#define SSD1306_MORE_CHARS_REQUIRED
EFontStyle
void ssd1306_drawBufferEx16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
Definition: ssd1306_16bit.c:66
#define ssd1306_swap_data(a, b, type)
Definition: io.h:69
void ssd1306_drawVLine16(lcdint_t x1, lcdint_t y1, lcdint_t y2)