SSD1306 OLED display driver  1.7.6
This library is developed to control SSD1306/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays
ssd1306_generic.c
1 /*
2  MIT License
3 
4  Copyright (c) 2016-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 
28 
29 #include "ssd1306.h"
30 #include "ssd1306_fonts.h"
31 #include "lcd/lcd_common.h"
32 #include "intf/i2c/ssd1306_i2c.h"
33 #include "intf/spi/ssd1306_spi.h"
34 #include "intf/ssd1306_interface.h"
35 #include "ssd1306_hal/io.h"
36 #include "nano_gfx_types.h"
37 
38 uint16_t ssd1306_color = 0xFFFF;
39 lcduint_t ssd1306_cursorX = 0;
40 lcduint_t ssd1306_cursorY = 0;
42 #ifdef CONFIG_SSD1306_UNICODE_ENABLE
43 uint8_t g_ssd1306_unicode = 1;
44 #endif
45 
47 {
48  return ssd1306_lcd.height;
49 }
50 
52 {
53  return ssd1306_lcd.width;
54 }
55 
56 void ssd1306_setCursor(lcdint_t x, lcdint_t y)
57 {
58  ssd1306_cursorX = x;
59  ssd1306_cursorY = y;
60 }
61 
62 void ssd1306_setFixedFont(const uint8_t * progmemFont)
63 {
64  s_fixedFont.h.type = pgm_read_byte(&progmemFont[0]);
65  s_fixedFont.h.width = pgm_read_byte(&progmemFont[1]);
66  s_fixedFont.h.height = pgm_read_byte(&progmemFont[2]);
67  s_fixedFont.h.ascii_offset = pgm_read_byte(&progmemFont[3]);
68  s_fixedFont.pages = (s_fixedFont.h.height + 7) >> 3;
69  s_fixedFont.glyph_size = s_fixedFont.pages * s_fixedFont.h.width;
70  s_fixedFont.primary_table = progmemFont + sizeof(SFontHeaderRecord);
71 #ifdef CONFIG_SSD1306_UNICODE_ENABLE
72  s_fixedFont.secondary_table = NULL;
73 #endif
74 }
75 
76 void ssd1306_setSecondaryFont(const uint8_t * progmemUnicode)
77 {
78  s_fixedFont.secondary_table = progmemUnicode;
79  if (s_fixedFont.secondary_table != NULL)
80  {
81  s_fixedFont.secondary_table += sizeof(SFontHeaderRecord);
82  }
83 }
84 
85 void ssd1306_getCharBitmap(char ch, SCharInfo *info)
86 {
87  if (info)
88  {
89  info->width = s_fixedFont.h.width;
90  info->height = s_fixedFont.h.height;
91  info->data = ssd1306_getCharGlyph( ch );
92  }
93 }
94 
95 const uint8_t *ssd1306_getCharGlyph(char ch)
96 {
97  return &s_fixedFont.primary_table[ (ch - s_fixedFont.h.ascii_offset) *
98  s_fixedFont.glyph_size +
99  (s_fixedFont.h.type == 0x01 ? sizeof(SUnicodeBlockRecord) : 0) ];
100 }
101 
102 #ifdef CONFIG_SSD1306_UNICODE_ENABLE
103 static void ssd1306_readUnicodeRecord(SUnicodeBlockRecord *r, const uint8_t *p)
104 {
105  r->start_code = pgm_read_byte(&p[0]) | (pgm_read_byte(&p[1]) << 8);
106  r->count = pgm_read_byte(&p[2]) | (pgm_read_byte(&p[3]) << 8);
107 }
108 #endif
109 
110 static const uint8_t *ssd1306_searchCharGlyph(const uint8_t * unicode_table, uint16_t unicode)
111 {
113  const uint8_t *data = unicode_table;
114  // looking for required unicode table
115  while (1)
116  {
117  ssd1306_readUnicodeRecord( &r, data );
118  if (r.count == 0)
119  {
120  break;
121  }
122  data += sizeof(SUnicodeBlockRecord);
123  if ( ( unicode >= r.start_code) && ( unicode < (r.start_code + r.count) ) )
124  {
125  break;
126  }
127  data += r.count * s_fixedFont.glyph_size;
128  }
129  if (r.count == 0)
130  {
131  // Sorry, no glyph found for the specified character
132  return NULL;
133  }
134  return &data[ (unicode - r.start_code) * s_fixedFont.glyph_size ];
135 }
136 
137 const uint8_t *ssd1306_getU16CharGlyph(uint16_t unicode)
138 {
139 #ifdef CONFIG_SSD1306_UNICODE_ENABLE
140  const uint8_t * glyph = NULL;
141  if ((unicode < 128) && (s_fixedFont.h.type == 0x00) && (s_fixedFont.primary_table != NULL))
142  {
143  return ssd1306_getCharGlyph(unicode);
144  }
145  if (s_fixedFont.primary_table)
146  {
147  glyph = ssd1306_searchCharGlyph( s_fixedFont.primary_table, unicode );
148  }
149  if (!glyph && s_fixedFont.secondary_table)
150  {
151  glyph = ssd1306_searchCharGlyph( s_fixedFont.secondary_table, unicode );
152  }
153  if (!glyph)
154  {
155  return ssd1306_getCharGlyph( s_fixedFont.h.ascii_offset );
156  }
157  return glyph;
158 #else
159  return ssd1306_getCharGlyph(unicode);
160 #endif
161 }
162 
163 uint16_t ssd1306_unicode16FromUtf8(uint8_t ch)
164 {
165  static uint16_t unicode = 0;
166  ch &= 0x000000FF;
167  if (!unicode)
168  {
169  if ( ch >= 0xc0 )
170  {
171  unicode = ch;
173  }
174  return ch;
175  }
176  uint16_t code = ((unicode & 0x1f) << 6) | (ch & 0x3f);
177  unicode = 0;
178  return code;
179 }
180 
182 {
183 #ifdef CONFIG_SSD1306_UNICODE_ENABLE
184  g_ssd1306_unicode = 1;
185 #endif
186 }
187 
189 {
190 #ifdef CONFIG_SSD1306_UNICODE_ENABLE
191  g_ssd1306_unicode = 0;
192 #endif
193 }
void ssd1306_setCursor(lcdint_t x, lcdint_t y)
Sets cursor position for text mode print functions.
const uint8_t * data
char data, located in progmem.
uint8_t height
char height in pixels
const uint8_t * primary_table
font chars bits
void ssd1306_enableUtf8Mode()
uint16_t start_code
unicode start code
uint8_t width
width in pixels
uint8_t type
font type: 0 - Fixed Font
uint8_t height
height in pixels
uint8_t ssd1306_displayWidth()
uint8_t ascii_offset
ascii offset
ssd1306_lcd_t ssd1306_lcd
Definition: lcd_common.c:32
void ssd1306_setFixedFont(const uint8_t *progmemFont)
uint8_t count
count of unicode chars in block
lcduint_t height
Definition: lcd_common.h:97
uint8_t width
char width in pixels
const uint8_t * secondary_table
font chars bits
SFixedFontInfo s_fixedFont
SFontHeaderRecord h
record, containing information on font
void ssd1306_setSecondaryFont(const uint8_t *progmemUnicode)
void ssd1306_getCharBitmap(char ch, SCharInfo *info)
returns char data for currently set (active) font.
#define SSD1306_MORE_CHARS_REQUIRED
Definition: ssd1306_fonts.h:44
uint8_t ssd1306_displayHeight()
lcduint_t width
Definition: lcd_common.h:94
uint8_t glyph_size
glyph size in bytes
uint8_t pages
height in pages (each page height is 8-pixels)
void ssd1306_enableAsciiMode()