-
Notifications
You must be signed in to change notification settings - Fork 0
/
EInk.h
147 lines (122 loc) · 3.21 KB
/
EInk.h
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef _EINK_H_
#define _EINK_H_
#include <cassert>
#include "mbed.h"
#include "GraphicsApi.h"
class EInk152 {
public:
EInk152(SPI& spi, DigitalOut& cs, DigitalOut &dc, DigitalOut& reset, DigitalIn& busy) :
spi_(spi), cs_(cs), dc_(dc), reset_(reset), busy_(busy) {
reset_ = 0;
cs_ = 1;
}
const uint32_t kBusyTimeoutUs = 100 * 1000;
void init() {
cs_ = 0;
dc_ = 0;
reset_ = 0;
wait_us(5 * 1000);
reset_ = 1;
cs_ = 1;
command(0x00, (const uint8_t[]){0x0e}, 1); // soft reset
// eink_command(0x06, (const uint8_t[]){0x17, 0x17, 0x17}, 3); // booster soft start
// eink_command(0x63, (const uint8_t[]){0x80, 0x01, 0x28}, 3); // resolution
// eink_command(0x50, (const uint8_t[]){0x87}, 1); // Vcom / data interval
command(0xe0, (const uint8_t[]){0x02}, 1); // active temperature
command(0xe5, (const uint8_t[]){0x19}, 1); // input temperature: 25c
}
void draw(uint8_t blackFrame[], uint8_t redFrame[]) {
Timer busyTimeout;
if (blackFrame == NULL) {
commandConstPayload(0x10, 0x00, 2888);
} else {
command(0x10, blackFrame, 2888);
}
if (redFrame == NULL) {
commandConstPayload(0x13, 0x00, 2888);
} else {
command(0x13, redFrame, 2888);
}
// TODO check busy = 0
command(0x04, NULL, 0); // power on
busyTimeout.start();
while ((busy_ == 0) && ((unsigned int)busyTimeout.read_us() < kBusyTimeoutUs));
// wait_us(kBusyTimeoutUs);
command(0x12, NULL, 0); // refresh
// while (busy_ == 0);
}
protected:
void command(uint8_t index, const uint8_t payload[], size_t len) {
spi_.format(8, 0);
spi_.frequency(10 * 1000 * 1000);
dc_ = 0;
cs_ = 0;
wait_us(1);
spi_.write(index);
wait_us(1);
dc_ = 1;
cs_ = 1;
for (size_t i=0; i<len; i++) {
wait_us(1);
cs_ = 0;
wait_us(1);
spi_.write(payload[i]);
wait_us(1);
cs_ = 1;
}
}
void commandConstPayload(uint8_t index, uint8_t payloadRepeat, size_t len) {
spi_.format(8, 0);
spi_.frequency(10 * 1000 * 1000);
dc_ = 0;
cs_ = 0;
wait_us(1);
spi_.write(index);
wait_us(1);
dc_ = 1;
cs_ = 1;
for (size_t i=0; i<len; i++) {
wait_us(1);
cs_ = 0;
wait_us(1);
spi_.write(payloadRepeat);
wait_us(1);
cs_ = 1;
}
}
SPI& spi_;
DigitalOut& cs_;
DigitalOut& dc_;
DigitalOut& reset_;
DigitalIn& busy_;
};
class EInk152Graphics : public EInk152, public PixelGraphics {
public:
EInk152Graphics(SPI& spi, DigitalOut& cs, DigitalOut &dc, DigitalOut& reset, DigitalIn& busy) :
EInk152(spi, cs, dc, reset, busy) {
}
void update() {
draw(NULL, frameBuffer_);
}
uint16_t getWidth() {
return 152;
}
uint16_t getHeight() {
return 152;
}
void drawPixel(uint16_t x, uint16_t y, uint8_t contrast) {
if ((x >= 152) || (y >= 152)) { // out of bounds
return;
}
uint8_t* bufferByte = frameBuffer_ + (y * (152/8) + (x / 8));
uint8_t bufferBitMask = 1 << (7 - (x%8));
if (contrast < 127) {
*bufferByte = *bufferByte & ~bufferBitMask;
} else {
*bufferByte = *bufferByte | bufferBitMask;
}
}
protected:
uint8_t frameBuffer_[2888] = {0};
};
#endif