| 126 |
pfowler |
1 |
#include <avr/io.h>
|
|
|
2 |
#include <stdlib.h>
|
|
|
3 |
#include <avr/pgmspace.h>
|
|
|
4 |
#include "wire.h"
|
|
|
5 |
#include "avrutil.h"
|
|
|
6 |
#include <util/delay.h>
|
|
|
7 |
#include <string.h>
|
|
|
8 |
|
|
|
9 |
#include "oled.h"
|
|
|
10 |
|
|
|
11 |
#define OLED_SETCONTRAST 0x81
|
|
|
12 |
#define OLED_DISPLAYALLON_RESUME 0xA4
|
|
|
13 |
#define OLED_DISPLAYALLON 0xA5
|
|
|
14 |
#define OLED_NORMALDISPLAY 0xA6
|
|
|
15 |
#define OLED_INVERTDISPLAY 0xA7
|
|
|
16 |
#define OLED_DISPLAYOFF 0xAE
|
|
|
17 |
#define OLED_DISPLAYON 0xAF
|
|
|
18 |
|
|
|
19 |
#define OLED_SETDISPLAYOFFSET 0xD3
|
|
|
20 |
#define OLED_SETCOMPINS 0xDA
|
|
|
21 |
|
|
|
22 |
#define OLED_SETVCOMDETECT 0xDB
|
|
|
23 |
|
|
|
24 |
#define OLED_SETDISPLAYCLOCKDIV 0xD5
|
|
|
25 |
#define OLED_SETPRECHARGE 0xD9
|
|
|
26 |
|
|
|
27 |
#define OLED_SETMULTIPLEX 0xA8
|
|
|
28 |
|
|
|
29 |
#define OLED_SETLOWCOLUMN 0x00
|
|
|
30 |
#define OLED_SETHIGHCOLUMN 0x10
|
|
|
31 |
#define OLED_SETSTARTLINE 0x40
|
|
|
32 |
|
|
|
33 |
#define OLED_MEMORYMODE 0x20
|
|
|
34 |
#define OLED_COMSCANINC 0xC0
|
|
|
35 |
#define OLED_COMSCANDEC 0xC8
|
|
|
36 |
#define OLED_SEGREMAP 0xA0
|
|
|
37 |
#define OLED_CHARGEPUMP 0x8D
|
|
|
38 |
|
|
|
39 |
/**
|
|
|
40 |
* Color is simply true (white) or false (black)
|
|
|
41 |
*/
|
|
|
42 |
void oled_drawPixel(uint8_t* buffer, uint16_t x, uint16_t y, uint8_t color) {
|
|
|
43 |
if (color)
|
|
|
44 |
buffer[x+ (y/8)*oled.width] |= _BV((y%8));
|
|
|
45 |
else
|
|
|
46 |
buffer[x+ (y/8)*oled.width] &= ~_BV((y%8));
|
|
|
47 |
}
|
|
|
48 |
|
|
|
49 |
|
|
|
50 |
void oled_invert(uint8_t i) {
|
|
|
51 |
if (i)
|
|
|
52 |
oled_cmd(OLED_INVERTDISPLAY);
|
|
|
53 |
else
|
|
|
54 |
oled_cmd(OLED_NORMALDISPLAY);
|
|
|
55 |
}
|
|
|
56 |
|
|
|
57 |
uint8_t* oled_getBuffer(void) {
|
|
|
58 |
return oled.buffer;
|
|
|
59 |
}
|
|
|
60 |
|
|
|
61 |
uint8_t* oled_init(uint8_t width, uint8_t height, uint8_t vccstate, uint8_t address) {
|
|
|
62 |
oled.i2c_addr = address;
|
|
|
63 |
oled.width = width;
|
|
|
64 |
oled.height = height;
|
|
|
65 |
|
|
|
66 |
oled.buffer = malloc((oled.height * oled.width / 8) * sizeof(uint8_t));
|
|
|
67 |
|
|
|
68 |
//Reset high, (1), Low (10), High
|
|
|
69 |
|
|
|
70 |
// Init Sequence
|
|
|
71 |
oled_cmd(OLED_DISPLAYOFF);
|
|
|
72 |
oled_cmd(OLED_SETDISPLAYCLOCKDIV);
|
|
|
73 |
oled_cmd(0x80); // ratio
|
|
|
74 |
oled_cmd(OLED_SETMULTIPLEX);
|
|
|
75 |
oled_cmd(0x3F);
|
|
|
76 |
oled_cmd(OLED_SETDISPLAYOFFSET);
|
|
|
77 |
oled_cmd(0x0);
|
|
|
78 |
oled_cmd(OLED_SETSTARTLINE | 0x0); // line 0
|
|
|
79 |
oled_cmd(OLED_CHARGEPUMP);
|
|
|
80 |
(vccstate) ? oled_cmd(0x14) : oled_cmd(0x10);
|
|
|
81 |
oled_cmd(OLED_MEMORYMODE);
|
|
|
82 |
oled_cmd(0x00);
|
|
|
83 |
oled_cmd(OLED_SEGREMAP | 0x01);
|
|
|
84 |
oled_cmd(OLED_COMSCANDEC);
|
|
|
85 |
oled_cmd(OLED_SETCOMPINS);
|
|
|
86 |
oled_cmd(0x12);
|
|
|
87 |
oled_cmd(OLED_SETCONTRAST);
|
|
|
88 |
(vccstate) ? oled_cmd(0xCF) : oled_cmd(0x9F);
|
|
|
89 |
oled_cmd(OLED_SETPRECHARGE);
|
|
|
90 |
(vccstate) ? oled_cmd(0xF1) : oled_cmd(0x22);
|
|
|
91 |
oled_cmd(OLED_SETVCOMDETECT);
|
|
|
92 |
oled_cmd(0x40);
|
|
|
93 |
oled_cmd(OLED_DISPLAYALLON_RESUME);
|
|
|
94 |
oled_cmd(OLED_NORMALDISPLAY);
|
|
|
95 |
oled_cmd(OLED_DISPLAYON);
|
|
|
96 |
|
|
|
97 |
return oled.buffer;
|
|
|
98 |
}
|
|
|
99 |
|
|
|
100 |
inline void oled_cmd(uint8_t cmd) {
|
|
|
101 |
const uint8_t CONTROL = 0x00;
|
|
|
102 |
oled_write(CONTROL, cmd);
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
inline void oled_data(uint8_t data) {
|
|
|
106 |
const uint8_t CONTROL = 0x04;
|
|
|
107 |
oled_write(CONTROL, data);
|
|
|
108 |
}
|
|
|
109 |
|
|
|
110 |
void oled_write(uint8_t control, uint8_t data) {
|
|
|
111 |
i2c_beginTransmission(oled.i2c_addr);
|
|
|
112 |
i2c_writeByte(control);
|
|
|
113 |
i2c_writeByte(data);
|
|
|
114 |
i2c_endTransmission(1);
|
|
|
115 |
}
|
|
|
116 |
|
|
|
117 |
void oled_clear(void) {
|
|
|
118 |
memset(oled.buffer, 0, (oled.width*oled.height/8));
|
|
|
119 |
}
|
|
|
120 |
|
|
|
121 |
void oled_power(uint8_t pwr) {
|
|
|
122 |
if (pwr)
|
|
|
123 |
oled_cmd(OLED_DISPLAYON);
|
|
|
124 |
else
|
|
|
125 |
oled_cmd(OLED_DISPLAYOFF);
|
|
|
126 |
}
|
|
|
127 |
|
|
|
128 |
void oled_display(void) {
|
|
|
129 |
oled_cmd(OLED_SETLOWCOLUMN | 0x0);
|
|
|
130 |
oled_cmd(OLED_SETHIGHCOLUMN | 0x0);
|
|
|
131 |
oled_cmd(OLED_SETSTARTLINE | 0x0);
|
|
|
132 |
|
|
|
133 |
uint16_t i;
|
|
|
134 |
for (i=0; i<(oled.width * oled.height / 8); i++) {
|
|
|
135 |
|
|
|
136 |
// @todo: Get twi to send 17 bytes
|
|
|
137 |
// Need to fix this up
|
|
|
138 |
// my twi lib can only send 4 bytes at a time...
|
|
|
139 |
// though can change to 15 if needed
|
|
|
140 |
// still not enough to send full block
|
|
|
141 |
uint8_t x;
|
|
|
142 |
for (x=0; x<16; x++) {
|
|
|
143 |
i2c_beginTransmission(oled.i2c_addr);
|
|
|
144 |
i2c_writeByte(0x40);
|
|
|
145 |
i2c_writeByte(oled.buffer[i]);
|
|
|
146 |
i2c_endTransmission(1);
|
|
|
147 |
i++;
|
|
|
148 |
}
|
|
|
149 |
i--;
|
|
|
150 |
}
|
|
|
151 |
}
|
|
|
152 |
|
|
|
153 |
|