Update oXs_out_frsky.cpp
[openXsensor.git] / locator_receiver / SSD1306Ascii.cpp
blobdc49fb61a4502221c7d03340b55488273029c763
1 /* Arduino SSD1306Ascii Library
2 * Copyright (C) 2015 by William Greiman
4 * This file is part of the Arduino SSD1306Ascii Library
6 * This Library 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.
11 * This Library 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.
16 * You should have received a copy of the GNU General Public License
17 * along with the Arduino SSD1306Ascii Library. If not, see
18 * <http://www.gnu.org/licenses/>.
20 #include "SSD1306Ascii.h"
21 //------------------------------------------------------------------------------
22 uint8_t SSD1306Ascii::charWidth(uint8_t c) const {
23 if (!m_font) {
24 return 0;
26 uint8_t first = readFontByte(m_font + FONT_FIRST_CHAR);
27 uint8_t count = readFontByte(m_font + FONT_CHAR_COUNT);
28 if (c < first || c >= (first + count)) {
29 return 0;
31 if (fontSize() > 1) {
32 // Proportional font.
33 return m_magFactor*readFontByte(m_font + FONT_WIDTH_TABLE + c - first);
35 // Fixed width font.
36 return m_magFactor*readFontByte(m_font + FONT_WIDTH);
38 //------------------------------------------------------------------------------
39 void SSD1306Ascii::clear() {
40 #if INCLUDE_SCROLLING
41 m_pageOffset = 0;
42 setStartLine(0);
43 #endif // INCLUDE_SCROLLING
44 clear(0, displayWidth() - 1, 0 , displayRows() - 1);
46 //------------------------------------------------------------------------------
47 void SSD1306Ascii::clear(uint8_t c0, uint8_t c1, uint8_t r0, uint8_t r1) {
48 if (r1 >= displayRows()) r1 = displayRows() - 1;
49 for (uint8_t r = r0; r <= r1; r++) {
50 setCursor(c0, r);
51 for (uint8_t c = c0; c <= c1; c++) {
52 // Insure clear() writes zero. result is (m_invertMask^m_invertMask).
53 ssd1306WriteRamBuf(m_invertMask);
56 setCursor(c0, r0);
58 //------------------------------------------------------------------------------
59 void SSD1306Ascii::clearToEOL() {
60 clear(m_col, displayWidth() -1, m_row, m_row + fontRows() - 1);
62 //------------------------------------------------------------------------------
63 void SSD1306Ascii::clearField(uint8_t col, uint8_t row, uint8_t n) {
64 clear(col, col + fieldWidth(n) - 1, row, row + fontRows() - 1);
66 //------------------------------------------------------------------------------
67 void SSD1306Ascii::displayRemap(bool mode) {
68 ssd1306WriteCmd(mode ? SSD1306_SEGREMAP : SSD1306_SEGREMAP | 1);
69 ssd1306WriteCmd(mode ? SSD1306_COMSCANINC : SSD1306_COMSCANDEC);
71 //------------------------------------------------------------------------------
72 size_t SSD1306Ascii::fieldWidth(uint8_t n) {
73 return n*(fontWidth() + letterSpacing());
75 //------------------------------------------------------------------------------
76 uint8_t SSD1306Ascii::fontCharCount() const {
77 return m_font ? readFontByte(m_font + FONT_CHAR_COUNT) : 0;
79 //------------------------------------------------------------------------------
80 char SSD1306Ascii::fontFirstChar() const {
81 return m_font ? readFontByte(m_font + FONT_FIRST_CHAR) : 0;
83 //------------------------------------------------------------------------------
84 uint8_t SSD1306Ascii::fontHeight() const {
85 return m_font ? m_magFactor*readFontByte(m_font + FONT_HEIGHT) : 0;
87 //------------------------------------------------------------------------------
88 uint8_t SSD1306Ascii::fontRows() const {
89 return m_font ? m_magFactor*((readFontByte(m_font + FONT_HEIGHT) + 7)/8) : 0;
91 //------------------------------------------------------------------------------
92 uint16_t SSD1306Ascii::fontSize() const {
93 return (readFontByte(m_font) << 8) | readFontByte(m_font + 1);
95 //------------------------------------------------------------------------------
96 uint8_t SSD1306Ascii::fontWidth() const {
97 return m_font ? m_magFactor*readFontByte(m_font + FONT_WIDTH) : 0;
99 //------------------------------------------------------------------------------
100 void SSD1306Ascii::init(const DevType* dev) {
101 m_col = 0;
102 m_row = 0;
103 #ifdef __AVR__
104 const uint8_t* table = (const uint8_t*)pgm_read_word(&dev->initcmds);
105 #else // __AVR__
106 const uint8_t* table = dev->initcmds;
107 #endif // __AVR
108 uint8_t size = readFontByte(&dev->initSize);
109 m_displayWidth = readFontByte(&dev->lcdWidth);
110 m_displayHeight = readFontByte(&dev->lcdHeight);
111 m_colOffset = readFontByte(&dev->colOffset);
112 for (uint8_t i = 0; i < size; i++) {
113 ssd1306WriteCmd(readFontByte(table + i));
115 clear();
117 //------------------------------------------------------------------------------
118 void SSD1306Ascii::invertDisplay(bool invert) {
119 ssd1306WriteCmd(invert ? SSD1306_INVERTDISPLAY : SSD1306_NORMALDISPLAY);
121 //------------------------------------------------------------------------------
122 void SSD1306Ascii::setCol(uint8_t col) {
123 if (col >= m_displayWidth) return;
124 m_col = col;
125 col += m_colOffset;
126 ssd1306WriteCmd(SSD1306_SETLOWCOLUMN | (col & 0XF));
127 ssd1306WriteCmd(SSD1306_SETHIGHCOLUMN | (col >> 4));
129 //------------------------------------------------------------------------------
130 void SSD1306Ascii::setContrast(uint8_t value) {
131 ssd1306WriteCmd(SSD1306_SETCONTRAST);
132 ssd1306WriteCmd(value);
134 //------------------------------------------------------------------------------
135 void SSD1306Ascii::setCursor(uint8_t col, uint8_t row) {
136 setCol(col);
137 setRow(row);
139 //------------------------------------------------------------------------------
140 void SSD1306Ascii::setFont(const uint8_t* font) {
141 m_font = font;
142 if (font && fontSize() == 1) {
143 m_letterSpacing = 0;
144 } else {
145 m_letterSpacing = 1;
148 //------------------------------------------------------------------------------
149 void SSD1306Ascii::setRow(uint8_t row) {
150 if (row >= displayRows()) {
151 return;
153 m_row = row;
154 #if INCLUDE_SCROLLING
155 ssd1306WriteCmd(SSD1306_SETSTARTPAGE | ((m_row + m_pageOffset) & 7));
156 #else // INCLUDE_SCROLLING
157 ssd1306WriteCmd(SSD1306_SETSTARTPAGE | m_row);
158 #endif // INCLUDE_SCROLLING
160 #if INCLUDE_SCROLLING
161 //------------------------------------------------------------------------------
162 void SSD1306Ascii::setPageOffset(uint8_t page) {
163 m_pageOffset = page & 7;
164 setRow(m_row);
166 //------------------------------------------------------------------------------
167 void SSD1306Ascii::setStartLine(uint8_t line) {
168 m_startLine = line & 0X3F;
169 ssd1306WriteCmd(SSD1306_SETSTARTLINE | m_startLine);
171 #endif // INCLUDE_SCROLLING
172 //-----------------------------------------------------------------------------
173 void SSD1306Ascii::ssd1306WriteRam(uint8_t c) {
174 if (m_col >= m_displayWidth) return;
175 writeDisplay(c^m_invertMask, SSD1306_MODE_RAM);
176 m_col++;
178 //-----------------------------------------------------------------------------
179 void SSD1306Ascii::ssd1306WriteRamBuf(uint8_t c) {
180 if (m_col >= m_displayWidth) return;
181 writeDisplay(c^m_invertMask, SSD1306_MODE_RAM_BUF);
182 m_col++;
184 //------------------------------------------------------------------------------
185 GLCDFONTDECL(scaledNibble) = {
186 0X00, 0X03, 0X0C, 0X0F,
187 0X30, 0X33, 0X3C, 0X3F,
188 0XC0, 0XC3, 0XCC, 0XCF,
189 0XF0, 0XF3, 0XFC, 0XFF
191 //------------------------------------------------------------------------------
192 size_t SSD1306Ascii::strWidth(const char* str) const {
193 size_t sw = 0;
194 while (*str) {
195 uint8_t cw = charWidth(*str++);
196 if (cw == 0) {
197 return 0;
199 sw += cw + letterSpacing();
201 return sw;
203 //------------------------------------------------------------------------------
204 size_t SSD1306Ascii::write(uint8_t ch) {
205 if (!m_font) {
206 return 0;
208 uint8_t w = readFontByte(m_font + FONT_WIDTH);
209 uint8_t h = readFontByte(m_font + FONT_HEIGHT);
210 uint8_t nr = (h + 7)/8;
211 uint8_t first = readFontByte(m_font + FONT_FIRST_CHAR);
212 uint8_t count = readFontByte(m_font + FONT_CHAR_COUNT);
213 const uint8_t* base = m_font + FONT_WIDTH_TABLE;
215 if (ch < first || ch >= (first + count)) {
216 if (ch == '\r') {
217 setCol(0);
218 return 1;
220 if (ch == '\n') {
221 setCol(0);
222 uint8_t fr = m_magFactor*nr;
223 #if INCLUDE_SCROLLING
224 uint8_t dr = displayRows();
225 uint8_t tmpRow = m_row + fr;
226 int8_t delta = tmpRow + fr - dr;
227 if (m_scrollMode == SCROLL_MODE_OFF || delta <= 0) {
228 setRow(tmpRow);
229 } else {
230 m_pageOffset = (m_pageOffset + delta) & 7;
231 m_row = dr - fr;
232 // Cursor will be positioned by clearToEOL.
233 clearToEOL();
234 if (m_scrollMode == SCROLL_MODE_AUTO) {
235 setStartLine(8*m_pageOffset);
238 #else // INCLUDE_SCROLLING
239 setRow(m_row + fr);
240 #endif // INCLUDE_SCROLLING
241 return 1;
243 return 0;
245 ch -= first;
246 uint8_t s = letterSpacing();
247 uint8_t thieleShift = 0;
248 if (fontSize() < 2) {
249 // Fixed width font.
250 base += nr*w*ch;
251 } else {
252 if (h & 7) {
253 thieleShift = 8 - (h & 7);
255 uint16_t index = 0;
256 for (uint8_t i = 0; i < ch; i++) {
257 index += readFontByte(base + i);
259 w = readFontByte(base + ch);
260 base += nr*index + count;
262 uint8_t scol = m_col;
263 uint8_t srow = m_row;
264 for (uint8_t r = 0; r < nr; r++) {
265 for (uint8_t m = 0; m < m_magFactor; m++) {
266 if (r || m) setCursor(scol, m_row + 1);
267 for (uint8_t c = 0; c < w; c++) {
268 uint8_t b = readFontByte(base + c + r*w);
269 if (thieleShift && (r + 1) == nr) {
270 b >>= thieleShift;
272 if (m_magFactor == 2) {
273 b = m ? b >> 4 : b & 0XF;
274 b = readFontByte(scaledNibble + b);
275 ssd1306WriteRamBuf(b);
277 ssd1306WriteRamBuf(b);
279 for (uint8_t i = 0; i < s; i++) {
280 ssd1306WriteRamBuf(0);
284 setRow(srow);
285 return 1;