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