LCDGFX LCD display driver  1.0.2
This library is developed to control SSD1306/SSD1325/SSD1327/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays
ssd1306_16bit.inl
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 "lcd_hal/io.h"
26 
27 //extern uint16_t ssd1306_color;
28 extern uint8_t s_ssd1306_invertByte;
29 //extern lcduint_t ssd1306_cursorX;
30 //extern lcduint_t ssd1306_cursorY;
31 
32 #if 0
33 void ssd1306_setRgbColor16(uint8_t r, uint8_t g, uint8_t b)
34 {
35  ssd1306_color = RGB_COLOR16(r,g,b);
36 }
37 
38 static void ssd1306_drawBufferPitch16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
39 {
40  ssd1306_lcd.set_block(x, y, w);
41  while (h--)
42  {
43  lcduint_t line = w << 1;
44  while (line--)
45  {
46  ssd1306_intf.send( *data );
47  data++;
48  }
49  data += pitch - (w << 1);
50  }
52 }
53 
54 void ssd1306_drawBufferFast16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
55 {
56  ssd1306_drawBufferPitch16(x, y, w, h, w<<1, data);
57 }
58 
59 void ssd1306_drawBufferEx16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
60 {
61  ssd1306_drawBufferPitch16( x, y, w, h, pitch, data );
62 }
63 
64 void ssd1306_putColorPixel16(lcdint_t x, lcdint_t y, uint16_t color)
65 {
66  ssd1306_lcd.set_block(x, y, 0);
67  ssd1306_lcd.send_pixels16( color );
69 }
70 
71 void ssd1306_drawBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
72 {
73  ssd1306_lcd.set_block(xpos, ypos, w);
74  uint32_t count = (w) * (h);
75  while (count--)
76  {
77  ssd1306_lcd.send_pixels16( (pgm_read_byte( &bitmap[0] ) << 8) | pgm_read_byte( &bitmap[1] ) );
78  bitmap += 2;
79  }
81 }
82 
83 void ssd1306_clearBlock16(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
84 {
85  ssd1306_lcd.set_block(x, y, w);
86  uint32_t count = w * h;
87  while (count--)
88  {
89  ssd1306_lcd.send_pixels16( 0x0000 );
90  }
92 }
93 
94 void ssd1306_setCursor16(lcduint_t x, lcduint_t y)
95 {
96  ssd1306_cursorX = x;
97  ssd1306_cursorY = y;
98 }
99 
100 void ssd1306_printChar16(uint8_t c)
101 {
102  uint16_t unicode = ssd1306_unicode16FromUtf8(c);
103  if (unicode == SSD1306_MORE_CHARS_REQUIRED) return;
104  SCharInfo char_info;
105  ssd1306_getCharBitmap(unicode, &char_info);
106  ssd1306_drawMonoBitmap16(ssd1306_cursorX,
107  ssd1306_cursorY,
108  char_info.width,
109  char_info.height,
110  char_info.glyph );
111 }
112 
113 size_t ssd1306_write16(uint8_t ch)
114 {
115  if (ch == '\r')
116  {
117  ssd1306_cursorX = 0;
118  return 0;
119  }
120  else if ( (ssd1306_cursorX > ssd1306_lcd.width - m_font->getHeader().width) || (ch == '\n') )
121  {
122  ssd1306_cursorX = 0;
123  ssd1306_cursorY += m_font->getHeader().height;
124  if ( ssd1306_cursorY > ssd1306_lcd.height - m_font->getHeader().height )
125  {
126  ssd1306_cursorY = 0;
127  }
128  ssd1306_clearBlock16(0, ssd1306_cursorY, ssd1306_lcd.width, m_font->getHeader().height);
129  if (ch == '\n')
130  {
131  return 0;
132  }
133  }
134  uint16_t unicode = m_font->unicode16FromUtf8(ch);
135  if (unicode == SSD1306_MORE_CHARS_REQUIRED) return 0;
136  SCharInfo char_info;
137  m_font->getCharBitmap(unicode, &char_info);
138  ssd1306_drawMonoBitmap16( ssd1306_cursorX,
139  ssd1306_cursorY,
140  char_info.width,
141  char_info.height,
142  char_info.glyph);
143  ssd1306_cursorX += char_info.width + char_info.spacing;
144  return 1;
145 }
146 
147 size_t ssd1306_print16(const char ch[])
148 {
149  size_t n = 0;
150  while (*ch)
151  {
152  n += ssd1306_write16(*ch);
153  ch++;
154  }
155  return n;
156 }
157 
158 uint8_t ssd1306_printFixed16(lcdint_t x, lcdint_t y, const char *ch, EFontStyle style)
159 {
160  ssd1306_cursorX = x;
161  ssd1306_cursorY = y;
162  return ssd1306_print16(ch);
163 }
164 
165 #endif
166 
168 //
169 // 16-BIT GRAPHICS
170 //
172 
173 template <class I>
175 {
176  this->m_intf.startBlock(x, y, 0);
177  this->m_intf.send( this->m_color >> 8 );
178  this->m_intf.send( this->m_color & 0xFF );
179  this->m_intf.endBlock();
180 }
181 
182 template <class I>
184 {
185  this->m_intf.startBlock(x1, y1, 0);
186  while (x1 < x2)
187  {
188  this->m_intf.send( this->m_color >> 8 );
189  this->m_intf.send( this->m_color & 0xFF );
190  x1++;
191  }
192  this->m_intf.endBlock();
193 }
194 
195 template <class I>
197 {
198  this->m_intf.startBlock(x1, y1, 1);
199  while (y1<=y2)
200  {
201  this->m_intf.send( this->m_color >> 8 );
202  this->m_intf.send( this->m_color & 0xFF );
203  y1++;
204  }
205  this->m_intf.endBlock();
206 }
207 
208 template <class I>
210 {
211  if (y1 > y2)
212  {
213  ssd1306_swap_data(y1, y2, lcdint_t);
214  }
215  if (x1 > x2)
216  {
217  ssd1306_swap_data(x1, x2, lcdint_t);
218  }
219  this->m_intf.startBlock(x1, y1, x2 - x1 + 1);
220  uint16_t count = (x2 - x1 + 1) * (y2 - y1 + 1);
221  while (count--)
222  {
223  this->m_intf.send( this->m_color >> 8 );
224  this->m_intf.send( this->m_color & 0xFF );
225  }
226  this->m_intf.endBlock();
227 }
228 
229 template <class I>
230 void NanoDisplayOps16<I>::fill(uint16_t color)
231 {
232  this->m_intf.startBlock(0, 0, 0);
233  uint32_t count = (uint32_t)this->m_w * (uint32_t)this->m_h;
234  while (count--)
235  {
236  this->m_intf.send( color >> 8 );
237  this->m_intf.send( color & 0xFF );
238  }
239  this->m_intf.endBlock();
240 }
241 
242 template <class I>
244 {
245  fill( 0x00 );
246 }
247 
248 template <class I>
250 {
251  // TODO:
252 }
253 
254 template <class I>
255 void NanoDisplayOps16<I>::drawBitmap1(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
256 {
257  uint8_t bit = 1;
258  uint16_t blackColor = s_ssd1306_invertByte ? this->m_color : 0x0000;
259  uint16_t color = s_ssd1306_invertByte ? 0x0000 : this->m_color;
260  this->m_intf.startBlock(xpos, ypos, w);
261  while (h--)
262  {
263  lcduint_t wx = w;
264  while ( wx-- )
265  {
266  uint8_t data = pgm_read_byte( bitmap );
267  if ( data & bit )
268  {
269  this->m_intf.send( color >> 8 );
270  this->m_intf.send( color & 0xFF );
271  }
272  else
273  {
274  this->m_intf.send( blackColor >> 8 );
275  this->m_intf.send( blackColor & 0xFF );
276  }
277  bitmap++;
278  }
279  bit <<= 1;
280  if ( bit == 0 )
281  {
282  bit = 1;
283  }
284  else
285  {
286  bitmap -= w;
287  }
288  }
289  this->m_intf.endBlock();
290 }
291 
292 template <class I>
294 {
295  // NOT IMPLEMENTED
296 }
297 
298 template <class I>
300 {
301  this->m_intf.startBlock(x, y, w);
302  uint32_t count = (w) * (h);
303  while (count--)
304  {
305  uint16_t color = RGB8_TO_RGB16(pgm_read_byte(bitmap));
306  this->m_intf.send( color >> 8 );
307  this->m_intf.send( color & 0xFF );
308  bitmap++;
309  }
310  this->m_intf.endBlock();
311 }
312 
313 template <class I>
315 {
316  this->m_intf.startBlock(x, y, w);
317  uint32_t count = (w) * (h);
318  while (count--)
319  {
320  this->m_intf.send( pgm_read_byte( &bitmap[0] ) );
321  this->m_intf.send( pgm_read_byte( &bitmap[1] ) );
322  bitmap += 2;
323  }
324  this->m_intf.endBlock();
325 }
326 
327 template <class I>
328 void NanoDisplayOps16<I>::drawBuffer1(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *buffer)
329 {
330  uint8_t bit = 1;
331  uint16_t blackColor = s_ssd1306_invertByte ? this->m_color : 0x0000;
332  uint16_t color = s_ssd1306_invertByte ? 0x0000 : this->m_color;
333  this->m_intf.startBlock(xpos, ypos, w);
334  while (h--)
335  {
336  lcduint_t wx = w;
337  while ( wx-- )
338  {
339  uint8_t data = *buffer;
340  if ( data & bit )
341  {
342  this->m_intf.send( color >> 8 );
343  this->m_intf.send( color & 0xFF );
344  }
345  else
346  {
347  this->m_intf.send( blackColor >> 8 );
348  this->m_intf.send( blackColor & 0xFF );
349  }
350  buffer++;
351  }
352  bit <<= 1;
353  if ( bit == 0 )
354  {
355  bit = 1;
356  }
357  else
358  {
359  buffer -= w;
360  }
361  }
362  this->m_intf.endBlock();
363 }
364 
365 template <class I>
367 {
368  this->drawBuffer1( x, y, w, h, buf );
369 }
370 
371 template <class I>
373 {
374  // NOT IMPLEMENTED
375 }
376 
377 template <class I>
379 {
380  this->m_intf.startBlock(x, y, w);
381  uint32_t count = (w) * (h);
382  while (count--)
383  {
384  uint16_t color = RGB8_TO_RGB16((*buffer));
385  this->m_intf.send( color >> 8 );
386  this->m_intf.send( color & 0xFF );
387  buffer++;
388  }
389  this->m_intf.endBlock();
390 }
391 
392 template <class I>
394 {
395  this->m_intf.startBlock(x, y, w);
396  uint32_t count = (w) * (h);
397  while (count--)
398  {
399  this->m_intf.send( buffer[0] );
400  this->m_intf.send( buffer[1] );
401  buffer += 2;
402  }
403  this->m_intf.endBlock();
404 }
405 
406 template <class I>
408 {
409  uint16_t unicode = this->m_font->unicode16FromUtf8(c);
410  if (unicode == SSD1306_MORE_CHARS_REQUIRED) return 0;
411  SCharInfo char_info;
412  this->m_font->getCharBitmap(unicode, &char_info);
413  uint8_t mode = this->m_textMode;
414  for (uint8_t i = 0; i<(this->m_fontStyle == STYLE_BOLD ? 2: 1); i++)
415  {
416  this->drawBitmap1(this->m_cursorX + i,
417  this->m_cursorY,
418  char_info.width,
419  char_info.height,
420  char_info.glyph );
421  this->m_textMode |= CANVAS_MODE_TRANSPARENT;
422  }
423  this->m_textMode = mode;
424  this->m_cursorX += (lcdint_t)(char_info.width + char_info.spacing);
425  if ( ( (this->m_textMode & CANVAS_TEXT_WRAP_LOCAL) &&
426  (this->m_cursorX > ((lcdint_t)this->m_w - (lcdint_t)this->m_font->getHeader().width) ) )
427  || ( (this->m_textMode & CANVAS_TEXT_WRAP) &&
428  (this->m_cursorX > ((lcdint_t)this->m_w - (lcdint_t)this->m_font->getHeader().width)) ) )
429  {
430  this->m_cursorY += (lcdint_t)this->m_font->getHeader().height;
431  this->m_cursorX = 0;
432  if ( (this->m_textMode & CANVAS_TEXT_WRAP_LOCAL) &&
433  (this->m_cursorY > ((lcdint_t)this->m_h - (lcdint_t)this->m_font->getHeader().height)) )
434  {
435  this->m_cursorY = 0;
436  }
437  }
438  return 1;
439 }
440 
441 template <class I>
442 size_t NanoDisplayOps16<I>::write(uint8_t c)
443 {
444  if (c == '\n')
445  {
446  this->m_cursorY += (lcdint_t)this->m_font->getHeader().height;
447  this->m_cursorX = 0;
448  }
449  else if (c == '\r')
450  {
451  // skip non-printed char
452  }
453  else
454  {
455  return printChar( c );
456  }
457  return 1;
458 }
459 
460 template <class I>
461 void NanoDisplayOps16<I>::printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style)
462 {
463  // TODO: fontstyle not supported
464  // m_fontStyle = style;
465  this->m_cursorX = xpos;
466  this->m_cursorY = y;
467  while (*ch)
468  {
469  this->write(*ch);
470  ch++;
471  }
472 }
473 
474 
uint8_t printChar(uint8_t c)
uint8_t height
char height in pixels
Definition: canvas_types.h:145
uint8_t lcduint_t
Definition: canvas_types.h:81
#define RGB_COLOR16(r, g, b)
Definition: canvas_types.h:64
void(* send)(uint8_t data)
Definition: interface.h:154
void drawVLine(lcdint_t x1, lcdint_t y1, lcdint_t y2)
void(* stop)(void)
Definition: interface.h:149
void drawHLine(lcdint_t x1, lcdint_t y1, lcdint_t x2)
size_t write(uint8_t c) __attribute__((noinline))
int8_t lcdint_t
Definition: canvas_types.h:79
#define SSD1306_MORE_CHARS_REQUIRED
Definition: canvas_types.h:43
void drawBitmap8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Draws 8-bit color bitmap in color buffer. Draws 8-bit color bitmap in color buffer.
#define RGB8_TO_RGB16(c)
Definition: canvas_types.h:67
void drawBuffer1Fast(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
ssd1306_interface_t ssd1306_intf
Definition: interface.c:34
uint8_t width
char width in pixels
Definition: canvas_types.h:144
const uint8_t * glyph
char data, located in progmem.
Definition: canvas_types.h:147
void fillRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2) __attribute__((noinline))
void drawBuffer16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
void drawBuffer8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
void drawBuffer1(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
void printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style=STYLE_NORMAL) __attribute__((noinline))
void putPixel(lcdint_t x, lcdint_t y) __attribute__((noinline))
uint8_t spacing
additional spaces after char in pixels
Definition: canvas_types.h:146
EFontStyle
Definition: canvas_types.h:90
void drawXBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
void drawBitmap1(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap) __attribute__((noinline))
Draws monochrome bitmap in color buffer using color, specified via setColor() method Draws monochrome...
void drawBuffer4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
void drawBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
void drawBitmap4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap) __attribute__((noinline))
Draws 4-bit gray-color bitmap in color buffer. Draws 4-bit gray-color bitmap in color buffer...
#define ssd1306_swap_data(a, b, type)
Definition: io.h:102
void fill(uint16_t color)