forked from Seeed-Studio/Small_ePaper_Shield
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEPD.h
176 lines (146 loc) · 5.35 KB
/
EPD.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Copyright 2013 Pervasive Displays, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language
// governing permissions and limitations under the License.
#if !defined(EPD_H)
#define EPD_H 1
#include <Arduino.h>
#include <SPI.h>
#if defined(__MSP430_CPU__)
#define PROGMEM
#else
#include <avr/pgmspace.h>
#endif
// if more SRAM available (8 kBytes)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define EPD_ENABLE_EXTRA_SRAM 1
#endif
typedef enum {
EPD_1_44, // 128 x 96
EPD_2_0, // 200 x 96
EPD_2_7 // 264 x 176
} EPD_size;
typedef enum { // Image pixel -> Display pixel
EPD_compensate, // B -> W, W -> B (Current Image)
EPD_white, // B -> N, W -> W (Current Image)
EPD_inverse, // B -> N, W -> B (New Image)
EPD_normal // B -> B, W -> W (New Image)
} EPD_stage;
typedef void EPD_reader(void *buffer, uint32_t address, uint16_t length);
class EPD_Class
{
private:
int EPD_Pin_EPD_CS;
int EPD_Pin_PANEL_ON;
int EPD_Pin_BORDER;
int EPD_Pin_DISCHARGE;
int EPD_Pin_PWM;
int EPD_Pin_RESET;
int EPD_Pin_BUSY;
EPD_size size;
uint16_t stage_time;
uint16_t factored_stage_time;
uint16_t lines_per_display;
uint16_t dots_per_line;
uint16_t bytes_per_line;
uint16_t bytes_per_scan;
PROGMEM const uint8_t *gate_source;
uint16_t gate_source_length;
PROGMEM const uint8_t *channel_select;
uint16_t channel_select_length;
bool filler;
public:
unsigned char lineDta[33];
public:
// power up and power down the EPD panel
void begin(EPD_size sz);
void start();
void end();
void setFactor(int temperature = 25) {
this->factored_stage_time = this->stage_time * this->temperature_to_factor_10x(temperature) / 10;
}
// clear display (anything -> white)
void clear()
{
this->frame_fixed_repeat(0xff, EPD_compensate);
this->frame_fixed_repeat(0xff, EPD_white);
this->frame_fixed_repeat(0xaa, EPD_inverse);
this->frame_fixed_repeat(0xaa, EPD_normal);
}
// assuming a clear (white) screen output an image (PROGMEM data)
void image(PROGMEM const uint8_t *image)
{
this->frame_fixed_repeat(0xaa, EPD_compensate);
this->frame_fixed_repeat(0xaa, EPD_white);
this->frame_data_repeat(image, EPD_inverse);
this->frame_data_repeat(image, EPD_normal);
}
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328P__)
void image_sd()
{
this->frame_fixed_repeat(0xaa, EPD_compensate);
this->frame_fixed_repeat(0xaa, EPD_white);
this->frame_data_repeat_sd(EPD_inverse);
this->frame_data_repeat_sd(EPD_normal);
}
#endif
// change from old image to new image (PROGMEM data)
void image(PROGMEM const uint8_t *old_image, PROGMEM const uint8_t *new_image)
{
this->frame_data_repeat(old_image, EPD_compensate);
this->frame_data_repeat(old_image, EPD_white);
this->frame_data_repeat(new_image, EPD_inverse);
this->frame_data_repeat(new_image, EPD_normal);
}
#if defined(EPD_ENABLE_EXTRA_SRAM)
// change from old image to new image (SRAM version)
void image_sram(unsigned char *new_image)
{
this->frame_fixed_repeat(0xaa, EPD_compensate);
this->frame_fixed_repeat(0xaa, EPD_white);
this->frame_sram_repeat(new_image, EPD_inverse);
this->frame_sram_repeat(new_image, EPD_normal);
}
#endif
// Low level API calls
// ===================
// single frame refresh
void frame_fixed(uint8_t fixed_value, EPD_stage stage);
void frame_data(PROGMEM const uint8_t *new_image, EPD_stage stage);
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328P__)
void frame_data_sd(EPD_stage stage);
#endif
#if defined(EPD_ENABLE_EXTRA_SRAM)
void frame_sram(const uint8_t *new_image, EPD_stage stage);
#endif
void frame_cb(uint32_t address, EPD_reader *reader, EPD_stage stage);
// stage_time frame refresh
void frame_fixed_repeat(uint8_t fixed_value, EPD_stage stage);
void frame_data_repeat(PROGMEM const uint8_t *new_image, EPD_stage stage);
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328P__)
void frame_data_repeat_sd(EPD_stage stage);
#endif
#if defined(EPD_ENABLE_EXTRA_SRAM)
void frame_sram_repeat(const uint8_t *new_image, EPD_stage stage);
#endif
void frame_cb_repeat(uint32_t address, EPD_reader *reader, EPD_stage stage);
// convert temperature to compensation factor
int temperature_to_factor_10x(int temperature);
// single line display - very low-level
// also has to handle AVR progmem
void line(uint16_t line, const uint8_t *data, uint8_t fixed_value, bool read_progmem, EPD_stage stage);
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328P__)
void line_sd(uint16_t line, const uint8_t *data, uint8_t fixed_value, bool read_progmem, EPD_stage stage);
#endif
};
extern EPD_Class EPD;
#endif