Skip to content

Commit f1186e0

Browse files
committed
v0.6.400
1 parent 36c24ec commit f1186e0

File tree

3 files changed

+568
-0
lines changed

3 files changed

+568
-0
lines changed

broken204/Adafruit_SH110X.cpp

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
/*!
2+
* @file Adafruit_SH110X.cpp
3+
*
4+
* @mainpage Arduino library for monochrome OLEDs based on SH110X drivers.
5+
*
6+
* @section intro_sec Introduction
7+
*
8+
* This is documentation for Adafruit's SH110X library for monochrome
9+
* OLED displays: http://www.adafruit.com/category/63_98
10+
*
11+
* These displays use I2C or SPI to communicate. I2C requires 2 pins
12+
* (SCL+SDA) and optionally a RESET pin. SPI requires 4 pins (MOSI, SCK,
13+
* select, data/command) and optionally a reset pin. Hardware SPI or
14+
* 'bitbang' software SPI are both supported.
15+
*
16+
* Adafruit invests time and resources providing this open source code,
17+
* please support Adafruit and open-source hardware by purchasing
18+
* products from Adafruit!
19+
*
20+
* @section dependencies Dependencies
21+
*
22+
* This library depends on <a
23+
* href="https://github.com/adafruit/Adafruit-GFX-Library"> Adafruit_GFX</a>
24+
* being present on your system. Please make sure you have installed the latest
25+
* version before using this library.
26+
*
27+
* @section author Author
28+
*
29+
* Written by Limor Fried/Ladyada for Adafruit Industries, with
30+
* contributions from the open source community.
31+
*
32+
* @section license License
33+
*
34+
* BSD license, all text above, and the splash screen included below,
35+
* must be included in any redistribution.
36+
*
37+
*/
38+
39+
#include "Adafruit_SH110X.h"
40+
#include "splash.h"
41+
42+
// CONSTRUCTORS, DESTRUCTOR ------------------------------------------------
43+
44+
/*!
45+
@brief Constructor for I2C-interfaced SH110X displays.
46+
@param w
47+
Display width in pixels
48+
@param h
49+
Display height in pixels
50+
@param twi
51+
Pointer to an existing TwoWire instance (e.g. &Wire, the
52+
microcontroller's primary I2C bus).
53+
@param rst_pin
54+
Reset pin (using Arduino pin numbering), or -1 if not used
55+
(some displays might be wired to share the microcontroller's
56+
reset pin).
57+
@param clkDuring
58+
Speed (in Hz) for Wire transmissions in SH110X library calls.
59+
Defaults to 400000 (400 KHz), a known 'safe' value for most
60+
microcontrollers, and meets the SH110X datasheet spec.
61+
Some systems can operate I2C faster (800 KHz for ESP32, 1 MHz
62+
for many other 32-bit MCUs), and some (perhaps not all)
63+
SH110X's can work with this -- so it's optionally be specified
64+
here and is not a default behavior. (Ignored if using pre-1.5.7
65+
Arduino software, which operates I2C at a fixed 100 KHz.)
66+
@param clkAfter
67+
Speed (in Hz) for Wire transmissions following SH110X library
68+
calls. Defaults to 100000 (100 KHz), the default Arduino Wire
69+
speed. This is done rather than leaving it at the 'during' speed
70+
because other devices on the I2C bus might not be compatible
71+
with the faster rate. (Ignored if using pre-1.5.7 Arduino
72+
software, which operates I2C at a fixed 100 KHz.)
73+
@note Call the object's begin() function before use -- buffer
74+
allocation is performed there!
75+
*/
76+
Adafruit_SH110X::Adafruit_SH110X(uint16_t w, uint16_t h, TwoWire *twi,
77+
int8_t rst_pin, uint32_t clkDuring,
78+
uint32_t clkAfter)
79+
: Adafruit_GrayOLED(1, w, h, twi, rst_pin, clkDuring, clkAfter) {}
80+
81+
/*!
82+
@brief Constructor for SPI SH110X displays, using software (bitbang)
83+
SPI.
84+
@param w
85+
Display width in pixels
86+
@param h
87+
Display height in pixels
88+
@param mosi_pin
89+
MOSI (master out, slave in) pin (using Arduino pin numbering).
90+
This transfers serial data from microcontroller to display.
91+
@param sclk_pin
92+
SCLK (serial clock) pin (using Arduino pin numbering).
93+
This clocks each bit from MOSI.
94+
@param dc_pin
95+
Data/command pin (using Arduino pin numbering), selects whether
96+
display is receiving commands (low) or data (high).
97+
@param rst_pin
98+
Reset pin (using Arduino pin numbering), or -1 if not used
99+
(some displays might be wired to share the microcontroller's
100+
reset pin).
101+
@param cs_pin
102+
Chip-select pin (using Arduino pin numbering) for sharing the
103+
bus with other devices. Active low.
104+
@note Call the object's begin() function before use -- buffer
105+
allocation is performed there!
106+
*/
107+
Adafruit_SH110X::Adafruit_SH110X(uint16_t w, uint16_t h, int8_t mosi_pin,
108+
int8_t sclk_pin, int8_t dc_pin, int8_t rst_pin,
109+
int8_t cs_pin)
110+
: Adafruit_GrayOLED(1, w, h, mosi_pin, sclk_pin, dc_pin, rst_pin, cs_pin) {}
111+
112+
/*!
113+
@brief Constructor for SPI SH110X displays, using native hardware SPI.
114+
@param w
115+
Display width in pixels
116+
@param h
117+
Display height in pixels
118+
@param spi
119+
Pointer to an existing SPIClass instance (e.g. &SPI, the
120+
microcontroller's primary SPI bus).
121+
@param dc_pin
122+
Data/command pin (using Arduino pin numbering), selects whether
123+
display is receiving commands (low) or data (high).
124+
@param rst_pin
125+
Reset pin (using Arduino pin numbering), or -1 if not used
126+
(some displays might be wired to share the microcontroller's
127+
reset pin).
128+
@param cs_pin
129+
Chip-select pin (using Arduino pin numbering) for sharing the
130+
bus with other devices. Active low.
131+
@param bitrate
132+
SPI clock rate for transfers to this display. Default if
133+
unspecified is 8000000UL (8 MHz).
134+
@note Call the object's begin() function before use -- buffer
135+
allocation is performed there!
136+
*/
137+
Adafruit_SH110X::Adafruit_SH110X(uint16_t w, uint16_t h, SPIClass *spi,
138+
int8_t dc_pin, int8_t rst_pin, int8_t cs_pin,
139+
uint32_t bitrate)
140+
: Adafruit_GrayOLED(1, w, h, spi, dc_pin, rst_pin, cs_pin, bitrate) {}
141+
142+
/*!
143+
@brief Destructor for Adafruit_SH110X object.
144+
*/
145+
Adafruit_SH110X::~Adafruit_SH110X(void) {}
146+
147+
// REFRESH DISPLAY ---------------------------------------------------------
148+
149+
/*!
150+
@brief Push data currently in RAM to SH110X display.
151+
@note Drawing operations are not visible until this function is
152+
called. Call after each graphics command, or after a whole set
153+
of graphics commands, as best needed by one's own application.
154+
*/
155+
void Adafruit_SH110X::display(void) {
156+
// ESP8266 needs a periodic yield() call to avoid watchdog reset.
157+
// With the limited size of SH110X displays, and the fast bitrate
158+
// being used (1 MHz or more), I think one yield() immediately before
159+
// a screen write and one immediately after should cover it. But if
160+
// not, if this becomes a problem, yields() might be added in the
161+
// 32-byte transfer condition below.
162+
yield();
163+
164+
uint16_t count = WIDTH * ((HEIGHT + 7) / 8); (void)count;
165+
uint8_t *ptr = buffer;
166+
uint8_t dc_byte = 0x40;
167+
uint8_t pages = ((HEIGHT + 7) / 8);
168+
169+
uint8_t bytes_per_page = WIDTH;
170+
171+
/*
172+
Serial.print("Window: (");
173+
Serial.print(window_x1);
174+
Serial.print(", ");
175+
Serial.print(window_y1);
176+
Serial.print(" -> (");
177+
Serial.print(window_x2);
178+
Serial.print(", ");
179+
Serial.print(window_y2);
180+
Serial.println(")");
181+
*/
182+
183+
uint8_t first_page = window_y1 / 8;
184+
uint8_t last_page = (window_y2 + 7) / 8; (void)last_page;
185+
uint8_t page_start = min(bytes_per_page, (uint8_t)window_x1);
186+
uint8_t page_end = (uint8_t)max((int)0, (int)window_x2);
187+
/*
188+
Serial.print("Pages: ");
189+
Serial.print(first_page);
190+
Serial.print(" -> ");
191+
Serial.println(last_page);
192+
pages = min(pages, last_page);
193+
194+
Serial.print("Page addr: ");
195+
Serial.print(page_start);
196+
Serial.print(" -> ");
197+
Serial.println(page_end);
198+
*/
199+
200+
for (uint8_t p = first_page; p < pages; p++) {
201+
uint8_t bytes_remaining = bytes_per_page;
202+
ptr = buffer + (uint16_t)p * (uint16_t)bytes_per_page;
203+
// fast forward to dirty rectangle beginning
204+
ptr += page_start;
205+
bytes_remaining -= page_start;
206+
// cut off end of dirty rectangle
207+
bytes_remaining -= (WIDTH - 1) - page_end;
208+
209+
if (i2c_dev) { // I2C
210+
uint16_t maxbuff = i2c_dev->maxBufferSize() - 1;
211+
212+
uint8_t cmd[] = {
213+
0x00, (uint8_t)(SH110X_SETPAGEADDR + p),
214+
(uint8_t)(0x10 + ((page_start + _page_start_offset) >> 4)),
215+
(uint8_t)((page_start + _page_start_offset) & 0xF)};
216+
217+
// Set high speed clk
218+
i2c_dev->setSpeed(i2c_preclk);
219+
220+
i2c_dev->write(cmd, 4);
221+
222+
while (bytes_remaining) {
223+
uint8_t to_write = min(bytes_remaining, (uint8_t)maxbuff);
224+
i2c_dev->write(ptr, to_write, true, &dc_byte, 1);
225+
ptr += to_write;
226+
bytes_remaining -= to_write;
227+
yield();
228+
}
229+
230+
// Set low speed clk
231+
i2c_dev->setSpeed(i2c_postclk);
232+
233+
} else { // SPI
234+
uint8_t cmd[] = {
235+
(uint8_t)(SH110X_SETPAGEADDR + p),
236+
(uint8_t)(0x10 + ((page_start + _page_start_offset) >> 4)),
237+
(uint8_t)((page_start + _page_start_offset) & 0xF)};
238+
239+
digitalWrite(dcPin, LOW);
240+
spi_dev->write(cmd, 3);
241+
digitalWrite(dcPin, HIGH);
242+
spi_dev->write(ptr, bytes_remaining);
243+
}
244+
}
245+
// reset dirty window
246+
window_x1 = 1024;
247+
window_y1 = 1024;
248+
window_x2 = -1;
249+
window_y2 = -1;
250+
}

0 commit comments

Comments
 (0)