-
Notifications
You must be signed in to change notification settings - Fork 5
/
ssd1306.c
126 lines (117 loc) · 8.78 KB
/
ssd1306.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Display something on SSD1306 LCD in a Raspberry PI
// $ cc ssd1306.c && ./a.out
// Originally based on https://github.com/pive/rpi1306i2c/blob/master/rpi1306i2c.hpp
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define MEMORYMODE 0x20
#define COLUMNADDR 0x21
#define PAGEADDR 0x22
#define SETSTARTLINE 0x40
#define SETCONTRAST 0x81
#define CHARGEPUMP 0x8D
#define SEGREMAP 0xA0
#define DISPLAYALLON_RESUME 0xA4
#define DISPLAYALLON 0xA5
#define NORMALDISPLAY 0xA6
#define SETMULTIPLEX 0xA8
#define DISPLAYOFF 0xAE
#define DISPLAYON 0xAF
#define SETPAGE 0xB0
#define COMSCANINC 0xC0
#define COMSCANDEC 0xC8
#define SETDISPLAYOFFSET 0xD3
#define SETDISPLAYCLOCKDIV 0xD5
#define SETPRECHARGE 0xD9
#define SETCOMPINS 0xDA
#define SETVCOMDETECT 0xDB
const uint8_t ssd1306_128x32_init_seq[] = {
0x80, DISPLAYOFF,
0x80, SETDISPLAYCLOCKDIV, 0x80, 0x80,
0x80, SETMULTIPLEX, 0x80, 0x1F,
0x80, SETDISPLAYOFFSET, 0x80, 0x00,
0x80, SETSTARTLINE | 0x00,
0x80, CHARGEPUMP, 0x80, 0x14,
0x80, SEGREMAP,
0x80, COMSCANDEC,
0x80, SETCOMPINS, 0x80, 0x12,
0x80, SETCONTRAST, 0x80, 0x1,//0x7F, brightness
0x80, SETPRECHARGE, 0x80, 0x22,
0x80, SETVCOMDETECT, 0x80, 0x20,
0x80, MEMORYMODE,
0x80, DISPLAYALLON_RESUME,
0x80, NORMALDISPLAY,
0x80, COLUMNADDR, 0x80, 0, 0x80, 128 - 1,
0x80, PAGEADDR, 0x80, 0, 0x80, (32 >> 3) - 1,
0x80, DISPLAYON,
};
// This image is brought from https://github.com/dwhinham/mt32-pi/blob/ee645df6e/include/lcd/images.h#L71-L105
const uint8_t image[] = {
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000011, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00111111, 0b11100000, 0b00000011, 0b11111100, 0b00001111, 0b11100000, 0b00111111, 0b11110000, 0b11111111, 0b11111111, 0b11100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00111111, 0b11111000, 0b00000011, 0b11111111, 0b00011111, 0b11110000, 0b11111111, 0b11111110, 0b11111111, 0b11111111, 0b11111000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00111111, 0b11111000, 0b00000111, 0b11111111, 0b10011111, 0b11110001, 0b11111111, 0b11111110, 0b11111111, 0b11111111, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00111111, 0b11111100, 0b00000111, 0b11111111, 0b10011111, 0b11110011, 0b11111111, 0b11111100, 0b11111111, 0b11111111, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00111111, 0b11111100, 0b00000111, 0b11111111, 0b10011111, 0b11100111, 0b11111111, 0b11111101, 0b11111111, 0b11111111, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b01111111, 0b11111100, 0b00001111, 0b11111111, 0b10001111, 0b11001111, 0b11111111, 0b11111001, 0b11111111, 0b11111111, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b01111111, 0b11111100, 0b00001111, 0b11111111, 0b10000011, 0b00001111, 0b11111000, 0b00000001, 0b11111111, 0b11111111, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b01111111, 0b11111100, 0b00011111, 0b11111111, 0b10000000, 0b00001111, 0b11110000, 0b00000000, 0b00000011, 0b11111100, 0b00000000, 0b01110000, 0b00000000, 0b00000000, 0b11000000,
0b00000000, 0b01111111, 0b11111100, 0b00011111, 0b11111111, 0b10111110, 0b00001111, 0b11110000, 0b00000000, 0b00000011, 0b11111100, 0b00000111, 0b11111110, 0b00001111, 0b11110011, 0b11000000,
0b00000000, 0b01111110, 0b11111100, 0b00111111, 0b01111111, 0b10111111, 0b10001111, 0b11111000, 0b00000000, 0b00000011, 0b11111100, 0b00011111, 0b11111111, 0b10001111, 0b11110111, 0b11000000,
0b00000000, 0b11111110, 0b11111100, 0b00111111, 0b01111111, 0b00111111, 0b10001111, 0b11111110, 0b00000000, 0b00000111, 0b11111000, 0b00111111, 0b11111111, 0b10001111, 0b11111111, 0b11000000,
0b00000000, 0b11111110, 0b11111100, 0b01111110, 0b11111111, 0b00111111, 0b10001111, 0b11111111, 0b10000000, 0b00000111, 0b11111000, 0b01111111, 0b11111111, 0b11001111, 0b11111111, 0b11000000,
0b00000000, 0b11111110, 0b11111100, 0b01111110, 0b11111111, 0b00111111, 0b10000111, 0b11111111, 0b11000000, 0b00000111, 0b11111000, 0b11111111, 0b00011111, 0b11011111, 0b11111111, 0b10000000,
0b00000000, 0b11111110, 0b11111100, 0b01111100, 0b11111111, 0b01111111, 0b10000111, 0b11111111, 0b11100000, 0b00000111, 0b11111000, 0b11111110, 0b00011111, 0b11011111, 0b11111111, 0b10000000,
0b00000001, 0b11111110, 0b11111100, 0b11111100, 0b11111111, 0b01111111, 0b10000011, 0b11111111, 0b11110000, 0b00000111, 0b11111001, 0b11111100, 0b00111111, 0b11011111, 0b11111000, 0b00000000,
0b00000001, 0b11111100, 0b11111110, 0b11111001, 0b11111110, 0b01111111, 0b10000000, 0b11111111, 0b11110000, 0b00001111, 0b11110001, 0b11111111, 0b11111111, 0b10011111, 0b11100000, 0b00000000,
0b00000001, 0b11111100, 0b11111111, 0b11111001, 0b11111110, 0b01111111, 0b10000000, 0b00111111, 0b11111000, 0b00001111, 0b11110001, 0b11111111, 0b11111111, 0b10011111, 0b11100000, 0b00000000,
0b00000001, 0b11111100, 0b11111111, 0b11111001, 0b11111110, 0b11111111, 0b00000000, 0b00001111, 0b11111000, 0b00001111, 0b11110011, 0b11111111, 0b11111111, 0b00111111, 0b11000000, 0b00000000,
0b00000001, 0b11111100, 0b11111111, 0b11110001, 0b11111110, 0b11111111, 0b00000000, 0b00001111, 0b11111000, 0b00001111, 0b11110011, 0b11111111, 0b11111100, 0b00111111, 0b11000000, 0b00000000,
0b00000011, 0b11111100, 0b01111111, 0b11110001, 0b11111100, 0b11111111, 0b00110000, 0b00000111, 0b11111000, 0b00001111, 0b11110011, 0b11111111, 0b10000000, 0b00111111, 0b11000000, 0b00000000,
0b00000011, 0b11111000, 0b01111111, 0b11100011, 0b11111100, 0b11111111, 0b00111100, 0b00001111, 0b11111000, 0b00011111, 0b11100011, 0b11111100, 0b00000000, 0b00111111, 0b11000000, 0b00000000,
0b00000011, 0b11111000, 0b01111111, 0b11100011, 0b11111100, 0b11111110, 0b00111111, 0b11111111, 0b11110000, 0b00011111, 0b11100011, 0b11111110, 0b00000110, 0b00111111, 0b10000000, 0b00000000,
0b00000011, 0b11111000, 0b01111111, 0b11000011, 0b11111100, 0b11111110, 0b00111111, 0b11111111, 0b11110000, 0b00011111, 0b11100001, 0b11111111, 0b11111110, 0b01111111, 0b10000000, 0b00000000,
0b00000011, 0b11111000, 0b01111111, 0b11000011, 0b11111100, 0b11111110, 0b00111111, 0b11111111, 0b11100000, 0b00011111, 0b11100001, 0b11111111, 0b11111110, 0b01111111, 0b10000000, 0b00000000,
0b00000011, 0b11110000, 0b01111111, 0b10000011, 0b11111000, 0b11111110, 0b01111111, 0b11111111, 0b11000000, 0b00011111, 0b11100000, 0b11111111, 0b11111110, 0b00111111, 0b10000000, 0b00000000,
0b00000001, 0b11110000, 0b01111111, 0b10000001, 0b11111000, 0b01111110, 0b00111111, 0b11111111, 0b10000000, 0b00001111, 0b11000000, 0b01111111, 0b11111100, 0b00011111, 0b10000000, 0b00000000,
0b00000000, 0b11110000, 0b01111111, 0b00000000, 0b01111000, 0b00111100, 0b00001111, 0b11111110, 0b00000000, 0b00000011, 0b11000000, 0b00011111, 0b11110000, 0b00001111, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
};
static void writeBuffer(int deviceNode, const uint8_t *buffer, unsigned size) {
if (write(deviceNode, buffer, size) != size) {
printf("Could not write on the device");
abort();
}
}
int main() {
const int deviceNode = open("/dev/i2c-1", O_RDWR);
const uint8_t addr = 0x3C;
if (deviceNode < 0 || ioctl(deviceNode, I2C_SLAVE, addr) < 0) {
printf("Could not open\n");
abort();
}
writeBuffer(deviceNode, ssd1306_128x32_init_seq, sizeof(ssd1306_128x32_init_seq));
uint8_t buffer[513] = {SETSTARTLINE};
unsigned tick = 0;
while (1) {
++tick;
for (unsigned i = 0; i < sizeof(buffer) - 1; ++i) {
unsigned x = 127 - ((i - tick) % 128);
unsigned y = (i / 128) * 8;
#define P(j) ((unsigned) !!(image[x / 8 + (y + j) * 16] & (1 << (7 - (x % 8)))) << j)
buffer[i + 1] = P(0) | P(1) | P(2) | P(3) | P(4) | P(5) | P(6) | P(7);
#undef P
}
writeBuffer(deviceNode, buffer, sizeof(buffer));
usleep(10000);
}
close(deviceNode);
return 0;
}