SSD1306 OLED display driver  1.3.1
This library is developed to control SSD1306 i2c/spi OLED display
ssd1306.cpp
1 /*
2  Copyright (C) 2016-2017 Alexey Dynda
3 
4  This file is part of SSD1306 library.
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "font6x8.h"
21 #include "ssd1306.h"
22 #include "lcd/lcd_common.h"
23 #include "i2c/ssd1306_i2c.h"
24 #include "spi/ssd1306_spi.h"
25 #include "intf/ssd1306_interface.h"
26 
27 // TODO: remove
28 #include "lcd/ssd1306_commands.h"
29 
33 static uint8_t s_invertByte = 0x00000000;
34 const uint8_t *s_font6x8 = ssd1306xled_font6x8;
35 
37 {
38  return s_displayHeight;
39 }
40 
42 {
43  return s_displayWidth;
44 }
45 
46 void ssd1306_fillScreen(uint8_t fill_Data)
47 {
48  fill_Data ^= s_invertByte;
49  ssd1306_setRamBlock(0, 0, 0);
51  for(uint8_t m=(s_displayHeight >> 3); m>0; m--)
52  {
53  for(uint8_t n=s_displayWidth; n>0; n--)
54  {
55  ssd1306_sendByte(fill_Data);
56  }
58  }
60 }
61 
63 {
64  ssd1306_setRamBlock(0, 0, 0);
66  for(uint8_t m=(s_displayHeight >> 3); m>0; m--)
67  {
68  for(uint8_t n=s_displayWidth; n>0; n--)
69  {
70  ssd1306_sendByte( s_invertByte );
71  }
73  }
75 }
76 
77 
79 {
80  ssd1306_sendCommand(SSD1306_DISPLAYOFF);
81 }
82 
83 
85 {
86  ssd1306_sendCommand(SSD1306_DISPLAYON);
87 }
88 
89 uint8_t ssd1306_charF6x8(uint8_t x, uint8_t y, const char ch[], EFontStyle style)
90 {
91  uint8_t i, j=0;
94  while(ch[j] != '\0')
95  {
96  uint8_t c = ch[j] - 32;
97  if(x>s_displayWidth-2)
98  {
99  x=0;
100  y++;
101  }
102  uint8_t ldata = 0;
103  for(i=0;i<6;i++)
104  {
105  uint8_t data;
106  if ( style == STYLE_NORMAL )
107  {
108  data = pgm_read_byte(&s_font6x8[c*6+i]);
109  }
110  else if ( style == STYLE_BOLD )
111  {
112  uint8_t temp = pgm_read_byte(&s_font6x8[c*6+i]);
113  data = temp | ldata;
114  ldata = temp;
115  }
116  else
117  {
118  uint8_t temp = pgm_read_byte(&s_font6x8[c*6+i + 1]);
119  data = (temp & 0xF0) | ldata;
120  ldata = (temp & 0x0F);
121  }
122  ssd1306_sendByte(data^s_invertByte);
123  }
124  x += 6;
125  j++;
126  }
128  return j;
129 }
130 
131 uint8_t ssd1306_charF6x8_eol(uint8_t left,
132  uint8_t y,
133  const char ch[],
134  EFontStyle style,
135  uint8_t right)
136 {
137  uint8_t len = ssd1306_charF6x8(left, y, ch, style);
138  uint8_t text_end_pos = len * 6 + left;
139  if (text_end_pos <= right)
140  {
141  ssd1306_clearBlock(text_end_pos, y, right - text_end_pos + 1, 8);
142  }
143  return len;
144 }
145 
146 void ssd1306_setFont6x8(const uint8_t * progmemFont)
147 {
148  s_font6x8 = progmemFont;
149 }
150 
151 void ssd1306_putPixel(uint8_t x, uint8_t y)
152 {
153  ssd1306_setRamBlock(x, y >> 3, 1);
155  ssd1306_sendByte((1 << (y & 0x07))^s_invertByte);
157 }
158 
159 void ssd1306_putPixels(uint8_t x, uint8_t y, uint8_t pixels)
160 {
161  ssd1306_setRamBlock(x, y >> 3, 1);
163  ssd1306_sendByte(pixels^s_invertByte);
165 }
166 
167 void ssd1306_drawHLine(uint8_t x1, uint8_t y1, uint8_t x2)
168 {
169  ssd1306_setRamBlock(x1, y1 >> 3, x2 - x1 + 1);
171  for (uint8_t x = x1; x <= x2; x++)
172  {
173  ssd1306_sendByte((1 << (y1 & 0x07))^s_invertByte);
174  }
176 }
177 
178 void ssd1306_drawVLine(uint8_t x1, uint8_t y1, uint8_t y2)
179 {
180  ssd1306_setRamBlock(x1, y1 >> 3, 1);
182  ssd1306_sendByte( (0xFF << (y1 & 0x07))^s_invertByte );
183  uint8_t y;
184  for ( y = ((y1 >> 3) + 1); y <= ((y2 >> 3) - 1); y++)
185  {
187  ssd1306_sendByte( 0xFF^s_invertByte );
188  }
190  ssd1306_sendByte( (0xFF >> (0x07 - (y2 & 0x07)))^s_invertByte );
192 }
193 
194 void ssd1306_drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
195 {
196  ssd1306_drawHLine(x1+1, y1, x2-1);
197  ssd1306_drawHLine(x1+1, y2, x2-1);
198  ssd1306_drawVLine(x1, y1, y2);
199  ssd1306_drawVLine(x2, y1, y2);
200 }
201 
202 void ssd1306_drawBuffer(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
203 {
204  uint8_t i, j;
205  ssd1306_setRamBlock(x, y, w);
207  for(j=0; j<(h >> 3); j++)
208  {
209  for(i=0;i<w;i++)
210  {
211  ssd1306_sendByte(s_invertByte^*buf++);
212  }
214  }
216 }
217 
218 void ssd1306_drawBitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
219 {
220  uint8_t i, j;
221  ssd1306_setRamBlock(x, y, w);
223  for(j=0; j<(h >> 3); j++)
224  {
225  for(i=w;i>0;i--)
226  {
227  ssd1306_sendByte(s_invertByte^pgm_read_byte(buf++));
228  }
230  }
232 }
233 
234 
235 void ssd1306_clearBlock(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
236 {
237  uint8_t i, j;
238  ssd1306_setRamBlock(x, y, w);
240  for(j=0; j<(h >> 3); j++)
241  {
242  for(i=w;i>0;i--)
243  {
244  ssd1306_sendByte(s_invertByte);
245  }
247  }
249 }
250 
251 
252 void ssd1306_drawSpriteEx(uint8_t x, uint8_t y, uint8_t w, const uint8_t *sprite)
253 {
254  uint8_t i;
255  ssd1306_setRamBlock(x,y,w);
257  for(i=0;i<w;i++)
258  {
259  ssd1306_sendByte(s_invertByte^pgm_read_byte(&sprite[i]));
260  }
262 }
263 
264 
266 {
267  uint8_t posy = sprite->y >> 3;
268  uint8_t offsety = sprite->y & 0x7;
269  if (posy < (s_displayHeight >> 3))
270  {
271  ssd1306_setRamBlock(sprite->x, posy, sprite->w);
273  for (uint8_t i=0; i < sprite->w; i++)
274  {
275  ssd1306_sendByte( s_invertByte^(pgm_read_byte( &sprite->data[i] ) << offsety) );
276  }
278  }
279  if (offsety && (posy + 1 < (s_displayHeight >> 3)))
280  {
281  ssd1306_setRamBlock(sprite->x, posy + 1, sprite->w);
283  for (uint8_t i=0; i < sprite->w; i++)
284  {
285  ssd1306_sendByte( s_invertByte^(pgm_read_byte( &sprite->data[i] ) >> (8 - offsety)) );
286  }
287  }
289  sprite->lx = sprite->x;
290  sprite->ly = sprite->y;
291 }
292 
293 
295 {
296  uint8_t posy = sprite->y >> 3;
297  uint8_t offsety = sprite->y & 0x7;
298  ssd1306_setRamBlock(sprite->x, posy, sprite->w);
300  for (uint8_t i=0; i < sprite->w; i++)
301  {
302  ssd1306_sendByte( s_invertByte );
303  }
305  if (offsety)
306  {
307  ssd1306_setRamBlock(sprite->x, posy + 1, sprite->w);
309  for (uint8_t i=0; i < sprite->w; i++)
310  {
311  ssd1306_sendByte( s_invertByte );
312  }
313  }
315 }
316 
317 
319 {
320  uint8_t y1 = sprite->ly >> 3;
321  uint8_t y2 = (sprite->ly + 7) >> 3;
322  if (sprite->ly < sprite->y)
323  y2 = min(y2, (uint8_t)((sprite->y >> 3) - 1));
324  else
325  y1 = max(y1, (sprite->ly + 7) >> 3);
326  for(uint8_t y = y1; y <= y2; y++)
327  {
328  ssd1306_setRamBlock(sprite->lx, y, sprite->w);
330  for(uint8_t x = sprite->lx; x < sprite->lx + sprite->w; x++)
331  {
332  ssd1306_sendByte( s_invertByte );
333  }
335  }
336  if (sprite->lx != sprite->x)
337  {
338  uint8_t x1 = sprite->lx;
339  uint8_t x2 = sprite->lx + sprite->w - 1;
340  if (sprite->x < sprite->lx)
341  x1 = max(x1, sprite->x + sprite->w);
342  else
343  x2 = min((uint8_t)(sprite->x - 1), x2);
344  for(uint8_t y = sprite->ly >> 3; y <= (sprite->ly + 7) >> 3; y++)
345  {
346  ssd1306_setRamBlock(x1, y, x2 - x1 +1 );
348  for(uint8_t x = x1; x <= x2; x++)
349  {
350  ssd1306_sendByte( s_invertByte );
351  }
353  }
354  }
355 }
356 
357 SPRITE ssd1306_createSprite(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data)
358 {
359  return {x,y,w,x,y,data,nullptr};
360 }
361 
362 void ssd1306_replaceSprite(SPRITE *sprite, const uint8_t *data)
363 {
364  sprite->data = data;
365 }
366 
368 {
369  ssd1306_sendCommand(SSD1306_INVERTDISPLAY);
370 }
371 
373 {
374  ssd1306_sendCommand(SSD1306_NORMALDISPLAY);
375 }
376 
378 {
379  s_invertByte = 0xFF;
380 }
381 
383 {
384  s_invertByte = 0x00;
385 }
void ssd1306_drawBitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
Definition: ssd1306.cpp:218
void ssd1306_negativeMode()
Definition: ssd1306.cpp:377
const uint8_t * data
Pointer to PROGMEM data, representing sprite image.
void(* ssd1306_sendByte)(uint8_t data)
void ssd1306_displayOff()
Definition: ssd1306.cpp:78
void(* ssd1306_dataStart)()
void(* ssd1306_endTransmission)()
uint8_t ssd1306_displayHeight()
Definition: ssd1306.cpp:36
void ssd1306_replaceSprite(SPRITE *sprite, const uint8_t *data)
Definition: ssd1306.cpp:362
void ssd1306_drawHLine(uint8_t x1, uint8_t y1, uint8_t x2)
Definition: ssd1306.cpp:167
void(* ssd1306_nextRamPage)()
void ssd1306_setFont6x8(const uint8_t *progmemFont)
Definition: ssd1306.cpp:146
uint8_t ssd1306_charF6x8_eol(uint8_t left, uint8_t y, const char ch[], EFontStyle style, uint8_t right)
Definition: ssd1306.cpp:131
void ssd1306_displayOn()
Definition: ssd1306.cpp:84
void ssd1306_drawVLine(uint8_t x1, uint8_t y1, uint8_t y2)
Definition: ssd1306.cpp:178
void ssd1306_positiveMode()
Definition: ssd1306.cpp:382
void ssd1306_putPixels(uint8_t x, uint8_t y, uint8_t pixels)
Definition: ssd1306.cpp:159
SPRITE ssd1306_createSprite(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data)
Definition: ssd1306.cpp:357
void ssd1306_drawSpriteEx(uint8_t x, uint8_t y, uint8_t w, const uint8_t *sprite)
Definition: ssd1306.cpp:252
void ssd1306_sendCommand(uint8_t command)
void ssd1306_fillScreen(uint8_t fill_Data)
Definition: ssd1306.cpp:46
void ssd1306_drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
Definition: ssd1306.cpp:194
void ssd1306_clearScreen()
Definition: ssd1306.cpp:62
uint8_t y
draw position Y on the screen
uint8_t ssd1306_charF6x8(uint8_t x, uint8_t y, const char ch[], EFontStyle style)
Definition: ssd1306.cpp:89
void ssd1306_clearBlock(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
Definition: ssd1306.cpp:235
void ssd1306_invertMode()
Definition: ssd1306.cpp:367
uint8_t x
draw position X on the screen
uint8_t ssd1306_displayWidth()
Definition: ssd1306.cpp:41
void ssd1306_drawSprite(SPRITE *sprite)
Definition: ssd1306.cpp:265
void ssd1306_eraseTrace(SPRITE *sprite)
Definition: ssd1306.cpp:318
void ssd1306_drawBuffer(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
Definition: ssd1306.cpp:202
void ssd1306_eraseSprite(SPRITE *sprite)
Definition: ssd1306.cpp:294
uint8_t g_lcd_type
Definition: ssd1306.cpp:32
uint8_t s_displayHeight
Definition: ssd1306.cpp:30
void ssd1306_normalMode()
Definition: ssd1306.cpp:372
uint8_t w
sprite width
void(* ssd1306_setRamBlock)(uint8_t x, uint8_t y, uint8_t w)
void ssd1306_putPixel(uint8_t x, uint8_t y)
Definition: ssd1306.cpp:151
uint8_t lx
last draw position X on the screen
EFontStyle
uint8_t s_displayWidth
Definition: ssd1306.cpp:31
uint8_t ly
last draw position Y on the screen