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