Skip to content

Commit 2e48df9

Browse files
authored
Merge branch 'master' into cleanup-warnings
2 parents ca4e8b7 + aaa38d8 commit 2e48df9

File tree

22 files changed

+987
-188
lines changed

22 files changed

+987
-188
lines changed

OLEDDisplay.cpp

Lines changed: 85 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -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() {
6363
void 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+
7579
void 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

224229
void 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

257262
void 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+
555565
void 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+
560575
void OLEDDisplay::clear(void) {
561-
memset(buffer, 0, DISPLAY_BUFFER_SIZE);
576+
memset(buffer, 0, displayBufferSize);
562577
}
563578

564579
void 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+
596619
bool 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!
786806
char* 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

Comments
 (0)