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