EaPaper Library for EM027BS013
Dependencies: EM027BS013 TFT_fonts
Fork of EaEpaper by
EPD.cpp@3:1371614703cd, 2014-06-25 (annotated)
- Committer:
- dreschpe
- Date:
- Wed Jun 25 17:43:32 2014 +0000
- Revision:
- 3:1371614703cd
- Parent:
- 0:fedcef5319f5
remove the use of the BurstSPI driver to make the lib compatible with all platforms. There is no time difference, because the display itself need so much time.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dreschpe | 0:fedcef5319f5 | 1 | // Copyright 2013 Pervasive Displays, Inc. |
dreschpe | 0:fedcef5319f5 | 2 | // |
dreschpe | 0:fedcef5319f5 | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
dreschpe | 0:fedcef5319f5 | 4 | // you may not use this file except in compliance with the License. |
dreschpe | 0:fedcef5319f5 | 5 | // You may obtain a copy of the License at: |
dreschpe | 0:fedcef5319f5 | 6 | // |
dreschpe | 0:fedcef5319f5 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
dreschpe | 0:fedcef5319f5 | 8 | // |
dreschpe | 0:fedcef5319f5 | 9 | // Unless required by applicable law or agreed to in writing, |
dreschpe | 0:fedcef5319f5 | 10 | // software distributed under the License is distributed on an |
dreschpe | 0:fedcef5319f5 | 11 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
dreschpe | 0:fedcef5319f5 | 12 | // express or implied. See the License for the specific language |
dreschpe | 0:fedcef5319f5 | 13 | // governing permissions and limitations under the License. |
dreschpe | 0:fedcef5319f5 | 14 | |
dreschpe | 0:fedcef5319f5 | 15 | |
dreschpe | 0:fedcef5319f5 | 16 | |
dreschpe | 0:fedcef5319f5 | 17 | #include <limits.h> |
dreschpe | 0:fedcef5319f5 | 18 | |
dreschpe | 0:fedcef5319f5 | 19 | #include "EPD.h" |
dreschpe | 0:fedcef5319f5 | 20 | #include "mbed.h" |
dreschpe | 0:fedcef5319f5 | 21 | |
dreschpe | 0:fedcef5319f5 | 22 | // delays - more consistent naming |
dreschpe | 0:fedcef5319f5 | 23 | #define Delay_ms(ms) wait_ms(ms) |
dreschpe | 0:fedcef5319f5 | 24 | #define Delay_us(us) wait_us(us) |
dreschpe | 0:fedcef5319f5 | 25 | |
dreschpe | 0:fedcef5319f5 | 26 | // inline arrays |
dreschpe | 0:fedcef5319f5 | 27 | #define ARRAY(type, ...) ((type[]){__VA_ARGS__}) |
dreschpe | 0:fedcef5319f5 | 28 | #define CU8(...) (ARRAY(const uint8_t, __VA_ARGS__)) |
dreschpe | 0:fedcef5319f5 | 29 | |
dreschpe | 0:fedcef5319f5 | 30 | #define LOW (0) |
dreschpe | 0:fedcef5319f5 | 31 | #define HIGH (1) |
dreschpe | 0:fedcef5319f5 | 32 | #define digitalWrite(pin, state) (pin) = (state) |
dreschpe | 0:fedcef5319f5 | 33 | #define digitalRead(pin) (pin) |
dreschpe | 0:fedcef5319f5 | 34 | |
dreschpe | 0:fedcef5319f5 | 35 | Timer _time; |
dreschpe | 0:fedcef5319f5 | 36 | #define millis() _time.read_ms() |
dreschpe | 0:fedcef5319f5 | 37 | #define millis_start() _time.start() |
dreschpe | 0:fedcef5319f5 | 38 | |
dreschpe | 0:fedcef5319f5 | 39 | |
dreschpe | 0:fedcef5319f5 | 40 | //static void PWM_start(int pin); |
dreschpe | 0:fedcef5319f5 | 41 | //static void PWM_stop(int pin); |
dreschpe | 0:fedcef5319f5 | 42 | |
dreschpe | 0:fedcef5319f5 | 43 | //static void SPI_put(uint8_t c); |
dreschpe | 0:fedcef5319f5 | 44 | //static void SPI_put_wait(uint8_t c, int busy_pin); |
dreschpe | 0:fedcef5319f5 | 45 | //static void SPI_send(uint8_t cs_pin, const uint8_t *buffer, uint16_t length); |
dreschpe | 0:fedcef5319f5 | 46 | |
dreschpe | 0:fedcef5319f5 | 47 | |
dreschpe | 0:fedcef5319f5 | 48 | EPD_Class::EPD_Class(EPD_size size, |
dreschpe | 0:fedcef5319f5 | 49 | PinName panel_on_pin, |
dreschpe | 0:fedcef5319f5 | 50 | PinName border_pin, |
dreschpe | 0:fedcef5319f5 | 51 | PinName discharge_pin, |
dreschpe | 0:fedcef5319f5 | 52 | PinName pwm_pin, |
dreschpe | 0:fedcef5319f5 | 53 | PinName reset_pin, |
dreschpe | 0:fedcef5319f5 | 54 | PinName busy_pin, |
dreschpe | 0:fedcef5319f5 | 55 | PinName chip_select_pin, |
dreschpe | 0:fedcef5319f5 | 56 | PinName mosi, |
dreschpe | 0:fedcef5319f5 | 57 | PinName miso, |
dreschpe | 0:fedcef5319f5 | 58 | PinName sck) : |
dreschpe | 0:fedcef5319f5 | 59 | EPD_Pin_PANEL_ON(panel_on_pin), |
dreschpe | 0:fedcef5319f5 | 60 | EPD_Pin_BORDER(border_pin), |
dreschpe | 0:fedcef5319f5 | 61 | EPD_Pin_DISCHARGE(discharge_pin), |
dreschpe | 0:fedcef5319f5 | 62 | EPD_Pin_PWM(pwm_pin), |
dreschpe | 0:fedcef5319f5 | 63 | EPD_Pin_RESET(reset_pin), |
dreschpe | 0:fedcef5319f5 | 64 | EPD_Pin_BUSY(busy_pin), |
dreschpe | 0:fedcef5319f5 | 65 | EPD_Pin_EPD_CS(chip_select_pin), |
dreschpe | 0:fedcef5319f5 | 66 | spi_(mosi,miso,sck) { |
dreschpe | 0:fedcef5319f5 | 67 | |
dreschpe | 0:fedcef5319f5 | 68 | this->size = size; |
dreschpe | 0:fedcef5319f5 | 69 | this->stage_time = 480; // milliseconds |
dreschpe | 0:fedcef5319f5 | 70 | this->lines_per_display = 96; |
dreschpe | 0:fedcef5319f5 | 71 | this->dots_per_line = 128; |
dreschpe | 0:fedcef5319f5 | 72 | this->bytes_per_line = 128 / 8; |
dreschpe | 0:fedcef5319f5 | 73 | this->bytes_per_scan = 96 / 4; |
dreschpe | 0:fedcef5319f5 | 74 | this->filler = false; |
dreschpe | 0:fedcef5319f5 | 75 | spi_.frequency(12000000); // 12 MHz SPI clock |
dreschpe | 0:fedcef5319f5 | 76 | |
dreschpe | 0:fedcef5319f5 | 77 | // display size dependant items |
dreschpe | 0:fedcef5319f5 | 78 | { |
dreschpe | 0:fedcef5319f5 | 79 | static uint8_t cs[] = {0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00}; |
dreschpe | 0:fedcef5319f5 | 80 | static uint8_t gs[] = {0x72, 0x03}; |
dreschpe | 0:fedcef5319f5 | 81 | this->channel_select = cs; |
dreschpe | 0:fedcef5319f5 | 82 | this->channel_select_length = sizeof(cs); |
dreschpe | 0:fedcef5319f5 | 83 | this->gate_source = gs; |
dreschpe | 0:fedcef5319f5 | 84 | this->gate_source_length = sizeof(gs); |
dreschpe | 0:fedcef5319f5 | 85 | } |
dreschpe | 0:fedcef5319f5 | 86 | |
dreschpe | 0:fedcef5319f5 | 87 | // set up size structure |
dreschpe | 0:fedcef5319f5 | 88 | switch (size) { |
dreschpe | 0:fedcef5319f5 | 89 | default: |
dreschpe | 0:fedcef5319f5 | 90 | case EPD_1_44: // default so no change |
dreschpe | 0:fedcef5319f5 | 91 | break; |
dreschpe | 0:fedcef5319f5 | 92 | |
dreschpe | 0:fedcef5319f5 | 93 | case EPD_2_0: { |
dreschpe | 0:fedcef5319f5 | 94 | this->lines_per_display = 96; |
dreschpe | 0:fedcef5319f5 | 95 | this->dots_per_line = 200; |
dreschpe | 0:fedcef5319f5 | 96 | this->bytes_per_line = 200 / 8; |
dreschpe | 0:fedcef5319f5 | 97 | this->bytes_per_scan = 96 / 4; |
dreschpe | 0:fedcef5319f5 | 98 | this->filler = true; |
dreschpe | 0:fedcef5319f5 | 99 | static uint8_t cs[] = {0x72, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00}; |
dreschpe | 0:fedcef5319f5 | 100 | static uint8_t gs[] = {0x72, 0x03}; |
dreschpe | 0:fedcef5319f5 | 101 | this->channel_select = cs; |
dreschpe | 0:fedcef5319f5 | 102 | this->channel_select_length = sizeof(cs); |
dreschpe | 0:fedcef5319f5 | 103 | this->gate_source = gs; |
dreschpe | 0:fedcef5319f5 | 104 | this->gate_source_length = sizeof(gs); |
dreschpe | 0:fedcef5319f5 | 105 | break; |
dreschpe | 0:fedcef5319f5 | 106 | } |
dreschpe | 0:fedcef5319f5 | 107 | |
dreschpe | 0:fedcef5319f5 | 108 | case EPD_2_7: { |
dreschpe | 0:fedcef5319f5 | 109 | this->stage_time = 630; // milliseconds |
dreschpe | 0:fedcef5319f5 | 110 | this->lines_per_display = 176; |
dreschpe | 0:fedcef5319f5 | 111 | this->dots_per_line = 264; |
dreschpe | 0:fedcef5319f5 | 112 | this->bytes_per_line = 264 / 8; |
dreschpe | 0:fedcef5319f5 | 113 | this->bytes_per_scan = 176 / 4; |
dreschpe | 0:fedcef5319f5 | 114 | this->filler = true; |
dreschpe | 0:fedcef5319f5 | 115 | static uint8_t cs[] = {0x72, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00}; |
dreschpe | 0:fedcef5319f5 | 116 | static uint8_t gs[] = {0x72, 0x00}; |
dreschpe | 0:fedcef5319f5 | 117 | this->channel_select = cs; |
dreschpe | 0:fedcef5319f5 | 118 | this->channel_select_length = sizeof(cs); |
dreschpe | 0:fedcef5319f5 | 119 | this->gate_source = gs; |
dreschpe | 0:fedcef5319f5 | 120 | this->gate_source_length = sizeof(gs); |
dreschpe | 0:fedcef5319f5 | 121 | break; |
dreschpe | 0:fedcef5319f5 | 122 | } |
dreschpe | 0:fedcef5319f5 | 123 | } |
dreschpe | 0:fedcef5319f5 | 124 | |
dreschpe | 0:fedcef5319f5 | 125 | this->factored_stage_time = this->stage_time; |
dreschpe | 0:fedcef5319f5 | 126 | } |
dreschpe | 0:fedcef5319f5 | 127 | |
dreschpe | 0:fedcef5319f5 | 128 | |
dreschpe | 0:fedcef5319f5 | 129 | void EPD_Class::begin() { |
dreschpe | 0:fedcef5319f5 | 130 | |
dreschpe | 0:fedcef5319f5 | 131 | // power up sequence |
dreschpe | 0:fedcef5319f5 | 132 | SPI_put(0x00); |
dreschpe | 0:fedcef5319f5 | 133 | |
dreschpe | 0:fedcef5319f5 | 134 | digitalWrite(this->EPD_Pin_RESET, LOW); |
dreschpe | 0:fedcef5319f5 | 135 | digitalWrite(this->EPD_Pin_PANEL_ON, LOW); |
dreschpe | 0:fedcef5319f5 | 136 | digitalWrite(this->EPD_Pin_DISCHARGE, LOW); |
dreschpe | 0:fedcef5319f5 | 137 | digitalWrite(this->EPD_Pin_BORDER, LOW); |
dreschpe | 0:fedcef5319f5 | 138 | digitalWrite(this->EPD_Pin_EPD_CS, LOW); |
dreschpe | 0:fedcef5319f5 | 139 | |
dreschpe | 0:fedcef5319f5 | 140 | //PWM_start(this->EPD_Pin_PWM); |
dreschpe | 0:fedcef5319f5 | 141 | EPD_Pin_PWM = 0.5; |
dreschpe | 0:fedcef5319f5 | 142 | Delay_ms(5); |
dreschpe | 0:fedcef5319f5 | 143 | digitalWrite(this->EPD_Pin_PANEL_ON, HIGH); |
dreschpe | 0:fedcef5319f5 | 144 | Delay_ms(10); |
dreschpe | 0:fedcef5319f5 | 145 | |
dreschpe | 0:fedcef5319f5 | 146 | digitalWrite(this->EPD_Pin_RESET, HIGH); |
dreschpe | 0:fedcef5319f5 | 147 | digitalWrite(this->EPD_Pin_BORDER, HIGH); |
dreschpe | 0:fedcef5319f5 | 148 | digitalWrite(this->EPD_Pin_EPD_CS, HIGH); |
dreschpe | 0:fedcef5319f5 | 149 | Delay_ms(5); |
dreschpe | 0:fedcef5319f5 | 150 | |
dreschpe | 0:fedcef5319f5 | 151 | digitalWrite(this->EPD_Pin_RESET, LOW); |
dreschpe | 0:fedcef5319f5 | 152 | Delay_ms(5); |
dreschpe | 0:fedcef5319f5 | 153 | |
dreschpe | 0:fedcef5319f5 | 154 | digitalWrite(this->EPD_Pin_RESET, HIGH); |
dreschpe | 0:fedcef5319f5 | 155 | Delay_ms(5); |
dreschpe | 0:fedcef5319f5 | 156 | |
dreschpe | 0:fedcef5319f5 | 157 | // wait for COG to become ready |
dreschpe | 0:fedcef5319f5 | 158 | while (HIGH == digitalRead(this->EPD_Pin_BUSY)) { |
dreschpe | 0:fedcef5319f5 | 159 | } |
dreschpe | 0:fedcef5319f5 | 160 | |
dreschpe | 0:fedcef5319f5 | 161 | // channel select |
dreschpe | 0:fedcef5319f5 | 162 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 163 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x01), 2); |
dreschpe | 0:fedcef5319f5 | 164 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 165 | SPI_send(this->EPD_Pin_EPD_CS, this->channel_select, this->channel_select_length); |
dreschpe | 0:fedcef5319f5 | 166 | |
dreschpe | 0:fedcef5319f5 | 167 | // DC/DC frequency |
dreschpe | 0:fedcef5319f5 | 168 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 169 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x06), 2); |
dreschpe | 0:fedcef5319f5 | 170 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 171 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0xff), 2); |
dreschpe | 0:fedcef5319f5 | 172 | |
dreschpe | 0:fedcef5319f5 | 173 | // high power mode osc |
dreschpe | 0:fedcef5319f5 | 174 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 175 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x07), 2); |
dreschpe | 0:fedcef5319f5 | 176 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 177 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x9d), 2); |
dreschpe | 0:fedcef5319f5 | 178 | |
dreschpe | 0:fedcef5319f5 | 179 | |
dreschpe | 0:fedcef5319f5 | 180 | // disable ADC |
dreschpe | 0:fedcef5319f5 | 181 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 182 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x08), 2); |
dreschpe | 0:fedcef5319f5 | 183 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 184 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
dreschpe | 0:fedcef5319f5 | 185 | |
dreschpe | 0:fedcef5319f5 | 186 | // Vcom level |
dreschpe | 0:fedcef5319f5 | 187 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 188 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x09), 2); |
dreschpe | 0:fedcef5319f5 | 189 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 190 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0xd0, 0x00), 3); |
dreschpe | 0:fedcef5319f5 | 191 | |
dreschpe | 0:fedcef5319f5 | 192 | // gate and source voltage levels |
dreschpe | 0:fedcef5319f5 | 193 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 194 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
dreschpe | 0:fedcef5319f5 | 195 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 196 | SPI_send(this->EPD_Pin_EPD_CS, this->gate_source, this->gate_source_length); |
dreschpe | 0:fedcef5319f5 | 197 | |
dreschpe | 0:fedcef5319f5 | 198 | Delay_ms(5); //??? |
dreschpe | 0:fedcef5319f5 | 199 | |
dreschpe | 0:fedcef5319f5 | 200 | // driver latch on |
dreschpe | 0:fedcef5319f5 | 201 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 202 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x03), 2); |
dreschpe | 0:fedcef5319f5 | 203 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 204 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x01), 2); |
dreschpe | 0:fedcef5319f5 | 205 | |
dreschpe | 0:fedcef5319f5 | 206 | // driver latch off |
dreschpe | 0:fedcef5319f5 | 207 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 208 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x03), 2); |
dreschpe | 0:fedcef5319f5 | 209 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 210 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
dreschpe | 0:fedcef5319f5 | 211 | |
dreschpe | 0:fedcef5319f5 | 212 | Delay_ms(5); |
dreschpe | 0:fedcef5319f5 | 213 | |
dreschpe | 0:fedcef5319f5 | 214 | // charge pump positive voltage on |
dreschpe | 0:fedcef5319f5 | 215 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 216 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
dreschpe | 0:fedcef5319f5 | 217 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 218 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x01), 2); |
dreschpe | 0:fedcef5319f5 | 219 | |
dreschpe | 0:fedcef5319f5 | 220 | // final delay before PWM off |
dreschpe | 0:fedcef5319f5 | 221 | Delay_ms(30); |
dreschpe | 0:fedcef5319f5 | 222 | //PWM_stop(this->EPD_Pin_PWM); |
dreschpe | 0:fedcef5319f5 | 223 | EPD_Pin_PWM = 0.0; |
dreschpe | 0:fedcef5319f5 | 224 | |
dreschpe | 0:fedcef5319f5 | 225 | // charge pump negative voltage on |
dreschpe | 0:fedcef5319f5 | 226 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 227 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
dreschpe | 0:fedcef5319f5 | 228 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 229 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x03), 2); |
dreschpe | 0:fedcef5319f5 | 230 | |
dreschpe | 0:fedcef5319f5 | 231 | Delay_ms(30); |
dreschpe | 0:fedcef5319f5 | 232 | |
dreschpe | 0:fedcef5319f5 | 233 | // Vcom driver on |
dreschpe | 0:fedcef5319f5 | 234 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 235 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
dreschpe | 0:fedcef5319f5 | 236 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 237 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0f), 2); |
dreschpe | 0:fedcef5319f5 | 238 | |
dreschpe | 0:fedcef5319f5 | 239 | Delay_ms(30); |
dreschpe | 0:fedcef5319f5 | 240 | |
dreschpe | 0:fedcef5319f5 | 241 | // output enable to disable |
dreschpe | 0:fedcef5319f5 | 242 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 243 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x02), 2); |
dreschpe | 0:fedcef5319f5 | 244 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 245 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x24), 2); |
dreschpe | 0:fedcef5319f5 | 246 | } |
dreschpe | 0:fedcef5319f5 | 247 | |
dreschpe | 0:fedcef5319f5 | 248 | |
dreschpe | 0:fedcef5319f5 | 249 | void EPD_Class::end() { |
dreschpe | 0:fedcef5319f5 | 250 | |
dreschpe | 0:fedcef5319f5 | 251 | this->frame_fixed(0x55, EPD_normal); // dummy frame |
dreschpe | 0:fedcef5319f5 | 252 | this->line(0x7fffu, 0, 0x55, false, EPD_normal); // dummy_line |
dreschpe | 0:fedcef5319f5 | 253 | |
dreschpe | 0:fedcef5319f5 | 254 | Delay_ms(25); |
dreschpe | 0:fedcef5319f5 | 255 | |
dreschpe | 0:fedcef5319f5 | 256 | digitalWrite(this->EPD_Pin_BORDER, LOW); |
dreschpe | 0:fedcef5319f5 | 257 | Delay_ms(30); |
dreschpe | 0:fedcef5319f5 | 258 | |
dreschpe | 0:fedcef5319f5 | 259 | digitalWrite(this->EPD_Pin_BORDER, HIGH); |
dreschpe | 0:fedcef5319f5 | 260 | |
dreschpe | 0:fedcef5319f5 | 261 | // latch reset turn on |
dreschpe | 0:fedcef5319f5 | 262 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 263 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x03), 2); |
dreschpe | 0:fedcef5319f5 | 264 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 265 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x01), 2); |
dreschpe | 0:fedcef5319f5 | 266 | |
dreschpe | 0:fedcef5319f5 | 267 | // output enable off |
dreschpe | 0:fedcef5319f5 | 268 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 269 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x02), 2); |
dreschpe | 0:fedcef5319f5 | 270 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 271 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x05), 2); |
dreschpe | 0:fedcef5319f5 | 272 | |
dreschpe | 0:fedcef5319f5 | 273 | // Vcom power off |
dreschpe | 0:fedcef5319f5 | 274 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 275 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
dreschpe | 0:fedcef5319f5 | 276 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 277 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0e), 2); |
dreschpe | 0:fedcef5319f5 | 278 | |
dreschpe | 0:fedcef5319f5 | 279 | // power off negative charge pump |
dreschpe | 0:fedcef5319f5 | 280 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 281 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
dreschpe | 0:fedcef5319f5 | 282 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 283 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x02), 2); |
dreschpe | 0:fedcef5319f5 | 284 | |
dreschpe | 0:fedcef5319f5 | 285 | // discharge |
dreschpe | 0:fedcef5319f5 | 286 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 287 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
dreschpe | 0:fedcef5319f5 | 288 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 289 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0c), 2); |
dreschpe | 0:fedcef5319f5 | 290 | |
dreschpe | 0:fedcef5319f5 | 291 | Delay_ms(120); |
dreschpe | 0:fedcef5319f5 | 292 | |
dreschpe | 0:fedcef5319f5 | 293 | // all charge pumps off |
dreschpe | 0:fedcef5319f5 | 294 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 295 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
dreschpe | 0:fedcef5319f5 | 296 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 297 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
dreschpe | 0:fedcef5319f5 | 298 | |
dreschpe | 0:fedcef5319f5 | 299 | // turn of osc |
dreschpe | 0:fedcef5319f5 | 300 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 301 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x07), 2); |
dreschpe | 0:fedcef5319f5 | 302 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 303 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0d), 2); |
dreschpe | 0:fedcef5319f5 | 304 | |
dreschpe | 0:fedcef5319f5 | 305 | // discharge internal - 1 |
dreschpe | 0:fedcef5319f5 | 306 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 307 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
dreschpe | 0:fedcef5319f5 | 308 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 309 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x50), 2); |
dreschpe | 0:fedcef5319f5 | 310 | |
dreschpe | 0:fedcef5319f5 | 311 | Delay_ms(40); |
dreschpe | 0:fedcef5319f5 | 312 | |
dreschpe | 0:fedcef5319f5 | 313 | // discharge internal - 2 |
dreschpe | 0:fedcef5319f5 | 314 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 315 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
dreschpe | 0:fedcef5319f5 | 316 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 317 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0xA0), 2); |
dreschpe | 0:fedcef5319f5 | 318 | |
dreschpe | 0:fedcef5319f5 | 319 | Delay_ms(40); |
dreschpe | 0:fedcef5319f5 | 320 | |
dreschpe | 0:fedcef5319f5 | 321 | // discharge internal - 3 |
dreschpe | 0:fedcef5319f5 | 322 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 323 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
dreschpe | 0:fedcef5319f5 | 324 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 325 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
dreschpe | 0:fedcef5319f5 | 326 | |
dreschpe | 0:fedcef5319f5 | 327 | // turn of power and all signals |
dreschpe | 0:fedcef5319f5 | 328 | digitalWrite(this->EPD_Pin_RESET, LOW); |
dreschpe | 0:fedcef5319f5 | 329 | digitalWrite(this->EPD_Pin_PANEL_ON, LOW); |
dreschpe | 0:fedcef5319f5 | 330 | digitalWrite(this->EPD_Pin_BORDER, LOW); |
dreschpe | 0:fedcef5319f5 | 331 | digitalWrite(this->EPD_Pin_EPD_CS, LOW); |
dreschpe | 0:fedcef5319f5 | 332 | |
dreschpe | 0:fedcef5319f5 | 333 | digitalWrite(this->EPD_Pin_DISCHARGE, HIGH); |
dreschpe | 0:fedcef5319f5 | 334 | |
dreschpe | 0:fedcef5319f5 | 335 | SPI_put(0x00); |
dreschpe | 0:fedcef5319f5 | 336 | |
dreschpe | 0:fedcef5319f5 | 337 | Delay_ms(150); |
dreschpe | 0:fedcef5319f5 | 338 | |
dreschpe | 0:fedcef5319f5 | 339 | digitalWrite(this->EPD_Pin_DISCHARGE, LOW); |
dreschpe | 0:fedcef5319f5 | 340 | } |
dreschpe | 0:fedcef5319f5 | 341 | |
dreschpe | 0:fedcef5319f5 | 342 | |
dreschpe | 0:fedcef5319f5 | 343 | // convert a temperature in Celcius to |
dreschpe | 0:fedcef5319f5 | 344 | // the scale factor for frame_*_repeat methods |
dreschpe | 0:fedcef5319f5 | 345 | int EPD_Class::temperature_to_factor_10x(int temperature) { |
dreschpe | 0:fedcef5319f5 | 346 | if (temperature <= -10) { |
dreschpe | 0:fedcef5319f5 | 347 | return 170; |
dreschpe | 0:fedcef5319f5 | 348 | } else if (temperature <= -5) { |
dreschpe | 0:fedcef5319f5 | 349 | return 120; |
dreschpe | 0:fedcef5319f5 | 350 | } else if (temperature <= 5) { |
dreschpe | 0:fedcef5319f5 | 351 | return 80; |
dreschpe | 0:fedcef5319f5 | 352 | } else if (temperature <= 10) { |
dreschpe | 0:fedcef5319f5 | 353 | return 40; |
dreschpe | 0:fedcef5319f5 | 354 | } else if (temperature <= 15) { |
dreschpe | 0:fedcef5319f5 | 355 | return 30; |
dreschpe | 0:fedcef5319f5 | 356 | } else if (temperature <= 20) { |
dreschpe | 0:fedcef5319f5 | 357 | return 20; |
dreschpe | 0:fedcef5319f5 | 358 | } else if (temperature <= 40) { |
dreschpe | 0:fedcef5319f5 | 359 | return 10; |
dreschpe | 0:fedcef5319f5 | 360 | } |
dreschpe | 0:fedcef5319f5 | 361 | return 7; |
dreschpe | 0:fedcef5319f5 | 362 | } |
dreschpe | 0:fedcef5319f5 | 363 | |
dreschpe | 0:fedcef5319f5 | 364 | |
dreschpe | 0:fedcef5319f5 | 365 | // One frame of data is the number of lines * rows. For example: |
dreschpe | 0:fedcef5319f5 | 366 | // The 1.44” frame of data is 96 lines * 128 dots. |
dreschpe | 0:fedcef5319f5 | 367 | // The 2” frame of data is 96 lines * 200 dots. |
dreschpe | 0:fedcef5319f5 | 368 | // The 2.7” frame of data is 176 lines * 264 dots. |
dreschpe | 0:fedcef5319f5 | 369 | |
dreschpe | 0:fedcef5319f5 | 370 | // the image is arranged by line which matches the display size |
dreschpe | 0:fedcef5319f5 | 371 | // so smallest would have 96 * 32 bytes |
dreschpe | 0:fedcef5319f5 | 372 | |
dreschpe | 0:fedcef5319f5 | 373 | void EPD_Class::frame_fixed(uint8_t fixed_value, EPD_stage stage) { |
dreschpe | 0:fedcef5319f5 | 374 | for (uint8_t line = 0; line < this->lines_per_display ; ++line) { |
dreschpe | 0:fedcef5319f5 | 375 | this->line(line, 0, fixed_value, false, stage); |
dreschpe | 0:fedcef5319f5 | 376 | } |
dreschpe | 0:fedcef5319f5 | 377 | } |
dreschpe | 0:fedcef5319f5 | 378 | |
dreschpe | 0:fedcef5319f5 | 379 | |
dreschpe | 0:fedcef5319f5 | 380 | void EPD_Class::frame_data(PROGMEM const uint8_t *image, EPD_stage stage){ |
dreschpe | 0:fedcef5319f5 | 381 | for (uint8_t line = 0; line < this->lines_per_display ; ++line) { |
dreschpe | 0:fedcef5319f5 | 382 | this->line(line, &image[line * this->bytes_per_line], 0, true, stage); |
dreschpe | 0:fedcef5319f5 | 383 | } |
dreschpe | 0:fedcef5319f5 | 384 | } |
dreschpe | 0:fedcef5319f5 | 385 | |
dreschpe | 0:fedcef5319f5 | 386 | |
dreschpe | 0:fedcef5319f5 | 387 | #if defined(EPD_ENABLE_EXTRA_SRAM) |
dreschpe | 0:fedcef5319f5 | 388 | void EPD_Class::frame_sram(const uint8_t *image, EPD_stage stage){ |
dreschpe | 0:fedcef5319f5 | 389 | for (uint8_t line = 0; line < this->lines_per_display ; ++line) { |
dreschpe | 0:fedcef5319f5 | 390 | this->line(line, &image[line * this->bytes_per_line], 0, false, stage); |
dreschpe | 0:fedcef5319f5 | 391 | } |
dreschpe | 0:fedcef5319f5 | 392 | } |
dreschpe | 0:fedcef5319f5 | 393 | #endif |
dreschpe | 0:fedcef5319f5 | 394 | |
dreschpe | 0:fedcef5319f5 | 395 | |
dreschpe | 0:fedcef5319f5 | 396 | void EPD_Class::frame_cb(uint32_t address, EPD_reader *reader, EPD_stage stage) { |
dreschpe | 0:fedcef5319f5 | 397 | static uint8_t buffer[264 / 8]; |
dreschpe | 0:fedcef5319f5 | 398 | for (uint8_t line = 0; line < this->lines_per_display; ++line) { |
dreschpe | 0:fedcef5319f5 | 399 | reader(buffer, address + line * this->bytes_per_line, this->bytes_per_line); |
dreschpe | 0:fedcef5319f5 | 400 | this->line(line, buffer, 0, false, stage); |
dreschpe | 0:fedcef5319f5 | 401 | } |
dreschpe | 0:fedcef5319f5 | 402 | } |
dreschpe | 0:fedcef5319f5 | 403 | |
dreschpe | 0:fedcef5319f5 | 404 | void EPD_Class::frame_fixed_repeat(uint8_t fixed_value, EPD_stage stage) { |
dreschpe | 0:fedcef5319f5 | 405 | long stage_time = this->factored_stage_time; |
dreschpe | 0:fedcef5319f5 | 406 | |
dreschpe | 0:fedcef5319f5 | 407 | do { |
dreschpe | 0:fedcef5319f5 | 408 | millis_start(); |
dreschpe | 0:fedcef5319f5 | 409 | unsigned long t_start = millis(); |
dreschpe | 0:fedcef5319f5 | 410 | this->frame_fixed(fixed_value, stage); |
dreschpe | 0:fedcef5319f5 | 411 | unsigned long t_end = millis(); |
dreschpe | 0:fedcef5319f5 | 412 | if (t_end > t_start) { |
dreschpe | 0:fedcef5319f5 | 413 | stage_time -= t_end - t_start; |
dreschpe | 0:fedcef5319f5 | 414 | } else { |
dreschpe | 0:fedcef5319f5 | 415 | stage_time -= t_start - t_end + 1 + ULONG_MAX; |
dreschpe | 0:fedcef5319f5 | 416 | } |
dreschpe | 0:fedcef5319f5 | 417 | } while (stage_time > 0); |
dreschpe | 0:fedcef5319f5 | 418 | } |
dreschpe | 0:fedcef5319f5 | 419 | |
dreschpe | 0:fedcef5319f5 | 420 | |
dreschpe | 0:fedcef5319f5 | 421 | void EPD_Class::frame_data_repeat(PROGMEM const uint8_t *image, EPD_stage stage) { |
dreschpe | 0:fedcef5319f5 | 422 | long stage_time = this->factored_stage_time; |
dreschpe | 0:fedcef5319f5 | 423 | do { |
dreschpe | 0:fedcef5319f5 | 424 | millis_start(); |
dreschpe | 0:fedcef5319f5 | 425 | unsigned long t_start = millis(); |
dreschpe | 0:fedcef5319f5 | 426 | this->frame_data(image, stage); |
dreschpe | 0:fedcef5319f5 | 427 | unsigned long t_end = millis(); |
dreschpe | 0:fedcef5319f5 | 428 | if (t_end > t_start) { |
dreschpe | 0:fedcef5319f5 | 429 | stage_time -= t_end - t_start; |
dreschpe | 0:fedcef5319f5 | 430 | } else { |
dreschpe | 0:fedcef5319f5 | 431 | stage_time -= t_start - t_end + 1 + ULONG_MAX; |
dreschpe | 0:fedcef5319f5 | 432 | } |
dreschpe | 0:fedcef5319f5 | 433 | } while (stage_time > 0); |
dreschpe | 0:fedcef5319f5 | 434 | } |
dreschpe | 0:fedcef5319f5 | 435 | |
dreschpe | 0:fedcef5319f5 | 436 | |
dreschpe | 0:fedcef5319f5 | 437 | #if defined(EPD_ENABLE_EXTRA_SRAM) |
dreschpe | 0:fedcef5319f5 | 438 | void EPD_Class::frame_sram_repeat(const uint8_t *image, EPD_stage stage) { |
dreschpe | 0:fedcef5319f5 | 439 | long stage_time = this->factored_stage_time; |
dreschpe | 0:fedcef5319f5 | 440 | do { |
dreschpe | 0:fedcef5319f5 | 441 | millis_start(); |
dreschpe | 0:fedcef5319f5 | 442 | unsigned long t_start = millis(); |
dreschpe | 0:fedcef5319f5 | 443 | this->frame_sram(image, stage); |
dreschpe | 0:fedcef5319f5 | 444 | unsigned long t_end = millis(); |
dreschpe | 0:fedcef5319f5 | 445 | if (t_end > t_start) { |
dreschpe | 0:fedcef5319f5 | 446 | stage_time -= t_end - t_start; |
dreschpe | 0:fedcef5319f5 | 447 | } else { |
dreschpe | 0:fedcef5319f5 | 448 | stage_time -= t_start - t_end + 1 + ULONG_MAX; |
dreschpe | 0:fedcef5319f5 | 449 | } |
dreschpe | 0:fedcef5319f5 | 450 | } while (stage_time > 0); |
dreschpe | 0:fedcef5319f5 | 451 | } |
dreschpe | 0:fedcef5319f5 | 452 | #endif |
dreschpe | 0:fedcef5319f5 | 453 | |
dreschpe | 0:fedcef5319f5 | 454 | |
dreschpe | 0:fedcef5319f5 | 455 | void EPD_Class::frame_cb_repeat(uint32_t address, EPD_reader *reader, EPD_stage stage) { |
dreschpe | 0:fedcef5319f5 | 456 | long stage_time = this->factored_stage_time; |
dreschpe | 0:fedcef5319f5 | 457 | do { |
dreschpe | 0:fedcef5319f5 | 458 | millis_start(); |
dreschpe | 0:fedcef5319f5 | 459 | unsigned long t_start = millis(); |
dreschpe | 0:fedcef5319f5 | 460 | this->frame_cb(address, reader, stage); |
dreschpe | 0:fedcef5319f5 | 461 | unsigned long t_end = millis(); |
dreschpe | 0:fedcef5319f5 | 462 | if (t_end > t_start) { |
dreschpe | 0:fedcef5319f5 | 463 | stage_time -= t_end - t_start; |
dreschpe | 0:fedcef5319f5 | 464 | } else { |
dreschpe | 0:fedcef5319f5 | 465 | stage_time -= t_start - t_end + 1 + ULONG_MAX; |
dreschpe | 0:fedcef5319f5 | 466 | } |
dreschpe | 0:fedcef5319f5 | 467 | } while (stage_time > 0); |
dreschpe | 0:fedcef5319f5 | 468 | } |
dreschpe | 0:fedcef5319f5 | 469 | |
dreschpe | 0:fedcef5319f5 | 470 | |
dreschpe | 0:fedcef5319f5 | 471 | void EPD_Class::line(uint16_t line, const uint8_t *data, uint8_t fixed_value, bool read_progmem, EPD_stage stage) { |
dreschpe | 0:fedcef5319f5 | 472 | // charge pump voltage levels |
dreschpe | 0:fedcef5319f5 | 473 | |
dreschpe | 0:fedcef5319f5 | 474 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 475 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
dreschpe | 0:fedcef5319f5 | 476 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 477 | SPI_send(this->EPD_Pin_EPD_CS, this->gate_source, this->gate_source_length); |
dreschpe | 0:fedcef5319f5 | 478 | |
dreschpe | 0:fedcef5319f5 | 479 | // send data |
dreschpe | 0:fedcef5319f5 | 480 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 481 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x0a), 2); |
dreschpe | 0:fedcef5319f5 | 482 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 483 | |
dreschpe | 0:fedcef5319f5 | 484 | // CS low |
dreschpe | 0:fedcef5319f5 | 485 | digitalWrite(this->EPD_Pin_EPD_CS, LOW); |
dreschpe | 0:fedcef5319f5 | 486 | SPI_put_wait(0x72, this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 487 | |
dreschpe | 0:fedcef5319f5 | 488 | // even pixels |
dreschpe | 0:fedcef5319f5 | 489 | for (uint16_t b = this->bytes_per_line; b > 0; --b) { |
dreschpe | 0:fedcef5319f5 | 490 | if (0 != data) { |
dreschpe | 0:fedcef5319f5 | 491 | |
dreschpe | 0:fedcef5319f5 | 492 | uint8_t pixels = data[b - 1] & 0xaa; |
dreschpe | 0:fedcef5319f5 | 493 | |
dreschpe | 0:fedcef5319f5 | 494 | switch(stage) { |
dreschpe | 0:fedcef5319f5 | 495 | case EPD_compensate: // B -> W, W -> B (Current Image) |
dreschpe | 0:fedcef5319f5 | 496 | pixels = 0xaa | ((pixels ^ 0xaa) >> 1); |
dreschpe | 0:fedcef5319f5 | 497 | break; |
dreschpe | 0:fedcef5319f5 | 498 | case EPD_white: // B -> N, W -> W (Current Image) |
dreschpe | 0:fedcef5319f5 | 499 | pixels = 0x55 + ((pixels ^ 0xaa) >> 1); |
dreschpe | 0:fedcef5319f5 | 500 | break; |
dreschpe | 0:fedcef5319f5 | 501 | case EPD_inverse: // B -> N, W -> B (New Image) |
dreschpe | 0:fedcef5319f5 | 502 | pixels = 0x55 | (pixels ^ 0xaa); |
dreschpe | 0:fedcef5319f5 | 503 | break; |
dreschpe | 0:fedcef5319f5 | 504 | case EPD_normal: // B -> B, W -> W (New Image) |
dreschpe | 0:fedcef5319f5 | 505 | pixels = 0xaa | (pixels >> 1); |
dreschpe | 0:fedcef5319f5 | 506 | break; |
dreschpe | 0:fedcef5319f5 | 507 | } |
dreschpe | 0:fedcef5319f5 | 508 | SPI_put_wait(pixels, this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 509 | } else { |
dreschpe | 0:fedcef5319f5 | 510 | SPI_put_wait(fixed_value, this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 511 | } } |
dreschpe | 0:fedcef5319f5 | 512 | |
dreschpe | 0:fedcef5319f5 | 513 | // scan line |
dreschpe | 0:fedcef5319f5 | 514 | for (uint16_t b = 0; b < this->bytes_per_scan; ++b) { |
dreschpe | 0:fedcef5319f5 | 515 | if (line / 4 == b) { |
dreschpe | 0:fedcef5319f5 | 516 | SPI_put_wait(0xc0 >> (2 * (line & 0x03)), this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 517 | } else { |
dreschpe | 0:fedcef5319f5 | 518 | SPI_put_wait(0x00, this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 519 | } |
dreschpe | 0:fedcef5319f5 | 520 | } |
dreschpe | 0:fedcef5319f5 | 521 | |
dreschpe | 0:fedcef5319f5 | 522 | // odd pixels |
dreschpe | 0:fedcef5319f5 | 523 | for (uint16_t b = 0; b < this->bytes_per_line; ++b) { |
dreschpe | 0:fedcef5319f5 | 524 | if (0 != data) { |
dreschpe | 0:fedcef5319f5 | 525 | |
dreschpe | 0:fedcef5319f5 | 526 | uint8_t pixels = data[b] & 0x55; |
dreschpe | 0:fedcef5319f5 | 527 | |
dreschpe | 0:fedcef5319f5 | 528 | switch(stage) { |
dreschpe | 0:fedcef5319f5 | 529 | case EPD_compensate: // B -> W, W -> B (Current Image) |
dreschpe | 0:fedcef5319f5 | 530 | pixels = 0xaa | (pixels ^ 0x55); |
dreschpe | 0:fedcef5319f5 | 531 | break; |
dreschpe | 0:fedcef5319f5 | 532 | case EPD_white: // B -> N, W -> W (Current Image) |
dreschpe | 0:fedcef5319f5 | 533 | pixels = 0x55 + (pixels ^ 0x55); |
dreschpe | 0:fedcef5319f5 | 534 | break; |
dreschpe | 0:fedcef5319f5 | 535 | case EPD_inverse: // B -> N, W -> B (New Image) |
dreschpe | 0:fedcef5319f5 | 536 | pixels = 0x55 | ((pixels ^ 0x55) << 1); |
dreschpe | 0:fedcef5319f5 | 537 | break; |
dreschpe | 0:fedcef5319f5 | 538 | case EPD_normal: // B -> B, W -> W (New Image) |
dreschpe | 0:fedcef5319f5 | 539 | pixels = 0xaa | pixels; |
dreschpe | 0:fedcef5319f5 | 540 | break; |
dreschpe | 0:fedcef5319f5 | 541 | } |
dreschpe | 0:fedcef5319f5 | 542 | uint8_t p1 = (pixels >> 6) & 0x03; |
dreschpe | 0:fedcef5319f5 | 543 | uint8_t p2 = (pixels >> 4) & 0x03; |
dreschpe | 0:fedcef5319f5 | 544 | uint8_t p3 = (pixels >> 2) & 0x03; |
dreschpe | 0:fedcef5319f5 | 545 | uint8_t p4 = (pixels >> 0) & 0x03; |
dreschpe | 0:fedcef5319f5 | 546 | pixels = (p1 << 0) | (p2 << 2) | (p3 << 4) | (p4 << 6); |
dreschpe | 0:fedcef5319f5 | 547 | SPI_put_wait(pixels, this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 548 | } else { |
dreschpe | 0:fedcef5319f5 | 549 | SPI_put_wait(fixed_value, this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 550 | } |
dreschpe | 0:fedcef5319f5 | 551 | } |
dreschpe | 0:fedcef5319f5 | 552 | |
dreschpe | 0:fedcef5319f5 | 553 | if (this->filler) { |
dreschpe | 0:fedcef5319f5 | 554 | SPI_put_wait(0x00, this->EPD_Pin_BUSY); |
dreschpe | 0:fedcef5319f5 | 555 | } |
dreschpe | 0:fedcef5319f5 | 556 | |
dreschpe | 0:fedcef5319f5 | 557 | // CS high |
dreschpe | 0:fedcef5319f5 | 558 | digitalWrite(this->EPD_Pin_EPD_CS, HIGH); |
dreschpe | 0:fedcef5319f5 | 559 | |
dreschpe | 0:fedcef5319f5 | 560 | // output data to panel |
dreschpe | 0:fedcef5319f5 | 561 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 562 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x02), 2); |
dreschpe | 0:fedcef5319f5 | 563 | Delay_us(10); |
dreschpe | 0:fedcef5319f5 | 564 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x2f), 2); |
dreschpe | 0:fedcef5319f5 | 565 | } |
dreschpe | 0:fedcef5319f5 | 566 | |
dreschpe | 0:fedcef5319f5 | 567 | |
dreschpe | 0:fedcef5319f5 | 568 | void EPD_Class::SPI_put(uint8_t c) { |
dreschpe | 0:fedcef5319f5 | 569 | |
dreschpe | 0:fedcef5319f5 | 570 | spi_.write(c); |
dreschpe | 0:fedcef5319f5 | 571 | //spi_.fastWrite(c); |
dreschpe | 0:fedcef5319f5 | 572 | |
dreschpe | 0:fedcef5319f5 | 573 | |
dreschpe | 0:fedcef5319f5 | 574 | } |
dreschpe | 0:fedcef5319f5 | 575 | |
dreschpe | 0:fedcef5319f5 | 576 | |
dreschpe | 0:fedcef5319f5 | 577 | |
dreschpe | 0:fedcef5319f5 | 578 | void EPD_Class::SPI_put_wait(uint8_t c, DigitalIn busy_pin) { |
dreschpe | 0:fedcef5319f5 | 579 | |
dreschpe | 0:fedcef5319f5 | 580 | SPI_put(c); |
dreschpe | 0:fedcef5319f5 | 581 | |
dreschpe | 0:fedcef5319f5 | 582 | // wait for COG ready |
dreschpe | 0:fedcef5319f5 | 583 | while (HIGH == digitalRead(busy_pin)) { |
dreschpe | 0:fedcef5319f5 | 584 | } |
dreschpe | 0:fedcef5319f5 | 585 | } |
dreschpe | 0:fedcef5319f5 | 586 | |
dreschpe | 0:fedcef5319f5 | 587 | |
dreschpe | 0:fedcef5319f5 | 588 | void EPD_Class::SPI_send(DigitalOut cs_pin, const uint8_t *buffer, uint16_t length) { |
dreschpe | 0:fedcef5319f5 | 589 | |
dreschpe | 0:fedcef5319f5 | 590 | // CS low |
dreschpe | 0:fedcef5319f5 | 591 | digitalWrite(cs_pin, LOW); |
dreschpe | 0:fedcef5319f5 | 592 | |
dreschpe | 0:fedcef5319f5 | 593 | // send all data |
dreschpe | 0:fedcef5319f5 | 594 | for (uint16_t i = 0; i < length; ++i) { |
dreschpe | 3:1371614703cd | 595 | spi_.write(*buffer++); |
dreschpe | 0:fedcef5319f5 | 596 | } |
dreschpe | 0:fedcef5319f5 | 597 | |
dreschpe | 0:fedcef5319f5 | 598 | // CS high |
dreschpe | 0:fedcef5319f5 | 599 | digitalWrite(cs_pin, HIGH); |
dreschpe | 0:fedcef5319f5 | 600 | } |
dreschpe | 0:fedcef5319f5 | 601 | |
dreschpe | 0:fedcef5319f5 | 602 | |
dreschpe | 0:fedcef5319f5 | 603 | //static void PWM_start(int pin) { |
dreschpe | 0:fedcef5319f5 | 604 | // analogWrite(pin, 128); // 50% duty cycle |
dreschpe | 0:fedcef5319f5 | 605 | //} |
dreschpe | 0:fedcef5319f5 | 606 | |
dreschpe | 0:fedcef5319f5 | 607 | |
dreschpe | 0:fedcef5319f5 | 608 | //static void PWM_stop(int pin) { |
dreschpe | 0:fedcef5319f5 | 609 | // analogWrite(pin, 0); |
dreschpe | 0:fedcef5319f5 | 610 | //} |