Skip to content

Commit b1e52e0

Browse files
authored
Merge pull request #171 from TD-er/bugfix/memory_leaks
Merged lots of PR + fix some memory leaks
2 parents 9790e13 + 943dd44 commit b1e52e0

File tree

4 files changed

+98
-63
lines changed

4 files changed

+98
-63
lines changed

OLEDDisplay.cpp

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,35 @@
2727

2828
#include "OLEDDisplay.h"
2929

30+
OLEDDisplay::~OLEDDisplay() {
31+
end();
32+
}
33+
3034
bool OLEDDisplay::init() {
3135
if (!this->connect()) {
3236
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Can't establish connection to display\n");
3337
return false;
3438
}
39+
40+
if(this->buffer==NULL) {
3541
this->buffer = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize);
42+
3643
if(!this->buffer) {
3744
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create display\n");
3845
return false;
3946
}
47+
}
4048

4149
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
50+
if(this->buffer_back==NULL) {
4251
this->buffer_back = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize);
52+
4353
if(!this->buffer_back) {
4454
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create back buffer\n");
4555
free(this->buffer);
4656
return false;
4757
}
58+
}
4859
#endif
4960

5061
sendInitCommands();
@@ -54,10 +65,11 @@ bool OLEDDisplay::init() {
5465
}
5566

5667
void OLEDDisplay::end() {
57-
if (this->buffer) free(this->buffer);
68+
if (this->buffer) { free(this->buffer); this->buffer = NULL; }
5869
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
59-
if (this->buffer_back) free(this->buffer_back);
70+
if (this->buffer_back) { free(this->buffer_back); this->buffer_back = NULL; }
6071
#endif
72+
if (this->logBuffer != NULL) { free(this->logBuffer); this->logBuffer = NULL; }
6173
}
6274

6375
void OLEDDisplay::resetDisplay(void) {
@@ -77,12 +89,11 @@ OLEDDISPLAY_COLOR OLEDDisplay::getColor() {
7789
}
7890

7991
void OLEDDisplay::setPixel(int16_t x, int16_t y) {
80-
if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) {
81-
92+
if (x >= 0 && x < this->width() && y >= 0 && y < this->height()) {
8293
switch (color) {
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;
94+
case WHITE: buffer[x + (y / 8) * this->width()] |= (1 << (y & 7)); break;
95+
case BLACK: buffer[x + (y / 8) * this->width()] &= ~(1 << (y & 7)); break;
96+
case INVERSE: buffer[x + (y / 8) * this->width()] ^= (1 << (y & 7)); break;
8697
}
8798
}
8899
}
@@ -227,21 +238,21 @@ void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) {
227238
}
228239

229240
void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
230-
if (y < 0 || y >= displayHeight) { return; }
241+
if (y < 0 || y >= this->height()) { return; }
231242

232243
if (x < 0) {
233244
length += x;
234245
x = 0;
235246
}
236247

237-
if ( (x + length) > displayWidth) {
238-
length = (displayWidth - x);
248+
if ( (x + length) > this->width()) {
249+
length = (this->width() - x);
239250
}
240251

241252
if (length <= 0) { return; }
242253

243254
uint8_t * bufferPtr = buffer;
244-
bufferPtr += (y >> 3) * displayWidth;
255+
bufferPtr += (y >> 3) * this->width();
245256
bufferPtr += x;
246257

247258
uint8_t drawBit = 1 << (y & 7);
@@ -260,15 +271,15 @@ void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
260271
}
261272

262273
void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
263-
if (x < 0 || x > displayWidth) return;
274+
if (x < 0 || x >= this->width()) return;
264275

265276
if (y < 0) {
266277
length += y;
267278
y = 0;
268279
}
269280

270-
if ( (y + length) > displayHeight) {
271-
length = (displayHeight - y);
281+
if ( (y + length) > this->height()) {
282+
length = (this->height() - y);
272283
}
273284

274285
if (length <= 0) return;
@@ -278,7 +289,7 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
278289
uint8_t drawBit;
279290
uint8_t *bufferPtr = buffer;
280291

281-
bufferPtr += (y >> 3) * displayWidth;
292+
bufferPtr += (y >> 3) * this->width();
282293
bufferPtr += x;
283294

284295
if (yOffset) {
@@ -298,7 +309,7 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
298309
if (length < yOffset) return;
299310

300311
length -= yOffset;
301-
bufferPtr += displayWidth;
312+
bufferPtr += this->width();
302313
}
303314

304315
if (length >= 8) {
@@ -308,14 +319,14 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
308319
drawBit = (color == WHITE) ? 0xFF : 0x00;
309320
do {
310321
*bufferPtr = drawBit;
311-
bufferPtr += displayWidth;
322+
bufferPtr += this->width();
312323
length -= 8;
313324
} while (length >= 8);
314325
break;
315326
case INVERSE:
316327
do {
317328
*bufferPtr = ~(*bufferPtr);
318-
bufferPtr += displayWidth;
329+
bufferPtr += this->width();
319330
length -= 8;
320331
} while (length >= 8);
321332
break;
@@ -398,8 +409,8 @@ void OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, char* text, u
398409
}
399410

400411
// Don't draw anything if it is not on the screen.
401-
if (xMove + textWidth < 0 || xMove > displayWidth ) {return;}
402-
if (yMove + textHeight < 0 || yMove > displayHeight) {return;}
412+
if (xMove + textWidth < 0 || xMove > this->width() ) {return;}
413+
if (yMove + textHeight < 0 || yMove > this->width() ) {return;}
403414

404415
for (uint16_t j = 0; j < textLength; j++) {
405416
int16_t xPos = xMove + cursorX;
@@ -552,9 +563,16 @@ void OLEDDisplay::normalDisplay(void) {
552563
sendCommand(NORMALDISPLAY);
553564
}
554565

555-
void OLEDDisplay::setContrast(char contrast) {
566+
void OLEDDisplay::setContrast(char contrast, char precharge, char comdetect) {
567+
sendCommand(SETPRECHARGE); //0xD9
568+
sendCommand(precharge); //0xF1 default, to lower the contrast, put 1-1F
556569
sendCommand(SETCONTRAST);
557-
sendCommand(contrast);
570+
sendCommand(contrast); // 0-255
571+
sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)
572+
sendCommand(comdetect); //0x40 default, to lower the contrast, put 0
573+
sendCommand(DISPLAYALLON_RESUME);
574+
sendCommand(NORMALDISPLAY);
575+
sendCommand(DISPLAYON);
558576
}
559577

560578
void OLEDDisplay::resetOrientation() {
@@ -621,6 +639,7 @@ bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
621639
uint16_t size = lines * chars;
622640
if (size > 0) {
623641
this->logBufferLine = 0; // Lines printed
642+
this->logBufferFilled = 0; // Nothing stored yet
624643
this->logBufferMaxLines = lines; // Lines max printable
625644
this->logBufferSize = size; // Total number of characters the buffer can hold
626645
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
@@ -700,8 +719,7 @@ void OLEDDisplay::sendInitCommands(void) {
700719
sendCommand(SETDISPLAYCLOCKDIV);
701720
sendCommand(0xF0); // Increase speed of the display max ~96Hz
702721
sendCommand(SETMULTIPLEX);
703-
//sendCommand(0x3F);
704-
sendCommand(displayHeight - 1);
722+
sendCommand(this->height() - 1);
705723
sendCommand(SETDISPLAYOFFSET);
706724
sendCommand(0x00);
707725
sendCommand(SETSTARTLINE);
@@ -718,7 +736,7 @@ void OLEDDisplay::sendInitCommands(void) {
718736
} else if (geometry == GEOMETRY_128_32) {
719737
sendCommand(0x02);
720738
}
721-
739+
722740
sendCommand(SETCONTRAST);
723741

724742
if (geometry == GEOMETRY_128_64) {
@@ -729,6 +747,8 @@ void OLEDDisplay::sendInitCommands(void) {
729747

730748
sendCommand(SETPRECHARGE);
731749
sendCommand(0xF1);
750+
sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)
751+
sendCommand(0x40); //0x40 default, to lower the contrast, put 0
732752
sendCommand(DISPLAYALLON_RESUME);
733753
sendCommand(NORMALDISPLAY);
734754
sendCommand(0x2e); // stop scroll
@@ -737,8 +757,8 @@ void OLEDDisplay::sendInitCommands(void) {
737757

738758
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) {
739759
if (width < 0 || height < 0) return;
740-
if (yMove + height < 0 || yMove > displayHeight) return;
741-
if (xMove + width < 0 || xMove > displayWidth) return;
760+
if (yMove + height < 0 || yMove > this->height()) return;
761+
if (xMove + width < 0 || xMove > this->width()) return;
742762

743763
uint8_t rasterHeight = 1 + ((height - 1) >> 3); // fast ceil(height / 8.0)
744764
int8_t yOffset = yMove & 7;
@@ -760,24 +780,26 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
760780
byte currentByte = pgm_read_byte(data + offset + i);
761781

762782
int16_t xPos = xMove + (i / rasterHeight);
763-
int16_t yPos = ((yMove >> 3) + (i % rasterHeight)) * displayWidth;
783+
int16_t yPos = ((yMove >> 3) + (i % rasterHeight)) * this->width();
764784

785+
// int16_t yScreenPos = yMove + yOffset;
765786
int16_t dataPos = xPos + yPos;
766787

767788
if (dataPos >= 0 && dataPos < displayBufferSize &&
768-
xPos >= 0 && xPos < displayWidth ) {
789+
xPos >= 0 && xPos < this->width() ) {
769790

770791
if (yOffset >= 0) {
771792
switch (this->color) {
772793
case WHITE: buffer[dataPos] |= currentByte << yOffset; break;
773794
case BLACK: buffer[dataPos] &= ~(currentByte << yOffset); break;
774795
case INVERSE: buffer[dataPos] ^= currentByte << yOffset; break;
775796
}
776-
if (dataPos < (displayBufferSize - displayWidth)) {
797+
798+
if (dataPos < (displayBufferSize - this->width())) {
777799
switch (this->color) {
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;
800+
case WHITE: buffer[dataPos + this->width()] |= currentByte >> (8 - yOffset); break;
801+
case BLACK: buffer[dataPos + this->width()] &= ~(currentByte >> (8 - yOffset)); break;
802+
case INVERSE: buffer[dataPos + this->width()] ^= currentByte >> (8 - yOffset); break;
781803
}
782804
}
783805
} else {

OLEDDisplay.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,15 @@ typedef byte (*FontTableLookupFunction)(const byte ch);
111111

112112

113113
class OLEDDisplay : public Print {
114+
private:
115+
const int _width, _height;
116+
114117
public:
115-
virtual ~OLEDDisplay() {}
116-
118+
virtual ~OLEDDisplay();
119+
120+
const int width(void) const { return displayWidth; };
121+
const int height(void) const { return displayHeight; };
122+
117123
// Initialize the display
118124
bool init();
119125

@@ -211,7 +217,9 @@ class OLEDDisplay : public Print {
211217
void normalDisplay(void);
212218

213219
// Set display contrast
214-
void setContrast(char contrast);
220+
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
221+
// normal brightness & contrast: contrast = 100
222+
void setContrast(char contrast, char precharge = 241, char comdetect = 64);
215223

216224
// Reset display rotation or mirroring
217225
void resetOrientation();
@@ -246,10 +254,10 @@ class OLEDDisplay : public Print {
246254
size_t write(uint8_t c);
247255
size_t write(const char* s);
248256

249-
uint8_t *buffer;
257+
uint8_t *buffer = NULL;
250258

251259
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
252-
uint8_t *buffer_back;
260+
uint8_t *buffer_back = NULL;
253261
#endif
254262

255263
protected:
@@ -276,7 +284,7 @@ class OLEDDisplay : public Print {
276284
virtual void sendCommand(uint8_t com) {(void)com;};
277285

278286
// Connect to the display
279-
virtual bool connect() {return false;};
287+
virtual bool connect() { return false; };
280288

281289
// Send all the init commands
282290
void sendInitCommands();

OLEDDisplayUi.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -251,32 +251,32 @@ void OLEDDisplayUi::drawFrame(){
251251
switch (this->state.frameState){
252252
case IN_TRANSITION: {
253253
float progress = (float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
254-
int16_t x = 0, y = 0, x1 = 0, y1 = 0;
254+
int16_t x = 0, y = 0, x1 = 0, y1 = 0;
255255
switch(this->frameAnimationDirection){
256256
case SLIDE_LEFT:
257-
x = -(this->display->getWidth()) * progress;
257+
x = -this->display->width() * progress;
258258
y = 0;
259-
x1 = x + this->display->getWidth();
259+
x1 = x + this->display->width();
260260
y1 = 0;
261261
break;
262262
case SLIDE_RIGHT:
263-
x = this->display->getWidth() * progress;
263+
x = this->display->width() * progress;
264264
y = 0;
265-
x1 = x - this->display->getWidth();
265+
x1 = x - this->display->width();
266266
y1 = 0;
267267
break;
268268
case SLIDE_UP:
269269
x = 0;
270-
y = -(this->display->getHeight()) * progress;
270+
y = -this->display->height() * progress;
271271
x1 = 0;
272-
y1 = y + (this->display->getHeight());
272+
y1 = y + this->display->height();
273273
break;
274274
case SLIDE_DOWN:
275275
default:
276276
x = 0;
277-
y = (this->display->getHeight()) * progress;
277+
y = this->display->height() * progress;
278278
x1 = 0;
279-
y1 = y - (this->display->getHeight());
279+
y1 = y - this->display->height();
280280
break;
281281
}
282282

@@ -371,27 +371,28 @@ void OLEDDisplayUi::drawIndicator() {
371371
uint16_t frameStartPos = (indicatorSpacing * frameCount / 2);
372372
const uint8_t *image;
373373

374-
uint16_t x,y;
374+
uint16_t x = 0,y = 0;
375+
375376

376377
for (byte i = 0; i < this->frameCount; i++) {
377378

378379
switch (this->indicatorPosition){
379380
case TOP:
380381
y = 0 - (8 * indicatorFadeProgress);
381-
x = (this->display->getWidth() / 2) - frameStartPos + indicatorSpacing * i;
382+
x = (this->display->width() / 2) - frameStartPos + 12 * i;
382383
break;
383384
case BOTTOM:
384-
y = (this->display->getHeight() - 8) + (8 * indicatorFadeProgress);
385-
x = (this->display->getWidth() / 2) - frameStartPos + indicatorSpacing * i;
385+
y = (this->display->height() - 8) + (8 * indicatorFadeProgress);
386+
x = (this->display->width() / 2) - frameStartPos + 12 * i;
386387
break;
387388
case RIGHT:
388-
x = (this->display->getWidth() - 8) + (8 * indicatorFadeProgress);
389-
y = (this->display->getHeight() / 2) - frameStartPos + indicatorSpacing * i;
389+
x = (this->display->width() - 8) + (8 * indicatorFadeProgress);
390+
y = (this->display->height() / 2) - frameStartPos + 2 + 12 * i;
390391
break;
391392
case LEFT:
392393
default:
393394
x = 0 - (8 * indicatorFadeProgress);
394-
y = (this->display->getHeight() / 2) - frameStartPos + indicatorSpacing * i;
395+
y = (this->display->height() / 2) - frameStartPos + 2 + indicatorSpacing * i;
395396
break;
396397
}
397398

0 commit comments

Comments
 (0)