@@ -32,14 +32,14 @@ bool OLEDDisplay::init() {
3232 DEBUG_OLEDDISPLAY (" [OLEDDISPLAY][init] Can't establish connection to display\n " );
3333 return false ;
3434 }
35- this ->buffer = (uint8_t *) malloc (sizeof (uint8_t ) * DISPLAY_BUFFER_SIZE );
35+ this ->buffer = (uint8_t *) malloc (sizeof (uint8_t ) * displayBufferSize );
3636 if (!this ->buffer ) {
3737 DEBUG_OLEDDISPLAY (" [OLEDDISPLAY][init] Not enough memory to create display\n " );
3838 return false ;
3939 }
4040
4141 #ifdef OLEDDISPLAY_DOUBLE_BUFFER
42- this ->buffer_back = (uint8_t *) malloc (sizeof (uint8_t ) * DISPLAY_BUFFER_SIZE );
42+ this ->buffer_back = (uint8_t *) malloc (sizeof (uint8_t ) * displayBufferSize );
4343 if (!this ->buffer_back ) {
4444 DEBUG_OLEDDISPLAY (" [OLEDDISPLAY][init] Not enough memory to create back buffer\n " );
4545 free (this ->buffer );
@@ -63,7 +63,7 @@ void OLEDDisplay::end() {
6363void OLEDDisplay::resetDisplay (void ) {
6464 clear ();
6565 #ifdef OLEDDISPLAY_DOUBLE_BUFFER
66- memset (buffer_back, 1 , DISPLAY_BUFFER_SIZE );
66+ memset (buffer_back, 1 , displayBufferSize );
6767 #endif
6868 display ();
6969}
@@ -72,12 +72,17 @@ void OLEDDisplay::setColor(OLEDDISPLAY_COLOR color) {
7272 this ->color = color;
7373}
7474
75+ OLEDDISPLAY_COLOR OLEDDisplay::getColor () {
76+ return this ->color ;
77+ }
78+
7579void OLEDDisplay::setPixel (int16_t x, int16_t y) {
76- if (x >= 0 && x < 128 && y >= 0 && y < 64 ) {
80+ if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) {
81+
7782 switch (color) {
78- case WHITE: buffer[x + (y / 8 ) * DISPLAY_WIDTH ] |= (1 << (y & 7 )); break ;
79- case BLACK: buffer[x + (y / 8 ) * DISPLAY_WIDTH ] &= ~(1 << (y & 7 )); break ;
80- case INVERSE: buffer[x + (y / 8 ) * DISPLAY_WIDTH ] ^= (1 << (y & 7 )); break ;
83+ case WHITE: buffer[x + (y / 8 ) * displayWidth ] |= (1 << (y & 7 )); break ;
84+ case BLACK: buffer[x + (y / 8 ) * displayWidth ] &= ~(1 << (y & 7 )); break ;
85+ case INVERSE: buffer[x + (y / 8 ) * displayWidth ] ^= (1 << (y & 7 )); break ;
8186 }
8287 }
8388}
@@ -222,21 +227,21 @@ void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) {
222227}
223228
224229void OLEDDisplay::drawHorizontalLine (int16_t x, int16_t y, int16_t length) {
225- if (y < 0 || y >= DISPLAY_HEIGHT ) { return ; }
230+ if (y < 0 || y >= displayHeight ) { return ; }
226231
227232 if (x < 0 ) {
228233 length += x;
229234 x = 0 ;
230235 }
231236
232- if ( (x + length) > DISPLAY_WIDTH ) {
233- length = (DISPLAY_WIDTH - x);
237+ if ( (x + length) > displayWidth ) {
238+ length = (displayWidth - x);
234239 }
235240
236241 if (length <= 0 ) { return ; }
237242
238243 uint8_t * bufferPtr = buffer;
239- bufferPtr += (y >> 3 ) * DISPLAY_WIDTH ;
244+ bufferPtr += (y >> 3 ) * displayWidth ;
240245 bufferPtr += x;
241246
242247 uint8_t drawBit = 1 << (y & 7 );
@@ -255,15 +260,15 @@ void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
255260}
256261
257262void OLEDDisplay::drawVerticalLine (int16_t x, int16_t y, int16_t length) {
258- if (x < 0 || x >= DISPLAY_WIDTH ) return ;
263+ if (x < 0 || x > displayWidth ) return ;
259264
260265 if (y < 0 ) {
261266 length += y;
262267 y = 0 ;
263268 }
264269
265- if ( (y + length) > DISPLAY_HEIGHT ) {
266- length = (DISPLAY_HEIGHT - y);
270+ if ( (y + length) > displayHeight ) {
271+ length = (displayHeight - y);
267272 }
268273
269274 if (length <= 0 ) return ;
@@ -273,7 +278,7 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
273278 uint8_t drawBit;
274279 uint8_t *bufferPtr = buffer;
275280
276- bufferPtr += (y >> 3 ) * DISPLAY_WIDTH ;
281+ bufferPtr += (y >> 3 ) * displayWidth ;
277282 bufferPtr += x;
278283
279284 if (yOffset) {
@@ -293,7 +298,7 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
293298 if (length < yOffset) return ;
294299
295300 length -= yOffset;
296- bufferPtr += DISPLAY_WIDTH ;
301+ bufferPtr += displayWidth ;
297302 }
298303
299304 if (length >= 8 ) {
@@ -303,14 +308,14 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
303308 drawBit = (color == WHITE) ? 0xFF : 0x00 ;
304309 do {
305310 *bufferPtr = drawBit;
306- bufferPtr += DISPLAY_WIDTH ;
311+ bufferPtr += displayWidth ;
307312 length -= 8 ;
308313 } while (length >= 8 );
309314 break ;
310315 case INVERSE:
311316 do {
312317 *bufferPtr = ~(*bufferPtr);
313- bufferPtr += DISPLAY_WIDTH ;
318+ bufferPtr += displayWidth ;
314319 length -= 8 ;
315320 } while (length >= 8 );
316321 break ;
@@ -347,11 +352,11 @@ void OLEDDisplay::drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16
347352 fillCircle (xRadius + maxProgressWidth, yRadius, innerRadius);
348353}
349354
350- void OLEDDisplay::drawFastImage (int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *image) {
355+ void OLEDDisplay::drawFastImage (int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *image) {
351356 drawInternal (xMove, yMove, width, height, image, 0 , 0 );
352357}
353358
354- void OLEDDisplay::drawXbm (int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *xbm) {
359+ void OLEDDisplay::drawXbm (int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *xbm) {
355360 int16_t widthInXbm = (width + 7 ) / 8 ;
356361 uint8_t data = 0 ;
357362
@@ -389,12 +394,12 @@ void OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, char* text, u
389394 xMove -= textWidth;
390395 break ;
391396 case TEXT_ALIGN_LEFT:
392- break ;
397+ break ;
393398 }
394399
395400 // Don't draw anything if it is not on the screen.
396- if (xMove + textWidth < 0 || xMove > DISPLAY_WIDTH ) {return ;}
397- if (yMove + textHeight < 0 || yMove > DISPLAY_HEIGHT ) {return ;}
401+ if (xMove + textWidth < 0 || xMove > displayWidth ) {return ;}
402+ if (yMove + textHeight < 0 || yMove > displayHeight ) {return ;}
398403
399404 for (uint16_t j = 0 ; j < textLength; j++) {
400405 int16_t xPos = xMove + cursorX;
@@ -527,7 +532,7 @@ void OLEDDisplay::setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment) {
527532 this ->textAlignment = textAlignment;
528533}
529534
530- void OLEDDisplay::setFont (const char *fontData) {
535+ void OLEDDisplay::setFont (const uint8_t *fontData) {
531536 this ->fontData = fontData;
532537}
533538
@@ -552,13 +557,23 @@ void OLEDDisplay::setContrast(char contrast) {
552557 sendCommand (contrast);
553558}
554559
560+ void OLEDDisplay::resetOrientation () {
561+ sendCommand (SEGREMAP);
562+ sendCommand (COMSCANINC); // Reset screen rotation or mirroring
563+ }
564+
555565void OLEDDisplay::flipScreenVertically () {
556566 sendCommand (SEGREMAP | 0x01 );
557567 sendCommand (COMSCANDEC); // Rotate screen 180 Deg
558568}
559569
570+ void OLEDDisplay::mirrorScreen () {
571+ sendCommand (SEGREMAP);
572+ sendCommand (COMSCANDEC); // Mirror screen
573+ }
574+
560575void OLEDDisplay::clear (void ) {
561- memset (buffer, 0 , DISPLAY_BUFFER_SIZE );
576+ memset (buffer, 0 , displayBufferSize );
562577}
563578
564579void OLEDDisplay::drawLogBuffer (uint16_t xMove, uint16_t yMove) {
@@ -593,6 +608,14 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
593608 }
594609}
595610
611+ uint16_t OLEDDisplay::getWidth (void ) {
612+ return displayWidth;
613+ }
614+
615+ uint16_t OLEDDisplay::getHeight (void ) {
616+ return displayHeight;
617+ }
618+
596619bool OLEDDisplay::setLogBuffer (uint16_t lines, uint16_t chars){
597620 if (logBuffer != NULL ) free (logBuffer);
598621 uint16_t size = lines * chars;
@@ -614,12 +637,17 @@ size_t OLEDDisplay::write(uint8_t c) {
614637 // Don't waste space on \r\n line endings, dropping \r
615638 if (c == 13 ) return 1 ;
616639
640+ // convert UTF-8 character to font table index
641+ c = (this ->fontTableLookupFunction )(c);
642+ // drop unknown character
643+ if (c == 0 ) return 1 ;
644+
617645 bool maxLineNotReached = this ->logBufferLine < this ->logBufferMaxLines ;
618646 bool bufferNotFull = this ->logBufferFilled < this ->logBufferSize ;
619647
620648 // Can we write to the buffer?
621649 if (bufferNotFull && maxLineNotReached) {
622- this ->logBuffer [logBufferFilled] = utf8ascii (c) ;
650+ this ->logBuffer [logBufferFilled] = c ;
623651 this ->logBufferFilled ++;
624652 // Keep track of lines written
625653 if (c == 10 ) this ->logBufferLine ++;
@@ -672,7 +700,8 @@ void OLEDDisplay::sendInitCommands(void) {
672700 sendCommand (SETDISPLAYCLOCKDIV);
673701 sendCommand (0xF0 ); // Increase speed of the display max ~96Hz
674702 sendCommand (SETMULTIPLEX);
675- sendCommand (0x3F );
703+ // sendCommand(0x3F);
704+ sendCommand (displayHeight - 1 );
676705 sendCommand (SETDISPLAYOFFSET);
677706 sendCommand (0x00 );
678707 sendCommand (SETSTARTLINE);
@@ -683,9 +712,21 @@ void OLEDDisplay::sendInitCommands(void) {
683712 sendCommand (SEGREMAP);
684713 sendCommand (COMSCANINC);
685714 sendCommand (SETCOMPINS);
686- sendCommand (0x12 );
715+
716+ if (geometry == GEOMETRY_128_64) {
717+ sendCommand (0x12 );
718+ } else if (geometry == GEOMETRY_128_32) {
719+ sendCommand (0x02 );
720+ }
721+
687722 sendCommand (SETCONTRAST);
688- sendCommand (0xCF );
723+
724+ if (geometry == GEOMETRY_128_64) {
725+ sendCommand (0xCF );
726+ } else if (geometry == GEOMETRY_128_32) {
727+ sendCommand (0x8F );
728+ }
729+
689730 sendCommand (SETPRECHARGE);
690731 sendCommand (0xF1 );
691732 sendCommand (DISPLAYALLON_RESUME);
@@ -694,10 +735,10 @@ void OLEDDisplay::sendInitCommands(void) {
694735 sendCommand (DISPLAYON);
695736}
696737
697- void inline OLEDDisplay::drawInternal (int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData) {
738+ void inline OLEDDisplay::drawInternal (int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) {
698739 if (width < 0 || height < 0 ) return ;
699- if (yMove + height < 0 || yMove > DISPLAY_HEIGHT ) return ;
700- if (xMove + width < 0 || xMove > DISPLAY_WIDTH ) return ;
740+ if (yMove + height < 0 || yMove > displayHeight ) return ;
741+ if (xMove + width < 0 || xMove > displayWidth ) return ;
701742
702743 uint8_t rasterHeight = 1 + ((height - 1 ) >> 3 ); // fast ceil(height / 8.0)
703744 int8_t yOffset = yMove & 7 ;
@@ -719,24 +760,24 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
719760 byte currentByte = pgm_read_byte (data + offset + i);
720761
721762 int16_t xPos = xMove + (i / rasterHeight);
722- int16_t yPos = ((yMove >> 3 ) + (i % rasterHeight)) * DISPLAY_WIDTH ;
763+ int16_t yPos = ((yMove >> 3 ) + (i % rasterHeight)) * displayWidth ;
723764
724765 int16_t dataPos = xPos + yPos;
725766
726- if (dataPos >= 0 && dataPos < DISPLAY_BUFFER_SIZE &&
727- xPos >= 0 && xPos < DISPLAY_WIDTH ) {
767+ if (dataPos >= 0 && dataPos < displayBufferSize &&
768+ xPos >= 0 && xPos < displayWidth ) {
728769
729770 if (yOffset >= 0 ) {
730771 switch (this ->color ) {
731772 case WHITE: buffer[dataPos] |= currentByte << yOffset; break ;
732773 case BLACK: buffer[dataPos] &= ~(currentByte << yOffset); break ;
733774 case INVERSE: buffer[dataPos] ^= currentByte << yOffset; break ;
734775 }
735- if (dataPos < (DISPLAY_BUFFER_SIZE - DISPLAY_WIDTH )) {
776+ if (dataPos < (displayBufferSize - displayWidth )) {
736777 switch (this ->color ) {
737- case WHITE: buffer[dataPos + DISPLAY_WIDTH ] |= currentByte >> (8 - yOffset); break ;
738- case BLACK: buffer[dataPos + DISPLAY_WIDTH ] &= ~(currentByte >> (8 - yOffset)); break ;
739- case INVERSE: buffer[dataPos + DISPLAY_WIDTH ] ^= currentByte >> (8 - yOffset); break ;
778+ case WHITE: buffer[dataPos + displayWidth ] |= currentByte >> (8 - yOffset); break ;
779+ case BLACK: buffer[dataPos + displayWidth ] &= ~(currentByte >> (8 - yOffset)); break ;
780+ case INVERSE: buffer[dataPos + displayWidth ] ^= currentByte >> (8 - yOffset); break ;
740781 }
741782 }
742783 } else {
@@ -761,27 +802,6 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
761802 }
762803}
763804
764- // Code form http://playground.arduino.cc/Main/Utf8ascii
765- uint8_t OLEDDisplay::utf8ascii (byte ascii) {
766- static uint8_t LASTCHAR;
767-
768- if ( ascii < 128 ) { // Standard ASCII-set 0..0x7F handling
769- LASTCHAR = 0 ;
770- return ascii;
771- }
772-
773- uint8_t last = LASTCHAR; // get last char
774- LASTCHAR = ascii;
775-
776- switch (last) { // conversion depnding on first UTF8-character
777- case 0xC2 : return (ascii); break ;
778- case 0xC3 : return (ascii | 0xC0 ); break ;
779- case 0x82 : if (ascii == 0xAC ) return (0x80 ); // special case Euro-symbol
780- }
781-
782- return 0 ; // otherwise: return zero, if character has to be ignored
783- }
784-
785805// You need to free the char!
786806char * OLEDDisplay::utf8ascii (String str) {
787807 uint16_t k = 0 ;
@@ -798,7 +818,7 @@ char* OLEDDisplay::utf8ascii(String str) {
798818 length--;
799819
800820 for (uint16_t i=0 ; i < length; i++) {
801- char c = utf8ascii (s[i]);
821+ char c = ( this -> fontTableLookupFunction ) (s[i]);
802822 if (c!=0 ) {
803823 s[k++]=c;
804824 }
@@ -809,3 +829,7 @@ char* OLEDDisplay::utf8ascii(String str) {
809829 // This will leak 's' be sure to free it in the calling function.
810830 return s;
811831}
832+
833+ void OLEDDisplay::setFontTableLookupFunction (FontTableLookupFunction function) {
834+ this ->fontTableLookupFunction = function;
835+ }
0 commit comments