SSD1306 I2C Display Driver  1.1.0
This library is developed to control SSD1306 I2C 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 "intf/ssd1306_interface.h"
23 
24 #include "i2c/ssd1306_i2c.h"
25 #include "lcd/ssd1306_128x64.h"
26 #include "lcd/ssd1306_128x32.h"
27 #include "intf/ssd1306_commands.h"
28 
29 static uint8_t s_displayHeight;
30 static uint8_t s_invertByte = 0x00000000;
31 const uint8_t *s_font6x8 = ssd1306xled_font6x8;
32 
34 {
35  return s_displayHeight;
36 }
37 
38 
39 void ssd1306_i2cInit()
40 {
41  ssd1306_startTransmission = ssd1306_i2cStart;
42  ssd1306_endTransmission = ssd1306_i2cStop;
43  ssd1306_sendByte = ssd1306_i2cSendByte;
44 }
45 
47 {
48  ssd1306_i2cInit();
49  ssd1306_endTransmission();
50  s_displayHeight = 64;
51  for( uint8_t i=0; i<s_oled128x64_dataLength; i++)
52  {
53  ssd1306_sendCommand(pgm_read_byte(&s_oled128x64_initData[i]));
54  }
55 }
56 
58 {
59  ssd1306_i2cInit();
60  ssd1306_endTransmission();
61  s_displayHeight = 32;
62  for( uint8_t i=0; i<s_oled128x32_dataLength; i++)
63  {
64  ssd1306_sendCommand(pgm_read_byte(&s_oled128x32_initData[i]));
65  }
66 }
67 
68 void ssd1306_setRamBlock(uint8_t x, uint8_t y, uint8_t w)
69 {
70  ssd1306_startTransmission();
71  ssd1306_sendByte(0x00); //write command
72  ssd1306_sendByte(SSD1306_COLUMNADDR);
73  ssd1306_sendByte(x);
74  ssd1306_sendByte(x + w - 1);
75  ssd1306_sendByte(0xb0+y);
76  ssd1306_sendByte((x>>4) | 0x10);
77  ssd1306_sendByte(x&0x0f);
78  ssd1306_endTransmission();
79 }
80 
81 void ssd1306_setPos(uint8_t x, uint8_t y)
82 {
83  ssd1306_startTransmission();
84  ssd1306_sendByte(0x00); //write command
85  ssd1306_sendByte(0xb0+y);
86  ssd1306_sendByte((x>>4) | 0x10);
87  ssd1306_sendByte(x&0x0f);
88  ssd1306_endTransmission();
89 }
90 
91 void ssd1306_sendData(uint8_t data)
92 {
93  ssd1306_dataStart();
94  ssd1306_sendByte( data );
95  ssd1306_endTransmission();
96 }
97 
98 
99 void ssd1306_fillScreen(uint8_t fill_Data)
100 {
101  fill_Data ^= s_invertByte;
102  ssd1306_setRamBlock(0, 0, 128);
103  ssd1306_dataStart();
104  for(uint8_t m=0; m<(s_displayHeight >> 3); m++)
105  {
106  for(uint8_t n=0; n<128; n++)
107  {
108  ssd1306_sendByte(fill_Data);
109  }
110  }
111  ssd1306_endTransmission();
112 }
113 
115 {
116  ssd1306_setRamBlock(0, 0, 128);
117  ssd1306_dataStart();
118  for(uint8_t m=0;m<(s_displayHeight >> 3);m++)
119  {
120  for(uint8_t n=0;n<128;n++)
121  {
122  ssd1306_sendByte(s_invertByte);
123  }
124  }
125  ssd1306_endTransmission();
126 }
127 
128 
130 {
131  ssd1306_sendCommand(SSD1306_DISPLAYOFF);
132 }
133 
134 
136 {
137  ssd1306_sendCommand(SSD1306_DISPLAYON);
138 }
139 
140 void ssd1306_charF6x8(uint8_t x, uint8_t y, const char ch[], EFontStyle style)
141 {
142  uint8_t c,i,j=0;
143  ssd1306_setRamBlock(0, 0, 128);
144  ssd1306_setPos(x,y);
145  ssd1306_dataStart();
146  while(ch[j] != '\0')
147  {
148  c = ch[j] - 32;
149  if(x>126)
150  {
151  x=0;
152  y++;
153  }
154  uint8_t ldata = 0;
155  for(i=0;i<6;i++)
156  {
157  uint8_t data;
158  if ( style == STYLE_NORMAL )
159  {
160  data = pgm_read_byte(&s_font6x8[c*6+i]);
161  }
162  else if ( style == STYLE_BOLD )
163  {
164  uint8_t temp = pgm_read_byte(&s_font6x8[c*6+i]);
165  data = temp | ldata;
166  ldata = temp;
167  }
168  else
169  {
170  uint8_t temp = pgm_read_byte(&s_font6x8[c*6+i + 1]);
171  data = (temp & 0xF0) | ldata;
172  ldata = (temp & 0x0F);
173  }
174  ssd1306_sendByte(data^s_invertByte);
175  }
176  x += 6;
177  j++;
178  }
179  ssd1306_endTransmission();
180 }
181 
182 void ssd1306_setFont6x8(const uint8_t * progmemFont)
183 {
184  s_font6x8 = progmemFont;
185 }
186 
187 void ssd1306_putPixel(uint8_t x, uint8_t y)
188 {
189  ssd1306_setRamBlock(0, y >> 3, 128);
190  ssd1306_setPos(x,y >> 3);
191  ssd1306_dataStart();
192  ssd1306_sendByte((1 << (y & 0x07))^s_invertByte);
193  ssd1306_endTransmission();
194 }
195 
196 void ssd1306_putPixels(uint8_t x, uint8_t y, uint8_t pixels)
197 {
198  ssd1306_setRamBlock(0, 0, 128);
199  ssd1306_setPos(x,y);
200  ssd1306_dataStart();
201  ssd1306_sendByte(pixels^s_invertByte);
202  ssd1306_endTransmission();
203 }
204 
205 void ssd1306_drawHLine(uint8_t x1, uint8_t y1, uint8_t x2)
206 {
207  ssd1306_setRamBlock(x1, y1 >> 3, x2 - x1 + 1);
208  ssd1306_dataStart();
209  for (uint8_t x = x1; x <= x2; x++)
210  {
211  ssd1306_sendByte((1 << (y1 & 0x07))^s_invertByte);
212  }
213  ssd1306_endTransmission();
214 }
215 
216 void ssd1306_drawVLine(uint8_t x1, uint8_t y1, uint8_t y2)
217 {
218  ssd1306_setRamBlock(x1, y1 >> 3, 1);
219  ssd1306_dataStart();
220  ssd1306_sendByte( (0xFF << (y1 & 0x07))^s_invertByte );
221  for ( uint8_t y = ((y1 >> 3) + 1); y <= ((y2 >> 3) - 1); y++)
222  {
223  ssd1306_sendByte( 0xFF^s_invertByte );
224  }
225  ssd1306_sendByte( (0xFF >> (0x07 - (y2 & 0x07)))^s_invertByte );
226  ssd1306_endTransmission();
227 }
228 
229 void ssd1306_drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
230 {
231  ssd1306_drawHLine(x1+1, y1, x2-1);
232  ssd1306_drawHLine(x1+1, y2, x2-1);
233  ssd1306_drawVLine(x1, y1, y2);
234  ssd1306_drawVLine(x2, y1, y2);
235 }
236 
237 void ssd1306_drawBuffer(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
238 {
239  uint8_t i, j;
240  ssd1306_setRamBlock(x, y, w);
241  ssd1306_dataStart();
242  for(j=0; j<(h >> 3); j++)
243  {
244  for(i=0;i<w;i++)
245  {
246  ssd1306_sendByte(s_invertByte^*buf++);
247  }
248  }
249  ssd1306_endTransmission();
250 }
251 
252 void ssd1306_drawBitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
253 {
254  uint8_t i, j;
255  ssd1306_setRamBlock(x, y, w);
256  ssd1306_dataStart();
257  for(j=0; j<(h >> 3); j++)
258  {
259  for(i=w;i>0;i--)
260  {
261  ssd1306_sendByte(s_invertByte^pgm_read_byte(buf++));
262  }
263  }
264  ssd1306_endTransmission();
265 }
266 
267 
268 void ssd1306_clearBlock(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
269 {
270  uint8_t i, j;
271  ssd1306_setRamBlock(x, y, w);
272  ssd1306_dataStart();
273  for(j=0; j<(h >> 3); j++)
274  {
275  for(i=w;i>0;i--)
276  {
277  ssd1306_sendByte(s_invertByte);
278  }
279  }
280  ssd1306_endTransmission();
281 }
282 
283 
284 void ssd1306_drawSpriteEx(uint8_t x, uint8_t y, uint8_t w, const uint8_t *sprite)
285 {
286  uint8_t i;
287  ssd1306_setPos(x,y);
288  ssd1306_dataStart();
289  for(i=0;i<w;i++)
290  {
291  ssd1306_sendByte(s_invertByte^pgm_read_byte(&sprite[i]));
292  }
293  ssd1306_endTransmission();
294 }
295 
296 
298 {
299  uint8_t posy = sprite->y >> 3;
300  uint8_t offsety = sprite->y & 0x7;
301  if (posy < (s_displayHeight >> 3))
302  {
303  ssd1306_setPos(sprite->x, posy);
304  ssd1306_dataStart();
305  for (uint8_t i=0; i < sprite->w; i++)
306  {
307  ssd1306_sendByte( s_invertByte^(pgm_read_byte( &sprite->data[i] ) << offsety) );
308  }
309  ssd1306_endTransmission();
310  }
311  if (offsety && (posy + 1 < (s_displayHeight >> 3)))
312  {
313  ssd1306_setPos(sprite->x, posy + 1);
314  ssd1306_dataStart();
315  for (uint8_t i=0; i < sprite->w; i++)
316  {
317  ssd1306_sendByte( s_invertByte^(pgm_read_byte( &sprite->data[i] ) >> (8 - offsety)) );
318  }
319  }
320  ssd1306_endTransmission();
321  sprite->lx = sprite->x;
322  sprite->ly = sprite->y;
323 }
324 
325 
327 {
328  uint8_t posy = sprite->y >> 3;
329  uint8_t offsety = sprite->y & 0x7;
330  ssd1306_setPos(sprite->x, posy);
331  ssd1306_dataStart();
332  for (uint8_t i=0; i < sprite->w; i++)
333  {
334  ssd1306_sendByte( s_invertByte );
335  }
336  ssd1306_endTransmission();
337  if (offsety)
338  {
339  ssd1306_setPos(sprite->x, posy + 1);
340  ssd1306_dataStart();
341  for (uint8_t i=0; i < sprite->w; i++)
342  {
343  ssd1306_sendByte( s_invertByte );
344  }
345  }
346  ssd1306_endTransmission();
347 }
348 
349 
351 {
352  uint8_t y1 = sprite->ly >> 3;
353  uint8_t y2 = (sprite->ly + 7) >> 3;
354  if (sprite->ly < sprite->y)
355  y2 = min(y2, (uint8_t)((sprite->y >> 3) - 1));
356  else
357  y1 = max(y1, (sprite->ly + 7) >> 3);
358  for(uint8_t y = y1; y <= y2; y++)
359  {
360  ssd1306_setPos(sprite->lx, y);
361  ssd1306_dataStart();
362  for(uint8_t x = sprite->lx; x < sprite->lx + sprite->w; x++)
363  {
364  ssd1306_sendByte( s_invertByte );
365  }
366  ssd1306_endTransmission();
367  }
368  if (sprite->lx != sprite->x)
369  {
370  uint8_t x1 = sprite->lx;
371  uint8_t x2 = sprite->lx + sprite->w - 1;
372  if (sprite->x < sprite->lx)
373  x1 = max(x1, sprite->x + sprite->w);
374  else
375  x2 = min((uint8_t)(sprite->x - 1), x2);
376  for(uint8_t y = sprite->ly >> 3; y <= (sprite->ly + 7) >> 3; y++)
377  {
378  ssd1306_setPos(x1, y);
379  ssd1306_dataStart();
380  for(uint8_t x = x1; x <= x2; x++)
381  {
382  ssd1306_sendByte( s_invertByte );
383  }
384  ssd1306_endTransmission();
385  }
386  }
387 }
388 
389 SPRITE ssd1306_createSprite(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data)
390 {
391  return {x,y,w,x,y,data,nullptr};
392 }
393 
394 void ssd1306_replaceSprite(SPRITE *sprite, const uint8_t *data)
395 {
396  sprite->data = data;
397 }
398 
400 {
401  ssd1306_sendCommand(SSD1306_INVERTDISPLAY);
402 }
403 
405 {
406  ssd1306_sendCommand(SSD1306_NORMALDISPLAY);
407 }
408 
410 {
411  s_invertByte = 0xFF;
412 }
413 
415 {
416  s_invertByte = 0x00;
417 }
void ssd1306_charF6x8(uint8_t x, uint8_t y, const char ch[], EFontStyle style)
Definition: ssd1306.cpp:140
void ssd1306_drawBitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
Definition: ssd1306.cpp:252
void ssd1306_negativeMode()
Definition: ssd1306.cpp:409
const uint8_t * data
Pointer to PROGMEM data, representing sprite image.
void ssd1306_displayOff()
Definition: ssd1306.cpp:129
void ssd1306_128x32_i2c_init()
Definition: ssd1306.cpp:57
uint8_t ssd1306_displayHeight()
Definition: ssd1306.cpp:33
void ssd1306_replaceSprite(SPRITE *sprite, const uint8_t *data)
Definition: ssd1306.cpp:394
void ssd1306_drawHLine(uint8_t x1, uint8_t y1, uint8_t x2)
Definition: ssd1306.cpp:205
void ssd1306_setFont6x8(const uint8_t *progmemFont)
Definition: ssd1306.cpp:182
void ssd1306_displayOn()
Definition: ssd1306.cpp:135
void ssd1306_drawVLine(uint8_t x1, uint8_t y1, uint8_t y2)
Definition: ssd1306.cpp:216
void ssd1306_128x64_i2c_init()
Definition: ssd1306.cpp:46
void ssd1306_positiveMode()
Definition: ssd1306.cpp:414
void ssd1306_putPixels(uint8_t x, uint8_t y, uint8_t pixels)
Definition: ssd1306.cpp:196
SPRITE ssd1306_createSprite(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data)
Definition: ssd1306.cpp:389
void ssd1306_drawSpriteEx(uint8_t x, uint8_t y, uint8_t w, const uint8_t *sprite)
Definition: ssd1306.cpp:284
void ssd1306_fillScreen(uint8_t fill_Data)
Definition: ssd1306.cpp:99
void ssd1306_drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
Definition: ssd1306.cpp:229
void ssd1306_clearScreen()
Definition: ssd1306.cpp:114
uint8_t y
draw position Y on the screen
void ssd1306_clearBlock(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
Definition: ssd1306.cpp:268
void ssd1306_invertMode()
Definition: ssd1306.cpp:399
uint8_t x
draw position X on the screen
void ssd1306_drawSprite(SPRITE *sprite)
Definition: ssd1306.cpp:297
void ssd1306_eraseTrace(SPRITE *sprite)
Definition: ssd1306.cpp:350
void ssd1306_drawBuffer(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
Definition: ssd1306.cpp:237
void ssd1306_eraseSprite(SPRITE *sprite)
Definition: ssd1306.cpp:326
void ssd1306_sendData(uint8_t data)
Definition: ssd1306.cpp:91
void ssd1306_setPos(uint8_t x, uint8_t y)
Definition: ssd1306.cpp:81
void ssd1306_normalMode()
Definition: ssd1306.cpp:404
uint8_t w
sprite width
void ssd1306_putPixel(uint8_t x, uint8_t y)
Definition: ssd1306.cpp:187
uint8_t lx
last draw position X on the screen
EFontStyle
uint8_t ly
last draw position Y on the screen