SSD1306 OLED display driver  1.6.3
This library is developed to control SSD1306/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays
ssd1331_api.c
1 /*
2  MIT License
3 
4  Copyright (c) 2018, 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 "ssd1306.h"
26 #include "ssd1331_api.h"
27 #include "intf/ssd1306_interface.h"
28 #include "intf/spi/ssd1306_spi.h"
29 #include "ssd1306_hal/io.h"
30 
31 #include "lcd/ssd1331_commands.h"
32 #include "lcd/lcd_common.h"
33 
34 #define swap_data(a, b ,type) { type t = a; a = b; b = t; }
35 
36 extern uint16_t ssd1306_color;
37 extern uint8_t s_ssd1306_invertByte;
38 extern lcduint_t ssd1306_cursorX;
39 extern lcduint_t ssd1306_cursorY;
41 
42 void ssd1331_setColor(uint16_t color)
43 {
44  ssd1306_color = color;
45 }
46 
47 void ssd1331_setRgbColor(uint8_t r, uint8_t g, uint8_t b)
48 {
49  ssd1306_color = RGB_COLOR8(r,g,b);
50 }
51 
52 void ssd1331_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint16_t color)
53 {
56  ssd1306_intf.send(SSD1331_DRAWLINE);
57  ssd1306_intf.send(x1);
58  ssd1306_intf.send(y1);
59  ssd1306_intf.send(x2);
60  ssd1306_intf.send(y2);
61  ssd1306_intf.send( (color & 0x03) << 4 );
62  ssd1306_intf.send( (color & 0x1C) << 2 );
63  ssd1306_intf.send( (color & 0xE0) >> 2 );
65 }
66 
67 void ssd1331_drawMonoBuffer8(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
68 {
69  uint8_t bit = 1;
70  uint8_t blackColor = s_ssd1306_invertByte ? ssd1306_color : 0x00;
71  uint8_t color = s_ssd1306_invertByte ? 0x00 : ssd1306_color;
72  ssd1306_lcd.set_block(xpos, ypos, w);
73  while (h--)
74  {
75  uint8_t wx = w;
76  while (wx--)
77  {
78  uint8_t data = *bitmap;
79  if ( data & bit )
80  ssd1306_lcd.send_pixels8( color );
81  else
82  ssd1306_lcd.send_pixels8( blackColor );
83  bitmap++;
84  }
85  bit <<= 1;
86  if (bit == 0)
87  {
88  bit = 1;
89  }
90  else
91  {
92  bitmap -= w;
93  }
94  }
96 }
97 
98 void ssd1331_drawBufferFast8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
99 {
100  uint16_t count = w * h;
101  ssd1306_lcd.set_block(x, y, w);
102  while (count--)
103  {
104  ssd1306_lcd.send_pixels8( *data );
105  data++;
106  }
107  ssd1306_intf.stop();
108 }
109 
110 void ssd1331_drawBufferFast16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
111 {
112  uint16_t count = (w * h) << 1;
113  ssd1306_lcd.set_block(x, y, w);
114  while (count--)
115  {
116  ssd1306_intf.send( *data );
117  data++;
118  }
119  ssd1306_intf.stop();
120 }
121 
122 void ssd1331_fillScreen8(uint8_t fill_Data)
123 {
124  ssd1306_lcd.set_block(0, 0, 0);
125  uint16_t count = ssd1306_lcd.width * ssd1306_lcd.height;
126  while (count--)
127  {
128  ssd1306_lcd.send_pixels8( fill_Data );
129  }
130  ssd1306_intf.stop();
131 }
132 
134 {
135  ssd1331_fillScreen8( 0x00 );
136 }
137 
139 {
140  ssd1306_lcd.set_block(x, y, 0);
141  ssd1306_lcd.send_pixels8( ssd1306_color );
142  ssd1306_intf.stop();
143 }
144 
146 {
147  ssd1306_lcd.set_block(x1, y1, 1);
148  while (y1<=y2)
149  {
150  ssd1306_lcd.send_pixels8( ssd1306_color );
151  y1++;
152  }
153  ssd1306_intf.stop();
154 }
155 
157 {
158  ssd1306_lcd.set_block(x1, y1, 0);
159  while (x1 < x2)
160  {
161  ssd1306_lcd.send_pixels8( ssd1306_color );
162  x1++;
163  }
164  ssd1306_intf.stop();
165 }
166 
168 {
169  lcduint_t dx = x1 > x2 ? (x1 - x2): (x2 - x1);
170  lcduint_t dy = y1 > y2 ? (y1 - y2): (y2 - y1);
171  lcduint_t err = 0;
172  if (dy > dx)
173  {
174  if (y1 > y2)
175  {
176  swap_data(x1, x2, lcdint_t);
177  swap_data(y1, y2, lcdint_t);
178  }
179  for(; y1<=y2; y1++)
180  {
181  err += dx;
182  if (err >= dy)
183  {
184  err -= dy;
185  x1 < x2 ? x1++: x1--;
186  }
187  ssd1331_putPixel8( x1, y1 );
188  }
189  }
190  else
191  {
192  if (x1 > x2)
193  {
194  swap_data(x1, x2, lcdint_t);
195  swap_data(y1, y2, lcdint_t);
196  }
197  for(; x1<=x2; x1++)
198  {
199  err += dy;
200  if (err >= dx)
201  {
202  err -= dx;
203  if (y1 < y2) y1++; else y1--;
204  }
205  ssd1331_putPixel8( x1, y1 );
206  }
207  }
208 }
209 
211 {
212  ssd1331_drawHLine8(x1,y1,x2);
213  ssd1331_drawHLine8(x1,y2,x2);
214  ssd1331_drawVLine8(x1,y1,y2);
215  ssd1331_drawVLine8(x2,y1,y2);
216 }
217 
219 {
220  if (y1 > y2)
221  {
222  swap_data(y1, y2, lcdint_t);
223  }
224  if (x1 > x2)
225  {
226  swap_data(x1, x2, lcdint_t);
227  }
228  ssd1306_lcd.set_block(x1, y1, x2 - x1 + 1);
229  uint16_t count = (x2 - x1 + 1) * (y2 - y1 + 1);
230  while (count--)
231  {
232  ssd1306_lcd.send_pixels8( ssd1306_color );
233  }
234  ssd1306_intf.stop();
235 }
236 
237 void ssd1331_drawMonoBitmap8(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
238 {
239  uint8_t bit = 1;
240  uint8_t blackColor = s_ssd1306_invertByte ? ssd1306_color : 0x00;
241  uint8_t color = s_ssd1306_invertByte ? 0x00 : ssd1306_color;
242  ssd1306_lcd.set_block(xpos, ypos, w);
243  while (h--)
244  {
245  uint8_t wx = w;
246  while (wx--)
247  {
248  uint8_t data = pgm_read_byte( bitmap );
249  if ( data & bit )
250  ssd1306_lcd.send_pixels8( color );
251  else
252  ssd1306_lcd.send_pixels8( blackColor );
253  bitmap++;
254  }
255  bit <<= 1;
256  if (bit == 0)
257  {
258  bit = 1;
259  }
260  else
261  {
262  bitmap -= w;
263  }
264  }
265  ssd1306_intf.stop();
266 }
267 
268 void ssd1331_drawBitmap8(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
269 {
270  ssd1306_lcd.set_block(xpos, ypos, w);
271  uint16_t count = (w) * (h);
272  while (count--)
273  {
274  ssd1306_lcd.send_pixels8( pgm_read_byte( bitmap ) );
275  bitmap++;
276  }
277  ssd1306_intf.stop();
278 }
279 
280 void ssd1331_clearBlock8(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
281 {
282  ssd1306_lcd.set_block(x, y, w);
283  uint16_t count = w * h;
284  while (count--)
285  {
286  ssd1306_lcd.send_pixels8( 0x00 );
287  }
288  ssd1306_intf.stop();
289 }
290 
292 {
293  ssd1306_cursorX = x;
294  ssd1306_cursorY = y;
295 }
296 
297 void ssd1331_printChar8(uint8_t c)
298 {
299  c -= s_fixedFont.ascii_offset;
300  ssd1331_drawMonoBitmap8(ssd1306_cursorX,
301  ssd1306_cursorY,
302  s_fixedFont.width,
303  s_fixedFont.height,
304  &s_fixedFont.data[ c * s_fixedFont.pages * s_fixedFont.width ] );
305 }
306 
307 size_t ssd1331_write8(uint8_t ch)
308 {
309  if (ch == '\r')
310  {
311  ssd1306_cursorX = 0;
312  return 0;
313  }
314  else if ( (ssd1306_cursorX > ssd1306_lcd.width - s_fixedFont.width) || (ch == '\n') )
315  {
316  ssd1306_cursorX = 0;
317  ssd1306_cursorY += s_fixedFont.height;
318  if ( ssd1306_cursorY > ssd1306_lcd.height - s_fixedFont.height )
319  {
320  ssd1306_cursorY = 0;
321  }
322  ssd1331_clearBlock8(0, ssd1306_cursorY, ssd1306_lcd.width, s_fixedFont.height);
323  if (ch == '\n')
324  {
325  return 0;
326  }
327  }
328  ch -= s_fixedFont.ascii_offset;
329  ssd1331_drawMonoBitmap8( ssd1306_cursorX,
330  ssd1306_cursorY,
331  s_fixedFont.width,
332  s_fixedFont.height,
333  &s_fixedFont.data[ ch * s_fixedFont.pages * s_fixedFont.width ] );
334  ssd1306_cursorX += s_fixedFont.width;
335  return 1;
336 }
337 
338 size_t ssd1331_print8(const char ch[])
339 {
340  size_t n = 0;
341  while (*ch)
342  {
343  n += ssd1331_write8(*ch);
344  ch++;
345  }
346  return n;
347 }
348 
349 uint8_t ssd1331_printFixed8(lcdint_t x, lcdint_t y, const char *ch, EFontStyle style)
350 {
351  ssd1306_cursorX = x;
352  ssd1306_cursorY = y;
353  return ssd1331_print8(ch);
354 }
355 
356 
unsigned int lcduint_t
Definition: io.h:42
void ssd1331_drawBufferFast16(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
Definition: ssd1331_api.c:110
void ssd1331_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint16_t color)
Definition: ssd1331_api.c:52
size_t ssd1331_write8(uint8_t ch)
Prints single character to display at current cursor position.
Definition: ssd1331_api.c:307
void ssd1331_fillRect8(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: ssd1331_api.c:218
void(* send)(uint8_t data)
void ssd1331_drawLine8(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: ssd1331_api.c:167
void ssd1331_drawHLine8(lcdint_t x1, lcdint_t y1, lcdint_t x2)
Definition: ssd1331_api.c:156
void ssd1331_drawBitmap8(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Definition: ssd1331_api.c:268
void ssd1331_clearScreen8()
Definition: ssd1331_api.c:133
#define RGB_COLOR8(r, g, b)
size_t ssd1331_print8(const char ch[])
Prints null-terminated string to display at current cursor position.
Definition: ssd1331_api.c:338
void(* set_block)(lcduint_t x, lcduint_t y, lcduint_t w)
Sets block in RAM of lcd display controller to write data to.
Definition: lcd_common.h:114
SFixedFontInfo s_fixedFont
Definition: tiler.h:39
void(* send_pixels8)(uint8_t data)
Sends RGB pixel encoded in 3-3-2 format to OLED driver. Sends RGB pixel encoded in 3-3-2 format to OL...
Definition: lcd_common.h:142
void ssd1306_spiDataMode(uint8_t mode)
Definition: ssd1306_spi.c:54
void ssd1331_setRgbColor(uint8_t r, uint8_t g, uint8_t b)
Sets default color.
Definition: ssd1331_api.c:47
uint8_t ascii_offset
ascii offset
void ssd1331_drawBufferFast8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
Definition: ssd1331_api.c:98
void ssd1331_drawRect8(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: ssd1331_api.c:210
ssd1306_lcd_t ssd1306_lcd
Definition: lcd_common.c:32
void ssd1331_setColor(uint16_t color)
Sets default color, generated by RGB_COLOR8 or RGB_COLOR16 macros.
Definition: ssd1331_api.c:42
void ssd1331_fillScreen8(uint8_t fill_Data)
Definition: ssd1331_api.c:122
void ssd1331_printChar8(uint8_t c)
Definition: ssd1331_api.c:297
ssd1306_interface_t ssd1306_intf
void ssd1331_setCursor8(lcduint_t x, lcduint_t y)
Definition: ssd1331_api.c:291
uint8_t ssd1331_printFixed8(lcdint_t x, lcdint_t y, const char *ch, EFontStyle style)
Definition: ssd1331_api.c:349
lcduint_t height
Definition: lcd_common.h:97
int lcdint_t
Definition: io.h:40
uint8_t width
width in pixels
void ssd1331_drawMonoBitmap8(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Definition: ssd1331_api.c:237
void ssd1331_putPixel8(lcdint_t x, lcdint_t y)
Definition: ssd1331_api.c:138
void ssd1331_drawMonoBuffer8(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Definition: ssd1331_api.c:67
lcduint_t width
Definition: lcd_common.h:94
const uint8_t * data
font chars bits
EFontStyle
uint8_t pages
height in pages (each page height is 8-pixels)
void ssd1331_drawVLine8(lcdint_t x1, lcdint_t y1, lcdint_t y2)
Definition: ssd1331_api.c:145
void ssd1331_clearBlock8(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
Definition: ssd1331_api.c:280
uint8_t height
height in pixels