Skip to content

Commit 7278496

Browse files
author
dave
committed
working example for SPI and I2C
1 parent 9ed1e96 commit 7278496

File tree

6 files changed

+106
-435
lines changed

6 files changed

+106
-435
lines changed

Adafruit_GFX_Config.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@
44
// Uncomment this to turn off the builtin splash
55
//#define NO_SPLASH_ADAFRUIT
66

7-
// Uncomment this to enable all functionality
8-
//#define GFX_WANT_ABSTRACTS
9-
10-
// Uncomment this to enable only runtime font scaling, without all the rest of the Abstracts
11-
//#define GFX_SIZEABLE_TEXT
7+
// Turn on or off IoAbstraction extensions. Default is on.
8+
#define USE_IOABSTRACTION_TCMENU
129

1310

1411
#endif

Adafruit_SSD1306_I2c.h

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,43 +51,26 @@ class Adafruit_SSD1306_I2c : public Adafruit_SSD1306
5151
protected:
5252
void sendDisplayBuffer() override
5353
{
54+
char buff[133];
5455

55-
if(mDisplayType == SH_1106) {
56-
char buff[133];
56+
auto rows = uint8_t(HEIGHT / 8);
57+
uint16_t col = 2;
58+
for(uint8_t row=0; row < rows; row++) {
59+
// for each row we go into command mode and send the new row offset, SH1106 cannot do this
60+
// automatically, so we need to do it and it's compatible with SSD1306 too.
61+
command(0xB0 + row);//set page address
62+
command(col & 0xfU);//set lower column address
63+
command(0x10U | (col >> 4U));//set higher column address
5764

58-
auto rows = uint8_t(HEIGHT / 8);
59-
uint16_t col = 2;
60-
for(uint8_t row=0; row < rows; row++) {
61-
// for each row we go into command mode and send the new row offset, SH1106 cannot do this
62-
// automatically, so we need to do it for it.
63-
command(0xB0 + row);//set page address
64-
command(col & 0xfU);//set lower column address
65-
command(0x10U | (col >> 4U));//set higher column address
66-
67-
buff[0] = 0x40; // start data mode
68-
// now we prepare a whole row of data, no need to mess around with smaller segments, then dump
69-
// the lot into i2c.
70-
for(int i=0;i<WIDTH;i++) {
71-
buff[i + 1] = buffer[(row * WIDTH) + i];
72-
}
73-
mi2c.write(mi2cAddress, buff, WIDTH);
74-
}
75-
}
76-
else {
77-
// for SSD1306 we do what we used to do..
78-
char buff[20];
79-
buff[0] = 0x40; // Data Mode all the way for SSD1306!
80-
81-
// send display buffer in 16 byte chunks
82-
for (uint16_t i = 0, q = buffSize; i < q; i += 16) {
83-
uint16_t x;
84-
// TODO - this will segfault if buffer.size() % 16 != 0
85-
for (x = 1; x < sizeof(buff); x++)
86-
buff[x] = buffer[i + x - 1];
87-
mi2c.write(mi2cAddress, buff, sizeof(buff));
65+
buff[0] = 0x40; // start data mode
66+
// now we prepare a whole row of data, no need to mess around with smaller segments, then dump
67+
// the lot into i2c.
68+
for(int i=0;i<WIDTH;i++) {
69+
buff[i + 1] = buffer[(row * WIDTH) + i];
8870
}
71+
mi2c.write(mi2cAddress, buff, WIDTH);
8972
}
90-
};
73+
}
9174

9275
I2C &mi2c;
9376
uint8_t mi2cAddress;

Adafruit_SSD1306_Spi.h

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,58 +38,43 @@ class Adafruit_SSD1306_Spi : public Adafruit_SSD1306
3838
dc = dcState;
3939
wait_us(1);
4040
cs = 0;
41-
wait_us(1);
4241
}
4342

44-
virtual void command(uint8_t c)
43+
void command(uint8_t c) override
4544
{
4645
toggleDC(0);
4746
mspi.write(c);
4847
cs = 1;
4948
};
5049

51-
virtual void data(uint8_t c)
50+
void data(uint8_t c) override
5251
{
5352
toggleDC(1);
5453
mspi.write(c);
5554
cs = 1;
5655
};
5756

5857
protected:
59-
virtual void sendDisplayBuffer()
58+
void sendDisplayBuffer() override
6059
{
61-
if(mDisplayType == SH_1106) {
62-
auto rows = HEIGHT / 8;
63-
auto col = 2;
64-
for(uint8_t row=0; row < rows; row++) {
65-
// for each row we go into command mode and send the new row offset, SH1106 cannot do this
66-
// automatically, so we need to do it for it.
67-
command(0xB0 + row);//set page address
68-
command(col & 0xfU);//set lower column address
69-
command(0x10U | (col >> 4U));//set higher column address
70-
71-
toggleDC(1);
60+
auto rows = HEIGHT / 8;
61+
auto col = 2;
62+
for(uint8_t row=0; row < rows; row++) {
63+
// for each row we go into command mode and send the new row offset, SH1106 cannot do this
64+
// automatically, so we need to do it for it.
65+
command(0xB0 + row);//set page address
66+
command(col & 0xfU);//set lower column address
67+
command(0x10U | (col >> 4U));//set higher column address
7268

73-
// now we prepare a whole row of data, no need to mess around with smaller segments, then dump
74-
// the lot into i2c.
75-
for(int i=0;i<WIDTH;i++) {
76-
mspi.write(buffer[(row * WIDTH) + i]);
77-
}
78-
}
79-
}
80-
else {
8169
toggleDC(1);
82-
for(uint16_t i=0, q=buffSize; i<q; i++)
83-
mspi.write(buffer[i]);
84-
}
8570

86-
if(HEIGHT == 32)
87-
{
88-
toggleDC(1);
89-
for(uint16_t i=0, q=buffSize; i<q; i++)
90-
mspi.write(0);
71+
// now we prepare a whole row of data to send over SPI.
72+
for(int i=0;i<WIDTH;i++) {
73+
mspi.write(buffer[(row * WIDTH) + i]);
74+
}
9175
}
9276

77+
// make sure we de-select the chip
9378
cs = 1;
9479
};
9580

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ Although many newer mbed RTOS chipsets have inbuilt hardware LCD drivers, there'
2020
* You can use the regular [Adafruit_GFX introductory guide](https://learn.adafruit.com/adafruit-gfx-graphics-library/overview) as this fork has high compatibility.
2121
* It also integrates well with tcMenu, IoAbstraction and TaskManagerIO.
2222

23+
## Issues
24+
25+
Unless you are absolutely sure that the issue is a core Adafruit_GFX issue, please raise the issue here first for us to triage it.
26+
2327
## Usage
2428

2529
This library can work with SSD1306 and SH1106 displays over I2C or SPI. There's a couple of really simple examples packaged that show basic usage. However, you can look at almost any Adafruit example, as this library is completely compatible, especially wit the IoAbstraction extensions.
2630

27-
Although not required, this library has the ability to integrate with IoAbstraction by defining USE_IOABSTRACTION_TCMENU, this provides a complete Print interface that is nearly compatible with Arduino's print functions. I'll be honest, we all but assume this flag is set because all our development uses it.
31+
Although not required, this library has the ability to integrate with IoAbstraction by defining USE_IOABSTRACTION_TCMENU, this provides a complete Print interface that is nearly compatible with Arduino's print functions. I'll be honest, we all but assume this flag is set because all our development uses it. To completely remove IoAbstraction, remove the flag in the config header.
2832

2933
Performance, at the moment the SSD1306 class could be significantly optimised. However, our first aim is to get it stable on mbed 5/6, we'll look at performance later.
3034

examples/mbedAdaExample/main.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
2+
#include <cstdio>
3+
#include <TaskManager.h>
4+
#include <SwitchInput.h>
5+
#include "mbed.h"
6+
//#include "Adafruit_SSD1306_I2c.h"
7+
#include "Adafruit_SSD1306_Spi.h"
8+
#include <IoLogging.h>
9+
#include <Fonts/FreeSans9pt7b.h>
10+
11+
// Host PC Communication channels
12+
BufferedSerial pc(USBTX, USBRX); // tx, rx
13+
FILE* serPort = fdopen(&pc, "w");
14+
MBedLogger LoggingPort(pc);
15+
16+
//I2C i2c(PF_0,PF_1);
17+
//Adafruit_SSD1306_I2c gfx(i2c, NC, SSD_I2C_ADDRESS, 64, 132, SH_1106);
18+
19+
SPI spi(PA_7, PA_6, PA_5);
20+
Adafruit_SSD1306_Spi gfx(spi, PD_15, PF_12, PF_13, 64, 128, SSD_1306);
21+
22+
bool exitApp = false;
23+
24+
const uint8_t iconWifiThreeBar[] = {
25+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03,
26+
0x30, 0x0c, 0x08, 0x10, 0xc0, 0x03, 0x20, 0x04, 0x80, 0x01, 0x80, 0x01
27+
};
28+
int main()
29+
{
30+
//i2c.frequency(400000);
31+
gfx.begin();
32+
pc.set_baud(115200);
33+
fprintf(serPort, "Hello from mbed graphics demo\n");
34+
35+
switches.initialise(internalDigitalIo(), true);
36+
switches.addSwitch(PE_4, [] (pinid_t id, bool held) {
37+
fprintf(serPort, "Switch Pressed %d, %d\n", (int)id, (int) held);
38+
});
39+
switches.addSwitch(USER_BUTTON, [] (pinid_t id, bool held) {
40+
fprintf(serPort, "User Pressed %d, %d\n", (int)id, (int) held);
41+
}, NO_REPEAT, true);
42+
43+
setupRotaryEncoderWithInterrupt(PE_2, PE_5, []( int val) {
44+
fprintf(serPort, "Encoder %d\n", val);
45+
});
46+
47+
fprintf(serPort, "Created\n");
48+
49+
// Display with the Adafruit Library
50+
gfx.clearDisplay();
51+
52+
taskManager.scheduleFixedRate(75, [] {
53+
gfx.setFont(nullptr);
54+
gfx.setCursor(0, 0);
55+
gfx.print("hello world");
56+
gfx.fillRect(10, 25, 50, 10, BLACK);
57+
gfx.setCursor(10, 25);
58+
gfx.print((double) millis() / 1000.0);
59+
gfx.drawXBitmap(40, 40, iconWifiThreeBar, 16, 12, WHITE);
60+
gfx.drawCircle(100, 40, 10, WHITE);
61+
gfx.display();
62+
});
63+
64+
while(!exitApp) {
65+
taskManager.runLoop();
66+
}
67+
}

0 commit comments

Comments
 (0)