Skip to content

Commit bd2ce40

Browse files
committed
Add driver for sh1107, not hooked into hw yet
1 parent 9c34298 commit bd2ce40

File tree

6 files changed

+181
-10
lines changed

6 files changed

+181
-10
lines changed

src/components/display/controller.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ bool DisplayController::Handle_Display_AddOrReplace(
5757
did_begin = display->beginTft(&msgAdd->config.config_tft,
5858
&msgAdd->interface_type.cfg_spi);
5959
} else if (msgAdd->which_config ==
60-
wippersnapper_display_v1_DisplayAddOrReplace_config_ssd1306_tag) {
61-
did_begin = display->beginOled(&msgAdd->config.config_ssd1306,
60+
wippersnapper_display_v1_DisplayAddOrReplace_config_oled_tag) {
61+
did_begin = display->beginOled(&msgAdd->config.config_oled,
6262
&msgAdd->interface_type.cfg_i2c);
6363
} else if (
6464
msgAdd->which_config ==

src/components/display/drivers/dispDrvBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class dispDrvBase {
125125
@param r
126126
The rotation of the display (0-3).
127127
*/
128-
void setRotation(uint8_t r) { _rotation = r; }
128+
virtual void setRotation(uint8_t r) { _rotation = r; }
129129

130130
/*!
131131
@brief Sets the text size for the display.
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*!
2+
* @file src/components/display/drivers/dispDrvSh1107.h
3+
*
4+
* Device driver for a SH1107 OLED Display
5+
*
6+
* Adafruit invests time and resources providing this open source code,
7+
* please support Adafruit and open-source hardware by purchasing
8+
* products from Adafruit!
9+
*
10+
* Copyright (c) Tyeth Gundry for Adafruit Industries 2025
11+
*
12+
* MIT license, all text here must be included in any redistribution.
13+
*
14+
*/
15+
#ifndef WS_DISP_DRV_SH1107_H
16+
#define WS_DISP_DRV_SH1107_H
17+
18+
#include "dispDrvBase.h"
19+
#include <Adafruit_SH110X.h>
20+
21+
#define WS_SH1107_DEFAULT_WIDTH \
22+
128 ///< Default width for a sh1107 128x64 display
23+
#define WS_SH1107_DEFAULT_HEIGHT \
24+
64 ///< Default height for a sh1107 128x64 display
25+
26+
#define OLED_128X64_WING_WIDTH 128 ///< Width of the 128x64 OLED FeatherWing
27+
#define OLED_128X64_WING_HEIGHT 64 ///< Height of the 128x64 OLED FeatherWing
28+
#define OLED_128X64_WING_ROTATION_90 1 ///< Rotation of OLED FeatherWing 0-3
29+
30+
/*!
31+
@brief Class that provides a driver interface for a SH1107
32+
OLED Display
33+
*/
34+
class dispDrvSh1107 : public dispDrvBase {
35+
public:
36+
/*!
37+
@brief Constructor for the SH1107 display driver.
38+
*/
39+
dispDrvSh1107(TwoWire *i2c, uint16_t sensorAddress)
40+
: dispDrvBase(i2c, sensorAddress), _display(nullptr) {
41+
_i2c = i2c;
42+
_sensorAddress = sensorAddress;
43+
_width = WS_SH1107_DEFAULT_WIDTH;
44+
_height = WS_SH1107_DEFAULT_HEIGHT;
45+
}
46+
47+
/*!
48+
@brief Destructor for a SH1107 display driver.
49+
*/
50+
~dispDrvSh1107() {
51+
if (_display != nullptr) {
52+
_display->clearDisplay();
53+
_display->display();
54+
_display->oled_command(SH110X_DISPLAYOFF);
55+
delete _display;
56+
_display = nullptr;
57+
}
58+
}
59+
60+
/*!
61+
@brief Attempts to initialize the SSD1306 display driver.
62+
@return True if the display was initialized successfully, false otherwise.
63+
*/
64+
bool begin() override {
65+
if (!_i2c)
66+
return false;
67+
68+
// Attempt to create and allocate a SH1107 obj.
69+
if (_width == OLED_128X64_WING_WIDTH &&
70+
_height == OLED_128X64_WING_HEIGHT &&
71+
_rotation == OLED_128X64_WING_ROTATION_90) {
72+
// FeatherWing needs to be rotated 90deg and swap w/h ctor args
73+
_display = new Adafruit_SH1107(_height, _width, _i2c);
74+
} else {
75+
_display = new Adafruit_SH1107(_width, _height, _i2c);
76+
}
77+
if (!_display->begin(_sensorAddress, true))
78+
return false;
79+
80+
// Clear the buffer.
81+
_display->clearDisplay();
82+
_display->display();
83+
_display->setRotation(_rotation); // 0-3, not degrees for SH1107
84+
85+
// Configure the text size and color
86+
_display->setTextSize(_text_sz);
87+
_display->setTextColor(SH110X_WHITE);
88+
_display->setCursor(0, 0);
89+
// Clear the buffer
90+
_display->clearDisplay();
91+
_display->display();
92+
return true;
93+
}
94+
95+
/*!
96+
@brief Sets the text size for the display.
97+
@param s
98+
The text size to set.
99+
@note This method overrides the base class method to provide specific
100+
functionality for the SSD1306 driver.
101+
*/
102+
void setTextSize(uint8_t s) override {
103+
if (!_display)
104+
return;
105+
_text_sz = s;
106+
_display->setTextSize(s);
107+
}
108+
109+
void setRotation(uint8_t r) override {
110+
if (!_display)
111+
return;
112+
_rotation = r % 90; // constrain to 0-3
113+
_display->setRotation(r);
114+
}
115+
116+
/*!
117+
@brief Writes a message to the display.
118+
@param message
119+
The message to write to the display.
120+
@note This method overrides the base class method to provide specific
121+
functionality for the SSD1306 driver.
122+
*/
123+
virtual void writeMessage(const char *message) override {
124+
if (_display == nullptr)
125+
return;
126+
// Start with a fresh display buffer
127+
// and settings
128+
int16_t y_idx = 0;
129+
_display->clearDisplay();
130+
_display->setTextSize(_text_sz);
131+
_display->setTextColor(SH110X_WHITE);
132+
_display->setCursor(0, y_idx);
133+
_display->display();
134+
135+
// Calculate the line height based on the text size (NOTE: base height is
136+
// 8px)
137+
int16_t line_height = 8 * _text_sz;
138+
uint16_t c_idx = 0;
139+
size_t msg_size = strlen(message);
140+
for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
141+
if (message[i] == '\\' && i + 1 < msg_size &&
142+
(message[i + 1] == 'n' || message[i + 1] == 'r')) {
143+
// Handle \r\n sequence as a single newline
144+
if (message[i + 1] == 'r' && i + 3 < msg_size &&
145+
message[i + 2] == '\\' && message[i + 3] == 'n') {
146+
// Skip to the next line
147+
y_idx += line_height;
148+
_display->setCursor(0, y_idx);
149+
i += 3;
150+
} else if (message[i + 1] == 'n') {
151+
// Skip to the next line
152+
y_idx += line_height;
153+
_display->setCursor(0, y_idx);
154+
i++;
155+
}
156+
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
157+
_display->write(char(248));
158+
_display->display();
159+
i++;
160+
} else {
161+
_display->print(message[i]);
162+
_display->display();
163+
}
164+
}
165+
}
166+
167+
private:
168+
Adafruit_SH1107 *_display;
169+
};
170+
171+
#endif // WS_DISP_DRV_SSD1306

src/components/display/drivers/dispDrvSsd1306.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ class dispDrvSsd1306 : public dispDrvBase {
102102
// and settings
103103
int16_t y_idx = 0;
104104
_display->clearDisplay();
105-
_display->setTextSize(_text_sz);
106-
_display->setTextColor(SSD1306_WHITE);
107105
_display->setCursor(0, y_idx);
108106
_display->display();
109107

src/components/display/hardware.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,11 @@ bool DisplayHardware::beginTft(wippersnapper_display_v1_TftConfig *config,
336336
@param config
337337
Pointer to the OLED's configuration structure.
338338
@param i2c_config
339-
Pointer to the I2C configuration structure for OLED.
339+
Pointer to the I2C configuration structure.
340340
@return True if configuration was successful, False otherwise.
341341
*/
342342
bool DisplayHardware::beginOled(
343-
wippersnapper_display_v1_SSD1306Config *config,
343+
wippersnapper_display_v1_OledConfig *config,
344344
wippersnapper_display_v1_I2cConfig *i2c_config) {
345345
// Validate pointers
346346
if (config == nullptr || i2c_config == nullptr || !i2c_config->has_i2c) {
@@ -355,6 +355,7 @@ bool DisplayHardware::beginOled(
355355
_drvDisp = nullptr;
356356
}
357357

358+
// Initialize OLED display driver based on device name
358359
if (strnlen(i2c_config->i2c.i2c_device_name,
359360
sizeof(i2c_config->i2c.i2c_device_name)) <
360361
sizeof(i2c_config->i2c.i2c_device_name) &&
@@ -376,8 +377,7 @@ bool DisplayHardware::beginOled(
376377
// Configure display dimensions and text size
377378
_drvDisp->setWidth(config->width);
378379
_drvDisp->setHeight(config->height);
379-
// tODO: Remove the ssd-1306 -specic text size setters
380-
// _drvDisp->setTextSize(config->text_size);
380+
_drvDisp->setTextSize(config->text_size);
381381

382382
// Initialize the display driver
383383
if (!_drvDisp->begin()) {
@@ -387,6 +387,7 @@ bool DisplayHardware::beginOled(
387387
return false;
388388
}
389389

390+
WS_DEBUG_PRINTLN("[display] OLED initialized successfully.");
390391
return true;
391392
}
392393

src/components/display/hardware.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define WS_DISPLAY_HARDWARE_H
1717
#include "Wippersnapper.h"
1818
#include "drivers/dispDrvBase.h"
19+
#include "drivers/dispDrvSh1107.h"
1920
#include "drivers/dispDrvSsd1306.h"
2021
#include "drivers/dispDrvSt7789.h"
2122
#include "drivers/dispDrvThinkInkGrayscale4Eaamfgn.h"
@@ -44,7 +45,7 @@ class DisplayHardware {
4445
wippersnapper_display_v1_SpiConfig *spi_config);
4546
bool beginTft(wippersnapper_display_v1_TftConfig *config,
4647
wippersnapper_display_v1_SpiConfig *spi_config);
47-
bool beginOled(wippersnapper_display_v1_SSD1306Config *config,
48+
bool beginOled(wippersnapper_display_v1_OledConfig *config,
4849
wippersnapper_display_v1_I2cConfig *i2c_config);
4950

5051
//

0 commit comments

Comments
 (0)