Skip to content

Commit 8648131

Browse files
authored
Merge pull request #251 from ThingPulse/helmut64-mbed_os_support_clean
Clean version of Helmut64's Mbed OS support branch
2 parents 2b12d3f + 10cd172 commit 8648131

File tree

13 files changed

+459
-103
lines changed

13 files changed

+459
-103
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[![Build Status](https://travis-ci.org/ThingPulse/esp8266-oled-ssd1306.svg?branch=master)](https://travis-ci.org/ThingPulse/esp8266-oled-ssd1306)
22

3-
# ThingPulse ESP8266 OLED SSD1306
3+
# ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS)
44

55
> We just released version 4.0.0. Please have a look at our [upgrade guide](UPGRADE-4.0.md)
66
7-
This is a driver for SSD1306 128x64 and 128x32 OLED displays running on the Arduino/ESP8266 platform.
7+
This is a driver for SSD1306 128x64 and 128x32 OLED displays running on the Arduino/ESP8266 & ESP32 and mbed-os platforms.
88
Can be used with either the I2C or SPI version of the display.
99

10-
You can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under "ESP8266 and ESP32 Oled Driver for SSD1306 display".
10+
You can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under "ESP8266 and ESP32 Oled Driver for SSD1306 display". For mbed-os a copy of the files are available as an mbed-os library.
1111

1212
It is also available as a platformio library. Just execute the following command:
1313
```
@@ -24,6 +24,9 @@ platformio lib install 562
2424
This library has initially been written by Daniel Eichhorn (@squix78). Many thanks go to Fabrice Weinberg (@FWeinb) for optimizing and refactoring many aspects of the library. Also many thanks to the many committers who helped to add new features and who fixed many bugs.
2525
The init sequence for the SSD1306 was inspired by Adafruit's library for the same display.
2626

27+
## mbed-os
28+
This library has been adopted to support the ARM mbed-os environment. A copy of this library is available in mbed-os under the name OLED_SSD1306 by Helmut Tschemernjak. An alternate installation option is to copy the following files into your mbed-os project: OLEDDisplay.cpp OLEDDisplay.h OLEDDisplayFonts.h OLEDDisplayUi.cpp OLEDDisplayUi.h SSD1306I2C.h
29+
2730
## Usage
2831

2932
Check out the examples folder for a few comprehensive demonstrations how to use the library. Also check out the [ESP8266 Weather Station](https://github.com/ThingPulse/esp8266-weather-station) library which uses the OLED library to display beautiful weather information.

src/OLEDDisplay.cpp

Lines changed: 110 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
55
* Copyright (c) 2018 by Fabrice Weinberg
6+
* Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de
67
*
78
* Permission is hereby granted, free of charge, to any person obtaining a copy
89
* of this software and associated documentation files (the "Software"), to deal
@@ -28,20 +29,50 @@
2829
*
2930
*/
3031

32+
/*
33+
* TODO Helmut
34+
* - test/finish dislplay.printf() on mbed-os
35+
* - Finish _putc with drawLogBuffer when running display
36+
*/
37+
3138
#include "OLEDDisplay.h"
3239

40+
OLEDDisplay::OLEDDisplay() {
41+
42+
displayWidth = 128;
43+
displayHeight = 64;
44+
displayBufferSize = displayWidth * displayHeight / 8;
45+
color = WHITE;
46+
geometry = GEOMETRY_128_64;
47+
textAlignment = TEXT_ALIGN_LEFT;
48+
fontData = ArialMT_Plain_10;
49+
fontTableLookupFunction = DefaultFontTableLookup;
50+
buffer = NULL;
51+
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
52+
buffer_back = NULL;
53+
#endif
54+
}
55+
3356
OLEDDisplay::~OLEDDisplay() {
3457
end();
3558
}
3659

3760
bool OLEDDisplay::init() {
61+
62+
logBufferSize = 0;
63+
logBufferFilled = 0;
64+
logBufferLine = 0;
65+
logBufferMaxLines = 0;
66+
logBuffer = NULL;
67+
3868
if (!this->connect()) {
3969
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Can't establish connection to display\n");
4070
return false;
4171
}
4272

4373
if(this->buffer==NULL) {
44-
this->buffer = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize);
74+
this->buffer = (uint8_t*) malloc((sizeof(uint8_t) * displayBufferSize) + getBufferOffset());
75+
this->buffer += getBufferOffset();
4576

4677
if(!this->buffer) {
4778
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create display\n");
@@ -51,11 +82,12 @@ bool OLEDDisplay::init() {
5182

5283
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
5384
if(this->buffer_back==NULL) {
54-
this->buffer_back = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize);
85+
this->buffer_back = (uint8_t*) malloc((sizeof(uint8_t) * displayBufferSize) + getBufferOffset());
86+
this->buffer_back += getBufferOffset();
5587

5688
if(!this->buffer_back) {
5789
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create back buffer\n");
58-
free(this->buffer);
90+
free(this->buffer - getBufferOffset());
5991
return false;
6092
}
6193
}
@@ -68,9 +100,9 @@ bool OLEDDisplay::init() {
68100
}
69101

70102
void OLEDDisplay::end() {
71-
if (this->buffer) { free(this->buffer); this->buffer = NULL; }
103+
if (this->buffer) { free(this->buffer - getBufferOffset()); this->buffer = NULL; }
72104
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
73-
if (this->buffer_back) { free(this->buffer_back); this->buffer_back = NULL; }
105+
if (this->buffer_back) { free(this->buffer_back - getBufferOffset()); this->buffer_back = NULL; }
74106
#endif
75107
if (this->logBuffer != NULL) { free(this->logBuffer); this->logBuffer = NULL; }
76108
}
@@ -405,8 +437,8 @@ void OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, char* text, u
405437
uint8_t firstChar = pgm_read_byte(fontData + FIRST_CHAR_POS);
406438
uint16_t sizeOfJumpTable = pgm_read_byte(fontData + CHAR_NUM_POS) * JUMPTABLE_BYTES;
407439

408-
uint8_t cursorX = 0;
409-
uint8_t cursorY = 0;
440+
uint16_t cursorX = 0;
441+
uint16_t cursorY = 0;
410442

411443
switch (textAlignment) {
412444
case TEXT_ALIGN_CENTER_BOTH:
@@ -430,15 +462,15 @@ void OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, char* text, u
430462
int16_t xPos = xMove + cursorX;
431463
int16_t yPos = yMove + cursorY;
432464

433-
byte code = text[j];
465+
uint8_t code = text[j];
434466
if (code >= firstChar) {
435-
byte charCode = code - firstChar;
467+
uint8_t charCode = code - firstChar;
436468

437469
// 4 Bytes per char code
438-
byte msbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES ); // MSB \ JumpAddress
439-
byte lsbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_LSB); // LSB /
440-
byte charByteSize = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_SIZE); // Size
441-
byte currentCharWidth = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_WIDTH); // Width
470+
uint8_t msbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES ); // MSB \ JumpAddress
471+
uint8_t lsbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_LSB); // LSB /
472+
uint8_t charByteSize = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_SIZE); // Size
473+
uint8_t currentCharWidth = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_WIDTH); // Width
442474

443475
// Test if the char is drawable
444476
if (!(msbJumpToChar == 255 && lsbJumpToChar == 255)) {
@@ -745,20 +777,50 @@ size_t OLEDDisplay::write(const char* str) {
745777
return length;
746778
}
747779

780+
#ifdef __MBED__
781+
int OLEDDisplay::_putc(int c) {
782+
783+
if (!fontData)
784+
return 1;
785+
if (!logBufferSize) {
786+
uint8_t textHeight = pgm_read_byte(fontData + HEIGHT_POS);
787+
uint16_t lines = this->displayHeight / textHeight;
788+
uint16_t chars = 2 * (this->displayWidth / textHeight);
789+
790+
if (this->displayHeight % textHeight)
791+
lines++;
792+
if (this->displayWidth % textHeight)
793+
chars++;
794+
setLogBuffer(lines, chars);
795+
}
796+
797+
return this->write((uint8_t)c);
798+
}
799+
#endif
800+
748801
// Private functions
749-
void OLEDDisplay::setGeometry(OLEDDISPLAY_GEOMETRY g) {
802+
void OLEDDisplay::setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width, uint16_t height) {
750803
this->geometry = g;
751-
if (g == GEOMETRY_128_64) {
752-
this->displayWidth = 128;
753-
this->displayHeight = 64;
754-
} else if (g == GEOMETRY_128_32) {
755-
this->displayWidth = 128;
756-
this->displayHeight = 32;
757-
}
758-
this->displayBufferSize = displayWidth*displayHeight/8;
804+
switch (g) {
805+
case GEOMETRY_128_64:
806+
this->displayWidth = 128;
807+
this->displayHeight = 64;
808+
break;
809+
case GEOMETRY_128_32:
810+
this->displayWidth = 128;
811+
this->displayHeight = 32;
812+
break;
813+
case GEOMETRY_RAWMODE:
814+
this->displayWidth = width > 0 ? width : 128;
815+
this->displayHeight = height > 0 ? height : 64;
816+
break;
817+
}
818+
this->displayBufferSize = displayWidth * displayHeight /8;
759819
}
760820

761821
void OLEDDisplay::sendInitCommands(void) {
822+
if (geometry == GEOMETRY_RAWMODE)
823+
return;
762824
sendCommand(DISPLAYOFF);
763825
sendCommand(SETDISPLAYCLOCKDIV);
764826
sendCommand(0xF0); // Increase speed of the display max ~96Hz
@@ -821,7 +883,7 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
821883
yOffset = initYOffset;
822884
}
823885

824-
byte currentByte = pgm_read_byte(data + offset + i);
886+
uint8_t currentByte = pgm_read_byte(data + offset + i);
825887

826888
int16_t xPos = xMove + (i / rasterHeight);
827889
int16_t yPos = ((yMove >> 3) + (i % rasterHeight)) * this->width();
@@ -862,8 +924,9 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
862924
// and setting the new yOffset
863925
yOffset = 8 - yOffset;
864926
}
865-
927+
#ifndef __MBED__
866928
yield();
929+
#endif
867930
}
868931
}
869932
}
@@ -899,3 +962,26 @@ char* OLEDDisplay::utf8ascii(String str) {
899962
void OLEDDisplay::setFontTableLookupFunction(FontTableLookupFunction function) {
900963
this->fontTableLookupFunction = function;
901964
}
965+
966+
967+
char DefaultFontTableLookup(const uint8_t ch) {
968+
// UTF-8 to font table index converter
969+
// Code form http://playground.arduino.cc/Main/Utf8ascii
970+
static uint8_t LASTCHAR;
971+
972+
if (ch < 128) { // Standard ASCII-set 0..0x7F handling
973+
LASTCHAR = 0;
974+
return ch;
975+
}
976+
977+
uint8_t last = LASTCHAR; // get last char
978+
LASTCHAR = ch;
979+
980+
switch (last) { // conversion depnding on first UTF8-character
981+
case 0xC2: return (uint8_t) ch;
982+
case 0xC3: return (uint8_t) (ch | 0xC0);
983+
case 0x82: if (ch == 0xAC) return (uint8_t) 0x80; // special case Euro-symbol
984+
}
985+
986+
return (uint8_t) 0; // otherwise: return zero, if character has to be ignored
987+
}

0 commit comments

Comments
 (0)