LCDGFX LCD display driver  1.1.5
This library is developed to control SSD1306/SSD1325/SSD1327/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays
ssd1306_8bit.inl
1 /*
2  MIT License
3 
4  Copyright (c) 2018-2020, 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 #if 0
28 void ssd1306_setRgbColor(uint8_t r, uint8_t g, uint8_t b)
29 {
30  ssd1306_color = RGB_COLOR8(r,g,b);
31 }
32 
33 void ssd1306_setRgbColor8(uint8_t r, uint8_t g, uint8_t b)
34 {
35  ssd1306_color = RGB_COLOR8(r,g,b);
36 }
37 
38 static void ssd1306_drawBufferPitch8(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;
44  while (line--)
45  {
46  ssd1306_lcd.send_pixels8( *data );
47  data++;
48  }
49  data += pitch - w;
50  }
51  ssd1306_intf.stop();
52 }
53 
54 void ssd1306_drawBufferFast8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
55 {
56  ssd1306_drawBufferPitch8( x, y, w, h, w, data );
57 }
58 
59 void ssd1306_drawBufferEx8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
60 {
61  ssd1306_drawBufferPitch8( x, y, w, h, pitch, data );
62 }
63 
64 void ssd1306_putColorPixel8(lcdint_t x, lcdint_t y, uint8_t color)
65 {
66  ssd1306_lcd.set_block(x, y, 0);
67  ssd1306_lcd.send_pixels8( color );
68  ssd1306_intf.stop();
69 }
70 
71 #endif
72 
74 //
75 // COMMON GRAPHICS
76 //
78 
79 // template class NanoDisplayOps8<I>;
80 
81 // template <class I>
82 // void NanoDisplayOps8<I>::printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style)
83 //{
84 // m_cursorX = xpos;
85 // m_cursorY = y;
86 // m_fontStyle = style;
87 // print( ch );
88 //}
89 
91 //
92 // 8-BIT GRAPHICS
93 //
95 
96 template <class I> void NanoDisplayOps8<I>::putPixel(lcdint_t x, lcdint_t y)
97 {
98  this->m_intf.startBlock(x, y, 0);
99  this->m_intf.send(this->m_color);
100  this->m_intf.endBlock();
101 }
102 
103 template <class I> void NanoDisplayOps8<I>::drawHLine(lcdint_t x1, lcdint_t y1, lcdint_t x2)
104 {
105  this->m_intf.startBlock(x1, y1, 0);
106  while ( x1 < x2 )
107  {
108  this->m_intf.send(this->m_color);
109  x1++;
110  }
111  this->m_intf.endBlock();
112 }
113 
114 template <class I> void NanoDisplayOps8<I>::drawVLine(lcdint_t x1, lcdint_t y1, lcdint_t y2)
115 {
116  this->m_intf.startBlock(x1, y1, 1);
117  while ( y1 <= y2 )
118  {
119  this->m_intf.send(this->m_color);
120  y1++;
121  }
122  this->m_intf.endBlock();
123 }
124 
125 template <class I> void NanoDisplayOps8<I>::fillRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
126 {
127  if ( y1 > y2 )
128  {
129  ssd1306_swap_data(y1, y2, lcdint_t);
130  }
131  if ( x1 > x2 )
132  {
133  ssd1306_swap_data(x1, x2, lcdint_t);
134  }
135  this->m_intf.startBlock(x1, y1, x2 - x1 + 1);
136  uint32_t count = (x2 - x1 + 1) * (y2 - y1 + 1);
137  while ( count-- )
138  {
139  this->m_intf.send(this->m_color);
140  }
141  this->m_intf.endBlock();
142 }
143 
144 template <class I> void NanoDisplayOps8<I>::fill(uint16_t color)
145 {
146  this->m_intf.startBlock(0, 0, 0);
147  uint32_t count = (uint32_t)this->m_w * (uint32_t)this->m_h;
148  while ( count-- )
149  {
150  this->m_intf.send(color);
151  }
152  this->m_intf.endBlock();
153 }
154 
155 template <class I> void NanoDisplayOps8<I>::clear()
156 {
157  fill(0x00);
158 }
159 
160 template <class I>
161 void NanoDisplayOps8<I>::drawXBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
162 {
163  // TODO:
164 }
165 
166 template <class I>
167 void NanoDisplayOps8<I>::drawBitmap1(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
168 {
169  uint8_t bit = 1;
170  uint8_t blackColor = this->m_bgColor;
171  uint8_t color = this->m_color;
172  this->m_intf.startBlock(xpos, ypos, w);
173  while ( h-- )
174  {
175  lcduint_t wx = w;
176  while ( wx-- )
177  {
178  uint8_t data = pgm_read_byte(bitmap);
179  if ( data & bit )
180  this->m_intf.send(color);
181  else
182  this->m_intf.send(blackColor);
183  bitmap++;
184  }
185  bit <<= 1;
186  if ( bit == 0 )
187  {
188  bit = 1;
189  }
190  else
191  {
192  bitmap -= w;
193  }
194  }
195  this->m_intf.endBlock();
196 }
197 
198 template <class I>
199 void NanoDisplayOps8<I>::drawBitmap4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
200 {
201  // NOT IMPLEMENTED
202 }
203 
204 template <class I>
205 void NanoDisplayOps8<I>::drawBitmap8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
206 {
207  this->m_intf.startBlock(x, y, w);
208  uint32_t count = (w) * (h);
209  while ( count-- )
210  {
211  this->m_intf.send(pgm_read_byte(bitmap));
212  bitmap++;
213  }
214  this->m_intf.endBlock();
215 }
216 
217 template <class I>
219 {
220  // NOT IMPLEMENTED
221 }
222 
223 template <class I>
224 void NanoDisplayOps8<I>::drawBuffer1(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *buffer)
225 {
226  uint8_t bit = 1;
227  uint8_t blackColor = this->m_bgColor;
228  uint8_t color = this->m_color;
229  this->m_intf.startBlock(xpos, ypos, w);
230  while ( h-- )
231  {
232  lcduint_t wx = w;
233  while ( wx-- )
234  {
235  uint8_t data = *buffer;
236  if ( data & bit )
237  this->m_intf.send(color);
238  else
239  this->m_intf.send(blackColor);
240  buffer++;
241  }
242  bit <<= 1;
243  if ( bit == 0 )
244  {
245  bit = 1;
246  }
247  else
248  {
249  buffer -= w;
250  }
251  }
252  this->m_intf.endBlock();
253 }
254 
255 template <class I>
257 {
258  this->drawBuffer1(x, y, w, h, buf);
259 }
260 
261 template <class I>
262 void NanoDisplayOps8<I>::drawBuffer4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
263 {
264  // NOT IMPLEMENTED
265 }
266 
267 template <class I>
268 void NanoDisplayOps8<I>::drawBuffer8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
269 {
270  this->m_intf.startBlock(x, y, w);
271  uint32_t count = (w) * (h);
272  while ( count-- )
273  {
274  this->m_intf.send(*buffer);
275  buffer++;
276  }
277  this->m_intf.endBlock();
278 }
279 
280 template <class I>
282 {
283  // NOT IMPLEMENTED
284 }
285 
286 template <class I> uint8_t NanoDisplayOps8<I>::printChar(uint8_t c)
287 {
288  uint16_t unicode = this->m_font->unicode16FromUtf8(c);
289  if ( unicode == SSD1306_MORE_CHARS_REQUIRED )
290  return 0;
291  SCharInfo char_info;
292  this->m_font->getCharBitmap(unicode, &char_info);
293  uint8_t mode = this->m_textMode;
294  for ( uint8_t i = 0; i < (this->m_fontStyle == STYLE_BOLD ? 2 : 1); i++ )
295  {
296  this->drawBitmap1(this->m_cursorX + i, this->m_cursorY, char_info.width, char_info.height, char_info.glyph);
297  this->m_textMode |= CANVAS_MODE_TRANSPARENT;
298  }
299  this->m_textMode = mode;
300  this->m_cursorX += (lcdint_t)(char_info.width + char_info.spacing);
301  if ( ((this->m_textMode & CANVAS_TEXT_WRAP_LOCAL) &&
302  (this->m_cursorX > ((lcdint_t)this->m_w - (lcdint_t)this->m_font->getHeader().width))) ||
303  ((this->m_textMode & CANVAS_TEXT_WRAP) &&
304  (this->m_cursorX > ((lcdint_t)this->m_w - (lcdint_t)this->m_font->getHeader().width))) )
305  {
306  this->m_cursorY += (lcdint_t)this->m_font->getHeader().height;
307  this->m_cursorX = 0;
308  if ( (this->m_textMode & CANVAS_TEXT_WRAP_LOCAL) &&
309  (this->m_cursorY > ((lcdint_t)this->m_h - (lcdint_t)this->m_font->getHeader().height)) )
310  {
311  this->m_cursorY = 0;
312  }
313  }
314  return 1;
315 }
316 
317 template <class I> size_t NanoDisplayOps8<I>::write(uint8_t c)
318 {
319  if ( c == '\n' )
320  {
321  this->m_cursorY += (lcdint_t)this->m_font->getHeader().height;
322  this->m_cursorX = 0;
323  }
324  else if ( c == '\r' )
325  {
326  // skip non-printed char
327  }
328  else
329  {
330  return printChar(c);
331  }
332  return 1;
333 }
334 
335 template <class I> void NanoDisplayOps8<I>::printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style)
336 {
337  // TODO: fontstyle not supported
338  // m_fontStyle = style;
339  this->m_cursorX = xpos;
340  this->m_cursorY = y;
341  while ( *ch )
342  {
343  this->write(*ch);
344  ch++;
345  }
346 }
void drawBuffer4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
uint8_t height
char height in pixels
Definition: canvas_types.h:144
uint8_t lcduint_t
Definition: canvas_types.h:79
void drawBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
int8_t lcdint_t
Definition: canvas_types.h:77
#define SSD1306_MORE_CHARS_REQUIRED
Definition: canvas_types.h:43
void fill(uint16_t color)
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.
void drawBuffer1Fast(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
uint8_t printChar(uint8_t c)
void printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style=STYLE_NORMAL) __attribute__((noinline))
void drawHLine(lcdint_t x1, lcdint_t y1, lcdint_t x2)
void fillRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2) __attribute__((noinline))
size_t write(uint8_t c) __attribute__((noinline))
void putPixel(lcdint_t x, lcdint_t y) __attribute__((noinline))
void drawVLine(lcdint_t x1, lcdint_t y1, lcdint_t y2)
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...
uint8_t width
char width in pixels
Definition: canvas_types.h:143
const uint8_t * glyph
char data, located in progmem.
Definition: canvas_types.h:146
void drawXBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
#define RGB_COLOR8(r, g, b)
Definition: canvas_types.h:52
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...
uint8_t spacing
additional spaces after char in pixels
Definition: canvas_types.h:145
EFontStyle
Definition: canvas_types.h:88
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))
#define ssd1306_swap_data(a, b, type)
Definition: io.h:114
void drawBuffer16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))