Skip to content

Commit 5722cf8

Browse files
author
jochen@homeland
committed
hardware SPI only version for Zero or feather M0 boards
1 parent a5d794c commit 5722cf8

8 files changed

+119
-378
lines changed

Adafruit_SSD1331.cpp

+64-103
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44
Pick one up today in the adafruit shop!
55
------> http://www.adafruit.com/products/684
66
7-
These displays use SPI to communicate, 4 or 5 pins are required to
8-
interface
7+
These displays use hardware SPI to communicate
8+
99
Adafruit invests time and resources providing this open source code,
1010
please support Adafruit and open-source hardware by purchasing
1111
products from Adafruit!
1212
1313
Written by Limor Fried/Ladyada for Adafruit Industries.
1414
BSD license, all text above must be included in any redistribution
15+
16+
Feb 2017 - code modified by Jochen Peters (no-go, Deadlockz)
17+
to run on a feather M0 / Arduino Zero (?) with hardware SPI
1518
****************************************************/
1619

1720
#include "Adafruit_GFX.h"
@@ -31,63 +34,25 @@
3134
/********************************** low level pin interface */
3235

3336
inline void Adafruit_SSD1331::spiwrite(uint8_t c) {
34-
35-
if (!_sid) {
36-
SPI.transfer(c);
37-
return;
38-
}
39-
40-
int8_t i;
41-
42-
*sclkportreg |= sclkpin;
43-
44-
for (i=7; i>=0; i--) {
45-
*sclkportreg &= ~sclkpin;
46-
//SCLK_PORT &= ~_BV(SCLK);
47-
48-
if (c & _BV(i)) {
49-
*sidportreg |= sidpin;
50-
//digitalWrite(_sid, HIGH);
51-
//SID_PORT |= _BV(SID);
52-
} else {
53-
*sidportreg &= ~sidpin;
54-
//digitalWrite(_sid, LOW);
55-
//SID_PORT &= ~_BV(SID);
56-
}
57-
58-
*sclkportreg |= sclkpin;
59-
//SCLK_PORT |= _BV(SCLK);
60-
}
37+
SPI.transfer(c);
38+
return;
6139
}
6240

6341

6442
void Adafruit_SSD1331::writeCommand(uint8_t c) {
65-
*rsportreg &= ~ rspin;
66-
//digitalWrite(_rs, LOW);
67-
68-
*csportreg &= ~ cspin;
69-
//digitalWrite(_cs, LOW);
70-
71-
//Serial.print("C ");
43+
digitalWrite(_cs, HIGH);
44+
digitalWrite(_rs, LOW);
45+
digitalWrite(_cs, LOW);
7246
spiwrite(c);
73-
74-
*csportreg |= cspin;
75-
//digitalWrite(_cs, HIGH);
47+
digitalWrite(_cs, HIGH);
7648
}
7749

7850

7951
void Adafruit_SSD1331::writeData(uint8_t c) {
80-
*rsportreg |= rspin;
81-
//digitalWrite(_rs, HIGH);
82-
83-
*csportreg &= ~ cspin;
84-
//digitalWrite(_cs, LOW);
85-
86-
//Serial.print("D ");
87-
spiwrite(c);
88-
89-
*csportreg |= cspin;
90-
//digitalWrite(_cs, HIGH);
52+
digitalWrite(_rs, HIGH);
53+
digitalWrite(_cs, LOW);
54+
spiwrite(c);
55+
digitalWrite(_cs, HIGH);
9156
}
9257

9358
/***********************************/
@@ -149,7 +114,7 @@ void Adafruit_SSD1331::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
149114
150115
// Bounds check
151116
if ((x >= TFTWIDTH) || (y >= TFTHEIGHT))
152-
return;
117+
return;
153118
154119
// Y bounds check
155120
if (y+h > TFTHEIGHT)
@@ -168,10 +133,10 @@ void Adafruit_SSD1331::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
168133
writeCommand(0x01);
169134
170135
writeCommand(SSD1331_CMD_DRAWRECT);
171-
writeCommand(x & 0xFF); // Starting column
172-
writeCommand(y & 0xFF); // Starting row
173-
writeCommand((x+w-1) & 0xFF); // End column
174-
writeCommand((y+h-1) & 0xFF); // End row
136+
writeCommand(x & 0xFF); // Starting column
137+
writeCommand(y & 0xFF); // Starting row
138+
writeCommand((x+w-1) & 0xFF); // End column
139+
writeCommand((y+h-1) & 0xFF); // End row
175140
176141
// Outline color
177142
writeCommand((uint8_t)((fillcolor >> 11) << 1));
@@ -187,7 +152,7 @@ void Adafruit_SSD1331::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
187152
}
188153
*/
189154

190-
void Adafruit_SSD1331::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
155+
void Adafruit_SSD1331::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
191156
// check rotation, move pixel around if necessary
192157
switch (getRotation()) {
193158
case 1:
@@ -212,9 +177,9 @@ void Adafruit_SSD1331::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
212177

213178
// Boundary check
214179
if ((y0 >= TFTHEIGHT) && (y1 >= TFTHEIGHT))
215-
return;
180+
return;
216181
if ((x0 >= TFTWIDTH) && (x1 >= TFTWIDTH))
217-
return;
182+
return;
218183
if (x0 >= TFTWIDTH)
219184
x0 = TFTWIDTH - 1;
220185
if (y0 >= TFTHEIGHT)
@@ -258,54 +223,49 @@ void Adafruit_SSD1331::drawPixel(int16_t x, int16_t y, uint16_t color)
258223

259224
goTo(x, y);
260225

261-
// setup for data
262-
*rsportreg |= rspin;
263-
*csportreg &= ~ cspin;
264-
226+
digitalWrite(_rs, HIGH);
227+
digitalWrite(_cs, LOW);
228+
265229
spiwrite(color >> 8);
266230
spiwrite(color);
267231

268-
*csportreg |= cspin;
232+
digitalWrite(_cs, HIGH);
269233
}
270234

271235
void Adafruit_SSD1331::pushColor(uint16_t color) {
272236
// setup for data
273-
*rsportreg |= rspin;
274-
*csportreg &= ~ cspin;
237+
digitalWrite(_rs, HIGH);
238+
digitalWrite(_cs, LOW);
275239

276240
spiwrite(color >> 8);
277241
spiwrite(color);
278242

279-
*csportreg |= cspin;
243+
digitalWrite(_cs, HIGH);
280244
}
281245

282246

283247
void Adafruit_SSD1331::begin(void) {
284248
// set pin directions
285249
pinMode(_rs, OUTPUT);
286250

287-
if (_sclk) {
288-
pinMode(_sclk, OUTPUT);
289-
sclkportreg = portOutputRegister(digitalPinToPort(_sclk));
290-
sclkpin = digitalPinToBitMask(_sclk);
291-
292-
pinMode(_sid, OUTPUT);
293-
sidportreg = portOutputRegister(digitalPinToPort(_sid));
294-
sidpin = digitalPinToBitMask(_sid);
295-
} else {
296251
// using the hardware SPI
297252
SPI.begin();
298-
SPI.setDataMode(SPI_MODE3);
299-
}
300-
253+
//SPI.setDataMode(SPI_MODE3);
254+
#ifdef SPI_HAS_TRANSACTION
255+
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
256+
#else
257+
SPI.setClockDivider (4);
258+
#endif
259+
301260
// Toggle RST low to reset; CS low so it'll listen to us
302261
pinMode(_cs, OUTPUT);
303262
digitalWrite(_cs, LOW);
263+
digitalWrite(_rs, LOW);
304264
cspin = digitalPinToBitMask(_cs);
305-
csportreg = portOutputRegister(digitalPinToPort(_cs));
265+
//csportreg = portOutputRegister(digitalPinToPort(_cs));
306266

307267
rspin = digitalPinToBitMask(_rs);
308-
rsportreg = portOutputRegister(digitalPinToPort(_rs));
268+
//rsportreg = portOutputRegister(digitalPinToPort(_rs));
309269

310270
if (_rst) {
311271
pinMode(_rst, OUTPUT);
@@ -317,47 +277,47 @@ void Adafruit_SSD1331::begin(void) {
317277
delay(500);
318278
}
319279
// Initialization Sequence
320-
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
321-
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
280+
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
281+
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
322282
#if defined SSD1331_COLORORDER_RGB
323-
writeCommand(0x72); // RGB Color
283+
writeCommand(0x72); // RGB Color
324284
#else
325-
writeCommand(0x76); // BGR Color
285+
writeCommand(0x76); // BGR Color
326286
#endif
327-
writeCommand(SSD1331_CMD_STARTLINE); // 0xA1
287+
writeCommand(SSD1331_CMD_STARTLINE); // 0xA1
328288
writeCommand(0x0);
329-
writeCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
289+
writeCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
330290
writeCommand(0x0);
331-
writeCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
332-
writeCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
333-
writeCommand(0x3F); // 0x3F 1/64 duty
334-
writeCommand(SSD1331_CMD_SETMASTER); // 0xAD
291+
writeCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
292+
writeCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
293+
writeCommand(0x3F); // 0x3F 1/64 duty
294+
writeCommand(SSD1331_CMD_SETMASTER); // 0xAD
335295
writeCommand(0x8E);
336-
writeCommand(SSD1331_CMD_POWERMODE); // 0xB0
296+
writeCommand(SSD1331_CMD_POWERMODE); // 0xB0
337297
writeCommand(0x0B);
338-
writeCommand(SSD1331_CMD_PRECHARGE); // 0xB1
298+
writeCommand(SSD1331_CMD_PRECHARGE); // 0xB1
339299
writeCommand(0x31);
340-
writeCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
300+
writeCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
341301
writeCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
342-
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
302+
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
343303
writeCommand(0x64);
344-
writeCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
304+
writeCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
345305
writeCommand(0x78);
346-
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8C
306+
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8C
347307
writeCommand(0x64);
348-
writeCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
308+
writeCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
349309
writeCommand(0x3A);
350-
writeCommand(SSD1331_CMD_VCOMH); // 0xBE
310+
writeCommand(SSD1331_CMD_VCOMH); // 0xBE
351311
writeCommand(0x3E);
352-
writeCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
312+
writeCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
353313
writeCommand(0x06);
354-
writeCommand(SSD1331_CMD_CONTRASTA); // 0x81
314+
writeCommand(SSD1331_CMD_CONTRASTA); // 0x81
355315
writeCommand(0x91);
356-
writeCommand(SSD1331_CMD_CONTRASTB); // 0x82
316+
writeCommand(SSD1331_CMD_CONTRASTB); // 0x82
357317
writeCommand(0x50);
358-
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
318+
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
359319
writeCommand(0x7D);
360-
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
320+
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
361321
}
362322

363323
/********************************* low level pin initialization */
@@ -377,3 +337,4 @@ Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t rs, uint8_t rst) : Adafru
377337
_sclk = 0;
378338
_rst = rst;
379339
}
340+

Adafruit_SSD1331.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44
Pick one up today in the adafruit shop!
55
------> http://www.adafruit.com/products/684
66
7-
These displays use SPI to communicate, 4 or 5 pins are required to
8-
interface
7+
These displays use hardware SPI to communicate
8+
99
Adafruit invests time and resources providing this open source code,
1010
please support Adafruit and open-source hardware by purchasing
1111
products from Adafruit!
1212
1313
Written by Limor Fried/Ladyada for Adafruit Industries.
1414
BSD license, all text above must be included in any redistribution
15+
16+
Feb 2017 - code modified by Jochen Peters (no-go, Deadlockz)
17+
to run on a feather M0 / Arduino Zero (?) with hardware SPI
1518
****************************************************/
1619

1720
#if defined(ARDUINO) && ARDUINO >= 100
@@ -22,6 +25,8 @@
2225

2326
#define gfx_swap(a, b) { uint16_t t = a; a = b; b = t; }
2427

28+
#define _BV(b) (1<<(b))
29+
2530
#ifdef __SAM3X8E__
2631
typedef volatile RwReg PortReg;
2732
typedef uint32_t PortMask;

README.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip
2+
3+
Pick one up today in the adafruit shop! http://www.adafruit.com/products/684
4+
5+
These displays use SPI to communicate, 4 or 5 pins are required to
6+
interface
7+
8+
Adafruit invests time and resources providing this open source code,
9+
please support Adafruit and open-source hardware by purchasing
10+
products from Adafruit!
11+
12+
Written by Limor Fried/Ladyada for Adafruit Industries.
13+
BSD license, check license.txt for more information
14+
All text above must be included in any redistribution
15+
16+
# Modification for SSD1331 (SPI) and Coretex M0
17+
18+
I did a evil hack to run the popular SSD1331 RGB oLED Display on
19+
hardware SPI with a feather M0. I compare the Adafruit SSD1306 Lib (monochrom)
20+
with the Adafruit SSD1331 Lib and modified it a bit.
21+
22+
Strange I2C and spark stuff is removed. Sorry.
23+
24+
Boards:
25+
26+
- Feather M0
27+
- Arduino Zero
28+
29+
I hope, that Adafruit merge that Idea/code and make it better (using a wrapper design pattern, maybe?).
30+
31+
# Action picture
32+
33+
Yes. It works! I am so happy about that. But it is a ugly version.
34+
35+
![RGB oLED on a Zero board](ssd1331_feather_M0.jpg)

README.txt

-23
This file was deleted.

0 commit comments

Comments
 (0)