Skip to content

Commit 8022edd

Browse files
committed
Add preemptive driver for ssd1306, no refactoring yet
1 parent bfb1d3a commit 8022edd

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

src/components/display/drivers/dispDrvBase.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ class dispDrvBase {
6363
: _pin_cs(cs), _pin_dc(dc), _pin_mosi(mosi), _pin_sck(sck), _pin_rst(rst),
6464
_pin_miso(miso) {}
6565

66+
67+
/*!
68+
@brief Creates a new I2C output component driver.
69+
@param i2c
70+
The I2C hardware interface, default is Wire.
71+
@param sensorAddress
72+
The I2C sensor's unique address.
73+
*/
74+
dispDrvBase(TwoWire *i2c, uint16_t sensorAddress) {
75+
// No-op constructor
76+
}
77+
6678
/*!
6779
@brief Destructor for the base display driver.
6880
This destructor is virtual to allow derived classes to clean up
@@ -133,6 +145,8 @@ class dispDrvBase {
133145
uint16_t _pin_mosi; ///< Optional MOSI pin for SPI TFT displays
134146
uint16_t _pin_miso; ///< Optional MISO pin for SPI TFT displays
135147
uint16_t _pin_sck; ///< Optional SCK pin for SPI TFT displays
148+
TwoWire *_i2c; ///< Optional pointer to the I2C driver's Wire object
149+
uint16_t _sensorAddress; ///< Optional I2C sensor address
136150
uint8_t _text_sz = 1; ///< Text size for displaying a message
137151
int16_t _height; ///< Height of the display
138152
int16_t _width; ///< Width of the display
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*!
2+
* @file src/components/display/drivers/dispDrvSsd1306.h
3+
*
4+
* Driver for SSD1306-based OLED displays.
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) Brent Rubell 2025 for Adafruit Industries.
11+
*
12+
* BSD license, all text here must be included in any redistribution.
13+
*
14+
*/
15+
#ifndef WS_DISP_DRV_SSD1306
16+
#define WS_DISP_DRV_SSD1306
17+
18+
#include "dispDrvBase.h"
19+
#include <Arduino.h>
20+
#include <Adafruit_SSD1306.h>
21+
22+
#define WS_SSD1306_DEFAULT_WIDTH \
23+
128 ///< Default width for a ssd1306 128x64 display
24+
#define WS_SSD1306_DEFAULT_HEIGHT \
25+
64 ///< Default height for a ssd1306 128x64 display
26+
27+
28+
/*!
29+
@brief Driver for SSD1306-based TFT displays.
30+
*/
31+
class dispDrvSsd1306 : public dispDrvBase {
32+
public:
33+
/*!
34+
@brief Constructor for the SSD1306 display driver.
35+
*/
36+
dispDrvSsd1306(TwoWire *i2c, uint16_t sensorAddress) : dispDrvBase(i2c, sensorAddress), _display(nullptr) {
37+
_i2c = i2c;
38+
_sensorAddress = sensorAddress;
39+
_width = WS_SSD1306_DEFAULT_WIDTH;
40+
_height = WS_SSD1306_DEFAULT_HEIGHT;
41+
}
42+
43+
~dispDrvSsd1306() {
44+
if (_display) {
45+
_display->clearDisplay();
46+
_display->display();
47+
_display->ssd1306_command(SSD1306_DISPLAYOFF);
48+
delete _display;
49+
_display = nullptr;
50+
}
51+
}
52+
53+
/*!
54+
@brief Attempts to initialize the SSD1306 display driver.
55+
@return True if the display was initialized successfully, false otherwise.
56+
*/
57+
bool begin() override {
58+
if (_i2c == nullptr)
59+
return false;
60+
// Attempt to create and allocate a SSD1306 obj.
61+
_display = new Adafruit_SSD1306(_width, _height, _i2c);
62+
if (!_display->begin(SSD1306_SWITCHCAPVCC, _sensorAddress))
63+
return false;
64+
// Configure the rotation, text size and color
65+
_display->setRotation(_rotation);
66+
_display->setTextSize(_text_sz);
67+
_display->setTextColor(SSD1306_WHITE);
68+
// Use full 256 char 'Code Page 437' font
69+
_display->cp437(true);
70+
// Clear the buffer
71+
_display->clearDisplay();
72+
_display->display();
73+
return true;
74+
}
75+
76+
/*!
77+
@brief Sets the text size for the display.
78+
@param s
79+
The text size to set.
80+
@note This method overrides the base class method to provide specific
81+
functionality for the SSD1306 driver.
82+
*/
83+
void setTextSize(uint8_t s) override {
84+
if (!_display)
85+
return;
86+
_text_sz = s;
87+
_display->setTextSize(s);
88+
}
89+
90+
/*!
91+
@brief Writes a message to the display.
92+
@param message
93+
The message to write to the display.
94+
@note This method overrides the base class method to provide specific
95+
functionality for the SSD1306 driver.
96+
*/
97+
virtual void writeMessage(const char *message) override {
98+
if (_display == nullptr)
99+
return;
100+
101+
// Start with a fresh display buffer
102+
// and settings
103+
int16_t y_idx = 0;
104+
_display->clearDisplay();
105+
_display->setTextSize(_text_sz);
106+
_display->setTextColor(SSD1306_WHITE);
107+
_display->setCursor(0, y_idx);
108+
_display->display();
109+
110+
// Calculate the line height based on the text size (NOTE: base height is
111+
// 8px)
112+
int16_t line_height = 8 * _text_sz;
113+
uint16_t c_idx = 0;
114+
size_t msg_size = strlen(message);
115+
for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
116+
if (message[i] == '\\' && i + 1 < msg_size &&
117+
(message[i + 1] == 'n' || message[i + 1] == 'r')) {
118+
// Handle \r\n sequence as a single newline
119+
if (message[i + 1] == 'r' && i + 3 < msg_size &&
120+
message[i + 2] == '\\' && message[i + 3] == 'n') {
121+
// Skip to the next line
122+
y_idx += line_height;
123+
_display->setCursor(0, y_idx);
124+
i += 3;
125+
} else if (message[i + 1] == 'n') {
126+
// Skip to the next line
127+
y_idx += line_height;
128+
_display->setCursor(0, y_idx);
129+
i++;
130+
}
131+
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
132+
_display->write(char(248));
133+
_display->display();
134+
i++;
135+
} else {
136+
_display->print(message[i]);
137+
_display->display();
138+
}
139+
}
140+
}
141+
142+
private:
143+
Adafruit_SSD1306 *_display;
144+
};
145+
146+
#endif // WS_DISP_DRV_SSD1306

src/components/display/hardware.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DisplayHardware {
4343
wippersnapper_display_v1_EpdSpiConfig *spi_config);
4444
bool beginTft(wippersnapper_display_v1_TftConfig *config,
4545
wippersnapper_display_v1_TftSpiConfig *spi_config);
46+
// TODO: bool beginOled(...);
4647

4748
//
4849
// API for Adafruit_GFX that abstracts hardware functionality

0 commit comments

Comments
 (0)